Loading libs/renderengine/gl/GLESRenderEngine.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1003,7 +1003,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, setViewportAndProjection(display.physicalDisplay, display.clip); setViewportAndProjection(display.physicalDisplay, display.clip); } else { } else { setViewportAndProjection(display.physicalDisplay, display.clip); setViewportAndProjection(display.physicalDisplay, display.clip); auto status = mBlurFilter->setAsDrawTarget(display); auto status = mBlurFilter->setAsDrawTarget(display, blurLayer->backgroundBlurRadius); if (status != NO_ERROR) { if (status != NO_ERROR) { ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).", ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).", buffer->handle); buffer->handle); Loading Loading @@ -1037,7 +1037,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, .build(); .build(); for (auto const layer : layers) { for (auto const layer : layers) { if (blurLayer == layer) { if (blurLayer == layer) { auto status = mBlurFilter->prepare(layer->backgroundBlurRadius); auto status = mBlurFilter->prepare(); if (status != NO_ERROR) { if (status != NO_ERROR) { ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).", ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).", buffer->handle); buffer->handle); Loading libs/renderengine/gl/GLFramebuffer.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,14 @@ void GLFramebuffer::bind() const { glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName); } } void GLFramebuffer::bindAsReadBuffer() const { glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferName); } void GLFramebuffer::bindAsDrawBuffer() const { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferName); } void GLFramebuffer::unbind() const { void GLFramebuffer::unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } } Loading libs/renderengine/gl/GLFramebuffer.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,8 @@ public: int32_t getBufferWidth() const { return mBufferWidth; } int32_t getBufferWidth() const { return mBufferWidth; } GLenum getStatus() const { return mStatus; } GLenum getStatus() const { return mStatus; } void bind() const; void bind() const; void bindAsReadBuffer() const; void bindAsDrawBuffer() const; void unbind() const; void unbind() const; private: private: Loading libs/renderengine/gl/filters/BlurFilter.cpp +38 −25 Original line number Original line Diff line number Diff line Loading @@ -31,29 +31,24 @@ namespace renderengine { namespace gl { namespace gl { BlurFilter::BlurFilter(GLESRenderEngine& engine) BlurFilter::BlurFilter(GLESRenderEngine& engine) : mEngine(engine), mCompositionFbo(engine), mBlurredFbo(engine), mSimpleProgram(engine) { : mEngine(engine), mCompositionFbo(engine), mBlurredFbo(engine), mMixProgram(engine) { mSimpleProgram.compile(getVertexShader(), getSimpleFragShader()); mMixProgram.compile(getVertexShader(), getMixFragShader()); mSPosLoc = mSimpleProgram.getAttributeLocation("aPosition"); mMPosLoc = mMixProgram.getAttributeLocation("aPosition"); mSUvLoc = mSimpleProgram.getAttributeLocation("aUV"); mMUvLoc = mMixProgram.getAttributeLocation("aUV"); mSTextureLoc = mSimpleProgram.getUniformLocation("uTexture"); mMTextureLoc = mMixProgram.getUniformLocation("uTexture"); mMCompositionTextureLoc = mMixProgram.getUniformLocation("uCompositionTexture"); mMMixLoc = mMixProgram.getUniformLocation("uMix"); } } status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display) { status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display, uint32_t radius) { ATRACE_NAME("BlurFilter::setAsDrawTarget"); ATRACE_NAME("BlurFilter::setAsDrawTarget"); mRadius = radius; if (!mTexturesAllocated) { if (!mTexturesAllocated) { mDisplayWidth = display.physicalDisplay.width(); mDisplayWidth = display.physicalDisplay.width(); mDisplayHeight = display.physicalDisplay.height(); mDisplayHeight = display.physicalDisplay.height(); mCompositionFbo.allocateBuffers(mDisplayWidth, mDisplayHeight); mCompositionFbo.allocateBuffers(mDisplayWidth, mDisplayHeight); // Let's use mimap filtering on the offscreen composition texture, // this will drastically improve overall shader quality. glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3); glBindTexture(GL_TEXTURE_2D, 0); const uint32_t fboWidth = floorf(mDisplayWidth * kFboScale); const uint32_t fboWidth = floorf(mDisplayWidth * kFboScale); const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale); const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale); mBlurredFbo.allocateBuffers(fboWidth, fboHeight); mBlurredFbo.allocateBuffers(fboWidth, fboHeight); Loading Loading @@ -94,27 +89,41 @@ void BlurFilter::drawMesh(GLuint uv, GLuint position) { status_t BlurFilter::render() { status_t BlurFilter::render() { ATRACE_NAME("BlurFilter::render"); ATRACE_NAME("BlurFilter::render"); // Now let's scale our blur up // Now let's scale our blur up. It will be interpolated with the larger composited mSimpleProgram.useProgram(); // texture for the first frames, to hide downscaling artifacts. GLfloat mix = fmin(1.0, mRadius / kMaxCrossFadeRadius); if (mix >= 1) { mBlurredFbo.bindAsReadBuffer(); glBlitFramebuffer(0, 0, mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight(), 0, 0, mDisplayWidth, mDisplayHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); return NO_ERROR; } mMixProgram.useProgram(); glUniform1f(mMMixLoc, mix); glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName()); glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName()); glUniform1i(mSTextureLoc, 0); glUniform1i(mMTextureLoc, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); glUniform1i(mMCompositionTextureLoc, 1); mEngine.checkErrors("Setting final pass uniforms"); mEngine.checkErrors("Setting final pass uniforms"); drawMesh(mSUvLoc, mSPosLoc); drawMesh(mMUvLoc, mMPosLoc); glUseProgram(0); glUseProgram(0); glActiveTexture(GL_TEXTURE0); return NO_ERROR; return NO_ERROR; } } string BlurFilter::getVertexShader() const { string BlurFilter::getVertexShader() const { return R"SHADER( return R"SHADER( #version 310 es #version 310 es precision lowp float; in vec2 aPosition; in vec2 aPosition; in mediump vec2 aUV; in highp vec2 aUV; out mediump vec2 vUV; out highp vec2 vUV; void main() { void main() { vUV = aUV; vUV = aUV; Loading @@ -123,18 +132,22 @@ string BlurFilter::getVertexShader() const { )SHADER"; )SHADER"; } } string BlurFilter::getSimpleFragShader() const { string BlurFilter::getMixFragShader() const { string shader = R"SHADER( string shader = R"SHADER( #version 310 es #version 310 es precision lowp float; precision mediump float; in mediump vec2 vUV; in highp vec2 vUV; out vec4 fragColor; out vec4 fragColor; uniform sampler2D uCompositionTexture; uniform sampler2D uTexture; uniform sampler2D uTexture; uniform float uMix; void main() { void main() { fragColor = texture(uTexture, vUV); vec4 blurred = texture(uTexture, vUV); vec4 composition = texture(uCompositionTexture, vUV); fragColor = mix(composition, blurred, uMix); } } )SHADER"; )SHADER"; return shader; return shader; Loading libs/renderengine/gl/filters/BlurFilter.h +13 −7 Original line number Original line Diff line number Diff line Loading @@ -31,22 +31,25 @@ class BlurFilter { public: public: // Downsample FBO to improve performance // Downsample FBO to improve performance static constexpr float kFboScale = 0.25f; static constexpr float kFboScale = 0.25f; // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited // image, up to this radius. static constexpr float kMaxCrossFadeRadius = 15.0f; explicit BlurFilter(GLESRenderEngine& engine); explicit BlurFilter(GLESRenderEngine& engine); virtual ~BlurFilter(){}; virtual ~BlurFilter(){}; // Set up render targets, redirecting output to offscreen texture. // Set up render targets, redirecting output to offscreen texture. status_t setAsDrawTarget(const DisplaySettings&); status_t setAsDrawTarget(const DisplaySettings&, uint32_t radius); // Allocate any textures needed for the filter. // Allocate any textures needed for the filter. virtual void allocateTextures() = 0; virtual void allocateTextures() = 0; // Execute blur passes, rendering to offscreen texture. // Execute blur passes, rendering to offscreen texture. virtual status_t prepare(uint32_t radius) = 0; virtual status_t prepare() = 0; // Render blur to the bound framebuffer (screen). // Render blur to the bound framebuffer (screen). status_t render(); status_t render(); protected: protected: uint32_t mRadius; void drawMesh(GLuint uv, GLuint position); void drawMesh(GLuint uv, GLuint position); string getSimpleFragShader() const; string getVertexShader() const; string getVertexShader() const; GLESRenderEngine& mEngine; GLESRenderEngine& mEngine; Loading @@ -58,12 +61,15 @@ protected: uint32_t mDisplayHeight; uint32_t mDisplayHeight; private: private: string getMixFragShader() const; bool mTexturesAllocated = false; bool mTexturesAllocated = false; GenericProgram mSimpleProgram; GenericProgram mMixProgram; GLuint mSPosLoc; GLuint mMPosLoc; GLuint mSUvLoc; GLuint mMUvLoc; GLuint mSTextureLoc; GLuint mMMixLoc; GLuint mMTextureLoc; GLuint mMCompositionTextureLoc; }; }; } // namespace gl } // namespace gl Loading Loading
libs/renderengine/gl/GLESRenderEngine.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -1003,7 +1003,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, setViewportAndProjection(display.physicalDisplay, display.clip); setViewportAndProjection(display.physicalDisplay, display.clip); } else { } else { setViewportAndProjection(display.physicalDisplay, display.clip); setViewportAndProjection(display.physicalDisplay, display.clip); auto status = mBlurFilter->setAsDrawTarget(display); auto status = mBlurFilter->setAsDrawTarget(display, blurLayer->backgroundBlurRadius); if (status != NO_ERROR) { if (status != NO_ERROR) { ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).", ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).", buffer->handle); buffer->handle); Loading Loading @@ -1037,7 +1037,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, .build(); .build(); for (auto const layer : layers) { for (auto const layer : layers) { if (blurLayer == layer) { if (blurLayer == layer) { auto status = mBlurFilter->prepare(layer->backgroundBlurRadius); auto status = mBlurFilter->prepare(); if (status != NO_ERROR) { if (status != NO_ERROR) { ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).", ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).", buffer->handle); buffer->handle); Loading
libs/renderengine/gl/GLFramebuffer.cpp +8 −0 Original line number Original line Diff line number Diff line Loading @@ -122,6 +122,14 @@ void GLFramebuffer::bind() const { glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName); glBindFramebuffer(GL_FRAMEBUFFER, mFramebufferName); } } void GLFramebuffer::bindAsReadBuffer() const { glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferName); } void GLFramebuffer::bindAsDrawBuffer() const { glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebufferName); } void GLFramebuffer::unbind() const { void GLFramebuffer::unbind() const { glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0); } } Loading
libs/renderengine/gl/GLFramebuffer.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -48,6 +48,8 @@ public: int32_t getBufferWidth() const { return mBufferWidth; } int32_t getBufferWidth() const { return mBufferWidth; } GLenum getStatus() const { return mStatus; } GLenum getStatus() const { return mStatus; } void bind() const; void bind() const; void bindAsReadBuffer() const; void bindAsDrawBuffer() const; void unbind() const; void unbind() const; private: private: Loading
libs/renderengine/gl/filters/BlurFilter.cpp +38 −25 Original line number Original line Diff line number Diff line Loading @@ -31,29 +31,24 @@ namespace renderengine { namespace gl { namespace gl { BlurFilter::BlurFilter(GLESRenderEngine& engine) BlurFilter::BlurFilter(GLESRenderEngine& engine) : mEngine(engine), mCompositionFbo(engine), mBlurredFbo(engine), mSimpleProgram(engine) { : mEngine(engine), mCompositionFbo(engine), mBlurredFbo(engine), mMixProgram(engine) { mSimpleProgram.compile(getVertexShader(), getSimpleFragShader()); mMixProgram.compile(getVertexShader(), getMixFragShader()); mSPosLoc = mSimpleProgram.getAttributeLocation("aPosition"); mMPosLoc = mMixProgram.getAttributeLocation("aPosition"); mSUvLoc = mSimpleProgram.getAttributeLocation("aUV"); mMUvLoc = mMixProgram.getAttributeLocation("aUV"); mSTextureLoc = mSimpleProgram.getUniformLocation("uTexture"); mMTextureLoc = mMixProgram.getUniformLocation("uTexture"); mMCompositionTextureLoc = mMixProgram.getUniformLocation("uCompositionTexture"); mMMixLoc = mMixProgram.getUniformLocation("uMix"); } } status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display) { status_t BlurFilter::setAsDrawTarget(const DisplaySettings& display, uint32_t radius) { ATRACE_NAME("BlurFilter::setAsDrawTarget"); ATRACE_NAME("BlurFilter::setAsDrawTarget"); mRadius = radius; if (!mTexturesAllocated) { if (!mTexturesAllocated) { mDisplayWidth = display.physicalDisplay.width(); mDisplayWidth = display.physicalDisplay.width(); mDisplayHeight = display.physicalDisplay.height(); mDisplayHeight = display.physicalDisplay.height(); mCompositionFbo.allocateBuffers(mDisplayWidth, mDisplayHeight); mCompositionFbo.allocateBuffers(mDisplayWidth, mDisplayHeight); // Let's use mimap filtering on the offscreen composition texture, // this will drastically improve overall shader quality. glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3); glBindTexture(GL_TEXTURE_2D, 0); const uint32_t fboWidth = floorf(mDisplayWidth * kFboScale); const uint32_t fboWidth = floorf(mDisplayWidth * kFboScale); const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale); const uint32_t fboHeight = floorf(mDisplayHeight * kFboScale); mBlurredFbo.allocateBuffers(fboWidth, fboHeight); mBlurredFbo.allocateBuffers(fboWidth, fboHeight); Loading Loading @@ -94,27 +89,41 @@ void BlurFilter::drawMesh(GLuint uv, GLuint position) { status_t BlurFilter::render() { status_t BlurFilter::render() { ATRACE_NAME("BlurFilter::render"); ATRACE_NAME("BlurFilter::render"); // Now let's scale our blur up // Now let's scale our blur up. It will be interpolated with the larger composited mSimpleProgram.useProgram(); // texture for the first frames, to hide downscaling artifacts. GLfloat mix = fmin(1.0, mRadius / kMaxCrossFadeRadius); if (mix >= 1) { mBlurredFbo.bindAsReadBuffer(); glBlitFramebuffer(0, 0, mBlurredFbo.getBufferWidth(), mBlurredFbo.getBufferHeight(), 0, 0, mDisplayWidth, mDisplayHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); return NO_ERROR; } mMixProgram.useProgram(); glUniform1f(mMMixLoc, mix); glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName()); glBindTexture(GL_TEXTURE_2D, mBlurredFbo.getTextureName()); glUniform1i(mSTextureLoc, 0); glUniform1i(mMTextureLoc, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, mCompositionFbo.getTextureName()); glUniform1i(mMCompositionTextureLoc, 1); mEngine.checkErrors("Setting final pass uniforms"); mEngine.checkErrors("Setting final pass uniforms"); drawMesh(mSUvLoc, mSPosLoc); drawMesh(mMUvLoc, mMPosLoc); glUseProgram(0); glUseProgram(0); glActiveTexture(GL_TEXTURE0); return NO_ERROR; return NO_ERROR; } } string BlurFilter::getVertexShader() const { string BlurFilter::getVertexShader() const { return R"SHADER( return R"SHADER( #version 310 es #version 310 es precision lowp float; in vec2 aPosition; in vec2 aPosition; in mediump vec2 aUV; in highp vec2 aUV; out mediump vec2 vUV; out highp vec2 vUV; void main() { void main() { vUV = aUV; vUV = aUV; Loading @@ -123,18 +132,22 @@ string BlurFilter::getVertexShader() const { )SHADER"; )SHADER"; } } string BlurFilter::getSimpleFragShader() const { string BlurFilter::getMixFragShader() const { string shader = R"SHADER( string shader = R"SHADER( #version 310 es #version 310 es precision lowp float; precision mediump float; in mediump vec2 vUV; in highp vec2 vUV; out vec4 fragColor; out vec4 fragColor; uniform sampler2D uCompositionTexture; uniform sampler2D uTexture; uniform sampler2D uTexture; uniform float uMix; void main() { void main() { fragColor = texture(uTexture, vUV); vec4 blurred = texture(uTexture, vUV); vec4 composition = texture(uCompositionTexture, vUV); fragColor = mix(composition, blurred, uMix); } } )SHADER"; )SHADER"; return shader; return shader; Loading
libs/renderengine/gl/filters/BlurFilter.h +13 −7 Original line number Original line Diff line number Diff line Loading @@ -31,22 +31,25 @@ class BlurFilter { public: public: // Downsample FBO to improve performance // Downsample FBO to improve performance static constexpr float kFboScale = 0.25f; static constexpr float kFboScale = 0.25f; // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited // image, up to this radius. static constexpr float kMaxCrossFadeRadius = 15.0f; explicit BlurFilter(GLESRenderEngine& engine); explicit BlurFilter(GLESRenderEngine& engine); virtual ~BlurFilter(){}; virtual ~BlurFilter(){}; // Set up render targets, redirecting output to offscreen texture. // Set up render targets, redirecting output to offscreen texture. status_t setAsDrawTarget(const DisplaySettings&); status_t setAsDrawTarget(const DisplaySettings&, uint32_t radius); // Allocate any textures needed for the filter. // Allocate any textures needed for the filter. virtual void allocateTextures() = 0; virtual void allocateTextures() = 0; // Execute blur passes, rendering to offscreen texture. // Execute blur passes, rendering to offscreen texture. virtual status_t prepare(uint32_t radius) = 0; virtual status_t prepare() = 0; // Render blur to the bound framebuffer (screen). // Render blur to the bound framebuffer (screen). status_t render(); status_t render(); protected: protected: uint32_t mRadius; void drawMesh(GLuint uv, GLuint position); void drawMesh(GLuint uv, GLuint position); string getSimpleFragShader() const; string getVertexShader() const; string getVertexShader() const; GLESRenderEngine& mEngine; GLESRenderEngine& mEngine; Loading @@ -58,12 +61,15 @@ protected: uint32_t mDisplayHeight; uint32_t mDisplayHeight; private: private: string getMixFragShader() const; bool mTexturesAllocated = false; bool mTexturesAllocated = false; GenericProgram mSimpleProgram; GenericProgram mMixProgram; GLuint mSPosLoc; GLuint mMPosLoc; GLuint mSUvLoc; GLuint mMUvLoc; GLuint mSTextureLoc; GLuint mMMixLoc; GLuint mMTextureLoc; GLuint mMCompositionTextureLoc; }; }; } // namespace gl } // namespace gl Loading