summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2010-06-07 00:07:47 -0700
committerSteve Kondik <shade@chemlab.org>2010-07-02 00:44:02 -0400
commitf067d7228f4c92a3ead4b8ead523b22c4c91d78b (patch)
tree457477dfbdec0b2f5a54e68bdbb728269451511d /libs
parentd9972b02d734f59c86f79935f5a9960b18139d75 (diff)
downloadframeworks_base-f067d7228f4c92a3ead4b8ead523b22c4c91d78b.zip
frameworks_base-f067d7228f4c92a3ead4b8ead523b22c4c91d78b.tar.gz
frameworks_base-f067d7228f4c92a3ead4b8ead523b22c4c91d78b.tar.bz2
Initial pass at SurfaceFlinger effects, night mode.
This change adds a mRenderEffect variable that can be used to control rendering effects at runtime. One example effect of "night mode" is included which renders the entire system in using a red-only filter. In particular, this is useful on devices with OLED displays where the power consumption of the red channel is much less than green and blue. Change-Id: I64fb47a186e5b1c6be5db7e179ab6796e66bf341
Diffstat (limited to 'libs')
-rw-r--r--libs/surfaceflinger/LayerBase.cpp34
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp9
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.h3
3 files changed, 44 insertions, 2 deletions
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
index a8b735e..a77b20b 100644
--- a/libs/surfaceflinger/LayerBase.cpp
+++ b/libs/surfaceflinger/LayerBase.cpp
@@ -33,6 +33,10 @@
#include "SurfaceFlinger.h"
#include "DisplayHardware/DisplayHardware.h"
+#define RENDER_EFFECT_NIGHT 1
+#define RENDER_EFFECT_TERMINAL 2
+#define RENDER_EFFECT_AMBER 3
+#define RENDER_EFFECT_SALMON 4
namespace android {
@@ -401,7 +405,10 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
glEnable(GL_TEXTURE_2D);
- if (UNLIKELY(s.alpha < 0xFF)) {
+ int renderEffect = mFlinger->getRenderEffect();
+ bool noEffect = renderEffect == 0;
+
+ if (UNLIKELY(s.alpha < 0xFF) && noEffect) {
// We have an alpha-modulation. We need to modulate all
// texture components by alpha because we're always using
// premultiplied alpha.
@@ -423,7 +430,7 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
glEnable(GL_BLEND);
glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
- } else {
+ } else if (noEffect) {
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
if (needsBlending()) {
@@ -433,6 +440,29 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
} else {
glDisable(GL_BLEND);
}
+ } else {
+ // Apply a render effect, which is simple color masks for now.
+ GLenum env, src;
+ env = GL_MODULATE;
+ src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+ const GGLfixed alpha = (s.alpha << 16)/255;
+ switch (renderEffect) {
+ case RENDER_EFFECT_NIGHT:
+ glColor4x(alpha, 0, 0, alpha);
+ break;
+ case RENDER_EFFECT_TERMINAL:
+ glColor4x(0, alpha, 0, alpha);
+ break;
+ case RENDER_EFFECT_AMBER:
+ glColor4x(alpha, alpha*0.75, 0, alpha);
+ break;
+ case RENDER_EFFECT_SALMON:
+ glColor4x(alpha, alpha*0.5, alpha*0.5, alpha);
+ break;
+ }
+ glEnable(GL_BLEND);
+ glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
}
Region::const_iterator it = clip.begin();
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 0722fda..45ca215 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -184,6 +184,7 @@ SurfaceFlinger::SurfaceFlinger()
mFreezeDisplayTime(0),
mDebugRegion(0),
mDebugBackground(0),
+ mRenderEffect(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
@@ -205,6 +206,8 @@ void SurfaceFlinger::init()
mDebugRegion = atoi(value);
property_get("debug.sf.showbackground", value, "0");
mDebugBackground = atoi(value);
+ property_get("debug.sf.render_effect", value, "0");
+ mRenderEffect = atoi(value);
LOGI_IF(mDebugRegion, "showupdates enabled");
LOGI_IF(mDebugBackground, "showbackground enabled");
@@ -1692,12 +1695,18 @@ status_t SurfaceFlinger::onTransact(
reply->writeInt32(0);
reply->writeInt32(mDebugRegion);
reply->writeInt32(mDebugBackground);
+ reply->writeInt32(mRenderEffect);
return NO_ERROR;
case 1013: {
Mutex::Autolock _l(mStateLock);
const DisplayHardware& hw(graphicPlane(0).displayHardware());
reply->writeInt32(hw.getPageFlipCount());
}
+ case 1014: { // RENDER_EFFECT
+ // TODO: filter to only allow valid effects
+ mRenderEffect = data.readInt32();
+ return NO_ERROR;
+ }
return NO_ERROR;
}
}
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index d75dc15..7cde719 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -174,6 +174,8 @@ public:
overlay_control_device_t* getOverlayEngine() const;
+ inline int getRenderEffect() const { return mRenderEffect; }
+
status_t removeLayer(const sp<LayerBase>& layer);
status_t addLayer(const sp<LayerBase>& layer);
@@ -354,6 +356,7 @@ private:
// don't use a lock for these, we don't care
int mDebugRegion;
int mDebugBackground;
+ int mRenderEffect;
volatile nsecs_t mDebugInSwapBuffers;
nsecs_t mLastSwapBufferTime;
volatile nsecs_t mDebugInTransaction;