#pragma once #include "../architecture/Frame_Scheduler.h" #include "../architecture/Render_Config.h" #include "../architecture/Triple_Buffer.h" #include "../base/Geometry.h" #include "../base/Object_Semantics.h" #include "../render/Image.h" #include #include #include #include #include namespace renderive { struct Update_State; enum class Plot_Render_Job_State { Idle, Running }; struct Plot_Frame { Plot_Frame(); std::atomic version{0}; Image image; std::pmr::vector> presented_update_states; Frame_Lifecycle_Record metadata; }; struct Plot_Frame_Lease : Move_Only { Plot_Frame_Lease() = default; Plot_Frame_Lease(Plot_Frame* buffer, Triple_Role_Buffer_Control* control, Triple_Buffer_Lease lease); Plot_Frame_Lease(Plot_Frame_Lease&& other) noexcept; Plot_Frame_Lease& operator=(Plot_Frame_Lease&& other) noexcept; ~Plot_Frame_Lease(); void reset(); Plot_Frame* frame{}; Triple_Role_Buffer_Control* control{}; Triple_Buffer_Lease lease{}; explicit operator bool() const { return frame && lease; } }; class Plot_Frame_Pipeline { public: struct Frame_Publish_Result { Rect dirty_rect; Plot_Frame* superseded_middle{}; Plot_Frame* dropped_frame{}; std::uint64_t update_request_id{}; std::uint64_t update_request_time{}; bool request_present{}; }; struct Frame_Consume_Result { Plot_Frame_Lease lease; Frame_Lifecycle_Record returned_frame; bool has_returned_frame{}; bool new_frame{}; bool update_was_pending{}; bool paint_acquire_dropped{}; }; Plot_Frame_Pipeline(); ~Plot_Frame_Pipeline(); void mark_edit_state(); [[nodiscard]] bool has_new_state() const; [[nodiscard]] Plot_Frame* frame_by_index(std::uint8_t index); [[nodiscard]] const Plot_Frame* frame_by_index(std::uint8_t index) const; [[nodiscard]] Plot_Frame* frame_by_role(std::uint8_t role); [[nodiscard]] const Plot_Frame* frame_by_role(std::uint8_t role) const; [[nodiscard]] Plot_Frame_Lease try_begin_render(); [[nodiscard]] Frame_Publish_Result try_publish_rendered(std::uint64_t now_ns); [[nodiscard]] Frame_Publish_Result request_paint_update(std::uint64_t now_ns); [[nodiscard]] Frame_Consume_Result try_begin_paint(std::uint64_t now_ns); [[nodiscard]] bool middle_has_new_frame() const; [[nodiscard]] bool paint_active() const; void cancel_all_update_states(); Triple_Role_Buffer_Control frame_control; std::array frames; std::atomic edit_state_version{1}; std::uint64_t render_state_version = 0; Plot_Render_Job_State job_state = Plot_Render_Job_State::Idle; Frame_Attempt_Accumulator attempts; std::atomic_bool paint_request_pending{false}; std::atomic pending_update_request_id{0}; std::atomic pending_update_request_time{0}; std::uint64_t next_update_request_id{}; }; } // namespace renderive