201 lines
9.7 KiB
C++
201 lines
9.7 KiB
C++
#pragma once
|
|
#include "Scene_Base.hpp"
|
|
#include <renderive/inheritance/Observation.hpp>
|
|
#include <renderive/render_graph/detail/Render_Graph_Runtime.hpp>
|
|
class Scene_Base::Impl
|
|
: public renderive::scene_inheritance::Impl_Root<Impl, Observation> {
|
|
public:
|
|
using Observer = Scene_Base::Observer;
|
|
struct Frame_Control_Capability {
|
|
virtual ~Frame_Control_Capability() = default;
|
|
virtual std::shared_ptr<Frame_Control_Strategy_Base> frame_control_strategy() = 0;
|
|
virtual std::shared_ptr<const Frame_Control_Strategy_Base> frame_control_strategy() const = 0;
|
|
virtual void replace_frame_control_strategy(
|
|
std::shared_ptr<Frame_Control_Strategy_Base> strategy) = 0;
|
|
};
|
|
struct Scene_State_Capability {
|
|
virtual ~Scene_State_Capability() = default;
|
|
virtual void before_scene_state_swap() = 0;
|
|
virtual void swap_scene_state() = 0;
|
|
virtual void after_scene_state_swap() {}
|
|
virtual std::uint64_t acquire_scene_state() = 0;
|
|
virtual void capture_scene_state(
|
|
Frame_Render_Snapshot& snapshot) const = 0;
|
|
};
|
|
struct Composition_Relationships {
|
|
virtual ~Composition_Relationships() = default;
|
|
virtual void attach(Renderable_Id id) = 0;
|
|
[[nodiscard]] virtual Scene_Edit_Error add_parent(
|
|
Renderable_Id child, Renderable_Id parent) = 0;
|
|
[[nodiscard]] virtual bool cleanup() = 0;
|
|
[[nodiscard]] virtual bool valid() const = 0;
|
|
virtual renderive::scene::dependency::Resolution<Renderable_Id> resolve() const = 0;
|
|
virtual void restore(
|
|
const renderive::scene::dependency::Resolution<Renderable_Id>&
|
|
resolution) = 0;
|
|
};
|
|
struct Raster_Capabilities {
|
|
virtual ~Raster_Capabilities() = default;
|
|
virtual std::shared_ptr<Color_Cache> make_renderable_color_cache() = 0;
|
|
virtual Frame_Viewport frame_viewport() const = 0;
|
|
};
|
|
struct Compositor {
|
|
virtual ~Compositor() = default;
|
|
virtual void begin_composite(
|
|
const Composite_Render_Context& context) = 0;
|
|
virtual void composite(const Composite_Render_Context& context) = 0;
|
|
};
|
|
struct Renderer {
|
|
virtual ~Renderer() = default;
|
|
virtual Node_Execution_Result render_scene(
|
|
const Scene_Render_Context& context) = 0;
|
|
};
|
|
using Composite_Render_Node_Function =
|
|
std::function<void(const Composite_Render_Context &)>;
|
|
using Scene_Render_Node_Function =
|
|
std::function<Node_Execution_Result(const Scene_Render_Context &)>;
|
|
using Execution_Function =
|
|
std::variant<Prepare_Render_Node_Function, Paint_Render_Node_Function,
|
|
Composite_Render_Node_Function,
|
|
Scene_Render_Node_Function>;
|
|
struct Execution_Binding {
|
|
std::optional<std::size_t> renderable_index;
|
|
Execution_Function function;
|
|
};
|
|
struct Compiled_Render_Plan;
|
|
struct Render_Completion {
|
|
Scene_Render_Result error{};
|
|
std::exception_ptr exception;
|
|
bool completed{};
|
|
bool observed{};
|
|
};
|
|
struct Render_Task {
|
|
std::shared_ptr<const Frame_Render_Snapshot> snapshot;
|
|
std::shared_ptr<Compiled_Render_Plan> compiled_plan;
|
|
std::shared_ptr<const Topology_Snapshot> topology;
|
|
std::shared_ptr<Abstract_Frame::Render_State> frame;
|
|
std::shared_ptr<Render_Completion> completion;
|
|
};
|
|
class Execution_Context;
|
|
class Render_Execution_Scope;
|
|
class Renderable_Edit_Transaction;
|
|
explicit Impl(std::pmr::memory_resource& upstream_memory_resource);
|
|
virtual ~Impl();
|
|
void initialize(Scene_Base& scene);
|
|
[[nodiscard]] Scene_Base& scene() noexcept;
|
|
[[nodiscard]] const Scene_Base& scene() const noexcept;
|
|
[[nodiscard]] virtual std::uint64_t now_ns() const noexcept;
|
|
[[nodiscard]] std::pmr::memory_resource& memory_resource() const noexcept;
|
|
[[nodiscard]] std::pmr::memory_resource& upstream_memory_resource() const noexcept;
|
|
[[nodiscard]] Frame_Control_Capability& frame_control();
|
|
[[nodiscard]] const Frame_Control_Capability& frame_control() const;
|
|
[[nodiscard]] Scene_State_Capability& scene_state();
|
|
[[nodiscard]] const Scene_State_Capability& scene_state() const;
|
|
[[nodiscard]] Composition_Relationships* composition() noexcept;
|
|
[[nodiscard]] const Composition_Relationships* composition() const noexcept;
|
|
[[nodiscard]] Raster_Capabilities* raster() noexcept;
|
|
[[nodiscard]] const Raster_Capabilities* raster() const noexcept;
|
|
[[nodiscard]] Scene_Render_Result submit_render(Abstract_Frame* frame);
|
|
void complete_pending_operation();
|
|
void record_pending_exception(std::exception_ptr exception);
|
|
void capture_edit_renderable(const Renderable& renderable);
|
|
void request_render_graph_rebuild(Renderable_Base& renderable);
|
|
[[nodiscard]] std::shared_ptr<Frame_Render_Snapshot> snapshot_live_model();
|
|
[[nodiscard]] std::shared_ptr<Frame_Render_Snapshot> capture_live_frame();
|
|
void publish_frame_state_locked();
|
|
void bind_observation_source(
|
|
std::unique_ptr<renderive::inheritance::Observation_Source> source);
|
|
void unbind_observation_source() noexcept;
|
|
void publish_observation();
|
|
std::shared_ptr<Compiled_Render_Plan> compile_render_plan(
|
|
const Frame_Render_Snapshot& snapshot);
|
|
void execute_render_task(std::shared_ptr<Render_Task> task);
|
|
[[nodiscard]] Scene_Edit_Error execute_renderable_edit(
|
|
std::function<Scene_Edit_Error()> edit);
|
|
[[nodiscard]] Scene_Render_Result execute_render_graph(Render_Task& task);
|
|
[[nodiscard]] Scene_Edit_Error renderable_scene_error(
|
|
const Renderable_Base& renderable) const noexcept;
|
|
[[nodiscard]] bool is_renderable_attached_locked(
|
|
const Renderable& renderable) const;
|
|
[[nodiscard]] Scene_Edit_Error validate_structure_locked() const;
|
|
[[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;
|
|
void invalidate_renderables();
|
|
void shutdown();
|
|
[[nodiscard]] Scene_Base::Edit_Operation enqueue_renderable_edit(
|
|
std::function<Scene_Edit_Error()> edit);
|
|
inline static thread_local Scene_Base* active_execution_scene_{};
|
|
inline static thread_local Scene_Base* active_renderable_edit_scene_{};
|
|
inline static thread_local Scene_Base* active_submitted_observer_scene_{};
|
|
Scene_Base* owner_{};
|
|
std::shared_ptr<Scene_Lifetime> scene_lifetime_;
|
|
std::shared_ptr<Scene_Memory_Domain> memory_domain_;
|
|
std::unique_ptr<Execution_Context> execution_context_;
|
|
std::pmr::unordered_map<Renderable_Id, Renderable> renderables_;
|
|
renderive::scene::dependency::Dependency_Resolver<Renderable_Id>
|
|
dependency_resolver_;
|
|
std::pmr::unordered_map<Renderable_Id, std::shared_ptr<Color_Cache>>
|
|
color_caches_;
|
|
mutable std::mutex model_mutex_;
|
|
mutable std::recursive_mutex task_mutex_;
|
|
std::condition_variable_any render_completed_;
|
|
std::shared_ptr<Render_Completion> current_completion_;
|
|
std::exception_ptr pending_exception_;
|
|
std::size_t deferred_render_count_{};
|
|
bool refresh_interval_reset_pending_{};
|
|
std::uint64_t render_sequence_{};
|
|
std::size_t pending_operations_{};
|
|
bool runtime_started_{};
|
|
bool shutting_down_{};
|
|
Renderable_Edit_Transaction* active_edit_transaction_{};
|
|
const Render_Node_Id composite_begin_node_id_;
|
|
const Render_Node_Id scene_render_node_id_;
|
|
Render_Plan_History render_plan_history_;
|
|
std::shared_ptr<Compiled_Render_Plan> compiled_render_plan_;
|
|
Capture_Controller capture_controller_;
|
|
Capture_Repository capture_repository_;
|
|
mutable std::mutex observation_mutex_;
|
|
std::shared_ptr<renderive::inheritance::Observation_Source>
|
|
observation_source_;
|
|
};
|
|
struct Scene_2D_Base::Impl
|
|
: Scene_Base::next_Impl<Impl>,
|
|
Scene_Base::Impl::Composition_Relationships {
|
|
using Observer = Scene_2D_Base::Observer;
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Impl, Scene_Base::next_Impl<Impl>,
|
|
Scene_2D_Base::next_Impl<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Impl_Node<
|
|
renderive::inheritance::Chain_Probe, Impl>>);
|
|
explicit Impl(std::pmr::memory_resource& memory_resource);
|
|
void with_initial_display_edit(std::function<void()> edit);
|
|
[[nodiscard]] Scene_Edit_Error set_display_parent_locked(
|
|
const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error add_display_parent_locked(
|
|
const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error clear_display_parent_locked(
|
|
const Renderable& child);
|
|
void attach(Renderable_Id id) override;
|
|
[[nodiscard]] Scene_Edit_Error add_parent(
|
|
Renderable_Id child, Renderable_Id parent) override;
|
|
[[nodiscard]] bool cleanup() override;
|
|
[[nodiscard]] bool valid() const override;
|
|
[[nodiscard]] renderive::scene::dependency::Resolution<Renderable_Id> resolve() const override;
|
|
void restore(
|
|
const renderive::scene::dependency::Resolution<Renderable_Id>&
|
|
resolution) override;
|
|
renderive::scene::dependency::Dependency_Resolver<Renderable_Id>
|
|
display_resolver_;
|
|
};
|
|
struct Scene_3D_Base::Impl
|
|
: Scene_Base::next_Impl<Impl> {
|
|
using Observer = Scene_3D_Base::Observer;
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Impl, Scene_Base::next_Impl<Impl>,
|
|
Scene_3D_Base::next_Impl<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Impl_Node<
|
|
renderive::inheritance::Chain_Probe, Impl>>);
|
|
explicit Impl(std::pmr::memory_resource& memory_resource) : Scene_Base::next_Impl<Impl>(memory_resource) {}
|
|
};
|