20 auto root_buf = std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer);
23 "GraphicsBatchProcessor can only process its associated RootGraphicsBuffer");
27 root_buf->cleanup_marked_buffers();
29 for (
auto& ch_buffer : root_buf->get_child_buffers()) {
33 if (ch_buffer->needs_removal()) {
37 if (!ch_buffer->has_data_for_cycle()) {
42 if (ch_buffer->needs_default_processing() && ch_buffer->get_default_processor()) {
43 ch_buffer->process_default();
46 if (
auto chain = ch_buffer->get_processing_chain()) {
47 if (ch_buffer->has_data_for_cycle()) {
48 chain->process(ch_buffer);
52 auto vk_buffer = std::dynamic_pointer_cast<Buffers::VKBuffer>(ch_buffer);
53 if (vk_buffer && vk_buffer->has_render_pipeline()) {
54 for (
const auto& [
id, window] : vk_buffer->get_render_pipelines()) {
61 root_buf->add_renderable_buffer(info);
64 "Registered buffer for rendering to window '{}'",
65 window->get_create_info().title);
69 }
catch (
const std::exception& e) {
71 "Error processing graphics buffer: {}", e.what());
78 auto root_graphics_buffer = std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer);
79 if (!root_graphics_buffer) {
80 error<std::invalid_argument>(
83 std::source_location::current(),
84 "GraphicsBatchProcessor can only be attached to RootGraphicsBuffer");
88 error<std::runtime_error>(
91 std::source_location::current(),
92 "GraphicsBatchProcessor token incompatible with RootGraphicsBuffer requirements");
98 return std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer) !=
nullptr;
102 : m_callback(
std::move(callback))
103 , m_root_buffer(nullptr)
109 : m_callback(nullptr)
110 , m_root_buffer(nullptr)
117 auto root_graphics_buffer = std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer);
118 if (!root_graphics_buffer) {
120 "RenderProcessor received non-RootGraphicsBuffer");
126 "RenderProcessor processing buffer that doesn't match attached root");
133 }
catch (
const std::exception& e) {
137 std::source_location::current(),
138 "RenderProcessor callback threw exception: {}",
148 auto root_graphics_buffer = std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer);
149 if (!root_graphics_buffer) {
150 error<std::invalid_argument>(
153 std::source_location::current(),
154 "RenderProcessor can only be attached to RootGraphicsBuffer");
158 error<std::runtime_error>(
161 std::source_location::current(),
162 "RenderProcessor token incompatible with RootGraphicsBuffer requirements");
168 "RenderProcessor attached to RootGraphicsBuffer (has_callback: {})",
174 if (
auto root = std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer)) {
181 "RenderProcessor detached from RootGraphicsBuffer");
186 return std::dynamic_pointer_cast<RootGraphicsBuffer>(buffer) !=
nullptr;
194 "RenderProcessor callback {} (attached: {})",
204 const auto& renderable_buffers = root->get_renderable_buffers();
206 if (renderable_buffers.empty()) {
208 "No renderable buffers found in fallback renderer");
213 "PresentProcessor submitting {} renderable buffers",
214 renderable_buffers.size());
216 std::unordered_map<Core::Window*, std::vector<const RootGraphicsBuffer::RenderableBufferInfo*>> buffers_by_window;
218 for (
const auto& renderable : renderable_buffers) {
219 buffers_by_window[renderable.target_window.get()].push_back(&renderable);
222 for (
const auto& [window_ptr, buffer_infos] : buffers_by_window) {
223 auto window = buffer_infos[0]->target_window;
227 "Skipping present: window no longer valid");
232 for (
const auto* info : buffer_infos) {
234 flow.present_rendered_image(
235 info->command_buffer_id,
241 "Presented {} buffers to window '{}'",
243 window->get_create_info().title);
245 }
catch (
const std::exception& e) {
247 "Failed to submit/present for window '{}': {}",
248 window->get_create_info().title,
252 for (
const auto* info : buffer_infos) {
253 info->buffer->clear_pipeline_commands();
257 root->clear_renderable_buffers();
261 : m_final_processor(nullptr)
277 if (batch_processor) {
297 auto it = std::remove_if(
300 [](
const std::shared_ptr<Buffer>& buf) {
301 return buf && buf->needs_removal();
306 if (removed_count > 0) {
310 "Cleaned up {} graphics buffers (remaining: {})",
334 std::vector<std::shared_ptr<VKBuffer>> filtered_buffers;
337 if (buffer && buffer->get_usage() == usage) {
338 filtered_buffers.push_back(buffer);
342 return filtered_buffers;
347 return std::make_shared<GraphicsBatchProcessor>(shared_from_this());
#define MF_INFO(comp, ctx,...)
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_RT_TRACE(comp, ctx,...)
#define MF_RT_DEBUG(comp, ctx,...)
ProcessingToken m_processing_token
bool is_compatible_with(std::shared_ptr< Buffer > buffer) const override
Checks compatibility with a specific buffer type.
std::shared_ptr< RootGraphicsBuffer > m_root_buffer
Shared pointer to the root buffer this processor manages.
void on_attach(std::shared_ptr< Buffer > buffer) override
Called when processor is attached to a buffer.
GraphicsBatchProcessor(std::shared_ptr< Buffer > root_buffer)
Creates a new graphics batch processor.
void processing_function(std::shared_ptr< Buffer > buffer) override
Processes a buffer by coordinating child buffer operations.
std::function< void(const std::shared_ptr< RootGraphicsBuffer > &root)> RenderCallback
Callback signature for render operations.
RenderCallback m_callback
User-provided render callback.
bool has_callback() const
Checks if a callback is configured.
void processing_function(std::shared_ptr< Buffer > buffer) override
Executes the render callback.
void set_callback(RenderCallback callback)
Sets or updates the render callback.
bool is_compatible_with(std::shared_ptr< Buffer > buffer) const override
Checks compatibility with a specific buffer type.
void fallback_renderer(const std::shared_ptr< RootGraphicsBuffer > &root)
void on_attach(std::shared_ptr< Buffer > buffer) override
Called when processor is attached to a buffer.
PresentProcessor()
Default constructor (no callback set)
void on_detach(std::shared_ptr< Buffer > buffer) override
Called when processor is detached from a buffer.
std::shared_ptr< RootGraphicsBuffer > m_root_buffer
Reference to root buffer (for validation and callbacks)
void process_pending_buffer_operations()
Process pending operations - call this at start of processing cycles.
bool has_pending_operations() const
ProcessingToken m_preferred_processing_token
Preferred processing token for this root buffer.
TokenEnforcementStrategy m_token_enforcement_strategy
Current token enforcement strategy for this root buffer.
std::vector< std::shared_ptr< VKBuffer > > m_child_buffers
Vector of tributary buffers that contribute to this root buffer.
void process_default() override
Processes this root buffer using default processing.
std::shared_ptr< BufferProcessor > get_final_processor() const
Gets the current final processor.
void cleanup_marked_buffers()
Removes buffers marked for deletion.
void set_final_processor(std::shared_ptr< BufferProcessor > processor)
Sets an optional final processor.
std::vector< std::shared_ptr< VKBuffer > > get_buffers_by_usage(VKBuffer::Usage usage) const
Gets buffers filtered by usage type.
std::shared_ptr< BufferProcessor > m_final_processor
Optional final processor (rarely used in graphics)
std::vector< std::shared_ptr< VKBuffer > > m_pending_removal
Buffers pending removal (cleaned up in next process cycle)
void initialize()
Initializes the root buffer with default processor.
bool has_buffer(const std::shared_ptr< VKBuffer > &buffer) const
Checks if a specific buffer is registered.
~RootGraphicsBuffer() override
Virtual destructor ensuring proper cleanup.
RootGraphicsBuffer()
Creates a new root graphics buffer.
std::shared_ptr< BufferProcessor > create_default_processor()
Creates the default graphics batch processor.
Root container for GPU buffer lifecycle management and batch processing.
std::shared_ptr< Buffers::BufferProcessor > get_default_processor() const override
Get the currently attached default processor.
void set_default_processor(std::shared_ptr< Buffers::BufferProcessor > processor) override
Set the buffer's default processor.
bool are_tokens_compatible(ProcessingToken preferred, ProcessingToken current)
Determines if two processing tokens are compatible for joint execution.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
@ STRICT
Strictly enforces token assignment with no cross-token sharing.
@ BufferManagement
Buffer Management (Buffers::BufferManager, creating buffers)
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
@ Core
Core engine, backend, subsystems.
MAYAFLUX_API RenderFlow & get_render_flow()
Get the global render flow instance.
MAYAFLUX_API ShaderFoundry & get_shader_foundry()
Get the global shader compiler instance.
constexpr CommandBufferID INVALID_COMMAND_BUFFER
CommandBufferID command_buffer_id
std::shared_ptr< VKBuffer > buffer
std::shared_ptr< Core::Window > target_window
RenderPipelineID pipeline_id
Information about a buffer that's ready to render.