diff options
author | Steven Luo <steven@steven676.net> | 2013-03-30 00:44:11 -0700 |
---|---|---|
committer | Steven Luo <steven@steven676.net> | 2013-04-06 23:30:07 -0700 |
commit | 0309f00908d2ed191de7336816c07ae3b469f9aa (patch) | |
tree | d9d551648f5829bb1fbccb9e8ba26311e0641129 | |
parent | a84f5dca506fff74addf9920bb1456db546ae9c6 (diff) | |
download | frameworks_native-0309f00908d2ed191de7336816c07ae3b469f9aa.zip frameworks_native-0309f00908d2ed191de7336816c07ae3b469f9aa.tar.gz frameworks_native-0309f00908d2ed191de7336816c07ae3b469f9aa.tar.bz2 |
Forward-port surface dithering from CM10
This allows the use of 16-bit color displays without excessive color
banding; behavior can be controlled by the persist.sys.use_dithering
property.
Incorporates http://review.cyanogenmod.org/19532 from CM10 as well as
code removed in upstream commit 1b03149.
Change-Id: I290ca4ed4787dc81ac756d9af92cd6a690865a08
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 18 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 2 | ||||
-rw-r--r-- | services/surfaceflinger/LayerBase.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 21 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 6 |
5 files changed, 52 insertions, 2 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 7edbdc5..c1561b2 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -63,6 +63,7 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client) mFormat(PIXEL_FORMAT_NONE), mGLExtensions(GLExtensions::getInstance()), mOpaqueLayer(true), + mNeedsDithering(false), mSecure(false), mProtectedByApp(false) { @@ -194,6 +195,23 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h, mSurfaceTexture->setDefaultBufferFormat(format); mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0)); + int displayMinColorDepth; + int layerRedsize; + switch (mFlinger->getUseDithering()) { + case 0: + mNeedsDithering = false; + break; + case 1: + displayMinColorDepth = mFlinger->getMinColorDepth(); + // we use the red index + layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED); + mNeedsDithering = (layerRedsize > displayMinColorDepth); + break; + case 2: + mNeedsDithering = true; + break; + } + return NO_ERROR; } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c5eb26b..a3d6ab9 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -77,6 +77,7 @@ public: virtual uint32_t doTransaction(uint32_t transactionFlags); virtual Region latchBuffer(bool& recomputeVisibleRegions); virtual bool isOpaque() const; + virtual bool needsDithering() const { return mNeedsDithering; } virtual bool isSecure() const { return mSecure; } virtual bool isProtected() const; virtual void onRemoved(); @@ -142,6 +143,7 @@ private: PixelFormat mFormat; const GLExtensions& mGLExtensions; bool mOpaqueLayer; + bool mNeedsDithering; // page-flip thread (currently main thread) bool mSecure; // no screenshots diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp index 9b03c74..612e47b 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -354,6 +354,7 @@ void LayerBase::clearWithOpenGL(const sp<const DisplayDevice>& hw, const Region& glDisable(GL_TEXTURE_EXTERNAL_OES); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); + glDisable(GL_DITHER); LayerMesh mesh; computeGeometry(hw, &mesh); @@ -428,6 +429,12 @@ void LayerBase::drawWithOpenGL(const sp<const DisplayDevice>& hw, const Region& texCoords[i].v = 1.0f - texCoords[i].v; } + if (needsDithering()) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } + glEnableClientState(GL_TEXTURE_COORD_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glVertexPointer(2, GL_FLOAT, 0, mesh.getVertices()); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index dc562f1..1842949 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -104,7 +104,8 @@ SurfaceFlinger::SurfaceFlinger() mLastSwapBufferTime(0), mDebugInTransaction(0), mLastTransactionTime(0), - mBootFinished(false) + mBootFinished(false), + mUseDithering(0) { ALOGI("SurfaceFlinger is starting"); @@ -122,8 +123,13 @@ SurfaceFlinger::SurfaceFlinger() mDebugDDMS = 0; } } + + property_get("persist.sys.use_dithering", value, "1"); + mUseDithering = atoi(value); + ALOGI_IF(mDebugRegion, "showupdates enabled"); ALOGI_IF(mDebugDDMS, "DDMS debugging enabled"); + ALOGI_IF(mUseDithering, "use dithering"); #ifdef SAMSUNG_HDMI_SUPPORT ALOGD(">>> Run service"); @@ -429,7 +435,11 @@ void SurfaceFlinger::initializeGL(EGLDisplay display) { glPixelStorei(GL_PACK_ALIGNMENT, 4); glEnableClientState(GL_VERTEX_ARRAY); glShadeModel(GL_FLAT); - glDisable(GL_DITHER); + if (mUseDithering == 2) { + glEnable(GL_DITHER); + } else { + glDisable(GL_DITHER); + } glDisable(GL_CULL_FACE); struct pack565 { @@ -467,6 +477,9 @@ void SurfaceFlinger::initializeGL(EGLDisplay display) { ALOGI("extensions: %s", extensions.getExtension()); ALOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize); ALOGI("GL_MAX_VIEWPORT_DIMS = %d x %d", mMaxViewportDims[0], mMaxViewportDims[1]); + + // XXX Assume bit depth for red is equal to minimum depth of all colors + mMinColorDepth = r; } status_t SurfaceFlinger::readyToRun() @@ -564,6 +577,10 @@ uint32_t SurfaceFlinger::getMaxTextureSize() const { return mMaxTextureSize; } +uint32_t SurfaceFlinger::getMinColorDepth() const { + return mMinColorDepth; +} + uint32_t SurfaceFlinger::getMaxViewportDims() const { return mMaxViewportDims[0] < mMaxViewportDims[1] ? mMaxViewportDims[0] : mMaxViewportDims[1]; diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index e8c4b9c..050d10f 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -324,8 +324,12 @@ private: static EGLContext createGLContext(EGLDisplay disp, EGLConfig config); void initializeGL(EGLDisplay display); uint32_t getMaxTextureSize() const; + uint32_t getMinColorDepth() const; uint32_t getMaxViewportDims() const; + // 0: surface doesn't need dithering, 1: use if necessary, 2: use permanently + inline int getUseDithering() const { return mUseDithering; } + /* ------------------------------------------------------------------------ * Display and layer stack management */ @@ -423,6 +427,7 @@ private: sp<EventThread> mEventThread; GLint mMaxViewportDims[2]; GLint mMaxTextureSize; + GLint mMinColorDepth; EGLContext mEGLContext; EGLConfig mEGLConfig; EGLDisplay mEGLDisplay; @@ -448,6 +453,7 @@ private: volatile nsecs_t mDebugInTransaction; nsecs_t mLastTransactionTime; bool mBootFinished; + int mUseDithering; // these are thread safe mutable MessageQueue mEventQueue; |