245{
246 const auto& renderable_buffers = root->get_renderable_buffers();
247 const auto& pending_refreshes = root->get_pending_presentation_refreshes();
248 if (renderable_buffers.empty() && pending_refreshes.empty()) {
249 return;
250 }
251
252 std::unordered_map<std::shared_ptr<Core::Window>, std::vector<const RootGraphicsBuffer::RenderableBufferInfo*>> buffers_by_window;
253 for (auto it = pending_refreshes.begin(); it != pending_refreshes.end();) {
254 const auto&
window = *it++;
255 if (
window->should_close() || !
window->is_graphics_registered()) {
256 root->clear_presentation_refresh(
window);
257 continue;
258 }
259 buffers_by_window.try_emplace(
window);
260 }
261
262 for (const auto& renderable : renderable_buffers) {
263 if (renderable.target_window && renderable.target_window->is_graphics_registered()
265 buffers_by_window[renderable.target_window].push_back(&renderable);
266 }
267 }
268
269 if (buffers_by_window.empty()) {
270 root->clear_renderable_buffers();
271 return;
272 }
273
275 "PresentProcessor submitting to {} windows", buffers_by_window.size());
276
281
282 if (!display_service) {
284 "DisplayService not available for dynamic rendering");
285 return;
286 }
287
288 for (
const auto& [
window, buffer_infos] : buffers_by_window) {
289 uint64_t image_bits = display_service->acquire_next_swapchain_image(
window);
290 if (image_bits == 0) {
292 "Failed to acquire swapchain image for window '{}'",
293 window->get_create_info().title);
294 continue;
295 }
296 vk::Image swapchain_image { reinterpret_cast<VkImage>(image_bits) };
297
299 auto primary_cmd = foundry.get_command_buffer(primary_cmd_id);
300
301 if (!primary_cmd) {
303 "Failed to create primary command buffer for window '{}'",
304 window->get_create_info().title);
305 for (const auto* info : buffer_infos) {
306 info->buffer->clear_pipeline_commands();
307 }
308 continue;
309 }
310
311 try {
312 bool window_needs_depth = false;
313 for (const auto* info : buffer_infos) {
314 if (info->needs_depth) {
315 window_needs_depth = true;
316 break;
317 }
318 }
319
320 vk::ImageView depth_view = nullptr;
321 if (window_needs_depth) {
322 display_service->ensure_depth_attachment(
window);
323 auto* view_ptr = display_service->get_depth_image_view(
window);
324 if (view_ptr) {
325 depth_view = *static_cast<vk::ImageView*>(view_ptr);
326 }
327 }
328
329 flow.begin_rendering(primary_cmd_id,
window, swapchain_image,
331
332 std::vector<vk::CommandBuffer> secondary_buffers;
333 for (const auto* info : buffer_infos) {
334 auto secondary = foundry.get_command_buffer(info->command_buffer_id);
335 if (secondary) {
336 secondary_buffers.push_back(secondary);
337 }
338 }
339
340 if (!secondary_buffers.empty()) {
341 primary_cmd.executeCommands(secondary_buffers);
342 }
343
344 flow.end_rendering(primary_cmd_id,
window);
345
346 foundry.end_commands(primary_cmd_id);
347 uint64_t primary_bits = *reinterpret_cast<uint64_t*>(&primary_cmd);
348 display_service->submit_and_present(
window, primary_bits);
349 root->clear_presentation_refresh(
window);
350
352 "Presented {} buffers to window '{}'",
353 secondary_buffers.size(),
window->get_create_info().title);
354
355 } catch (const std::exception& e) {
357 "Failed to submit/present for window '{}': {}",
358 window->get_create_info().title,
359 e.what());
360 }
361
362 for (const auto* info : buffer_infos) {
363 info->buffer->clear_pipeline_commands();
364 }
365 }
366
367 root->clear_renderable_buffers();
368}
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_RT_DEBUG(comp, ctx,...)
std::weak_ptr< Core::Window > window
Interface * get_service()
Query for a backend service.
static BackendRegistry & instance()
Get the global registry instance.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
const std::array< float, 4 > default_color
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