Added screen space cache
This commit is contained in:
parent
5143557e78
commit
fe4716765c
3 changed files with 99 additions and 3 deletions
|
|
@ -604,8 +604,7 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||||
else {
|
else {
|
||||||
canvas->saveLayer(nullptr, nullptr);
|
canvas->saveLayer(nullptr, nullptr);
|
||||||
canvas->clear(SkColor4f{0.0f, 0.0f, 0.0f, 0.0f});
|
canvas->clear(SkColor4f{0.0f, 0.0f, 0.0f, 0.0f});
|
||||||
drawCache.refresh_all_draw_cache(drawData);
|
drawCache.update_and_draw_cached_canvas(canvas, drawData);
|
||||||
drawCache.draw_components_to_canvas(canvas, drawData, {});
|
|
||||||
canvas->saveLayer(nullptr, nullptr);
|
canvas->saveLayer(nullptr, nullptr);
|
||||||
selection.draw_components(canvas, drawData);
|
selection.draw_components(canvas, drawData);
|
||||||
canvas->restore();
|
canvas->restore();
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::unordered_map<std::shared_ptr<DrawingProgramCacheBVHNode>, DrawingProgramCache::NodeCache> DrawingProgramCache::nodeCacheMap;
|
std::unordered_map<std::shared_ptr<DrawingProgramCacheBVHNode>, DrawingProgramCache::NodeCache> DrawingProgramCache::nodeCacheMap;
|
||||||
|
DrawingProgramCache::WindowCache DrawingProgramCache::windowCache;
|
||||||
|
|
||||||
DrawingProgramCache::DrawingProgramCache(DrawingProgram& initDrawP):
|
DrawingProgramCache::DrawingProgramCache(DrawingProgram& initDrawP):
|
||||||
drawP(initDrawP)
|
drawP(initDrawP)
|
||||||
|
|
@ -44,6 +45,14 @@ void DrawingProgramCache::invalidate_cache_at_aabb(const SCollision::AABB<WorldS
|
||||||
nodeCache.invalidBounds = aabb;
|
nodeCache.invalidBounds = aabb;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(SCollision::collide(aabb, drawP.world.drawData.cam.viewingAreaGenerousCollider)) {
|
||||||
|
if(windowCache.invalidBounds.has_value()) {
|
||||||
|
auto& iBounds = windowCache.invalidBounds.value();
|
||||||
|
iBounds.include_aabb_in_bounds(aabb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
windowCache.invalidBounds = aabb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DrawingProgramCache::should_rebuild() const {
|
bool DrawingProgramCache::should_rebuild() const {
|
||||||
|
|
@ -72,6 +81,8 @@ void DrawingProgramCache::clear_own_cached_surfaces() {
|
||||||
std::erase_if(nodeCacheMap, [&](auto& nodeCachePair) {
|
std::erase_if(nodeCacheMap, [&](auto& nodeCachePair) {
|
||||||
return nodeCachePair.second.attachedDrawingProgramCache == this;
|
return nodeCachePair.second.attachedDrawingProgramCache == this;
|
||||||
});
|
});
|
||||||
|
if(windowCache.attachedDrawingProgramCache == this)
|
||||||
|
windowCache.attachedDrawingProgramCache = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasComponentContainer::ObjInfo* DrawingProgramCache::get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection<float>& cC) {
|
CanvasComponentContainer::ObjInfo* DrawingProgramCache::get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection<float>& cC) {
|
||||||
|
|
@ -303,6 +314,77 @@ void DrawingProgramCache::refresh_draw_cache(const std::shared_ptr<DrawingProgra
|
||||||
nodeCacheMap.emplace(bvhNode, nodeCache); // Set the nodeCache after rendering is done, so that the draw function doesnt assume we have this node cached
|
nodeCacheMap.emplace(bvhNode, nodeCache); // Set the nodeCache after rendering is done, so that the draw function doesnt assume we have this node cached
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrawingProgramCache::set_clear_window_cache() {
|
||||||
|
windowCache.attachedDrawingProgramCache = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawingProgramCache::allocate_window_cache_area() {
|
||||||
|
const Vector2i& windowSize = drawP.world.main.window.size;
|
||||||
|
#ifdef USE_BACKEND_OPENGLES_3_0
|
||||||
|
SkImageInfo imgInfo = SkImageInfo::Make(windowSize.x(), windowSize.y(), kRGBA_8888_SkColorType, kPremul_SkAlphaType);
|
||||||
|
#else
|
||||||
|
SkImageInfo imgInfo = SkImageInfo::MakeN32Premul(windowSize.x(), windowSize.y());
|
||||||
|
#endif
|
||||||
|
#ifdef USE_SKIA_BACKEND_GRAPHITE
|
||||||
|
windowCache.surface = SkSurfaces::RenderTarget(drawP.world.main.window.recorder(), imgInfo, skgpu::Mipmapped::kNo, drawP.world.main.window.defaultMSAASurfaceProps);
|
||||||
|
#elif USE_SKIA_BACKEND_GANESH
|
||||||
|
windowCache.surface = SkSurfaces::RenderTarget(drawP.world.main.window.ctx.get(), skgpu::Budgeted::kNo, imgInfo, drawP.world.main.window.defaultMSAASampleCount, &drawP.world.main.window.defaultMSAASurfaceProps);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!windowCache.surface)
|
||||||
|
throw std::runtime_error("[DrawingProgramCache::allocate_window_cache_area] Could not make cache surface");
|
||||||
|
windowCache.size = windowSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawingProgramCache::update_window_cache_invalid_bounds(const DrawData& drawData) {
|
||||||
|
auto iBounds = windowCache.invalidBounds.value();
|
||||||
|
|
||||||
|
SCollision::AABB<float> cameraSpaceInvalidAABB = drawData.cam.c.world_collider_to_coords<SCollision::AABB<float>>(iBounds);
|
||||||
|
SCollision::AABB<float> clipRectBoundAABB{cameraSpaceInvalidAABB.min - Vector2f{4, 4}, cameraSpaceInvalidAABB.max + Vector2f{4, 4}};
|
||||||
|
|
||||||
|
SkIRect clipRect = SkIRect::MakeLTRB(clipRectBoundAABB.min.x(),
|
||||||
|
clipRectBoundAABB.min.y(),
|
||||||
|
clipRectBoundAABB.max.x(),
|
||||||
|
clipRectBoundAABB.max.y());
|
||||||
|
|
||||||
|
SCollision::AABB<WorldScalar> clipRectBoundAABBWorld = drawData.cam.c.collider_to_world<SCollision::AABB<WorldScalar>>(clipRectBoundAABB);
|
||||||
|
|
||||||
|
SkCanvas* cacheCanvas = windowCache.surface->getCanvas();
|
||||||
|
cacheCanvas->save();
|
||||||
|
cacheCanvas->clipIRect(clipRect);
|
||||||
|
cacheCanvas->clear(SkColor4f{0, 0, 0, 0});
|
||||||
|
draw_components_to_canvas(cacheCanvas, drawData, clipRectBoundAABBWorld);
|
||||||
|
cacheCanvas->restore();
|
||||||
|
windowCache.invalidBounds = std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawingProgramCache::window_cache_complete_refresh(const DrawData& drawData) {
|
||||||
|
SkCanvas* cacheCanvas = windowCache.surface->getCanvas();
|
||||||
|
cacheCanvas->save();
|
||||||
|
cacheCanvas->clear(SkColor4f{0, 0, 0, 0});
|
||||||
|
draw_components_to_canvas(cacheCanvas, drawData, std::nullopt);
|
||||||
|
cacheCanvas->restore();
|
||||||
|
windowCache.attachedDrawingProgramCache = this;
|
||||||
|
windowCache.coords = drawData.cam.c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawingProgramCache::update_and_draw_cached_canvas(SkCanvas* canvas, const DrawData& drawData) {
|
||||||
|
if(windowCache.surface == nullptr || drawData.main->window.size != windowCache.size) {
|
||||||
|
allocate_window_cache_area();
|
||||||
|
refresh_all_draw_cache(drawData);
|
||||||
|
window_cache_complete_refresh(drawData);
|
||||||
|
}
|
||||||
|
else if(windowCache.attachedDrawingProgramCache != this || drawData.cam.c != windowCache.coords) {
|
||||||
|
refresh_all_draw_cache(drawData);
|
||||||
|
window_cache_complete_refresh(drawData);
|
||||||
|
}
|
||||||
|
else if(windowCache.invalidBounds.has_value()) {
|
||||||
|
refresh_all_draw_cache(drawData);
|
||||||
|
update_window_cache_invalid_bounds(drawData);
|
||||||
|
}
|
||||||
|
canvas->drawImage(windowCache.surface->makeTemporaryImage(), 0, 0, {SkFilterMode::kNearest, SkMipmapMode::kNone}, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
void DrawingProgramCache::draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::optional<SCollision::AABB<WorldScalar>>& drawBounds) {
|
void DrawingProgramCache::draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::optional<SCollision::AABB<WorldScalar>>& drawBounds) {
|
||||||
if(drawP.layerMan.layer_tree_root_exists()) {
|
if(drawP.layerMan.layer_tree_root_exists()) {
|
||||||
std::vector<std::shared_ptr<DrawingProgramCacheBVHNode>> cachedNodesToDraw;
|
std::vector<std::shared_ptr<DrawingProgramCacheBVHNode>> cachedNodesToDraw;
|
||||||
|
|
|
||||||
|
|
@ -31,10 +31,12 @@ class DrawingProgramCache {
|
||||||
void node_loop_erase_if_components(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, std::function<bool(CanvasComponentContainer::ObjInfo* comp)> f);
|
void node_loop_erase_if_components(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, std::function<bool(CanvasComponentContainer::ObjInfo* comp)> f);
|
||||||
void node_loop_components(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, std::function<void(CanvasComponentContainer::ObjInfo* comp)> f);
|
void node_loop_components(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, std::function<void(CanvasComponentContainer::ObjInfo* comp)> f);
|
||||||
bool should_rebuild() const;
|
bool should_rebuild() const;
|
||||||
|
void update_and_draw_cached_canvas(SkCanvas* canvas, const DrawData& drawData);
|
||||||
void draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::optional<SCollision::AABB<WorldScalar>>& drawBounds);
|
void draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::optional<SCollision::AABB<WorldScalar>>& drawBounds);
|
||||||
bool unsorted_components_exist() const;
|
bool unsorted_components_exist() const;
|
||||||
void invalidate_cache_at_aabb(const SCollision::AABB<WorldScalar>& aabb);
|
void invalidate_cache_at_aabb(const SCollision::AABB<WorldScalar>& aabb);
|
||||||
void refresh_all_draw_cache(const DrawData& drawData);
|
void set_clear_window_cache();
|
||||||
|
|
||||||
CanvasComponentContainer::ObjInfo* get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection<float>& cC);
|
CanvasComponentContainer::ObjInfo* get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection<float>& cC);
|
||||||
~DrawingProgramCache();
|
~DrawingProgramCache();
|
||||||
private:
|
private:
|
||||||
|
|
@ -46,6 +48,19 @@ class DrawingProgramCache {
|
||||||
};
|
};
|
||||||
static std::unordered_map<std::shared_ptr<DrawingProgramCacheBVHNode>, NodeCache> nodeCacheMap;
|
static std::unordered_map<std::shared_ptr<DrawingProgramCacheBVHNode>, NodeCache> nodeCacheMap;
|
||||||
|
|
||||||
|
struct WindowCache {
|
||||||
|
sk_sp<SkSurface> surface;
|
||||||
|
DrawingProgramCache* attachedDrawingProgramCache = nullptr;
|
||||||
|
std::optional<SCollision::AABB<WorldScalar>> invalidBounds;
|
||||||
|
Vector2i size = {0, 0};
|
||||||
|
CoordSpaceHelper coords;
|
||||||
|
};
|
||||||
|
static WindowCache windowCache;
|
||||||
|
|
||||||
|
void refresh_all_draw_cache(const DrawData& drawData);
|
||||||
|
void update_window_cache_invalid_bounds(const DrawData& drawData);
|
||||||
|
void window_cache_complete_refresh(const DrawData& drawData);
|
||||||
|
void allocate_window_cache_area();
|
||||||
void internal_build(std::vector<CanvasComponentContainer::ObjInfo*> componentsToBuild, const std::unordered_set<CanvasComponentContainer::ObjInfo*>& objsToNotInclude);
|
void internal_build(std::vector<CanvasComponentContainer::ObjInfo*> componentsToBuild, const std::unordered_set<CanvasComponentContainer::ObjInfo*>& objsToNotInclude);
|
||||||
void build_bvh_node(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, const std::vector<CanvasComponentContainer::ObjInfo*>& components);
|
void build_bvh_node(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, const std::vector<CanvasComponentContainer::ObjInfo*>& components);
|
||||||
void build_bvh_node_coords_and_resolution(DrawingProgramCacheBVHNode& node);
|
void build_bvh_node_coords_and_resolution(DrawingProgramCacheBVHNode& node);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue