397 lines
17 KiB
C++
397 lines
17 KiB
C++
#pragma once
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#include <concepts>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <exception>
|
|
#include <functional>
|
|
#include <future>
|
|
#include <memory>
|
|
#include <memory_resource>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <unordered_map>
|
|
#include <typeindex>
|
|
#include <utility>
|
|
#include <variant>
|
|
#include <vector>
|
|
#include "renderive/base/memory/Memory_Resource.hpp"
|
|
#include "renderive/capture/Capture.hpp"
|
|
#include "renderive/frame_control/base/Frame_Control_Strategy_Base.hpp"
|
|
#include "renderive/renderable/Renderable_Graph_Builder.hpp"
|
|
#include "renderive/renderable/base/Renderable_Base.hpp"
|
|
#include "renderive/renderable/base/Renderive_Owner.hpp"
|
|
#include "renderive/render_graph/External_Operation.hpp"
|
|
#include "renderive/render_graph/Render_Plan.hpp"
|
|
#include "renderive/scene/Inheritance.hpp"
|
|
#include "renderive/scene/dependency/Dependency_Resolver.hpp"
|
|
#include "Abstract_Frame.hpp"
|
|
#include "Frame_Render_Snapshot.hpp"
|
|
#include "Frame_Viewport.hpp"
|
|
#include "Render_Contexts.hpp"
|
|
#include "Scene_Lifetime.hpp"
|
|
#include "renderive/base/Concepts.hpp"
|
|
namespace renderive::inheritance {
|
|
struct Observation_Source;
|
|
}
|
|
class Color_Cache;
|
|
enum class Scene_Render_Result : std::uint8_t {
|
|
none,
|
|
cancelled,
|
|
deadline_exceeded,
|
|
external_failure,
|
|
shutting_down
|
|
};
|
|
enum class Scene_Edit_Error : std::uint8_t {
|
|
none,
|
|
empty_edit,
|
|
null_renderable,
|
|
foreign_renderable,
|
|
renderable_not_attached,
|
|
dependency_self_reference,
|
|
dependency_cycle,
|
|
display_self_reference,
|
|
display_cycle,
|
|
dangling_dependency,
|
|
dangling_display,
|
|
shutting_down
|
|
};
|
|
struct Scene_Execution_Statistics {
|
|
std::size_t capacity{};
|
|
std::size_t queued{};
|
|
std::size_t peak_queued{};
|
|
std::uint64_t backpressure_count{};
|
|
std::uint64_t backpressure_wait_ns{};
|
|
};
|
|
class Scene_Base : public Non_Copyable {
|
|
public:
|
|
using Renderable = renderive_Owner<Renderable_Base>;
|
|
using Const_Renderable = renderive_Owner<const Renderable_Base>;
|
|
class Attach_Builder;
|
|
class Renderable_Editor
|
|
: public renderive::scene_inheritance::Editor_Root<Renderable_Editor> {
|
|
public:
|
|
template <class Next>
|
|
using next_Editor =
|
|
renderive::scene_inheritance::Editor_Node<Next, Renderable_Editor>;
|
|
[[nodiscard]] Scene_Edit_Error attach(Renderable renderable);
|
|
[[nodiscard]] Scene_Edit_Error detach(const Renderable& renderable);
|
|
[[nodiscard]] Scene_Edit_Error set_dependency_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error add_dependency_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error clear_dependency_parent(const Renderable& child);
|
|
void replace_frame_control_strategy(
|
|
std::shared_ptr<Frame_Control_Strategy_Base> strategy);
|
|
[[nodiscard]] Scene_Edit_Error error() const noexcept {
|
|
return error_;
|
|
}
|
|
protected:
|
|
explicit Renderable_Editor(Scene_Base& scene) : scene_(scene) {}
|
|
Scene_Base& scene_;
|
|
Scene_Edit_Error fail(Scene_Edit_Error error) noexcept;
|
|
private:
|
|
Scene_Edit_Error error_{};
|
|
friend class Scene_Base;
|
|
friend class Attach_Builder;
|
|
};
|
|
class Attach_Builder
|
|
: public renderive::scene_inheritance::Builder_Root<Attach_Builder> {
|
|
public:
|
|
template <class Next>
|
|
using next_Builder =
|
|
renderive::scene_inheritance::Builder_Node<Next, Attach_Builder>;
|
|
Attach_Builder(const Attach_Builder&) = delete;
|
|
Attach_Builder& operator=(const Attach_Builder&) = delete;
|
|
Attach_Builder(Attach_Builder&&) = delete;
|
|
Attach_Builder& operator=(Attach_Builder&&) = delete;
|
|
[[nodiscard]] Scene_Edit_Error attach(Renderable renderable);
|
|
[[nodiscard]] Scene_Edit_Error set_dependency_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error add_dependency_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error clear_dependency_parent(const Renderable& child);
|
|
protected:
|
|
explicit Attach_Builder(Scene_Base& scene);
|
|
Scene_Base& scene_;
|
|
std::unique_lock<std::recursive_mutex> task_lock_;
|
|
private:
|
|
friend class Scene_Base;
|
|
};
|
|
using Renderable_Edit = std::function<void(Renderable_Editor&)>;
|
|
class Edit_Operation {
|
|
public:
|
|
Edit_Operation() = default;
|
|
[[nodiscard]] Scene_Edit_Error wait() const;
|
|
private:
|
|
explicit Edit_Operation(std::shared_future<Scene_Edit_Error> result) : result_(std::move(result)) {}
|
|
std::shared_future<Scene_Edit_Error> result_;
|
|
friend class Scene_Base;
|
|
friend class Scene_2D_Base;
|
|
friend class Scene_3D_Base;
|
|
};
|
|
struct Topology_Relationship {
|
|
Const_Renderable child;
|
|
Const_Renderable parent;
|
|
};
|
|
struct Topology_Snapshot {
|
|
std::vector<Const_Renderable> renderables;
|
|
std::vector<Topology_Relationship> display;
|
|
std::vector<Topology_Relationship> dependency;
|
|
};
|
|
enum class Observation_Event {
|
|
render_submitted,
|
|
render_started,
|
|
render_completed,
|
|
render_cancelled,
|
|
render_failed
|
|
};
|
|
struct Observation {
|
|
Observation_Event event{};
|
|
std::uint64_t time_ns{};
|
|
std::uint64_t render_sequence{};
|
|
std::uint64_t scene_state_revision{};
|
|
std::size_t renderable_count{};
|
|
std::shared_ptr<const Topology_Snapshot> topology;
|
|
std::shared_ptr<const Frame_Render_Snapshot> frame_snapshot;
|
|
std::shared_ptr<const Render_Plan> render_plan;
|
|
};
|
|
Scene_Render_Result render();
|
|
Scene_Render_Result render(Abstract_Frame& frame);
|
|
Scene_Render_Result wait_for_render();
|
|
void publish_frame_state();
|
|
void publish_frame_state(Abstract_Frame& frame);
|
|
[[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit);
|
|
[[nodiscard]] std::size_t renderable_count() const;
|
|
[[nodiscard]] Topology_Snapshot topology_snapshot() const;
|
|
[[nodiscard]] std::vector<Const_Renderable> paint_order_snapshot() const;
|
|
[[nodiscard]] std::shared_ptr<const Render_Plan> render_plan_snapshot() const;
|
|
[[nodiscard]] std::shared_ptr<const Render_Plan> find_render_plan(Render_Plan_Version version) const;
|
|
[[nodiscard]] Capture_Request_Result capture_next_frame();
|
|
[[nodiscard]] Capture_Request_Result capture_frames(std::size_t count);
|
|
[[nodiscard]] Capture_Controller_State capture_state() const noexcept;
|
|
[[nodiscard]] std::optional<Capture_Session> capture_session(Capture_Session_Id session_id) const;
|
|
[[nodiscard]] std::vector<Capture_Session_Id> capture_sessions() const;
|
|
[[nodiscard]] std::vector<Node_Statistics> node_statistics(Capture_Session_Id session_id) const;
|
|
[[nodiscard]] std::vector<Plan_Version_Statistics> plan_version_statistics(Capture_Session_Id session_id) const;
|
|
[[nodiscard]] Scene_Execution_Statistics execution_statistics() const noexcept;
|
|
[[nodiscard]] std::pmr::memory_resource& memory_resource() const noexcept;
|
|
[[nodiscard]] std::pmr::memory_resource& upstream_memory_resource() const noexcept;
|
|
[[nodiscard]] auto frame_control_strategy() -> std::shared_ptr<Frame_Control_Strategy_Base>;
|
|
[[nodiscard]] auto frame_control_strategy() const -> std::shared_ptr<const Frame_Control_Strategy_Base>;
|
|
struct Observer
|
|
: renderive::scene_inheritance::Observer_Root<Observer> {};
|
|
protected:
|
|
Scene_Base();
|
|
explicit Scene_Base(std::pmr::memory_resource& upstream_memory_resource);
|
|
virtual ~Scene_Base();
|
|
struct Builder
|
|
: renderive::scene_inheritance::Builder_Root<Builder> {};
|
|
struct State
|
|
: renderive::scene_inheritance::State_Root<State> {};
|
|
class Impl;
|
|
template <class Next>
|
|
using next_Builder =
|
|
renderive::scene_inheritance::Builder_Node<Next, Builder>;
|
|
template <class Next>
|
|
using next_State =
|
|
renderive::scene_inheritance::State_Node<Next, State>;
|
|
template <class Next>
|
|
using next_Impl =
|
|
renderive::scene_inheritance::Impl_Node<Next, Impl>;
|
|
template <class Next>
|
|
using next_Observer =
|
|
renderive::scene_inheritance::Observer_Node<Next, Observer>;
|
|
template <class Next>
|
|
using next_Editor =
|
|
renderive::scene_inheritance::Editor_Node<Next, Renderable_Editor>;
|
|
Scene_Base(std::pmr::memory_resource& upstream_memory_resource,
|
|
std::unique_ptr<Impl> impl);
|
|
void bind_observation_source(
|
|
std::unique_ptr<renderive::inheritance::Observation_Source> source);
|
|
void unbind_observation_source() noexcept;
|
|
[[nodiscard]] bool observation_snapshot(
|
|
std::type_index type, void* destination) const;
|
|
template <class Implementation = Impl>
|
|
Implementation& d_func() noexcept {
|
|
return static_cast<Implementation&>(*impl_);
|
|
}
|
|
template <class Implementation = Impl>
|
|
const Implementation& d_func() const noexcept {
|
|
return static_cast<const Implementation&>(*impl_);
|
|
}
|
|
private:
|
|
friend class Renderable_Base;
|
|
friend class Scene_2D_Base;
|
|
std::unique_ptr<Impl> impl_;
|
|
};
|
|
class Scene_2D_Base : public Scene_Base {
|
|
public:
|
|
class Renderable_Editor
|
|
: public Scene_Base::Renderable_Editor::next_Editor<Renderable_Editor> {
|
|
public:
|
|
template <class Next>
|
|
using next_Editor =
|
|
renderive::scene_inheritance::Editor_Node<Next, Renderable_Editor>;
|
|
[[nodiscard]] Scene_Edit_Error set_display_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error add_display_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error clear_display_parent(const Renderable& child);
|
|
private:
|
|
explicit Renderable_Editor(Scene_2D_Base& scene) : Scene_Base::Renderable_Editor::next_Editor<
|
|
Renderable_Editor>(scene),
|
|
scene_2d_(scene) {}
|
|
Scene_2D_Base& scene_2d_;
|
|
friend class Scene_2D_Base;
|
|
friend class Attach_Builder;
|
|
};
|
|
class Attach_Builder
|
|
: public Scene_Base::Attach_Builder::next_Builder<Attach_Builder> {
|
|
public:
|
|
template <class Next>
|
|
using next_Builder =
|
|
renderive::scene_inheritance::Builder_Node<Next, Attach_Builder>;
|
|
[[nodiscard]] Scene_Edit_Error set_display_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error add_display_parent(const Renderable& child, const Renderable& parent);
|
|
[[nodiscard]] Scene_Edit_Error clear_display_parent(const Renderable& child);
|
|
private:
|
|
explicit Attach_Builder(Scene_2D_Base& scene) : Scene_Base::Attach_Builder::next_Builder<
|
|
Attach_Builder>(scene),
|
|
scene_2d_(scene) {}
|
|
Scene_2D_Base& scene_2d_;
|
|
friend class Scene_2D_Base;
|
|
};
|
|
using Renderable_Edit = std::function<void(Renderable_Editor&)>;
|
|
Scene_2D_Base();
|
|
explicit Scene_2D_Base(std::pmr::memory_resource& memory_resource);
|
|
Attach_Builder attach_builder();
|
|
[[nodiscard]] static Attach_Builder attach_builder(const Renderable& anchor);
|
|
[[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit);
|
|
struct Observer
|
|
: Scene_Base::next_Observer<Observer> {};
|
|
protected:
|
|
struct Builder : Scene_Base::next_Builder<Builder> {};
|
|
struct State : Scene_Base::next_State<State> {};
|
|
struct Impl;
|
|
template <class Next>
|
|
using next_Builder =
|
|
renderive::scene_inheritance::Builder_Node<Next, Builder>;
|
|
template <class Next>
|
|
using next_State =
|
|
renderive::scene_inheritance::State_Node<Next, State>;
|
|
template <class Next>
|
|
using next_Impl =
|
|
renderive::scene_inheritance::Impl_Node<Next, Impl>;
|
|
template <class Next>
|
|
using next_Observer =
|
|
renderive::scene_inheritance::Observer_Node<Next, Observer>;
|
|
template <class Next>
|
|
using next_Editor =
|
|
renderive::scene_inheritance::Editor_Node<Next, Renderable_Editor>;
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Builder, Scene_Base::next_Builder<Builder>,
|
|
next_Builder<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Builder_Node<
|
|
renderive::inheritance::Chain_Probe, Builder>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
State, Scene_Base::next_State<State>,
|
|
next_State<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::State_Node<
|
|
renderive::inheritance::Chain_Probe, State>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Observer, Scene_Base::next_Observer<Observer>,
|
|
next_Observer<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Observer_Node<
|
|
renderive::inheritance::Chain_Probe, Observer>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Renderable_Editor,
|
|
Scene_Base::Renderable_Editor::next_Editor<Renderable_Editor>,
|
|
next_Editor<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Editor_Node<
|
|
renderive::inheritance::Chain_Probe, Renderable_Editor>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Attach_Builder,
|
|
Scene_Base::Attach_Builder::next_Builder<Attach_Builder>,
|
|
Attach_Builder::next_Builder<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Builder_Node<
|
|
renderive::inheritance::Chain_Probe, Attach_Builder>>);
|
|
Scene_2D_Base(std::pmr::memory_resource& memory_resource,
|
|
std::unique_ptr<Scene_Base::Impl> impl);
|
|
private:
|
|
friend class Scene_Base;
|
|
};
|
|
class Scene_3D_Base : public Scene_Base {
|
|
public:
|
|
class Renderable_Editor : public Scene_Base::Renderable_Editor::next_Editor<Renderable_Editor> {
|
|
public:
|
|
template <class Next>
|
|
using next_Editor =
|
|
renderive::scene_inheritance::Editor_Node<Next, Renderable_Editor>;
|
|
private:
|
|
explicit Renderable_Editor(Scene_3D_Base& scene) : Scene_Base::Renderable_Editor::next_Editor<
|
|
Renderable_Editor>(scene) {}
|
|
friend class Scene_3D_Base;
|
|
};
|
|
class Attach_Builder : public Scene_Base::Attach_Builder::next_Builder<Attach_Builder> {
|
|
public:
|
|
template <class Next>
|
|
using next_Builder =
|
|
renderive::scene_inheritance::Builder_Node<Next, Attach_Builder>;
|
|
private:
|
|
explicit Attach_Builder(Scene_3D_Base& scene) : Scene_Base::Attach_Builder::next_Builder<
|
|
Attach_Builder>(scene) {}
|
|
friend class Scene_3D_Base;
|
|
};
|
|
using Renderable_Edit = std::function<void(Renderable_Editor&)>;
|
|
[[nodiscard]] Edit_Operation edit_renderables(Renderable_Edit edit);
|
|
struct Observer
|
|
: Scene_Base::next_Observer<Observer> {};
|
|
protected:
|
|
Scene_3D_Base();
|
|
explicit Scene_3D_Base(std::pmr::memory_resource& memory_resource);
|
|
struct Builder : Scene_Base::next_Builder<Builder> {};
|
|
struct State : Scene_Base::next_State<State> {};
|
|
struct Impl;
|
|
template <class Next>
|
|
using next_Builder =
|
|
renderive::scene_inheritance::Builder_Node<Next, Builder>;
|
|
template <class Next>
|
|
using next_State =
|
|
renderive::scene_inheritance::State_Node<Next, State>;
|
|
template <class Next>
|
|
using next_Impl =
|
|
renderive::scene_inheritance::Impl_Node<Next, Impl>;
|
|
template <class Next>
|
|
using next_Observer =
|
|
renderive::scene_inheritance::Observer_Node<Next, Observer>;
|
|
template <class Next>
|
|
using next_Editor =
|
|
renderive::scene_inheritance::Editor_Node<Next, Renderable_Editor>;
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Builder, Scene_Base::next_Builder<Builder>,
|
|
next_Builder<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Builder_Node<
|
|
renderive::inheritance::Chain_Probe, Builder>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
State, Scene_Base::next_State<State>,
|
|
next_State<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::State_Node<
|
|
renderive::inheritance::Chain_Probe, State>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Observer, Scene_Base::next_Observer<Observer>,
|
|
next_Observer<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Observer_Node<
|
|
renderive::inheritance::Chain_Probe, Observer>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Renderable_Editor,
|
|
Scene_Base::Renderable_Editor::next_Editor<Renderable_Editor>,
|
|
next_Editor<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Editor_Node<
|
|
renderive::inheritance::Chain_Probe, Renderable_Editor>>);
|
|
static_assert(renderive::inheritance::Defines_Chain_Layer<
|
|
Attach_Builder,
|
|
Scene_Base::Attach_Builder::next_Builder<Attach_Builder>,
|
|
Attach_Builder::next_Builder<renderive::inheritance::Chain_Probe>,
|
|
renderive::scene_inheritance::Builder_Node<
|
|
renderive::inheritance::Chain_Probe, Attach_Builder>>);
|
|
Scene_3D_Base(std::pmr::memory_resource& memory_resource,
|
|
std::unique_ptr<Scene_Base::Impl> impl);
|
|
};
|
|
#include "Scene_Base.inl"
|