#include "Renderable.h" #include "Renderable_p.h" #include #include "../render/Blend2D_Cache.h" #include namespace renderive { Renderable::Renderable(bool cache_enabled) : ::Renderable_Base(std::make_unique(), {.cache_enabled = cache_enabled}) {} Renderable::~Renderable() = default; Renderable_Cache_Mode Renderable::get_cache_mode() const noexcept { return d_func().configuration.load(std::memory_order_acquire).cache_enabled ? Renderable_Cache_Mode::Local_Pixel : Renderable_Cache_Mode::Direct; } void Renderable::set_cache_mode(Renderable_Cache_Mode mode) { d_func().set_configuration( {.cache_enabled = mode == Renderable_Cache_Mode::Local_Pixel}); } std::string Renderable::object_name() const { const auto& d = d_func(); std::lock_guard lock(d.metadata_mutex); return d.object_name; } void Renderable::set_object_name(std::string name) { auto& d = d_func(); std::lock_guard lock(d.metadata_mutex); d.object_name = std::move(name); } Renderable_Observation Renderable::observation() const noexcept { const auto& d = d_func(); std::lock_guard lock(d.observation_mutex); return d.observation; } void Renderable::observe_state(Renderable_Observer_Event event, std::uint64_t time_ns, std::uint64_t cache_update_count, std::uint64_t publish_count) noexcept { auto& d = d_func(); std::lock_guard lock(d.observation_mutex); d.observation.event = event; d.observation.event_time_ns = time_ns; d.observation.cache_update_count = cache_update_count; d.observation.publish_count = publish_count; } void Renderable::build_prepare_graph(Renderable_Graph_Builder& builder) { add_prepare_task(builder, "prepare", "Prepare", [this](const Prepare_Render_Context& context) { d_func().execute_prepare(context); }); } void Renderable::build_paint_graph(Renderable_Graph_Builder& builder) { const auto paint_task = add_paint_task(builder, "paint", "Paint", [this](detail::Painter& painter, const Paint_Render_Context& context) { paint(painter, context); }); builder.precede(builder.find("prepare"), paint_task); } Renderable_Graph_Builder::Task Renderable::add_prepare_task( Renderable_Graph_Builder& builder, std::string logical_key, std::string name, Prepare_Task_Function function) { return builder.emplace(std::move(logical_key), std::move(name), std::move(function)); } Renderable_Graph_Builder::Task Renderable::add_paint_task( Renderable_Graph_Builder& builder, std::string logical_key, std::string name, Paint_Task_Function function) { return builder.emplace(std::move(logical_key), std::move(name), [function = std::move(function)](const Paint_Render_Context& context) { if (!context.renderable.visible) return; auto* cache = dynamic_cast(&context.color_cache); if (!cache) return; detail::Painter painter(*cache, {context.frame.viewport.width, context.frame.viewport.height}); if (painter) function(painter, context); }); } void Renderable::changed() noexcept { d_func().invalidate_prepare(); d_func().notify_scene_model_dirty(); } void Renderable::paint_changed() noexcept { d_func().invalidate_paint(); d_func().notify_scene_model_dirty(); } void Renderable::render_graph_changed() { d_func().rebuild_render_graph(); } Renderable& Renderable::Impl::renderable() noexcept { return static_cast(owner()); } void Renderable::Impl::build_prepare_graph( Renderable_Graph_Builder& builder) { renderable().build_prepare_graph(builder); } void Renderable::Impl::build_paint_graph( Renderable_Graph_Builder& builder) { renderable().build_paint_graph(builder); } void Renderable::Impl::prepare(const Prepare_Render_Context& context) { renderable().prepare_frame(context); } } // namespace renderive