diff options
author | Danny Lin <danny@kdrag0n.dev> | 2021-04-12 22:10:18 -0700 |
---|---|---|
committer | alk3pInjection <webmaster@raspii.tech> | 2021-09-27 21:17:05 +0800 |
commit | 2cc4d0551d60ae4748f88ba1da73cb5db0b6c366 (patch) | |
tree | dafcec56e18627f2393b5dc954a7c197240d92d8 | |
parent | fe6ef85733f662394c6a1ba0abf74dfb2eb93f99 (diff) |
[ProtonAOSP] blur: Downscale image before blurring
Unintuitively, combining the initial blur pass with downscaling makes
the rendering process slower because sampling from the high-resolution
image with bilinear sampling uses more memory bandwidth. It also
increases the total amount of ALU work because it effectively introduces
an unnecessary blur pass.
By downscaling the image with glBlitFramebuffer before running blur
passes, we can save a blur pass and render a more correct result. When
tested with 2 layers of another 6-pass blur implementation, this saves
~800 µs of rendering time on an Adreno 640 GPU at 1440x3040 resolution.
Change-Id: Ie897a52f1628e40d34c3c31f5f779020594bb091
-rw-r--r-- | libs/renderengine/gl/filters/BlurFilter.cpp | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp index a48ce26741..f1d325b53f 100644 --- a/libs/renderengine/gl/filters/BlurFilter.cpp +++ b/libs/renderengine/gl/filters/BlurFilter.cpp @@ -176,18 +176,21 @@ status_t BlurFilter::prepare() { const float stepX = radiusByPasses / (float)mCompositionFbo.getBufferWidth(); const float stepY = radiusByPasses / (float)mCompositionFbo.getBufferHeight(); - // Let's start by downsampling and blurring the composited frame simultaneously. - mBlurProgram.useProgram(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); - glUniform2f(mBOffsetLoc, stepX, stepY); - glViewport(0, 0, mPingFbo.getBufferWidth(), mPingFbo.getBufferHeight()); - mPingFbo.bind(); - drawMesh(mBUvLoc, mBPosLoc); + // This initial downscaling blit makes the first pass correct and improves performance. + GLFramebuffer* read = &mCompositionFbo; + GLFramebuffer* draw = &mPingFbo; + read->bindAsReadBuffer(); + draw->bindAsDrawBuffer(); + glBlitFramebuffer(0, 0, + read->getBufferWidth(), read->getBufferHeight(), + 0, 0, + draw->getBufferWidth(), draw->getBufferHeight(), + GL_COLOR_BUFFER_BIT, GL_LINEAR); + read = &mPingFbo; + draw = &mPongFbo; // And now we'll ping pong between our textures, to accumulate the result of various offsets. - GLFramebuffer* read = &mPingFbo; - GLFramebuffer* draw = &mPongFbo; + mBlurProgram.useProgram(); glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight()); for (auto i = 1; i < passes; i++) { ATRACE_NAME("BlurFilter::renderPass"); @@ -199,9 +202,7 @@ status_t BlurFilter::prepare() { drawMesh(mBUvLoc, mBPosLoc); // Swap buffers for next iteration - auto tmp = draw; - draw = read; - read = tmp; + std::swap(read, draw); } mLastDrawTarget = read; |