Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ba8cee7 authored by Jeff Sharkey's avatar Jeff Sharkey Committed by Steve Kondik
Browse files

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
parent 88c07d2f
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -34,6 +34,10 @@
#include "DisplayHardware/DisplayHardware.h"
#include "TextureManager.h"

#define RENDER_EFFECT_NIGHT 1
#define RENDER_EFFECT_TERMINAL 2
#define RENDER_EFFECT_AMBER 3
#define RENDER_EFFECT_SALMON 4

namespace android {

@@ -373,7 +377,11 @@ void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
    uint32_t height = texture.height;

    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
    if (UNLIKELY(s.alpha < 0xFF)) {

    int renderEffect = mFlinger->getRenderEffect();
    bool noEffect = renderEffect == 0;

    if (UNLIKELY(s.alpha < 0xFF) && noEffect) {
        const GLfloat alpha = s.alpha * (1.0f/255.0f);
        if (mPremultipliedAlpha) {
            glColor4f(alpha, alpha, alpha, alpha);
@@ -383,7 +391,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, GL_MODULATE);
    } else {
    } else if (noEffect) {
        glColor4f(1, 1, 1, 1);
        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        if (needsBlending()) {
@@ -392,6 +400,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);
    }

    /*
+9 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ SurfaceFlinger::SurfaceFlinger()
        mFreezeDisplayTime(0),
        mDebugRegion(0),
        mDebugBackground(0),
        mRenderEffect(0),
        mDebugInSwapBuffers(0),
        mLastSwapBufferTime(0),
        mDebugInTransaction(0),
@@ -106,6 +107,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");
@@ -1529,12 +1532,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;
        }
    }
+4 −0
Original line number Diff line number Diff line
@@ -209,6 +209,9 @@ 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);
    status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
@@ -404,6 +407,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;