gled-core 2.30.2

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
//! One LED output frame: render every visible effect into the output buffer
//! and hand the buffer to the readback, which sends it as Art-Net/DMX.

use gled_gpu::{
    effect_state::EffectPipelines,
    gpu::OutputContext,
    scene_render::{EvalContext, prepare_project, render_scene_instance},
};
use gled_model::{asset::project::Project, timing::BeatState};
use wgpu::{CommandEncoderDescriptor, SubmissionIndex};

use crate::pipeline::extract_output::ExtractOutput;

/// Renders one LED output frame on the output device and dispatches its
/// readback to Art-Net/DMX. Render thread only.
#[cfg_attr(feature = "profiling", profiling::function)]
pub(crate) fn render_output(
    project: &Project,
    pipelines: &mut EffectPipelines,
    context: &OutputContext,
    beat_state: &BeatState,
    blackout: bool,
    eval: EvalContext<'_>,
    extract_output: &mut ExtractOutput,
) -> SubmissionIndex {
    let device = &context.gpu.device;
    let queue = &context.gpu.queue;
    prepare_project(project, pipelines, queue, beat_state, false, eval);

    #[allow(unused_mut)]
    let mut encoder = device.create_command_encoder(&CommandEncoderDescriptor {
        label: Some("Render output"),
    });

    #[cfg(feature = "profiling")]
    {
        let mut wgpu_profiler = crate::runtime::wgpu_profiler();
        context.clear_output(&mut wgpu_profiler.scope("OutputClear", &mut encoder));
        for instance in project.scenes_instances_grid.values() {
            render_scene_instance(
                instance,
                pipelines,
                &mut wgpu_profiler
                    .scope(format!("Render scene \"{}\"", instance.name), &mut encoder),
                blackout,
                false,
            );
        }
        extract_output.run(
            context,
            &mut wgpu_profiler.scope("ExtractOutput", &mut encoder),
        );
        wgpu_profiler.resolve_queries(&mut encoder);
    }

    #[cfg(not(feature = "profiling"))]
    {
        context.clear_output(&mut encoder);
        for instance in project.scenes_instances_grid.values() {
            render_scene_instance(instance, pipelines, &mut encoder, blackout, false);
        }
        extract_output.run(context, &mut encoder);
    }

    let submission = queue.submit([encoder.finish()]);
    // Let the output poll thread deliver this frame's readback as soon as the
    // GPU finishes it, independently of later frames.
    extract_output.notify_submitted(submission.clone());
    submission
}