#pragma once #include "../CanvasComponents/CanvasComponentContainer.hpp" #include struct DrawingProgramCacheBVHNode { public: SCollision::AABB bounds; CoordSpaceHelper coords; Vector2i resolution; private: std::vector components; std::vector> children; friend class DrawingProgramCache; }; class DrawingProgramCache { public: static size_t MINIMUM_COMPONENTS_TO_START_REBUILD; static size_t MAXIMUM_COMPONENTS_IN_SINGLE_NODE; static size_t MAXIMUM_DRAW_CACHE_SURFACES; static size_t CACHE_NODE_RESOLUTION; static size_t MILLISECOND_FRAME_TIME_TO_FORCE_CACHE_REFRESH; static size_t MILLISECOND_MINIMUM_TIME_TO_CHECK_FORCE_REFRESH; DrawingProgramCache(DrawingProgram& initDrawP); void add_component(CanvasComponentContainer::ObjInfo* c); void erase_component(CanvasComponentContainer::ObjInfo* c); void clear_own_cached_surfaces(); void preupdate_component(CanvasComponentContainer::ObjInfo* c); void build(const std::unordered_set& objsToExclude); void traverse_bvh_run_function(const SCollision::AABB& aabb, std::function& node)> f); void traverse_bvh_run_function_starting_at_node(const std::shared_ptr& bvhNode, const SCollision::AABB& aabb, std::function& node)> f); void traverse_bvh_run_function_starting_at_node_no_collision_check(const std::shared_ptr& bvhNode, std::function& node)> f); void node_loop_erase_if_components(const std::shared_ptr& bvhNode, std::function f); void node_loop_components(const std::shared_ptr& bvhNode, std::function f); bool should_rebuild() const; bool check_rebuild_needed_from_framerate(); void update_and_draw_cached_canvas(SkCanvas* canvas, const DrawData& drawData); void draw_components_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::optional>& drawBounds); void invalidate_cache_at_aabb(const SCollision::AABB& aabb); static void delete_all_draw_cache(); CanvasComponentContainer::ObjInfo* get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection& cC); ~DrawingProgramCache(); private: struct NodeCache { sk_sp surface; std::chrono::steady_clock::time_point lastRenderTime; DrawingProgramCache* attachedDrawingProgramCache; std::optional> invalidBounds; }; static std::unordered_map, NodeCache> nodeCacheMap; struct WindowCache { sk_sp surface; DrawingProgramCache* attachedDrawingProgramCache = nullptr; std::optional> 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 componentsToBuild, const std::unordered_set& objsToNotInclude); void build_bvh_node(const std::shared_ptr& bvhNode, const std::vector& components); void build_bvh_node_coords_and_resolution(DrawingProgramCacheBVHNode& node); void refresh_draw_cache(const std::shared_ptr& bvhNode, const DrawData& drawData); void draw_cache_image_to_canvas(SkCanvas* canvas, const DrawData& drawData, const std::shared_ptr& bvhNode); void recursive_draw_layer_item_to_canvas(const DrawingProgramLayerListItem& layerListItem, SkCanvas* canvas, const DrawData& drawData, const std::optional>& drawBounds, const std::vector>& nodesToDraw); std::optional badFrametimeTimePoint; std::optional unorderedObjectsExistTimePoint; std::shared_ptr bvhRoot; std::vector unsortedComponents; DrawingProgram& drawP; };