From c302353bd922f4518d16b5f323e796b7ed3e45ae Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Tue, 26 Aug 2025 12:03:09 +0300 Subject: [PATCH] Try a different cache refresh on lag strategy --- .../com.infinipaint.infinipaint.metainfo.xml | 2 +- src/DrawingProgram/DrawingProgram.cpp | 30 ++++++++++++------- src/DrawingProgram/DrawingProgram.hpp | 3 ++ src/DrawingProgram/DrawingProgramCache.cpp | 3 -- src/DrawingProgram/DrawingProgramCache.hpp | 3 +- src/MainProgram.hpp | 2 ++ src/main.cpp | 3 ++ 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/linuxinstall/com.infinipaint.infinipaint.metainfo.xml b/linuxinstall/com.infinipaint.infinipaint.metainfo.xml index 62b7e8b..d8c6f61 100644 --- a/linuxinstall/com.infinipaint.infinipaint.metainfo.xml +++ b/linuxinstall/com.infinipaint.infinipaint.metainfo.xml @@ -8,7 +8,7 @@ MIT - #8ff7ea + #83b9b2 #325652 diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 57a4c39..f90b612 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -233,6 +233,25 @@ void DrawingProgram::tool_options_gui() { } void DrawingProgram::update() { + if(world.main.window.lastFrameTime > std::chrono::milliseconds(33)) { // Around 30FPS + if(!badFrametimeTimePoint) + badFrametimeTimePoint = std::chrono::steady_clock::now(); + else if(unorderedObjectsExistTimePoint && std::chrono::steady_clock::now() - badFrametimeTimePoint.value() >= std::chrono::seconds(5) && std::chrono::steady_clock::now() - unorderedObjectsExistTimePoint.value() >= std::chrono::seconds(5)) { + force_rebuild_cache(); + unorderedObjectsExistTimePoint = std::nullopt; + badFrametimeTimePoint = std::nullopt; + } + } + else + badFrametimeTimePoint = std::nullopt; + + if(compCache.get_unsorted_component_list().empty()) { + unorderedObjectsExistTimePoint = std::nullopt; + } + else if(!unorderedObjectsExistTimePoint) { + unorderedObjectsExistTimePoint = std::chrono::steady_clock::now(); + } + if(drawTool->get_type() == DrawingProgramToolType::BRUSH && world.main.input.pen.isEraser && !temporaryEraser) { switch_to_tool(DrawingProgramToolType::ERASER); temporaryEraser = true; @@ -569,8 +588,6 @@ void DrawingProgram::write_to_file(cereal::PortableBinaryOutputArchive& a) { } void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) { - std::chrono::microseconds timeToDrawUnsortedComponents(0); - if(drawData.dontUseDrawProgCache) { parallel_loop_all_components([&](auto& c) { c->obj->calculate_draw_transform(drawData); @@ -584,9 +601,7 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) { canvas->saveLayer(nullptr, nullptr); canvas->clear(SkColor4f{0.0f, 0.0f, 0.0f, 0.0f}); compCache.refresh_all_draw_cache(drawData); - compCache.draw_components_to_canvas(canvas, drawData, { - .timeToDrawUnsortedComponents = &timeToDrawUnsortedComponents - }); + compCache.draw_components_to_canvas(canvas, drawData, {}); canvas->saveLayer(nullptr, nullptr); selection.draw_components(canvas, drawData); canvas->restore(); @@ -595,11 +610,6 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) { } drawTool->draw(canvas, drawData); - - // 10ms is an arbitrary value. If drawing only the unsorted components takes more than that amount of time, - // they're definitely causing lag and must be sorted so that they can be cached - if(timeToDrawUnsortedComponents >= std::chrono::microseconds(10000)) - force_rebuild_cache(); } Vector4f* DrawingProgram::get_foreground_color_ptr() { diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index f405df0..971332c 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -56,6 +56,9 @@ class DrawingProgram { void clear_draw_cache(); private: + std::optional badFrametimeTimePoint; + std::optional unorderedObjectsExistTimePoint; + void client_erase_set(std::unordered_set erasedComponents); // The set might be modified while this is being called, so dont pass by reference void check_delayed_update_timers(); diff --git a/src/DrawingProgram/DrawingProgramCache.cpp b/src/DrawingProgram/DrawingProgramCache.cpp index 6634efe..3f3315c 100644 --- a/src/DrawingProgram/DrawingProgramCache.cpp +++ b/src/DrawingProgram/DrawingProgramCache.cpp @@ -454,9 +454,6 @@ void DrawingProgramCache::draw_components_to_canvas(SkCanvas* canvas, const Draw if(optData.lastDrawnComponentPlacement) *optData.lastDrawnComponentPlacement = lastComponentDrawn; - - if(optData.timeToDrawUnsortedComponents) - *optData.timeToDrawUnsortedComponents = unsortedCompDrawTime; } void DrawingProgramCache::draw_cache_image_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::shared_ptr& bvhNode) { diff --git a/src/DrawingProgram/DrawingProgramCache.hpp b/src/DrawingProgram/DrawingProgramCache.hpp index 641e1e9..dffae37 100644 --- a/src/DrawingProgram/DrawingProgramCache.hpp +++ b/src/DrawingProgram/DrawingProgramCache.hpp @@ -35,7 +35,7 @@ class DrawingProgramCache { ~DrawingProgramCache(); static constexpr size_t MINIMUM_COMPONENTS_TO_START_REBUILD = 1000; - static constexpr size_t MAXIMUM_COMPONENTS_IN_SINGLE_NODE = 100; + static constexpr size_t MAXIMUM_COMPONENTS_IN_SINGLE_NODE = 50; bool check_if_rebuild_should_occur(); void test_rebuild(const std::vector& comps, bool force = false); @@ -60,7 +60,6 @@ class DrawingProgramCache { struct DrawComponentsToCanvasOptionalData { uint64_t* lastDrawnComponentPlacement = nullptr; std::optional> drawBounds; - std::chrono::microseconds* timeToDrawUnsortedComponents = nullptr; }; void draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, DrawComponentsToCanvasOptionalData optData); diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index d1fed38..3f5833f 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -1,6 +1,7 @@ #pragma once #include "DrawData.hpp" #include "GridManager.hpp" +#include #include #include "InputManager.hpp" #include "FontData.hpp" @@ -31,6 +32,7 @@ class MainProgram { Vector3f userColor; struct Window { + std::chrono::steady_clock::duration lastFrameTime = std::chrono::milliseconds(16); Vector2i size = {-1, -1}; Vector2i pos = {-1, -1}; Vector2i writtenSize = {-1, -1}; diff --git a/src/main.cpp b/src/main.cpp index 7c5a6e2..41cc6bf 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -520,6 +520,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { } SDL_AppResult SDL_AppIterate(void *appstate) { + std::chrono::steady_clock::time_point frameTimeStart = std::chrono::steady_clock::now(); MainStruct& mS = *((MainStruct*)appstate); #ifdef NDEBUG @@ -584,6 +585,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) { } #endif + mS.m->window.lastFrameTime = std::chrono::steady_clock::now() - frameTimeStart; + return SDL_APP_CONTINUE; }