Loading libs/renderengine/gl/filters/BlurFilter.cpp +24 −20 Original line number Diff line number Diff line Loading @@ -122,27 +122,35 @@ void BlurFilter::drawMesh(GLuint uv, GLuint position) { status_t BlurFilter::prepare() { ATRACE_NAME("BlurFilter::prepare"); blit(mCompositionFbo, mPingFbo); // Kawase is an approximation of Gaussian, but it behaves differently from it. // A radius transformation is required for approximating them, and also to introduce // non-integer steps, necessary to smoothly interpolate large radii. auto radius = mRadius / 6.0f; const auto radius = mRadius / 6.0f; // Calculate how many passes we'll do, based on the radius. // Too many passes will make the operation expensive. auto passes = min(kMaxPasses, (uint32_t)ceil(radius)); const auto passes = min(kMaxPasses, (uint32_t)ceil(radius)); // We'll ping pong between our textures, to accumulate the result of various offsets. const float radiusByPasses = radius / (float)passes; 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); glUniform1i(mBTextureLoc, 0); glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); glUniform2f(mBOffsetLoc, stepX, stepY); glViewport(0, 0, mPingFbo.getBufferWidth(), mPingFbo.getBufferHeight()); mPingFbo.bind(); drawMesh(mBUvLoc, mBPosLoc); // And now we'll ping pong between our textures, to accumulate the result of various offsets. GLFramebuffer* read = &mPingFbo; GLFramebuffer* draw = &mPongFbo; float stepX = radius / (float)mCompositionFbo.getBufferWidth() / (float)passes; float stepY = radius / (float)mCompositionFbo.getBufferHeight() / (float)passes; glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight()); glActiveTexture(GL_TEXTURE0); glUniform1i(mBTextureLoc, 0); for (auto i = 0; i < passes; i++) { for (auto i = 1; i < passes; i++) { ATRACE_NAME("BlurFilter::renderPass"); draw->bind(); Loading @@ -158,9 +166,6 @@ status_t BlurFilter::prepare() { } mLastDrawTarget = read; // Cleanup glBindFramebuffer(GL_FRAMEBUFFER, 0); return NO_ERROR; } Loading @@ -179,7 +184,6 @@ status_t BlurFilter::render(bool multiPass) { glBlitFramebuffer(0, 0, mLastDrawTarget->getBufferWidth(), mLastDrawTarget->getBufferHeight(), 0, 0, mDisplayWidth, mDisplayHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); return NO_ERROR; } Loading Loading @@ -258,12 +262,12 @@ string BlurFilter::getMixFragShader() const { } void BlurFilter::blit(GLFramebuffer& read, GLFramebuffer& draw) const { ATRACE_NAME("BlurFilter::blit"); read.bindAsReadBuffer(); draw.bindAsDrawBuffer(); glBlitFramebuffer(0, 0, read.getBufferWidth(), read.getBufferHeight(), 0, 0, draw.getBufferWidth(), draw.getBufferHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_FRAMEBUFFER, 0); } } // namespace gl Loading Loading
libs/renderengine/gl/filters/BlurFilter.cpp +24 −20 Original line number Diff line number Diff line Loading @@ -122,27 +122,35 @@ void BlurFilter::drawMesh(GLuint uv, GLuint position) { status_t BlurFilter::prepare() { ATRACE_NAME("BlurFilter::prepare"); blit(mCompositionFbo, mPingFbo); // Kawase is an approximation of Gaussian, but it behaves differently from it. // A radius transformation is required for approximating them, and also to introduce // non-integer steps, necessary to smoothly interpolate large radii. auto radius = mRadius / 6.0f; const auto radius = mRadius / 6.0f; // Calculate how many passes we'll do, based on the radius. // Too many passes will make the operation expensive. auto passes = min(kMaxPasses, (uint32_t)ceil(radius)); const auto passes = min(kMaxPasses, (uint32_t)ceil(radius)); // We'll ping pong between our textures, to accumulate the result of various offsets. const float radiusByPasses = radius / (float)passes; 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); glUniform1i(mBTextureLoc, 0); glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); glUniform2f(mBOffsetLoc, stepX, stepY); glViewport(0, 0, mPingFbo.getBufferWidth(), mPingFbo.getBufferHeight()); mPingFbo.bind(); drawMesh(mBUvLoc, mBPosLoc); // And now we'll ping pong between our textures, to accumulate the result of various offsets. GLFramebuffer* read = &mPingFbo; GLFramebuffer* draw = &mPongFbo; float stepX = radius / (float)mCompositionFbo.getBufferWidth() / (float)passes; float stepY = radius / (float)mCompositionFbo.getBufferHeight() / (float)passes; glViewport(0, 0, draw->getBufferWidth(), draw->getBufferHeight()); glActiveTexture(GL_TEXTURE0); glUniform1i(mBTextureLoc, 0); for (auto i = 0; i < passes; i++) { for (auto i = 1; i < passes; i++) { ATRACE_NAME("BlurFilter::renderPass"); draw->bind(); Loading @@ -158,9 +166,6 @@ status_t BlurFilter::prepare() { } mLastDrawTarget = read; // Cleanup glBindFramebuffer(GL_FRAMEBUFFER, 0); return NO_ERROR; } Loading @@ -179,7 +184,6 @@ status_t BlurFilter::render(bool multiPass) { glBlitFramebuffer(0, 0, mLastDrawTarget->getBufferWidth(), mLastDrawTarget->getBufferHeight(), 0, 0, mDisplayWidth, mDisplayHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); return NO_ERROR; } Loading Loading @@ -258,12 +262,12 @@ string BlurFilter::getMixFragShader() const { } void BlurFilter::blit(GLFramebuffer& read, GLFramebuffer& draw) const { ATRACE_NAME("BlurFilter::blit"); read.bindAsReadBuffer(); draw.bindAsDrawBuffer(); glBlitFramebuffer(0, 0, read.getBufferWidth(), read.getBufferHeight(), 0, 0, draw.getBufferWidth(), draw.getBufferHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_FRAMEBUFFER, 0); } } // namespace gl Loading