diff options
author | Dan Stoza <stoza@google.com> | 2014-10-20 15:46:09 -0700 |
---|---|---|
committer | Dan Stoza <stoza@google.com> | 2015-05-28 13:35:39 -0700 |
commit | 8e8eba5091de03d33d667ce1e6ba5fe7072926ba (patch) | |
tree | 5315da8b47114f616ad399a58bf0538ade2b6bc2 /services/surfaceflinger | |
parent | d74ba85c6f13bc1634ab1ae3c6c82d0fc837eb94 (diff) | |
download | frameworks_native-8e8eba5091de03d33d667ce1e6ba5fe7072926ba.zip frameworks_native-8e8eba5091de03d33d667ce1e6ba5fe7072926ba.tar.gz frameworks_native-8e8eba5091de03d33d667ce1e6ba5fe7072926ba.tar.bz2 |
SF: Skip render-to-texture for color transforms
In cases where SurfaceFlinger is applying a color matrix (usually for
accessibility features), we previously would perform a render-to-
texture for the initial composition, and then apply the matrix during
a copy to the framebuffer. This changes that behavior to just apply the
matrix during composition without a render-to-texture pass.
This may result in a perceived change of the image in cases with alpha
blending, since the blending is performed at a different stage of the
pipeline and the system effectively performs non-linear blends.
However, neither this nor the prior render-to-texture pass is strictly
correct in that regard, and this approach is less error-prone and
likely faster.
Change-Id: I2110ff0374f61d76df7b087dde8a1ed98990440c
(cherry picked from commit f008799d3753e52c10849824ff8146985ea66284)
Diffstat (limited to 'services/surfaceflinger')
8 files changed, 18 insertions, 94 deletions
diff --git a/services/surfaceflinger/RenderEngine/Description.cpp b/services/surfaceflinger/RenderEngine/Description.cpp index 1adcd1f..0dab872 100644 --- a/services/surfaceflinger/RenderEngine/Description.cpp +++ b/services/surfaceflinger/RenderEngine/Description.cpp @@ -88,5 +88,9 @@ void Description::setColorMatrix(const mat4& mtx) { mColorMatrixEnabled = (mtx != identity); } +const mat4& Description::getColorMatrix() const { + return mColorMatrix; +} + } /* namespace android */ diff --git a/services/surfaceflinger/RenderEngine/Description.h b/services/surfaceflinger/RenderEngine/Description.h index 43b835f..8a3447c 100644 --- a/services/surfaceflinger/RenderEngine/Description.h +++ b/services/surfaceflinger/RenderEngine/Description.h @@ -66,6 +66,7 @@ public: void setColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); void setProjectionMatrix(const mat4& mtx); void setColorMatrix(const mat4& mtx); + const mat4& getColorMatrix() const; private: bool mUniformsDirty; diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp index 2e6af49..1a9f59b 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp @@ -262,14 +262,6 @@ void GLES11RenderEngine::drawMesh(const Mesh& mesh) { } } -void GLES11RenderEngine::beginGroup(const mat4& /*colorTransform*/) { - // doesn't do anything in GLES 1.1 -} - -void GLES11RenderEngine::endGroup() { - // doesn't do anything in GLES 1.1 -} - void GLES11RenderEngine::dump(String8& result) { RenderEngine::dump(result); } diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h index 87eb3e4..08de646 100644 --- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h @@ -62,9 +62,6 @@ protected: virtual void drawMesh(const Mesh& mesh); - virtual void beginGroup(const mat4& colorTransform); - virtual void endGroup(); - virtual size_t getMaxTextureSize() const; virtual size_t getMaxViewportDims() const; }; diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp index 8712c9a..1fabaf5 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp @@ -169,6 +169,12 @@ void GLES20RenderEngine::setupLayerBlackedOut() { mState.setTexture(texture); } +mat4 GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) { + mat4 oldTransform = mState.getColorMatrix(); + mState.setColorMatrix(colorTransform); + return oldTransform; +} + void GLES20RenderEngine::disableTexturing() { mState.disableTexture(); } @@ -237,78 +243,6 @@ void GLES20RenderEngine::drawMesh(const Mesh& mesh) { } } -void GLES20RenderEngine::beginGroup(const mat4& colorTransform) { - - GLuint tname, name; - // create the texture - glGenTextures(1, &tname); - glBindTexture(GL_TEXTURE_2D, tname); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mVpWidth, mVpHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - - // create a Framebuffer Object to render into - glGenFramebuffers(1, &name); - glBindFramebuffer(GL_FRAMEBUFFER, name); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0); - - Group group; - group.texture = tname; - group.fbo = name; - group.width = mVpWidth; - group.height = mVpHeight; - group.colorTransform = colorTransform; - - mGroupStack.push(group); -} - -void GLES20RenderEngine::endGroup() { - - const Group group(mGroupStack.top()); - mGroupStack.pop(); - - // activate the previous render target - GLuint fbo = 0; - if (!mGroupStack.isEmpty()) { - fbo = mGroupStack.top().fbo; - } - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - - // set our state - Texture texture(Texture::TEXTURE_2D, group.texture); - texture.setDimensions(group.width, group.height); - glBindTexture(GL_TEXTURE_2D, group.texture); - - mState.setPlaneAlpha(1.0f); - mState.setPremultipliedAlpha(true); - mState.setOpaque(false); - mState.setTexture(texture); - mState.setColorMatrix(group.colorTransform); - glDisable(GL_BLEND); - - Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2); - Mesh::VertexArray<vec2> position(mesh.getPositionArray<vec2>()); - Mesh::VertexArray<vec2> texCoord(mesh.getTexCoordArray<vec2>()); - position[0] = vec2(0, 0); - position[1] = vec2(group.width, 0); - position[2] = vec2(group.width, group.height); - position[3] = vec2(0, group.height); - texCoord[0] = vec2(0, 0); - texCoord[1] = vec2(1, 0); - texCoord[2] = vec2(1, 1); - texCoord[3] = vec2(0, 1); - drawMesh(mesh); - - // reset color matrix - mState.setColorMatrix(mat4()); - - // free our fbo and texture - glDeleteFramebuffers(1, &group.fbo); - glDeleteTextures(1, &group.texture); -} - void GLES20RenderEngine::dump(String8& result) { RenderEngine::dump(result); } diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h index 3d6243e..819356a 100644 --- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h @@ -72,14 +72,12 @@ protected: virtual void setupLayerTexturing(const Texture& texture); virtual void setupLayerBlackedOut(); virtual void setupFillWithColor(float r, float g, float b, float a); + virtual mat4 setupColorTransform(const mat4& colorTransform); virtual void disableTexturing(); virtual void disableBlending(); virtual void drawMesh(const Mesh& mesh); - virtual void beginGroup(const mat4& colorTransform); - virtual void endGroup(); - virtual size_t getMaxTextureSize() const; virtual size_t getMaxViewportDims() const; }; diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h index 8d7529c..31a961e 100644 --- a/services/surfaceflinger/RenderEngine/RenderEngine.h +++ b/services/surfaceflinger/RenderEngine/RenderEngine.h @@ -99,18 +99,16 @@ public: virtual void setupLayerBlackedOut() = 0; virtual void setupFillWithColor(float r, float g, float b, float a) = 0; + virtual mat4 setupColorTransform(const mat4& /* colorTransform */) { + return mat4(); + } + virtual void disableTexturing() = 0; virtual void disableBlending() = 0; // drawing virtual void drawMesh(const Mesh& mesh) = 0; - // grouping - // creates a color-transform group, everything drawn in the group will be - // transformed by the given color transform when endGroup() is called. - virtual void beginGroup(const mat4& colorTransform) = 0; - virtual void endGroup() = 0; - // queries virtual size_t getMaxTextureSize() const = 0; virtual size_t getMaxViewportDims() const = 0; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 89be4dc..b6131b5 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1848,9 +1848,9 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw, if (mDaltonize) { colorMatrix = colorMatrix * mDaltonizer(); } - engine.beginGroup(colorMatrix); + mat4 oldMatrix = engine.setupColorTransform(colorMatrix); doComposeSurfaces(hw, dirtyRegion); - engine.endGroup(); + engine.setupColorTransform(oldMatrix); } // update the swap region and clear the dirty region |