Files
Renderive/Core/plot/Plot_Frame_Pipeline.h
T
2026-08-02 12:48:37 +08:00

84 lines
3.2 KiB
C++

#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 <array>
#include <atomic>
#include <cstdint>
#include <memory>
#include <memory_resource>
namespace renderive {
struct Update_State;
enum class Frame_Job_State {
Idle,
Running
};
struct Plot_Frame {
Plot_Frame();
std::atomic<std::uint64_t> version{0};
Image image;
std::pmr::vector<std::shared_ptr<Update_State>> presented_update_states;
std::shared_ptr<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;
std::shared_ptr<Frame_Lifecycle_Record> superseded_frame_record;
std::shared_ptr<Frame_Lifecycle_Record> dropped_frame_record;
std::uint64_t update_request_id{};
std::uint64_t update_request_time{};
bool request_present{};
};
struct Frame_Consume_Result {
Plot_Frame_Lease lease;
std::shared_ptr<Frame_Lifecycle_Record> returned_frame_record;
bool has_new_frame{};
bool present_request_was_pending{};
bool paint_frame_unavailable{};
};
Plot_Frame_Pipeline();
~Plot_Frame_Pipeline();
void advance_edit_version();
[[nodiscard]] bool has_unrendered_edit() 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_acquire_render_frame();
[[nodiscard]] Frame_Publish_Result try_publish_rendered_frame(Plot_Frame_Lease rendering_lease, std::uint64_t now_ns);
[[nodiscard]] Frame_Publish_Result request_present(std::uint64_t now_ns);
[[nodiscard]] Frame_Consume_Result try_acquire_paint_frame(std::uint64_t now_ns);
[[nodiscard]] bool middle_frame_ready() const;
[[nodiscard]] bool painting_frame_in_use() const;
void cancel_all_update_states();
Triple_Role_Buffer_Control frame_control;
std::array<Plot_Frame, 3> frames;
std::atomic<std::uint64_t> edit_version{1};
std::uint64_t rendered_edit_version = 0;
Frame_Job_State render_job_state = Frame_Job_State::Idle;
Frame_Attempt_Accumulator attempt_counters;
std::atomic_bool paint_request_pending{false};
std::atomic<std::uint64_t> pending_present_request_id{0};
std::atomic<std::uint64_t> pending_present_request_time_ns{0};
std::uint64_t next_present_request_id{};
};
} // namespace renderive