From cebc848472629d63cf633973a34df0bc9858efc6 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sun, 20 Feb 2022 17:00:00 +0200 Subject: Window-specific refresh When updating, mark pending refresh per window so one doesn't have to draw all of them at once. --- src/app.c | 11 ++++++++++- src/ui/root.c | 1 + src/ui/window.c | 11 ++++++++--- src/ui/window.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/app.c b/src/app.c index 543467ef..55f1add7 100644 --- a/src/app.c +++ b/src/app.c @@ -1761,6 +1761,9 @@ void refresh_App(void) { /* Draw each window. */ iConstForEach(PtrArray, j, &windows) { iWindow *win = j.ptr; + if (!d->warmupFrames && !exchange_Atomic(&win->isRefreshPending, iFalse)) { + continue; /* No need to draw this window. */ + } setCurrent_Window(win); switch (win->type) { case main_WindowType: { @@ -1775,6 +1778,7 @@ void refresh_App(void) { draw_Window(win); break; } + win->frameCount++; } } if (d->warmupFrames > 0) { @@ -1847,7 +1851,12 @@ void postRefresh_App(void) { #if defined (LAGRANGE_ENABLE_IDLE_SLEEP) d->isIdling = iFalse; #endif - const iBool wasPending = exchange_Atomic(&d->pendingRefresh, iTrue); + iAtomicInt *pendingWindow = (get_Window() ? &get_Window()->isRefreshPending + : NULL); + iBool wasPending = exchange_Atomic(&d->pendingRefresh, iTrue); + if (pendingWindow) { + wasPending |= exchange_Atomic(pendingWindow, iTrue); + } if (!wasPending) { SDL_Event ev = { .type = SDL_USEREVENT }; 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. */ static const iMenuItem navMenuItems_[] = { { openWindow_Icon " ${menu.newwindow}", SDLK_n, KMOD_PRIMARY, "window.new" }, { add_Icon " ${menu.newtab}", SDLK_t, KMOD_PRIMARY, "tabs.new" }, + { close_Icon " ${menu.closetab}", SDLK_w, KMOD_PRIMARY, "tabs.close" }, { "${menu.openlocation}", SDLK_l, KMOD_PRIMARY, "navigate.focus" }, { "---" }, { 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) d->isMinimized = iFalse; d->isInvalidated = iFalse; /* set when posting event, to avoid repeated events */ d->isMouseInside = iTrue; + set_Atomic(&d->isRefreshPending, iTrue); d->ignoreClick = iFalse; d->focusGainedAt = SDL_GetTicks(); - d->presentTime = 0.0; d->frameTime = SDL_GetTicks(); d->keyRoot = NULL; d->borderShadow = NULL; + d->frameCount = 0; iZap(d->roots); iZap(d->cursors); create_Window_(d, rect, flags); - /* No luck, maybe software only? This should always work as long as there is a display. */ + /* No luck, maybe software only? This should always work as long as there is a display. */ // SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); // flags &= ~SDL_WINDOW_OPENGL; // start_PerfTimer(create_Window_); @@ -1430,7 +1431,11 @@ void draw_MainWindow(iMainWindow *d) { } setCurrent_Root(NULL); #if !defined (NDEBUG) - draw_Text(uiLabelBold_FontId, safeRect_Root(w->roots[0]).pos, red_ColorId, "%d", drawCount_); + draw_Text(uiLabelBold_FontId, + safeRect_Root(w->roots[0]).pos, + d->base.frameCount & 1 ? red_ColorId : white_ColorId, + "%d", + drawCount_); drawCount_ = 0; #endif } 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 { iBool isMinimized; iBool isMouseInside; iBool isInvalidated; + iAtomicInt isRefreshPending; iBool ignoreClick; uint32_t focusGainedAt; SDL_Renderer *render; @@ -98,13 +99,13 @@ struct Impl_Window { float displayScale; /* DPI-based scaling factor of current display, affects uiScale only */ float uiScale; uint32_t frameTime; - double presentTime; SDL_Cursor * cursors[SDL_NUM_SYSTEM_CURSORS]; SDL_Cursor * pendingCursor; iRoot * roots[2]; /* root widget and UI state; second one is for split mode */ iRoot * keyRoot; /* root that has the current keyboard input focus */ SDL_Texture * borderShadow; iText * text; + unsigned int frameCount; }; struct Impl_MainWindow { -- cgit v1.2.3