diff --git a/client/include/app.h b/client/include/app.h index ca84d576..9066d6a8 100644 --- a/client/include/app.h +++ b/client/include/app.h @@ -81,7 +81,16 @@ void app_glSwapBuffers(void); #endif void app_registerOverlay(const struct LG_OverlayOps * ops, void * params); + +/** + * render the overlay + * returns: + * -1 for no overlay + * 0 for full output damage + * >0 number of rects written into rects + */ int app_renderOverlay(struct Rect * rects, int maxRects); + void app_freeOverlays(void); struct OverlayGraph; diff --git a/client/include/interface/overlay.h b/client/include/interface/overlay.h index 4f9bb682..7377c4b1 100644 --- a/client/include/interface/overlay.h +++ b/client/include/interface/overlay.h @@ -46,23 +46,21 @@ struct LG_OverlayOps /* general state flags, may be changed at any time */ enum LG_OverlayFlags flags; - /* get the number of windows that will be rendered when `render` is called - * - *`interactive` is true if the application is currently in overlay interaction - * mode - */ - int (*getWindowCount)(void * udata, bool interactive); - /* perform the actual drawing/rendering * * `interactive` is true if the application is currently in overlay interaction * mode. * - * The caller provides `windowRects` to be populated by the callee and is sized - * according to the return value of `getWindowCount`. Note, `windowRects` may - * be NULL if the caller does not want this information. + * `windowRects` is an array of window rects that were rendered using screen + * coordinates. Will be `NULL` if the information is not required. + * + * `maxRects` is the length of `windowRects`, or 0 if `windowRects` is `NULL` + * + * returns the number of rects written to `windowRects`, or -1 if there is not + * enough room left. */ - void (*render)(void * udata, bool interactive, struct Rect windowRects[]); + int (*render)(void * udata, bool interactive, struct Rect * windowRects, + int maxRects); /* TODO: add load/save settings capabillity */ }; @@ -71,7 +69,6 @@ struct LG_OverlayOps assert((x)->name ); \ assert((x)->init ); \ assert((x)->free ); \ - assert((x)->getWindowCount); \ assert((x)->render ); #endif diff --git a/client/src/app.c b/client/src/app.c index 94f98cad..ff425d59 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -628,7 +628,6 @@ struct Overlay { const struct LG_OverlayOps * ops; void * udata; - int windowCount; }; void app_registerOverlay(const struct LG_OverlayOps * ops, void * params) @@ -650,43 +649,40 @@ void app_registerOverlay(const struct LG_OverlayOps * ops, void * params) int app_renderOverlay(struct Rect * rects, int maxRects) { - int windowCount = 0; + int totalRects = 0; + bool totalDamage = false; struct Overlay * overlay; - // get the total window count - for (ll_reset(g_state.overlays); - ll_walk(g_state.overlays, (void **)&overlay); ) - { - overlay->windowCount = overlay->ops->getWindowCount(overlay->udata, false); - windowCount += overlay->windowCount; - } - - // return -1 if there are no windows to render - if (windowCount == 0) - return -1; - - if (windowCount > maxRects) - { - rects = NULL; - windowCount = 0; - } + igNewFrame(); // render the overlays - igNewFrame(); for (ll_reset(g_state.overlays); ll_walk(g_state.overlays, (void **)&overlay); ) { - if (overlay->windowCount == 0) + const int written = + overlay->ops->render(overlay->udata, false, rects, maxRects); + + if (!totalDamage) continue; - overlay->ops->render(overlay->udata, false, rects); - if (rects) - rects += overlay->windowCount; + if (written == -1) + { + // out of rects, return that the entire surface is damaged + totalDamage = true; + rects = NULL; + maxRects = 0; + totalRects = 0; + } + else + { + maxRects -= written; + rects += written; + } } igRender(); - return windowCount; + return totalDamage ? -1 : totalRects; } void app_freeOverlays(void) diff --git a/client/src/overlay/fps.c b/client/src/overlay/fps.c index dce1085f..aba099ef 100644 --- a/client/src/overlay/fps.c +++ b/client/src/overlay/fps.c @@ -32,14 +32,13 @@ static void fps_free(void * udata) { } -static int fps_getWindowCount(void * udata, bool interactive) +static int fps_render(void * udata, bool interactive, struct Rect * windowRects, + int maxRects) { - return g_state.showFPS ? 1 : 0; -} + if (!g_state.showFPS) + return 0; -static void fps_render(void * udata, bool interactive, struct Rect * windowRects) -{ - const ImVec2 pos = {0.0f, 0.0f}; + ImVec2 pos = {0.0f, 0.0f}; igSetNextWindowBgAlpha(0.6f); igSetNextWindowPos(pos, 0, pos); @@ -55,18 +54,21 @@ static void fps_render(void * udata, bool interactive, struct Rect * windowRects atomic_load_explicit(&g_state.fps, memory_order_relaxed), atomic_load_explicit(&g_state.ups, memory_order_relaxed)); - if (windowRects) + if (maxRects == 0) { - ImVec2 pos, size; - igGetWindowPos(&pos); - igGetWindowSize(&size); - windowRects[0].x = pos.x; - windowRects[0].y = pos.y; - windowRects[0].w = size.x; - windowRects[0].h = size.y; + return -1; + igEnd(); } + ImVec2 size; + igGetWindowPos(&pos); + igGetWindowSize(&size); + windowRects[0].x = pos.x; + windowRects[0].y = pos.y; + windowRects[0].w = size.x; + windowRects[0].h = size.y; igEnd(); + return 1; } struct LG_OverlayOps LGOverlayFPS = @@ -74,6 +76,5 @@ struct LG_OverlayOps LGOverlayFPS = .name = "FPS", .init = fps_init, .free = fps_free, - .getWindowCount = fps_getWindowCount, .render = fps_render }; diff --git a/client/src/overlay/graphs.c b/client/src/overlay/graphs.c index 25479620..cd68b3b0 100644 --- a/client/src/overlay/graphs.c +++ b/client/src/overlay/graphs.c @@ -54,11 +54,6 @@ static void graphs_free(void * udata) ll_free(gs.graphs); } -static int graphs_getWindowCount(void * udata, bool interactive) -{ - return g_state.showTiming ? 1 : 0; -} - struct BufferMetrics { float min; @@ -91,9 +86,13 @@ static bool rbCalcMetrics(int index, void * value_, void * udata_) return true; } -static void graphs_render(void * udata, bool interactive, struct Rect * windowRects) +static int graphs_render(void * udata, bool interactive, + struct Rect * windowRects, int maxRects) { - const ImVec2 pos = {0.0f, 0.0f}; + if (!g_state.showTiming) + return 0; + + ImVec2 pos = {0.0f, 0.0f}; igSetNextWindowBgAlpha(0.4f); igSetNextWindowPos(pos, 0, pos); @@ -139,18 +138,22 @@ static void graphs_render(void * udata, bool interactive, struct Rect * windowRe sizeof(float)); }; - if (windowRects) + if (maxRects == 0) { - ImVec2 pos, size; - igGetWindowPos(&pos); - igGetWindowSize(&size); - windowRects[0].x = pos.x; - windowRects[0].y = pos.y; - windowRects[0].w = size.x; - windowRects[0].h = size.y; + igEnd(); + return -1; } + ImVec2 size; + igGetWindowPos(&pos); + igGetWindowSize(&size); + windowRects[0].x = pos.x; + windowRects[0].y = pos.y; + windowRects[0].w = size.x; + windowRects[0].h = size.y; + igEnd(); + return 1; } struct LG_OverlayOps LGOverlayGraphs = @@ -158,7 +161,6 @@ struct LG_OverlayOps LGOverlayGraphs = .name = "Graphs", .init = graphs_init, .free = graphs_free, - .getWindowCount = graphs_getWindowCount, .render = graphs_render };