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 {
|
||||
canvas->saveLayer(nullptr, nullptr);
|
||||
canvas->clear(SkColor4f{0.0f, 0.0f, 0.0f, 0.0f});
|
||||
drawCache.refresh_all_draw_cache(drawData);
|
||||
drawCache.draw_components_to_canvas(canvas, drawData, {});
|
||||
drawCache.update_and_draw_cached_canvas(canvas, drawData);
|
||||
canvas->saveLayer(nullptr, nullptr);
|
||||
selection.draw_components(canvas, drawData);
|
||||
canvas->restore();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#endif
|
||||
|
||||
std::unordered_map<std::shared_ptr<DrawingProgramCacheBVHNode>, DrawingProgramCache::NodeCache> DrawingProgramCache::nodeCacheMap;
|
||||
DrawingProgramCache::WindowCache DrawingProgramCache::windowCache;
|
||||
|
||||
DrawingProgramCache::DrawingProgramCache(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
|
|
@ -44,6 +45,14 @@ void DrawingProgramCache::invalidate_cache_at_aabb(const SCollision::AABB<WorldS
|
|||
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 {
|
||||
|
|
@ -72,6 +81,8 @@ void DrawingProgramCache::clear_own_cached_surfaces() {
|
|||
std::erase_if(nodeCacheMap, [&](auto& nodeCachePair) {
|
||||
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) {
|
||||
|
|
@ -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
|
||||
}
|
||||
|
||||
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) {
|
||||
if(drawP.layerMan.layer_tree_root_exists()) {
|
||||
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_components(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, std::function<void(CanvasComponentContainer::ObjInfo* comp)> f);
|
||||
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);
|
||||
bool unsorted_components_exist() const;
|
||||
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);
|
||||
~DrawingProgramCache();
|
||||
private:
|
||||
|
|
@ -46,6 +48,19 @@ class DrawingProgramCache {
|
|||
};
|
||||
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 build_bvh_node(const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode, const std::vector<CanvasComponentContainer::ObjInfo*>& components);
|
||||
void build_bvh_node_coords_and_resolution(DrawingProgramCacheBVHNode& node);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue