diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2022-02-20 17:00:00 +0200 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2022-02-20 17:00:00 +0200 |
commit | cebc848472629d63cf633973a34df0bc9858efc6 (patch) | |
tree | ff254cf90ed20aeaaf99371361a5f81ea5224462 /src | |
parent | 2e756e225a6c2b7972cfd9914ff935c290aa3b68 (diff) |
Window-specific refresh
When updating, mark pending refresh per window so one doesn't have to draw all of them at once.
Diffstat (limited to 'src')
-rw-r--r-- | src/app.c | 11 | ||||
-rw-r--r-- | src/ui/root.c | 1 | ||||
-rw-r--r-- | src/ui/window.c | 11 | ||||
-rw-r--r-- | src/ui/window.h | 3 |
4 files changed, 21 insertions, 5 deletions
@@ -1761,6 +1761,9 @@ void refresh_App(void) { | |||
1761 | /* Draw each window. */ | 1761 | /* Draw each window. */ |
1762 | iConstForEach(PtrArray, j, &windows) { | 1762 | iConstForEach(PtrArray, j, &windows) { |
1763 | iWindow *win = j.ptr; | 1763 | iWindow *win = j.ptr; |
1764 | if (!d->warmupFrames && !exchange_Atomic(&win->isRefreshPending, iFalse)) { | ||
1765 | continue; /* No need to draw this window. */ | ||
1766 | } | ||
1764 | setCurrent_Window(win); | 1767 | setCurrent_Window(win); |
1765 | switch (win->type) { | 1768 | switch (win->type) { |
1766 | case main_WindowType: { | 1769 | case main_WindowType: { |
@@ -1775,6 +1778,7 @@ void refresh_App(void) { | |||
1775 | draw_Window(win); | 1778 | draw_Window(win); |
1776 | break; | 1779 | break; |
1777 | } | 1780 | } |
1781 | win->frameCount++; | ||
1778 | } | 1782 | } |
1779 | } | 1783 | } |
1780 | if (d->warmupFrames > 0) { | 1784 | if (d->warmupFrames > 0) { |
@@ -1847,7 +1851,12 @@ void postRefresh_App(void) { | |||
1847 | #if defined (LAGRANGE_ENABLE_IDLE_SLEEP) | 1851 | #if defined (LAGRANGE_ENABLE_IDLE_SLEEP) |
1848 | d->isIdling = iFalse; | 1852 | d->isIdling = iFalse; |
1849 | #endif | 1853 | #endif |
1850 | const iBool wasPending = exchange_Atomic(&d->pendingRefresh, iTrue); | 1854 | iAtomicInt *pendingWindow = (get_Window() ? &get_Window()->isRefreshPending |
1855 | : NULL); | ||
1856 | iBool wasPending = exchange_Atomic(&d->pendingRefresh, iTrue); | ||
1857 | if (pendingWindow) { | ||
1858 | wasPending |= exchange_Atomic(pendingWindow, iTrue); | ||
1859 | } | ||
1851 | if (!wasPending) { | 1860 | if (!wasPending) { |
1852 | SDL_Event ev = { .type = SDL_USEREVENT }; | 1861 | SDL_Event ev = { .type = SDL_USEREVENT }; |
1853 | ev.user.code = refresh_UserEventCode; | 1862 | ev.user.code = refresh_UserEventCode; |
diff --git a/src/ui/root.c b/src/ui/root.c index 1130cf67..32ecc6aa 100644 --- a/src/ui/root.c +++ b/src/ui/root.c | |||
@@ -58,6 +58,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | |||
58 | static const iMenuItem navMenuItems_[] = { | 58 | static const iMenuItem navMenuItems_[] = { |
59 | { openWindow_Icon " ${menu.newwindow}", SDLK_n, KMOD_PRIMARY, "window.new" }, | 59 | { openWindow_Icon " ${menu.newwindow}", SDLK_n, KMOD_PRIMARY, "window.new" }, |
60 | { add_Icon " ${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new" }, | 60 | { add_Icon " ${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new" }, |
61 | { close_Icon " ${menu.closetab}", SDLK_w, KMOD_PRIMARY, "tabs.close" }, | ||
61 | { "${menu.openlocation}", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, | 62 | { "${menu.openlocation}", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, |
62 | { "---" }, | 63 | { "---" }, |
63 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" }, | 64 | { download_Icon " " saveToDownloads_Label, SDLK_s, KMOD_PRIMARY, "document.save" }, |
diff --git a/src/ui/window.c b/src/ui/window.c index 9d372019..90588ccf 100644 --- a/src/ui/window.c +++ b/src/ui/window.c | |||
@@ -471,16 +471,17 @@ void init_Window(iWindow *d, enum iWindowType type, iRect rect, uint32_t flags) | |||
471 | d->isMinimized = iFalse; | 471 | d->isMinimized = iFalse; |
472 | d->isInvalidated = iFalse; /* set when posting event, to avoid repeated events */ | 472 | d->isInvalidated = iFalse; /* set when posting event, to avoid repeated events */ |
473 | d->isMouseInside = iTrue; | 473 | d->isMouseInside = iTrue; |
474 | set_Atomic(&d->isRefreshPending, iTrue); | ||
474 | d->ignoreClick = iFalse; | 475 | d->ignoreClick = iFalse; |
475 | d->focusGainedAt = SDL_GetTicks(); | 476 | d->focusGainedAt = SDL_GetTicks(); |
476 | d->presentTime = 0.0; | ||
477 | d->frameTime = SDL_GetTicks(); | 477 | d->frameTime = SDL_GetTicks(); |
478 | d->keyRoot = NULL; | 478 | d->keyRoot = NULL; |
479 | d->borderShadow = NULL; | 479 | d->borderShadow = NULL; |
480 | d->frameCount = 0; | ||
480 | iZap(d->roots); | 481 | iZap(d->roots); |
481 | iZap(d->cursors); | 482 | iZap(d->cursors); |
482 | create_Window_(d, rect, flags); | 483 | create_Window_(d, rect, flags); |
483 | /* No luck, maybe software only? This should always work as long as there is a display. */ | 484 | /* No luck, maybe software only? This should always work as long as there is a display. */ |
484 | // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); | 485 | // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); |
485 | // flags &= ~SDL_WINDOW_OPENGL; | 486 | // flags &= ~SDL_WINDOW_OPENGL; |
486 | // start_PerfTimer(create_Window_); | 487 | // start_PerfTimer(create_Window_); |
@@ -1430,7 +1431,11 @@ void draw_MainWindow(iMainWindow *d) { | |||
1430 | } | 1431 | } |
1431 | setCurrent_Root(NULL); | 1432 | setCurrent_Root(NULL); |
1432 | #if !defined (NDEBUG) | 1433 | #if !defined (NDEBUG) |
1433 | draw_Text(uiLabelBold_FontId, safeRect_Root(w->roots[0]).pos, red_ColorId, "%d", drawCount_); | 1434 | draw_Text(uiLabelBold_FontId, |
1435 | safeRect_Root(w->roots[0]).pos, | ||
1436 | d->base.frameCount & 1 ? red_ColorId : white_ColorId, | ||
1437 | "%d", | ||
1438 | drawCount_); | ||
1434 | drawCount_ = 0; | 1439 | drawCount_ = 0; |
1435 | #endif | 1440 | #endif |
1436 | } | 1441 | } |
diff --git a/src/ui/window.h b/src/ui/window.h index c3c34e1b..4df1be1e 100644 --- a/src/ui/window.h +++ b/src/ui/window.h | |||
@@ -86,6 +86,7 @@ struct Impl_Window { | |||
86 | iBool isMinimized; | 86 | iBool isMinimized; |
87 | iBool isMouseInside; | 87 | iBool isMouseInside; |
88 | iBool isInvalidated; | 88 | iBool isInvalidated; |
89 | iAtomicInt isRefreshPending; | ||
89 | iBool ignoreClick; | 90 | iBool ignoreClick; |
90 | uint32_t focusGainedAt; | 91 | uint32_t focusGainedAt; |
91 | SDL_Renderer *render; | 92 | SDL_Renderer *render; |
@@ -98,13 +99,13 @@ struct Impl_Window { | |||
98 | float displayScale; /* DPI-based scaling factor of current display, affects uiScale only */ | 99 | float displayScale; /* DPI-based scaling factor of current display, affects uiScale only */ |
99 | float uiScale; | 100 | float uiScale; |
100 | uint32_t frameTime; | 101 | uint32_t frameTime; |
101 | double presentTime; | ||
102 | SDL_Cursor * cursors[SDL_NUM_SYSTEM_CURSORS]; | 102 | SDL_Cursor * cursors[SDL_NUM_SYSTEM_CURSORS]; |
103 | SDL_Cursor * pendingCursor; | 103 | SDL_Cursor * pendingCursor; |
104 | iRoot * roots[2]; /* root widget and UI state; second one is for split mode */ | 104 | iRoot * roots[2]; /* root widget and UI state; second one is for split mode */ |
105 | iRoot * keyRoot; /* root that has the current keyboard input focus */ | 105 | iRoot * keyRoot; /* root that has the current keyboard input focus */ |
106 | SDL_Texture * borderShadow; | 106 | SDL_Texture * borderShadow; |
107 | iText * text; | 107 | iText * text; |
108 | unsigned int frameCount; | ||
108 | }; | 109 | }; |
109 | 110 | ||
110 | struct Impl_MainWindow { | 111 | struct Impl_MainWindow { |