summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Luo <steven@steven676.net>2013-03-30 00:44:11 -0700
committerSteven Luo <steven@steven676.net>2013-04-06 23:30:07 -0700
commit0309f00908d2ed191de7336816c07ae3b469f9aa (patch)
treed9d551648f5829bb1fbccb9e8ba26311e0641129
parenta84f5dca506fff74addf9920bb1456db546ae9c6 (diff)
downloadframeworks_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.cpp18
-rw-r--r--services/surfaceflinger/Layer.h2
-rw-r--r--services/surfaceflinger/LayerBase.cpp7
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp21
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h6
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;