Files
video-shader-toys/apps/RenderCadenceCompositor/render/RuntimeRenderScene.cpp
Aiden d07ea1f63a
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m59s
CI / Windows Release Package (push) Has been skipped
Render changes
2026-05-12 14:36:36 +10:00

115 lines
3.0 KiB
C++

#include "RuntimeRenderScene.h"
#include <algorithm>
#include <functional>
#include <utility>
RuntimeRenderScene::~RuntimeRenderScene()
{
ShutdownGl();
}
bool RuntimeRenderScene::CommitRenderLayers(const std::vector<RenderCadenceCompositor::RuntimeRenderLayerModel>& layers, std::string& error)
{
std::vector<std::string> nextOrder;
nextOrder.reserve(layers.size());
for (const RenderCadenceCompositor::RuntimeRenderLayerModel& layer : layers)
nextOrder.push_back(layer.id);
for (auto layerIt = mLayers.begin(); layerIt != mLayers.end();)
{
const bool stillPresent = std::find(nextOrder.begin(), nextOrder.end(), layerIt->layerId) != nextOrder.end();
if (stillPresent)
{
++layerIt;
continue;
}
if (layerIt->renderer)
layerIt->renderer->ShutdownGl();
layerIt = mLayers.erase(layerIt);
}
for (const RenderCadenceCompositor::RuntimeRenderLayerModel& layer : layers)
{
if (layer.artifact.fragmentShaderSource.empty())
continue;
const std::string fingerprint = Fingerprint(layer.artifact);
LayerProgram* program = FindLayer(layer.id);
if (!program)
{
LayerProgram next;
next.layerId = layer.id;
next.renderer = std::make_unique<RuntimeShaderRenderer>();
mLayers.push_back(std::move(next));
program = &mLayers.back();
}
if (program->shaderId == layer.shaderId && program->sourceFingerprint == fingerprint && program->renderer && program->renderer->HasProgram())
continue;
std::unique_ptr<RuntimeShaderRenderer> nextRenderer = std::make_unique<RuntimeShaderRenderer>();
if (!nextRenderer->CommitShaderArtifact(layer.artifact, error))
return false;
if (program->renderer)
program->renderer->ShutdownGl();
program->shaderId = layer.shaderId;
program->sourceFingerprint = fingerprint;
program->renderer = std::move(nextRenderer);
}
mLayerOrder = std::move(nextOrder);
error.clear();
return true;
}
void RuntimeRenderScene::RenderFrame(uint64_t frameIndex, unsigned width, unsigned height)
{
for (const std::string& layerId : mLayerOrder)
{
LayerProgram* layer = FindLayer(layerId);
if (!layer || !layer->renderer || !layer->renderer->HasProgram())
continue;
layer->renderer->RenderFrame(frameIndex, width, height);
}
}
void RuntimeRenderScene::ShutdownGl()
{
for (LayerProgram& layer : mLayers)
{
if (layer.renderer)
layer.renderer->ShutdownGl();
}
mLayers.clear();
mLayerOrder.clear();
}
RuntimeRenderScene::LayerProgram* RuntimeRenderScene::FindLayer(const std::string& layerId)
{
for (LayerProgram& layer : mLayers)
{
if (layer.layerId == layerId)
return &layer;
}
return nullptr;
}
const RuntimeRenderScene::LayerProgram* RuntimeRenderScene::FindLayer(const std::string& layerId) const
{
for (const LayerProgram& layer : mLayers)
{
if (layer.layerId == layerId)
return &layer;
}
return nullptr;
}
std::string RuntimeRenderScene::Fingerprint(const RuntimeShaderArtifact& artifact)
{
const std::hash<std::string> hasher;
return artifact.shaderId + ":" + std::to_string(artifact.fragmentShaderSource.size()) + ":" + std::to_string(hasher(artifact.fragmentShaderSource));
}