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