diff --git a/src/DrawComponents/DrawComponent.hpp b/src/DrawComponents/DrawComponent.hpp index 2c5c42b..09f4e81 100644 --- a/src/DrawComponents/DrawComponent.hpp +++ b/src/DrawComponents/DrawComponent.hpp @@ -43,7 +43,7 @@ class DrawComponent { float rotation; float scale; } transformData; - bool shouldDraw = true; + bool shouldDraw = false; unsigned mipmapLevel = 0; } drawSetupData; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 813792a..d74696e 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -617,31 +617,48 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) { } void DrawingProgram::draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, bool dontUseCache) { - for(auto& c : components.client_list()) - c->obj->drawSetupData.shouldDraw = false; - std::vector> cachedNodesToDraw; + std::vector uncachedCompsToDraw; + size_t numOfUncachedComponentsToDraw = 0; + + const size_t maxUncachedCompsToUseAltStrategy = 1000; + const size_t minCompsToUseAltStrategy = 100000; compCache.traverse_bvh_run_function(drawData.cam.viewingAreaGenerousCollider, [&](const std::shared_ptr& node, const std::vector& comps) { if(!dontUseCache && node && node->drawCache && node->coords.inverseScale <= drawData.cam.c.inverseScale) { cachedNodesToDraw.emplace_back(node); return false; } + for(auto& c : comps) c->obj->calculate_draw_transform(drawData); + + if(numOfUncachedComponentsToDraw < minCompsToUseAltStrategy && components.client_list().size() > maxUncachedCompsToUseAltStrategy) { + uncachedCompsToDraw.insert(uncachedCompsToDraw.end(), comps.begin(), comps.end()); + numOfUncachedComponentsToDraw += comps.size(); + } + return true; }); - for(uint64_t i = 0; i < components.client_list().size(); i++) { - auto& c = components.client_list()[i]; - c->obj->draw(canvas, drawData); - for(const std::shared_ptr& bvhNode : cachedNodesToDraw) { - auto& drawCache = bvhNode->drawCache.value(); - if(drawCache.lastDrawnComponentPlacement == i) { + if(numOfUncachedComponentsToDraw < minCompsToUseAltStrategy && components.client_list().size() > maxUncachedCompsToUseAltStrategy) { + std::sort(uncachedCompsToDraw.begin(), uncachedCompsToDraw.end(), [](auto& a, auto& b) { + return a->pos < b->pos; + }); + std::sort(cachedNodesToDraw.begin(), cachedNodesToDraw.end(), [](auto& a, auto& b) { + return a->drawCache.value().lastDrawnComponentPlacement < b->drawCache.value().lastDrawnComponentPlacement; + }); + size_t nextCacheToRender = 0; + for(auto& c : uncachedCompsToDraw) { + for(;;) { + if(nextCacheToRender >= cachedNodesToDraw.size() || c->pos >= cachedNodesToDraw[nextCacheToRender]->drawCache.value().lastDrawnComponentPlacement) + break; + auto& bvhNode = cachedNodesToDraw[nextCacheToRender]; + auto& drawCache = bvhNode->drawCache.value(); canvas->save(); bvhNode->coords.transform_sk_canvas(canvas, drawData); drawCache.lastRenderTime = std::chrono::steady_clock::now(); - + SkPaint p; p.setBlendMode(SkBlendMode::kSrc); @@ -649,7 +666,48 @@ void DrawingProgram::draw_components_to_canvas(SkCanvas* canvas, const DrawData& canvas->drawImage(drawCache.surface->makeTemporaryImage(), 0, 0, {SkFilterMode::kLinear, SkMipmapMode::kLinear}, &p); canvas->restore(); + nextCacheToRender++; } + c->obj->draw(canvas, drawData); + c->obj->drawSetupData.shouldDraw = false; + } + for(;nextCacheToRender < cachedNodesToDraw.size(); nextCacheToRender++) { + auto& bvhNode = cachedNodesToDraw[nextCacheToRender]; + auto& drawCache = bvhNode->drawCache.value(); + canvas->save(); + bvhNode->coords.transform_sk_canvas(canvas, drawData); + drawCache.lastRenderTime = std::chrono::steady_clock::now(); + + SkPaint p; + p.setBlendMode(SkBlendMode::kSrc); + + // Note, no mipmaps here. You might need to generate mipmaps in the future (withDefaultMipmaps) + canvas->drawImage(drawCache.surface->makeTemporaryImage(), 0, 0, {SkFilterMode::kLinear, SkMipmapMode::kLinear}, &p); + + canvas->restore(); + } + } + else { + for(uint64_t i = 0; i < components.client_list().size(); i++) { + auto& c = components.client_list()[i]; + c->obj->draw(canvas, drawData); + for(const std::shared_ptr& bvhNode : cachedNodesToDraw) { + auto& drawCache = bvhNode->drawCache.value(); + if(drawCache.lastDrawnComponentPlacement == i) { + canvas->save(); + bvhNode->coords.transform_sk_canvas(canvas, drawData); + drawCache.lastRenderTime = std::chrono::steady_clock::now(); + + SkPaint p; + p.setBlendMode(SkBlendMode::kSrc); + + // Note, no mipmaps here. You might need to generate mipmaps in the future (withDefaultMipmaps) + canvas->drawImage(drawCache.surface->makeTemporaryImage(), 0, 0, {SkFilterMode::kLinear, SkMipmapMode::kLinear}, &p); + + canvas->restore(); + } + } + c->obj->drawSetupData.shouldDraw = false; } } } diff --git a/src/DrawingProgram/DrawingProgramCache.cpp b/src/DrawingProgram/DrawingProgramCache.cpp index ed26e5e..b08034d 100644 --- a/src/DrawingProgram/DrawingProgramCache.cpp +++ b/src/DrawingProgram/DrawingProgramCache.cpp @@ -36,7 +36,7 @@ void DrawingProgramCache::build(std::vector compo } void DrawingProgramCache::update() { - if(unsortedComponents.size() >= 750 && (std::chrono::steady_clock::now() - lastBvhBuildTime) >= std::chrono::seconds(7)) + if(unsortedComponents.size() >= 1000 && (std::chrono::steady_clock::now() - lastBvhBuildTime) >= std::chrono::seconds(7)) force_rebuild(); }