From 44cac134655d5c3b2eeab2e42792c70a7aa8b92f Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 23 Sep 2009 18:34:53 -0700 Subject: [PATCH 1/2] fix [2142193] disable GL_LINEAR when not needed --- libs/surfaceflinger/LayerBase.cpp | 42 +++++++++++++++++-------------- libs/surfaceflinger/LayerBase.h | 1 + libs/surfaceflinger/Transform.h | 8 ++++++ 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index e08861d371a5a..8b9a84230098b 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -56,6 +56,7 @@ LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display) : dpy(display), contentDirty(false), mFlinger(flinger), mTransformed(false), + mUseLinearFiltering(false), mOrientation(0), mTransactionFlags(0), mPremultipliedAlpha(true), @@ -208,7 +209,19 @@ uint32_t LayerBase::doTransaction(uint32_t flags) flags |= eVisibleRegion; this->contentDirty = true; } - + + if (temp.sequence != front.sequence) { + const bool linearFiltering = mUseLinearFiltering; + mUseLinearFiltering = false; + if (!(mFlags & DisplayHardware::SLOW_CONFIG)) { + // we may use linear filtering, if the matrix scales us + const uint8_t type = temp.transform.getType(); + if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) { + mUseLinearFiltering = true; + } + } + } + // Commit the transaction commitTransaction(flags & eRestartTransaction); return flags; @@ -332,13 +345,8 @@ GLuint LayerBase::createTexture() const glBindTexture(GL_TEXTURE_2D, textureName); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (mFlags & DisplayHardware::SLOW_CONFIG) { - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } else { - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); return textureName; } @@ -434,12 +442,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const Region::const_iterator it = clip.begin(); Region::const_iterator const end = clip.end(); if (it != end) { - // always use high-quality filtering with fast configurations - bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); - if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } const GLfixed texCoords[4][2] = { { 0, 0 }, { 0, 0x10000 }, @@ -481,11 +483,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glScissor(r.left, sy, r.width(), r.height()); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); } - - if (!fast && s.flags & ISurfaceComposer::eLayerFilter) { - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - } glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } else { @@ -512,6 +509,13 @@ void LayerBase::validateTexture(GLint textureName) const glBindTexture(GL_TEXTURE_2D, textureName); // TODO: reload the texture if needed // this is currently done in loadTexture() below + if (mUseLinearFiltering) { + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + } else { + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + } } void LayerBase::loadTexture(Texture* texture, GLint textureName, diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 3a52240824395..2a07bf1407ada 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -254,6 +254,7 @@ protected: // cached during validateVisibility() bool mTransformed; + bool mUseLinearFiltering; int32_t mOrientation; GLfixed mVertices[4][2]; Rect mTransformedBounds; diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h index 4c4528ecd4bd8..78f5c19601767 100644 --- a/libs/surfaceflinger/Transform.h +++ b/libs/surfaceflinger/Transform.h @@ -50,6 +50,14 @@ public: ROT_INVALID = 0x80000000 }; + enum type_mask { + IDENTITY = 0, + TRANSLATE = 0x1, + SCALE = 0x2, + AFFINE = 0x4, + PERSPECTIVE = 0x8 + }; + bool transformed() const; int32_t getOrientation() const; bool preserveRects() const; From cc934763c3fc789f53edb64de16fc36d43c3705d Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Wed, 23 Sep 2009 19:16:27 -0700 Subject: [PATCH 2/2] turn dithering off if it's not needed --- libs/surfaceflinger/Layer.cpp | 15 ++++++++++++++- libs/surfaceflinger/Layer.h | 2 ++ libs/surfaceflinger/LayerBase.cpp | 14 ++++++-------- libs/surfaceflinger/LayerBase.h | 5 +++++ libs/surfaceflinger/SurfaceFlinger.cpp | 5 +++-- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp index 8dfc2cf766b9d..67ddcf9cee2e4 100644 --- a/libs/surfaceflinger/Layer.cpp +++ b/libs/surfaceflinger/Layer.cpp @@ -51,7 +51,8 @@ Layer::Layer(SurfaceFlinger* flinger, DisplayID display, const sp& c, int32_t i) : LayerBaseClient(flinger, display, c, i), mSecure(false), - mNeedsBlending(true) + mNeedsBlending(true), + mNeedsDithering(false) { // no OpenGL operation is possible here, since we might not be // in the OpenGL thread. @@ -106,10 +107,16 @@ status_t Layer::ditch() status_t Layer::setBuffers( uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) { + // this surfaces pixel format PixelFormatInfo info; status_t err = getPixelFormatInfo(format, &info); if (err) return err; + // the display's pixel format + const DisplayHardware& hw(graphicPlane(0).displayHardware()); + PixelFormatInfo displayInfo; + getPixelFormatInfo(hw.getFormat(), &displayInfo); + uint32_t bufferFlags = 0; if (flags & ISurfaceComposer::eSecure) bufferFlags |= Buffer::SECURE; @@ -119,6 +126,12 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, mHeight = h; mSecure = (bufferFlags & Buffer::SECURE) ? true : false; mNeedsBlending = (info.h_alpha - info.l_alpha) > 0; + + // we use the red index + int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED); + int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); + mNeedsDithering = layerRedsize > displayRedSize; + mBufferFlags = bufferFlags; for (size_t i=0 ; i createSurface() const; virtual status_t ditch(); @@ -109,6 +110,7 @@ private: bool mSecure; int32_t mFrontBufferIndex; bool mNeedsBlending; + bool mNeedsDithering; Region mPostedDirtyRegion; sp mFreezeLock; PixelFormat mFormat; diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 8b9a84230098b..5a93b2d46161a 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -393,14 +393,6 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const glEnable(GL_TEXTURE_2D); - // Dithering... - bool fast = !(mFlags & DisplayHardware::SLOW_CONFIG); - if (fast || s.flags & ISurfaceComposer::eLayerDither) { - glEnable(GL_DITHER); - } else { - glDisable(GL_DITHER); - } - if (UNLIKELY(s.alpha < 0xFF)) { // We have an alpha-modulation. We need to modulate all // texture components by alpha because we're always using @@ -516,6 +508,12 @@ void LayerBase::validateTexture(GLint textureName) const glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } + + if (needsDithering()) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } } void LayerBase::loadTexture(Texture* texture, GLint textureName, diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index 2a07bf1407ada..233737db158dd 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -187,6 +187,11 @@ public: */ virtual bool needsBlending() const { return false; } + /** + * needsDithering - true if this surface needs dithering + */ + virtual bool needsDithering() const { return false; } + /** * transformed -- true is this surface needs a to be transformed */ diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index e87b5634898e6..a0b48d4f2d2b5 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -1497,11 +1497,12 @@ status_t SurfaceFlinger::dump(int fd, const Vector& args) "+ %s %p\n" " " "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), " - "needsBlending=%1d, invalidate=%1d, " + "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, " "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n", layer->getTypeID(), layer.get(), s.z, layer->tx(), layer->ty(), s.w, s.h, - layer->needsBlending(), layer->contentDirty, + layer->needsBlending(), layer->needsDithering(), + layer->contentDirty, s.alpha, s.flags, s.transform[0], s.transform[1], s.transform[2], s.transform[3]);