Files
Renderive/render_2D/renderable/Renderable.cpp
T
2026-08-13 13:32:23 +08:00

134 lines
4.2 KiB
C++

#include "Renderable.h"
#include "Renderable_p.h"
#include <renderive/scene/base/Scene_Base.hpp>
#include "../render/Blend2D_Cache.h"
#include <renderive/scene/base/Render_Contexts.hpp>
namespace renderive {
Renderable::Renderable(bool cache_enabled)
: ::Renderable_Base(std::make_unique<Impl>(),
{.cache_enabled = cache_enabled}) {}
Renderable::~Renderable() = default;
Renderable_Cache_Mode Renderable::get_cache_mode() const noexcept {
return d_func<Impl>().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<Impl>();
std::lock_guard lock(d.metadata_mutex);
return d.object_name;
}
void Renderable::set_object_name(std::string name) {
auto& d = d_func<Impl>();
std::lock_guard lock(d.metadata_mutex);
d.object_name = std::move(name);
}
Renderable_Observation Renderable::observation() const noexcept {
const auto& d = d_func<Impl>();
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<Impl>();
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<detail::Blend2D_Color_Cache*>(&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<Renderable&>(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