升级
This commit is contained in:
@@ -141,26 +141,16 @@ void Renderable_Base::Impl::set_configuration(
|
||||
if (previous == value) return;
|
||||
configuration.store(value, std::memory_order_release);
|
||||
invalidate_prepare();
|
||||
notify_scene_model_dirty();
|
||||
}
|
||||
void Renderable_Base::Impl::set_visible(bool value) {
|
||||
if (visible.exchange(value, std::memory_order_acq_rel) == value) return;
|
||||
invalidate_prepare();
|
||||
notify_scene_model_dirty();
|
||||
}
|
||||
void Renderable_Base::Impl::discard_stale_frame_on_latest_data_update(
|
||||
bool enabled) noexcept {
|
||||
real_time_data_state->discard_stale_frame_on_latest_data_update.store(
|
||||
enabled, std::memory_order_release);
|
||||
}
|
||||
void Renderable_Base::Impl::notify_scene_model_dirty() {
|
||||
const auto& state = real_time_data_state;
|
||||
if (!state->attached.load(std::memory_order_acquire) ||
|
||||
!state->scene_lifetime)
|
||||
return;
|
||||
auto lease = state->scene_lifetime->acquire();
|
||||
if (lease) lease.scene().notify_model_dirty();
|
||||
}
|
||||
void Renderable_Base::Impl::build_prepare_graph(
|
||||
Renderable_Graph_Builder& builder) {
|
||||
builder.emplace("prepare", "Prepare",
|
||||
@@ -251,11 +241,9 @@ void Renderable_Base::discard_stale_frame_on_latest_data_update(
|
||||
}
|
||||
void Renderable_Base::Impl::changed() {
|
||||
invalidate_prepare();
|
||||
notify_scene_model_dirty();
|
||||
}
|
||||
void Renderable_Base::Impl::paint_changed() {
|
||||
invalidate_paint();
|
||||
notify_scene_model_dirty();
|
||||
}
|
||||
void Renderable_Base::Impl::render_graph_changed() {
|
||||
rebuild_render_graph();
|
||||
|
||||
@@ -39,7 +39,6 @@ public:
|
||||
[[nodiscard]] static Render_State_View render_state_view() noexcept;
|
||||
[[nodiscard]] Real_Time_Data_Binding bind_real_time_data(
|
||||
Real_Time_Data_Base& data);
|
||||
void notify_scene_model_dirty();
|
||||
void bind_scene(std::shared_ptr<Scene_Lifetime> lifetime);
|
||||
[[nodiscard]] std::shared_ptr<const Renderable_Graph> render_graph_snapshot();
|
||||
void mark_prepared(std::uint64_t revision) noexcept;
|
||||
|
||||
@@ -224,8 +224,7 @@ struct Scene_Base::Impl::Compiled_Render_Plan {
|
||||
};
|
||||
class Scene_Base::Impl::Renderable_Edit_Transaction {
|
||||
public:
|
||||
explicit Renderable_Edit_Transaction(Impl& scene) : scene_(scene), dependency_(scene.dependency_resolver_.resolve()),
|
||||
model_dirty_(scene.model_dirty_.load(std::memory_order_acquire)) {
|
||||
explicit Renderable_Edit_Transaction(Impl& scene) : scene_(scene), dependency_(scene.dependency_resolver_.resolve()) {
|
||||
renderables_.reserve(scene.renderables_.size());
|
||||
color_caches_.reserve(scene.color_caches_.size());
|
||||
for (const auto& [id, renderable] : scene.renderables_) {
|
||||
@@ -262,7 +261,6 @@ public:
|
||||
data.real_time_data_state->attached.store(state.attached, std::memory_order_release);
|
||||
data.prepare_revision.store(state.prepare_revision, std::memory_order_release);
|
||||
}
|
||||
scene_.model_dirty_.store(model_dirty_, std::memory_order_release);
|
||||
}
|
||||
private:
|
||||
struct Renderable_State {
|
||||
@@ -277,7 +275,6 @@ private:
|
||||
std::optional<renderive::scene::dependency::Resolution<Renderable_Id>> display_;
|
||||
std::vector<std::pair<Renderable_Id, std::shared_ptr<Color_Cache>>> color_caches_;
|
||||
std::vector<Renderable_State> renderable_states_;
|
||||
bool model_dirty_{};
|
||||
};
|
||||
Scene_Base::Impl::Impl(std::pmr::memory_resource& upstream_memory_resource) : memory_domain_(std::allocate_shared<Scene_Memory_Domain>(
|
||||
std::pmr::polymorphic_allocator<Scene_Memory_Domain>(
|
||||
@@ -415,7 +412,6 @@ Scene_Edit_Error Scene_Base::Renderable_Editor::attach(Renderable renderable) {
|
||||
}
|
||||
renderable_data.real_time_data_state->attached.store(true, std::memory_order_release);
|
||||
renderable_data.invalidate_prepare();
|
||||
scene_data.model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_Edit_Error Scene_Base::Renderable_Editor::detach(
|
||||
@@ -432,7 +428,6 @@ Scene_Edit_Error Scene_Base::Renderable_Editor::detach(
|
||||
renderable_data.real_time_data_state->attached.store(false, std::memory_order_release);
|
||||
scene_data.color_caches_.erase(id);
|
||||
scene_data.renderables_.erase(id);
|
||||
scene_data.model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_Edit_Error Scene_Base::Renderable_Editor::set_dependency_parent(
|
||||
@@ -453,7 +448,6 @@ Scene_Edit_Error Scene_Base::Renderable_Editor::set_dependency_parent(
|
||||
if (!result) return fail(relationship_error(result.error, false));
|
||||
if (!result.changed) return Scene_Edit_Error::none;
|
||||
child->d_func().invalidate_prepare();
|
||||
scene_data.model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_Edit_Error Scene_Base::Renderable_Editor::add_dependency_parent(
|
||||
@@ -474,7 +468,6 @@ Scene_Edit_Error Scene_Base::Renderable_Editor::add_dependency_parent(
|
||||
if (!result) return fail(relationship_error(result.error, false));
|
||||
if (!result.changed) return Scene_Edit_Error::none;
|
||||
child->d_func().invalidate_prepare();
|
||||
scene_data.model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_Edit_Error Scene_Base::Renderable_Editor::clear_dependency_parent(
|
||||
@@ -491,7 +484,6 @@ Scene_Edit_Error Scene_Base::Renderable_Editor::clear_dependency_parent(
|
||||
if (!result) return fail(relationship_error(result.error, false));
|
||||
if (!result.changed) return Scene_Edit_Error::none;
|
||||
child->d_func().invalidate_prepare();
|
||||
scene_data.model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
void Scene_Base::Renderable_Editor::replace_frame_control_strategy(
|
||||
@@ -602,7 +594,6 @@ Scene_Edit_Error Scene_2D_Base::Impl::set_display_parent_locked(
|
||||
const auto result = display_resolver_.replace_parents(
|
||||
child->renderable_id(), {parent->renderable_id()});
|
||||
if (!result) return relationship_error(result.error, true);
|
||||
if (result.changed) model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_Edit_Error Scene_2D_Base::Impl::add_display_parent_locked(
|
||||
@@ -618,7 +609,6 @@ Scene_Edit_Error Scene_2D_Base::Impl::add_display_parent_locked(
|
||||
const auto result = display_resolver_.add_parent(
|
||||
child->renderable_id(), parent->renderable_id());
|
||||
if (!result) return relationship_error(result.error, true);
|
||||
if (result.changed) model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_Edit_Error Scene_2D_Base::Impl::clear_display_parent_locked(
|
||||
@@ -629,7 +619,6 @@ Scene_Edit_Error Scene_2D_Base::Impl::clear_display_parent_locked(
|
||||
if (!is_renderable_attached_locked(child)) return Scene_Edit_Error::renderable_not_attached;
|
||||
const auto result = display_resolver_.clear_parents(child->renderable_id());
|
||||
if (!result) return relationship_error(result.error, true);
|
||||
if (result.changed) model_dirty_.store(true, std::memory_order_release);
|
||||
return Scene_Edit_Error::none;
|
||||
}
|
||||
Scene_3D_Base::Scene_3D_Base() : Scene_3D_Base(*std::pmr::get_default_resource()) {}
|
||||
@@ -922,7 +911,6 @@ void Scene_Base::Impl::request_render_graph_rebuild(
|
||||
if (renderable_scene_error(renderable) != Scene_Edit_Error::none) ::renderive::error::unexpected<std::logic_error>("attached renderable scene invariant violated");
|
||||
if (active_renderable_edit_scene_ == owner_) {
|
||||
renderable_data.reset_render_graph();
|
||||
model_dirty_.store(true, std::memory_order_release);
|
||||
return;
|
||||
}
|
||||
Renderable owner;
|
||||
@@ -936,13 +924,11 @@ void Scene_Base::Impl::request_render_graph_rebuild(
|
||||
std::lock_guard<std::recursive_mutex> lock(task_mutex_);
|
||||
if (!runtime_started_) {
|
||||
owner->d_func().reset_render_graph();
|
||||
model_dirty_.store(true, std::memory_order_release);
|
||||
return;
|
||||
}
|
||||
}
|
||||
static_cast<void>(enqueue_renderable_edit([owner = std::move(owner)] {
|
||||
owner->d_func().reset_render_graph();
|
||||
owner->d_func().notify_scene_model_dirty();
|
||||
return Scene_Edit_Error::none;
|
||||
}));
|
||||
}
|
||||
@@ -1016,16 +1002,12 @@ void Scene_Base::Impl::publish_frame_state_locked() {
|
||||
}
|
||||
publish_observation();
|
||||
}
|
||||
void Scene_Base::notify_model_dirty() noexcept {
|
||||
d_func().model_dirty_.store(true, std::memory_order_release);
|
||||
}
|
||||
void Scene_Base::Impl::invalidate_renderables() {
|
||||
std::lock_guard lock(model_mutex_);
|
||||
for (const auto& [id, renderable] : renderables_) {
|
||||
static_cast<void>(id);
|
||||
renderable->d_func().invalidate_prepare();
|
||||
}
|
||||
model_dirty_.store(true, std::memory_order_release);
|
||||
}
|
||||
std::size_t Scene_Base::renderable_count() const {
|
||||
const auto& implementation = d_func();
|
||||
@@ -1294,9 +1276,6 @@ std::unique_lock<std::recursive_mutex> Scene_Base::Impl::lock_render_idle() {
|
||||
bool Scene_Base::Impl::is_render_execution_context() const noexcept {
|
||||
return active_execution_scene_ == owner_;
|
||||
}
|
||||
bool Scene_Base::Impl::consume_model_dirty() noexcept {
|
||||
return model_dirty_.exchange(false, std::memory_order_acq_rel);
|
||||
}
|
||||
void Scene_Base::Impl::shutdown() {
|
||||
std::shared_ptr<Compiled_Render_Plan> compiled_plan;
|
||||
{
|
||||
|
||||
@@ -158,7 +158,6 @@ public:
|
||||
Scene_Render_Result wait_for_render();
|
||||
void publish_frame_state();
|
||||
void publish_frame_state(Abstract_Frame& frame);
|
||||
void notify_model_dirty() noexcept;
|
||||
[[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit);
|
||||
[[nodiscard]] std::size_t renderable_count() const;
|
||||
[[nodiscard]] Topology_Snapshot topology_snapshot() const;
|
||||
|
||||
@@ -119,7 +119,6 @@ public:
|
||||
[[nodiscard]] Scene_Edit_Error cleanup_detached_topology_locked();
|
||||
[[nodiscard]] std::unique_lock<std::recursive_mutex> lock_render_idle();
|
||||
[[nodiscard]] bool is_render_execution_context() const noexcept;
|
||||
[[nodiscard]] bool consume_model_dirty() noexcept;
|
||||
void invalidate_renderables();
|
||||
void shutdown();
|
||||
[[nodiscard]] Scene_Base::Edit_Operation enqueue_renderable_edit(
|
||||
@@ -131,7 +130,6 @@ public:
|
||||
std::shared_ptr<Scene_Lifetime> scene_lifetime_;
|
||||
std::shared_ptr<Scene_Memory_Domain> memory_domain_;
|
||||
std::unique_ptr<Execution_Context> execution_context_;
|
||||
std::atomic_bool model_dirty_{true};
|
||||
std::pmr::unordered_map<Renderable_Id, Renderable> renderables_;
|
||||
renderive::scene::dependency::Dependency_Resolver<Renderable_Id>
|
||||
dependency_resolver_;
|
||||
|
||||
@@ -8,7 +8,7 @@ Explicit_Plot::Explicit_Plot()
|
||||
: Abs_Plot(new Abs_Plot_Private(false)) {}
|
||||
|
||||
Render_Ticket Explicit_Plot::replot() {
|
||||
const auto result = d->scene->render_frame(true);
|
||||
const auto result = d->scene->render_frame();
|
||||
return {result && *result == Plot_Render_Status::rendered};
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,6 @@ inline std::shared_ptr<Performance_Overlay> attach_performance_overlay(Render_Sc
|
||||
inline std::shared_ptr<Performance_Overlay> attach_performance_overlay(Render_Scene_2D& scene, const Performance_Overlay_Options& options) {
|
||||
if (auto existing = scene.performance_overlay()) {
|
||||
existing->set_options(options);
|
||||
scene.request_redraw();
|
||||
return existing;
|
||||
}
|
||||
auto overlay = std::make_shared<Performance_Overlay>(options);
|
||||
@@ -83,13 +82,11 @@ inline void set_performance_plot_name(Render_Scene_2D& scene, std::string name)
|
||||
auto overlay = scene.performance_overlay();
|
||||
if (!overlay) overlay = attach_performance_overlay(scene);
|
||||
overlay->set_plot_name(std::move(name));
|
||||
scene.request_redraw();
|
||||
}
|
||||
inline void set_performance_overlay_enabled(Render_Scene_2D& scene, bool enabled) {
|
||||
auto overlay = scene.performance_overlay();
|
||||
if (!overlay && !enabled) return;
|
||||
if (!overlay) overlay = attach_performance_overlay(scene);
|
||||
overlay->set_enabled(enabled);
|
||||
scene.request_redraw();
|
||||
}
|
||||
} // namespace renderive
|
||||
|
||||
@@ -80,7 +80,6 @@ struct detail::Render_Scene_2D::Impl
|
||||
});
|
||||
const auto published = scene_state.published_state();
|
||||
if (pending.viewport != published.viewport) invalidate_renderables();
|
||||
else if (pending != published) scene().notify_model_dirty();
|
||||
}
|
||||
void swap_scene_state() override {
|
||||
scene_state.publish();
|
||||
@@ -154,17 +153,15 @@ void detail::Render_Scene_2D::dispatch_event(const Event& event) {
|
||||
}
|
||||
}
|
||||
}
|
||||
auto detail::Render_Scene_2D::render_frame(bool force) -> Expected<Plot_Render_Status, Plot_Render_Frame_Error> {
|
||||
if (!view_active() && !force) return Plot_Render_Status::view_inactive;
|
||||
auto detail::Render_Scene_2D::render_frame() -> Expected<Plot_Render_Status, Plot_Render_Frame_Error> {
|
||||
if (!view_active()) return Plot_Render_Status::view_inactive;
|
||||
const Size viewport = get<&State::viewport>();
|
||||
if (viewport.empty()) return Plot_Render_Status::empty_viewport;
|
||||
if (!d_func<Impl>().consume_model_dirty() && !force) return Plot_Render_Status::model_unchanged;
|
||||
const auto started = std::chrono::steady_clock::now();
|
||||
try {
|
||||
if (const auto result = d_func<Impl>().frame_control->request(*this); !result) return unexpected(result.error());
|
||||
}
|
||||
catch (...) {
|
||||
notify_model_dirty();
|
||||
::renderive::error::unexpected(
|
||||
"rolling back plot frame preparation",
|
||||
std::current_exception());
|
||||
@@ -205,7 +202,6 @@ void detail::Render_Scene_2D::with_frame(
|
||||
}
|
||||
void detail::Render_Scene_2D::activate_view() {
|
||||
d_func<Impl>().active.store(true, std::memory_order_release);
|
||||
notify_model_dirty();
|
||||
}
|
||||
void detail::Render_Scene_2D::deactivate_view() noexcept {
|
||||
d_func<Impl>().active.store(false, std::memory_order_release);
|
||||
@@ -213,9 +209,6 @@ void detail::Render_Scene_2D::deactivate_view() noexcept {
|
||||
bool detail::Render_Scene_2D::view_active() const noexcept {
|
||||
return d_func<Impl>().active.load(std::memory_order_acquire);
|
||||
}
|
||||
void detail::Render_Scene_2D::request_redraw() noexcept {
|
||||
notify_model_dirty();
|
||||
}
|
||||
void detail::Render_Scene_2D::set_presentation_sink(
|
||||
std::weak_ptr<Presentation_Sink> sink) {
|
||||
auto& impl = d_func<Impl>();
|
||||
@@ -229,11 +222,8 @@ std::shared_ptr<Performance_Overlay> detail::Render_Scene_2D::performance_overla
|
||||
}
|
||||
void detail::Render_Scene_2D::set_performance_overlay(
|
||||
std::shared_ptr<Performance_Overlay> overlay) {
|
||||
{
|
||||
auto& impl = d_func<Impl>();
|
||||
std::lock_guard lock(impl.control_mutex);
|
||||
impl.performance = std::move(overlay);
|
||||
}
|
||||
notify_model_dirty();
|
||||
auto& impl = d_func<Impl>();
|
||||
std::lock_guard lock(impl.control_mutex);
|
||||
impl.performance = std::move(overlay);
|
||||
}
|
||||
} // namespace renderive
|
||||
|
||||
@@ -17,7 +17,6 @@ enum class Plot_Render_Status : std::uint8_t {
|
||||
rendered,
|
||||
view_inactive,
|
||||
empty_viewport,
|
||||
model_unchanged
|
||||
};
|
||||
enum class Plot_Render_Frame_Error : std::uint8_t {
|
||||
painter_unavailable,
|
||||
@@ -108,12 +107,11 @@ public:
|
||||
struct Observer : Base::template next_Observer<Observer>, Observer_Fields {};
|
||||
[[nodiscard]] ::renderive_Owner<::renderive::Renderable> root_renderable() const;
|
||||
void dispatch_event(const Event& event);
|
||||
[[nodiscard]] auto render_frame(bool force = false) -> Expected<Plot_Render_Status, Plot_Render_Frame_Error>;
|
||||
[[nodiscard]] auto render_frame() -> Expected<Plot_Render_Status, Plot_Render_Frame_Error>;
|
||||
void with_frame(const std::function<void(Image_View)>& consumer);
|
||||
void activate_view();
|
||||
void deactivate_view() noexcept;
|
||||
[[nodiscard]] bool view_active() const noexcept;
|
||||
void request_redraw() noexcept;
|
||||
void set_presentation_sink(std::weak_ptr<Presentation_Sink> sink);
|
||||
[[nodiscard]] std::shared_ptr<Performance_Overlay> performance_overlay() const;
|
||||
void set_performance_overlay(
|
||||
|
||||
@@ -21,7 +21,7 @@ TEST(RenderScene2DFramePipeline, BuilderOwnsConstructionAndState) {
|
||||
EXPECT_EQ(scene->root_renderable()->object_name(), "root");
|
||||
}
|
||||
|
||||
TEST(RenderScene2DFramePipeline, ActiveDirtyAndForceGatesAreOrthogonal) {
|
||||
TEST(RenderScene2DFramePipeline, SceneValidityDoesNotGateStrategyProgress) {
|
||||
Render_Scene_2D::State state;
|
||||
state.viewport = {80, 45};
|
||||
auto scene = make_scene(state);
|
||||
@@ -30,8 +30,7 @@ TEST(RenderScene2DFramePipeline, ActiveDirtyAndForceGatesAreOrthogonal) {
|
||||
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::view_inactive);
|
||||
scene->activate_view();
|
||||
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
|
||||
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::model_unchanged);
|
||||
EXPECT_EQ(scene->render_frame(true).value(), Plot_Render_Status::rendered);
|
||||
EXPECT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
|
||||
EXPECT_EQ(scene->wait_for_render(), Scene_Render_Result::none);
|
||||
}
|
||||
|
||||
@@ -40,7 +39,7 @@ TEST(RenderScene2DFramePipeline, ObserverReadsPublishedDoubleBufferedState) {
|
||||
state.viewport = {32, 24};
|
||||
auto scene = make_scene(state);
|
||||
scene->activate_view();
|
||||
ASSERT_EQ(scene->render_frame(true).value(), Plot_Render_Status::rendered);
|
||||
ASSERT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
|
||||
ASSERT_EQ(scene->wait_for_render(), Scene_Render_Result::none);
|
||||
const auto observation = scene->observer();
|
||||
EXPECT_EQ(observation.state, state);
|
||||
|
||||
@@ -11,7 +11,7 @@ TEST(RenderScene2DIntegration, BuilderStatePublishesAtFrameBoundary) {
|
||||
auto scene = Render_Scene_2D::Builder{initial}.build(
|
||||
std::make_shared<Manual_Render_Scene_2D_Strategy>());
|
||||
scene->activate_view();
|
||||
ASSERT_EQ(scene->render_frame(true).value(), Plot_Render_Status::rendered);
|
||||
ASSERT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
|
||||
ASSERT_EQ(scene->wait_for_render(), Scene_Render_Result::none);
|
||||
EXPECT_EQ(scene->observer().state, initial);
|
||||
}
|
||||
@@ -22,7 +22,7 @@ TEST(RenderScene2DIntegration, FrameImageMatchesConfiguredViewport) {
|
||||
auto scene = Render_Scene_2D::Builder{state}.build(
|
||||
std::make_shared<Low_Latency_Render_Scene_2D_Strategy>());
|
||||
scene->activate_view();
|
||||
ASSERT_EQ(scene->render_frame(true).value(), Plot_Render_Status::rendered);
|
||||
ASSERT_EQ(scene->render_frame().value(), Plot_Render_Status::rendered);
|
||||
ASSERT_EQ(scene->wait_for_render(), Scene_Render_Result::none);
|
||||
scene->with_frame([](Image_View image) {
|
||||
EXPECT_EQ(image.width, 48);
|
||||
|
||||
@@ -132,7 +132,7 @@ struct detail::Render_Scene_3D::Impl
|
||||
backend_state(
|
||||
std::make_shared<Point_Backend_State>(gpu_index)) {}
|
||||
Scene_Control_Error dispatch_pointer(
|
||||
Render_Scene_3D& scene, ::renderive::Event_Type type, float x,
|
||||
::renderive::Event_Type type, float x,
|
||||
float y, ::renderive::Mouse_Button button,
|
||||
::renderive::Keyboard_Modifier modifiers) {
|
||||
const Extent viewport =
|
||||
@@ -147,12 +147,10 @@ struct detail::Render_Scene_3D::Impl
|
||||
return Scene_Control_Error::none;
|
||||
});
|
||||
if (!invocation) return Scene_Control_Error::backend_unavailable;
|
||||
const auto error = *invocation.value;
|
||||
if (error == Scene_Control_Error::none) scene.notify_model_dirty();
|
||||
return error;
|
||||
return *invocation.value;
|
||||
}
|
||||
Scene_Control_Error dispatch_wheel(
|
||||
Render_Scene_3D& scene, float x, float y, float delta_x,
|
||||
float x, float y, float delta_x,
|
||||
float delta_y, ::renderive::Keyboard_Modifier modifiers) {
|
||||
const Extent viewport =
|
||||
scene_state.template get<&State::viewport>();
|
||||
@@ -166,12 +164,9 @@ struct detail::Render_Scene_3D::Impl
|
||||
return Scene_Control_Error::none;
|
||||
});
|
||||
if (!invocation) return Scene_Control_Error::backend_unavailable;
|
||||
const auto error = *invocation.value;
|
||||
if (error == Scene_Control_Error::none) scene.notify_model_dirty();
|
||||
return error;
|
||||
return *invocation.value;
|
||||
}
|
||||
Scene_Control_Error dispatch_key(Render_Scene_3D& scene,
|
||||
const ::renderive::Key_Event& event) {
|
||||
Scene_Control_Error dispatch_key(const ::renderive::Key_Event& event) {
|
||||
const auto backend = backend_state;
|
||||
if (!backend->backend_available()) return Scene_Control_Error::backend_unavailable;
|
||||
const auto invocation = backend->render_domain->invoke(
|
||||
@@ -181,9 +176,7 @@ struct detail::Render_Scene_3D::Impl
|
||||
return Scene_Control_Error::none;
|
||||
});
|
||||
if (!invocation) return Scene_Control_Error::backend_unavailable;
|
||||
const auto error = *invocation.value;
|
||||
if (error == Scene_Control_Error::none) scene.notify_model_dirty();
|
||||
return error;
|
||||
return *invocation.value;
|
||||
}
|
||||
[[nodiscard]] std::shared_ptr<const Pixel_Frame> latest_frame() const {
|
||||
const auto backend = backend_state;
|
||||
@@ -394,7 +387,6 @@ struct detail::Render_Scene_3D::Impl
|
||||
});
|
||||
const auto published = scene_state.published_state();
|
||||
if (pending.viewport != published.viewport) invalidate_renderables();
|
||||
else if (pending != published) scene().notify_model_dirty();
|
||||
}
|
||||
void swap_scene_state() override {
|
||||
scene_state.publish();
|
||||
@@ -501,7 +493,7 @@ Scene_Control_Error detail::Render_Scene_3D::dispatch(
|
||||
!std::isfinite(angle_delta_y))
|
||||
return Scene_Control_Error::invalid_event;
|
||||
return d_func<Impl>().dispatch_wheel(
|
||||
*this, x, y,
|
||||
x, y,
|
||||
datoviz_wheel_step(pixel_delta_x, angle_delta_x),
|
||||
datoviz_wheel_step(pixel_delta_y, angle_delta_y),
|
||||
pointer->keyboard_modifiers());
|
||||
@@ -516,10 +508,10 @@ Scene_Control_Error detail::Render_Scene_3D::dispatch(
|
||||
event.type != ::renderive::Event_Type::Pointer_Release)
|
||||
return Scene_Control_Error::invalid_event;
|
||||
return d_func<Impl>().dispatch_pointer(
|
||||
*this, event.type, x, y, pointer->pointer_button(),
|
||||
event.type, x, y, pointer->pointer_button(),
|
||||
pointer->keyboard_modifiers());
|
||||
}
|
||||
if (const auto* key = dynamic_cast<const ::renderive::Key_Event*>(&event)) return d_func<Impl>().dispatch_key(*this, *key);
|
||||
if (const auto* key = dynamic_cast<const ::renderive::Key_Event*>(&event)) return d_func<Impl>().dispatch_key(*key);
|
||||
return Scene_Control_Error::none;
|
||||
}
|
||||
Frame_Request_Result detail::Render_Scene_3D::request_frame() {
|
||||
|
||||
@@ -22,7 +22,7 @@ struct Web_Plot_Session::Impl {
|
||||
return std::visit([this](const auto& value) -> std::optional<Web_Response> {
|
||||
using T = std::decay_t<decltype(value)>;
|
||||
if constexpr (std::same_as<T, Frame_Request>) {
|
||||
const auto result = scene->render_frame(true);
|
||||
const auto result = scene->render_frame();
|
||||
if (!result || scene->wait_for_render() != Scene_Render_Result::none)
|
||||
return std::nullopt;
|
||||
std::string pixels;
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
|
||||
bool request_frame() override {
|
||||
update_samples();
|
||||
const auto result = scene_->render_frame(true);
|
||||
const auto result = scene_->render_frame();
|
||||
if (!result || *result != Plot_Render_Status::rendered)
|
||||
return false;
|
||||
if (scene_->wait_for_render() != Scene_Render_Result::none)
|
||||
|
||||
Reference in New Issue
Block a user