147 lines
4.9 KiB
C++
147 lines
4.9 KiB
C++
#include "Renderable.h"
|
|
#include <renderive/scene/base/Scene_Base.hpp>
|
|
|
|
#include "../render/Blend2D_Cache.h"
|
|
|
|
#include <algorithm>
|
|
#include <renderive/scene/base/Scene_Render_Context.hpp>
|
|
|
|
namespace renderive {
|
|
|
|
Renderable_Observation Renderable_Observer::observation() const noexcept {
|
|
std::lock_guard lock(mutex_);
|
|
return observation_;
|
|
}
|
|
|
|
void Renderable_Observer::observe_state(Renderable_Observer_Event event,
|
|
std::uint64_t time_ns,
|
|
std::uint64_t cache_update_count,
|
|
std::uint64_t publish_count) noexcept {
|
|
std::lock_guard lock(mutex_);
|
|
observation_.event = event;
|
|
observation_.event_time_ns = time_ns;
|
|
observation_.cache_update_count = cache_update_count;
|
|
observation_.publish_count = publish_count;
|
|
}
|
|
|
|
Renderable::Renderable(::Scene_Base& scene, bool cache_enabled)
|
|
: ::Renderable_Base(scene, {.cache_enabled = cache_enabled}) {}
|
|
|
|
Renderable::~Renderable() = default;
|
|
|
|
void attach_renderable_child(::Scene_Base& scene, const std::shared_ptr<Renderable>& renderable, const std::shared_ptr<Renderable>& parent) {
|
|
scene.attach_renderable(renderable);
|
|
try {
|
|
scene.set_display_parent(*renderable, parent.get());
|
|
scene.set_dependency_parent(*renderable, parent.get());
|
|
} catch (...) {
|
|
scene.detach_renderable(*renderable);
|
|
throw;
|
|
}
|
|
scene.notify_model_dirty();
|
|
}
|
|
|
|
Renderable_Cache_Mode Renderable::get_cache_mode() const noexcept {
|
|
return configuration().cache_enabled
|
|
? Renderable_Cache_Mode::Local_Pixel
|
|
: Renderable_Cache_Mode::Direct;
|
|
}
|
|
|
|
void Renderable::set_cache_mode(Renderable_Cache_Mode mode) {
|
|
scene().set_renderable_configuration(*this, {.cache_enabled = mode == Renderable_Cache_Mode::Local_Pixel});
|
|
scene().notify_model_dirty();
|
|
}
|
|
|
|
std::string Renderable::object_name() const {
|
|
std::lock_guard lock(metadata_mutex_);
|
|
return object_name_;
|
|
}
|
|
|
|
void Renderable::set_object_name(std::string name) {
|
|
std::lock_guard lock(metadata_mutex_);
|
|
object_name_ = std::move(name);
|
|
}
|
|
|
|
bool Renderable::is_visible() const noexcept {
|
|
return visible_.load(std::memory_order_acquire);
|
|
}
|
|
|
|
void Renderable::set_visible(bool visible) {
|
|
if (visible_.exchange(visible, std::memory_order_acq_rel) != visible)
|
|
changed();
|
|
}
|
|
|
|
Renderable_Observation Renderable::observation() const noexcept {
|
|
return observer_.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 {
|
|
observer_.observe_state(event, time_ns, cache_update_count, publish_count);
|
|
}
|
|
|
|
void Renderable::build_prepare_graph(Renderable_Graph_Builder& builder) {
|
|
add_prepare_task(builder, "prepare", "Prepare",
|
|
[this](const Render_State_View& state, const Scene_Render_Context& context) {
|
|
prepare_frame(state, 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 Scene_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),
|
|
Render_Node_Kind::prepare,
|
|
[this, function = std::move(function)](const Scene_Render_Context& context) {
|
|
function(render_state_view(), context);
|
|
});
|
|
}
|
|
|
|
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),
|
|
Render_Node_Kind::paint,
|
|
[this, function = std::move(function)](const Scene_Render_Context& context) {
|
|
if (!is_visible() || context.color_cache == nullptr)
|
|
return;
|
|
auto* cache = dynamic_cast<detail::Blend2D_Color_Cache*>(context.color_cache);
|
|
if (!cache)
|
|
return;
|
|
detail::Painter painter(*cache, {context.viewport.width, context.viewport.height});
|
|
if (painter)
|
|
function(painter, context);
|
|
});
|
|
}
|
|
|
|
void Renderable::changed() noexcept {
|
|
invalidate_prepare();
|
|
scene().notify_model_dirty();
|
|
}
|
|
|
|
void Renderable::paint_changed() noexcept {
|
|
invalidate_paint();
|
|
scene().notify_model_dirty();
|
|
}
|
|
|
|
void Renderable::render_graph_changed() noexcept {
|
|
rebuild_render_graph();
|
|
scene().notify_model_dirty();
|
|
}
|
|
|
|
} // namespace renderive
|