#pragma once #include "GLExtensions.h" #include "ShaderTypes.h" #include #include #include #include #include struct RuntimeRenderState; class TemporalHistoryBuffers { public: struct Slot { GLuint texture = 0; GLuint framebuffer = 0; }; struct Ring { std::vector slots; std::size_t nextWriteIndex = 0; std::size_t filledCount = 0; unsigned effectiveLength = 0; TemporalHistorySource historySource = TemporalHistorySource::None; }; bool ValidateTextureUnitBudget(const std::vector& layerStates, unsigned historyCap, std::string& error) const; bool EnsureResources(const std::vector& layerStates, unsigned historyCap, unsigned frameWidth, unsigned frameHeight, std::string& error); bool CreateRing(Ring& ring, unsigned effectiveLength, TemporalHistorySource historySource, unsigned frameWidth, unsigned frameHeight, std::string& error); void DestroyRing(Ring& ring); void DestroyResources(); void ResetState(); void PushFramebuffer(GLuint sourceFramebuffer, Ring& ring, unsigned frameWidth, unsigned frameHeight); void PushSourceFramebuffer(GLuint sourceFramebuffer, unsigned frameWidth, unsigned frameHeight); void PushPreLayerFramebuffer(const std::string& layerId, GLuint sourceFramebuffer, unsigned frameWidth, unsigned frameHeight); void BindSamplers(const RuntimeRenderState& state, GLuint currentSourceTexture, unsigned historyCap); GLuint ResolveTexture(const Ring& ring, GLuint fallbackTexture, std::size_t framesAgo) const; unsigned SourceAvailableCount() const; unsigned AvailableCountForLayer(const std::string& layerId) const; private: Ring sourceHistoryRing; std::map preLayerHistoryByLayerId; bool mNeedsReset = true; };