Created
March 31, 2013 02:37
-
-
Save steven676/5279269 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 90c62d9d668ab7af42762219127ce1ddb6f5bee1 Mon Sep 17 00:00:00 2001 | |
From: Steven Luo <[email protected]> | |
Date: Sat, 30 Mar 2013 00:44:11 -0700 | |
Subject: [PATCH 2/2] 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 | |
--- | |
services/surfaceflinger/Layer.cpp | 18 ++++++++++++++++++ | |
services/surfaceflinger/Layer.h | 2 ++ | |
services/surfaceflinger/LayerBase.cpp | 7 +++++++ | |
services/surfaceflinger/SurfaceFlinger.cpp | 21 +++++++++++++++++++-- | |
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..5e55df3 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 red size is the minimum size | |
+ 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; | |
-- | |
1.7.2.5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment