84 lines
3.2 KiB
C++
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(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
|