diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 871322073e..fc0a5c89e0 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -286,13 +286,10 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha nextHeight = (int)rc.h; } - // No depth/stencil for post processing - Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ nextWidth, nextHeight, 1, 1, false, Draw::FBO_8888 }); - if (!fbo) { + if (!AllocateFramebuffer(nextWidth, nextHeight)) { pipeline->Release(); return false; } - postShaderFramebuffers_.push_back(fbo); } postShaderPipelines_.push_back(pipeline); @@ -300,6 +297,31 @@ bool PresentationCommon::BuildPostShader(const ShaderInfo *shaderInfo, const Sha return true; } +bool PresentationCommon::AllocateFramebuffer(int w, int h) { + using namespace Draw; + + // First, let's try to find a framebuffer of the right size that is NOT the most recent. + Framebuffer *last = postShaderFramebuffers_.empty() ? nullptr : postShaderFramebuffers_.back(); + for (const auto &prev : postShaderFBOUsage_) { + if (prev.w == w && prev.h == h && prev.fbo != last) { + // Great, this one's perfect. Ref it for when we release. + prev.fbo->AddRef(); + postShaderFramebuffers_.push_back(prev.fbo); + return true; + } + } + + // No depth/stencil for post processing + Draw::Framebuffer *fbo = draw_->CreateFramebuffer({ w, h, 1, 1, false, Draw::FBO_8888 }); + if (!fbo) { + return false; + } + + postShaderFBOUsage_.push_back({ fbo, w, h }); + postShaderFramebuffers_.push_back(fbo); + return true; +} + void PresentationCommon::ShowPostShaderError(const std::string &errorString) { // let's show the first line of the error string as an OSM. std::set blacklistedLines; @@ -435,6 +457,7 @@ void PresentationCommon::DestroyPostShader() { DoReleaseVector(postShaderPipelines_); DoReleaseVector(postShaderFramebuffers_); postShaderInfo_.clear(); + postShaderFBOUsage_.clear(); } Draw::ShaderModule *PresentationCommon::CompileShaderModule(Draw::ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString) { diff --git a/GPU/Common/PresentationCommon.h b/GPU/Common/PresentationCommon.h index 502ef318e9..96f6832f8d 100644 --- a/GPU/Common/PresentationCommon.h +++ b/GPU/Common/PresentationCommon.h @@ -122,6 +122,7 @@ protected: Draw::ShaderModule *CompileShaderModule(Draw::ShaderStage stage, ShaderLanguage lang, const std::string &src, std::string *errorString); Draw::Pipeline *CreatePipeline(std::vector shaders, bool postShader, const Draw::UniformBufferDesc *uniformDesc); bool BuildPostShader(const ShaderInfo *shaderInfo, const ShaderInfo *next); + bool AllocateFramebuffer(int w, int h); void BindSource(); @@ -155,4 +156,11 @@ protected: bool usePostShader_ = false; bool restorePostShader_ = false; ShaderLanguage lang_; + + struct PrevFBO { + Draw::Framebuffer *fbo; + int w; + int h; + }; + std::vector postShaderFBOUsage_; };