#include "RuntimeRenderScene.h" #include #include #include RuntimeRenderScene::~RuntimeRenderScene() { ShutdownGl(); } bool RuntimeRenderScene::CommitRenderLayers(const std::vector& layers, std::string& error) { std::vector 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(); 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 nextRenderer = std::make_unique(); 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 hasher; return artifact.shaderId + ":" + std::to_string(artifact.fragmentShaderSource.size()) + ":" + std::to_string(hasher(artifact.fragmentShaderSource)); }