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

Commit 44c35ec4 authored by Andy McFadden's avatar Andy McFadden Committed by Craig Mautner
Browse files

Allow "opaque" flag to be updated. DO NOT MERGE

Moves the "opaque layer" from Layer to Layer::State.  This allows
it to be updated as part of a transaction.

Bug 12387406

Change-Id: I0a114ce6adf77cd12fb08f96e0691b76c475768d
parent ed4d28dd
Loading
Loading
Loading
Loading
+6 −1
Original line number Original line Diff line number Diff line
@@ -30,11 +30,15 @@ namespace android {
class Parcel;
class Parcel;
class ISurfaceComposerClient;
class ISurfaceComposerClient;


/*
 * Used to communicate layer information between SurfaceFlinger and its clients.
 */
struct layer_state_t {
struct layer_state_t {




    enum {
    enum {
        eLayerHidden        = 0x01,
        eLayerHidden        = 0x01,     // SURFACE_HIDDEN in SurfaceControl.java
        eLayerOpaque        = 0x02,     // SURFACE_OPAQUE
    };
    };


    enum {
    enum {
@@ -47,6 +51,7 @@ struct layer_state_t {
        eVisibilityChanged          = 0x00000040,
        eVisibilityChanged          = 0x00000040,
        eLayerStackChanged          = 0x00000080,
        eLayerStackChanged          = 0x00000080,
        eCropChanged                = 0x00000100,
        eCropChanged                = 0x00000100,
        eOpacityChanged             = 0x00000200,
    };
    };


    layer_state_t()
    layer_state_t()
+6 −1
Original line number Original line Diff line number Diff line
@@ -309,7 +309,12 @@ status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
    layer_state_t* s = getLayerStateLocked(client, id);
    layer_state_t* s = getLayerStateLocked(client, id);
    if (!s)
    if (!s)
        return BAD_INDEX;
        return BAD_INDEX;
    if (mask & layer_state_t::eLayerOpaque) {
        s->what |= layer_state_t::eOpacityChanged;
    }
    if (mask & layer_state_t::eLayerHidden) {
        s->what |= layer_state_t::eVisibilityChanged;
        s->what |= layer_state_t::eVisibilityChanged;
    }
    s->flags &= ~mask;
    s->flags &= ~mask;
    s->flags |= (flags & mask);
    s->flags |= (flags & mask);
    s->mask |= mask;
    s->mask |= mask;
+11 −11
Original line number Original line Diff line number Diff line
@@ -64,7 +64,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
        mName("unnamed"),
        mName("unnamed"),
        mDebug(false),
        mDebug(false),
        mFormat(PIXEL_FORMAT_NONE),
        mFormat(PIXEL_FORMAT_NONE),
        mOpaqueLayer(true),
        mTransactionFlags(0),
        mTransactionFlags(0),
        mQueuedFrames(0),
        mQueuedFrames(0),
        mCurrentTransform(0),
        mCurrentTransform(0),
@@ -86,7 +85,9 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,


    uint32_t layerFlags = 0;
    uint32_t layerFlags = 0;
    if (flags & ISurfaceComposerClient::eHidden)
    if (flags & ISurfaceComposerClient::eHidden)
        layerFlags = layer_state_t::eLayerHidden;
        layerFlags |= layer_state_t::eLayerHidden;
    if (flags & ISurfaceComposerClient::eOpaque)
        layerFlags |= layer_state_t::eLayerOpaque;


    if (flags & ISurfaceComposerClient::eNonPremultiplied)
    if (flags & ISurfaceComposerClient::eNonPremultiplied)
        mPremultipliedAlpha = false;
        mPremultipliedAlpha = false;
@@ -189,7 +190,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,


    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
    mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
    mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
    mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
    mCurrentOpacity = getOpacityForFormat(format);
    mCurrentOpacity = getOpacityForFormat(format);


    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
    mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
@@ -352,7 +352,7 @@ void Layer::setGeometry(


    // this gives us only the "orientation" component of the transform
    // this gives us only the "orientation" component of the transform
    const State& s(getDrawingState());
    const State& s(getDrawingState());
    if (!isOpaque() || s.alpha != 0xFF) {
    if (!isOpaque(s) || s.alpha != 0xFF) {
        layer.setBlending(mPremultipliedAlpha ?
        layer.setBlending(mPremultipliedAlpha ?
                HWC_BLENDING_PREMULT :
                HWC_BLENDING_PREMULT :
                HWC_BLENDING_COVERAGE);
                HWC_BLENDING_COVERAGE);
@@ -596,7 +596,7 @@ void Layer::drawWithOpenGL(
    texCoords[3] = vec2(right, 1.0f - top);
    texCoords[3] = vec2(right, 1.0f - top);


    RenderEngine& engine(mFlinger->getRenderEngine());
    RenderEngine& engine(mFlinger->getRenderEngine());
    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
    engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
    engine.drawMesh(mMesh);
    engine.drawMesh(mMesh);
    engine.disableBlending();
    engine.disableBlending();
}
}
@@ -656,7 +656,7 @@ void Layer::computeGeometry(const sp<const DisplayDevice>& hw, Mesh& mesh) const
    }
    }
}
}


bool Layer::isOpaque() const
bool Layer::isOpaque(const Layer::State& s) const
{
{
    // if we don't have a buffer yet, we're translucent regardless of the
    // if we don't have a buffer yet, we're translucent regardless of the
    // layer's opaque flag.
    // layer's opaque flag.
@@ -666,7 +666,7 @@ bool Layer::isOpaque() const


    // if the layer has the opaque flag, then we're always opaque,
    // if the layer has the opaque flag, then we're always opaque,
    // otherwise we use the current buffer's format.
    // otherwise we use the current buffer's format.
    return mOpaqueLayer || mCurrentOpacity;
    return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
}
}


bool Layer::isProtected() const
bool Layer::isProtected() const
@@ -954,7 +954,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
        }
        }


        // Capture the old state of the layer for comparisons later
        // Capture the old state of the layer for comparisons later
        const bool oldOpacity = isOpaque();
        const State& s(getDrawingState());
        const bool oldOpacity = isOpaque(s);
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;
        sp<GraphicBuffer> oldActiveBuffer = mActiveBuffer;


        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
        struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
@@ -1122,12 +1123,11 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
        }
        }


        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
        mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
        if (oldOpacity != isOpaque()) {
        if (oldOpacity != isOpaque(s)) {
            recomputeVisibleRegions = true;
            recomputeVisibleRegions = true;
        }
        }


        // FIXME: postedRegion should be dirty & bounds
        // FIXME: postedRegion should be dirty & bounds
        const Layer::State& s(getDrawingState());
        Region dirtyRegion(Rect(s.active.w, s.active.h));
        Region dirtyRegion(Rect(s.active.w, s.active.h));


        // transform the dirty region to window-manager space
        // transform the dirty region to window-manager space
@@ -1188,7 +1188,7 @@ void Layer::dump(String8& result, Colorizer& colorizer) const
            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
            s.layerStack, s.z, s.transform.tx(), s.transform.ty(), s.active.w, s.active.h,
            s.active.crop.left, s.active.crop.top,
            s.active.crop.left, s.active.crop.top,
            s.active.crop.right, s.active.crop.bottom,
            s.active.crop.right, s.active.crop.bottom,
            isOpaque(), contentDirty,
            isOpaque(s), contentDirty,
            s.alpha, s.flags,
            s.alpha, s.flags,
            s.transform[0][0], s.transform[0][1],
            s.transform[0][0], s.transform[0][1],
            s.transform[1][0], s.transform[1][1],
            s.transform[1][0], s.transform[1][1],
+5 −2
Original line number Original line Diff line number Diff line
@@ -149,8 +149,12 @@ public:


    /*
    /*
     * isOpaque - true if this surface is opaque
     * isOpaque - true if this surface is opaque
     *
     * This takes into account the buffer format (i.e. whether or not the
     * pixel format includes an alpha channel) and the "opaque" flag set
     * on the layer.  It does not examine the current plane alpha value.
     */
     */
    virtual bool isOpaque() const;
    virtual bool isOpaque(const Layer::State& s) const;


    /*
    /*
     * isSecure - true if this surface is secure, that is if it prevents
     * isSecure - true if this surface is secure, that is if it prevents
@@ -335,7 +339,6 @@ private:
    String8 mName;
    String8 mName;
    mutable bool mDebug;
    mutable bool mDebug;
    PixelFormat mFormat;
    PixelFormat mFormat;
    bool mOpaqueLayer;


    // these are protected by an external lock
    // these are protected by an external lock
    State mCurrentState;
    State mCurrentState;
+5 −3
Original line number Original line Diff line number Diff line
@@ -1379,7 +1379,7 @@ void SurfaceFlinger::computeVisibleRegions(


        // handle hidden surfaces by setting the visible region to empty
        // handle hidden surfaces by setting the visible region to empty
        if (CC_LIKELY(layer->isVisible())) {
        if (CC_LIKELY(layer->isVisible())) {
            const bool translucent = !layer->isOpaque();
            const bool translucent = !layer->isOpaque(s);
            Rect bounds(s.transform.transform(layer->computeBounds()));
            Rect bounds(s.transform.transform(layer->computeBounds()));
            visibleRegion.set(bounds);
            visibleRegion.set(bounds);
            if (!visibleRegion.isEmpty()) {
            if (!visibleRegion.isEmpty()) {
@@ -1624,7 +1624,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
                        const Layer::State& state(layer->getDrawingState());
                        const Layer::State& state(layer->getDrawingState());
                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
                        if ((cur->getHints() & HWC_HINT_CLEAR_FB)
                                && i
                                && i
                                && layer->isOpaque() && (state.alpha == 0xFF)
                                && layer->isOpaque(state) && (state.alpha == 0xFF)
                                && hasGlesComposition) {
                                && hasGlesComposition) {
                            // never clear the very first layer since we're
                            // never clear the very first layer since we're
                            // guaranteed the FB is already cleared
                            // guaranteed the FB is already cleared
@@ -1868,7 +1868,9 @@ uint32_t SurfaceFlinger::setClientStateLocked(
            if (layer->setTransparentRegionHint(s.transparentRegion))
            if (layer->setTransparentRegionHint(s.transparentRegion))
                flags |= eTraversalNeeded;
                flags |= eTraversalNeeded;
        }
        }
        if (what & layer_state_t::eVisibilityChanged) {
        if ((what & layer_state_t::eVisibilityChanged) ||
                (what & layer_state_t::eOpacityChanged)) {
            // TODO: should we just use an eFlagsChanged for this?
            if (layer->setFlags(s.flags, s.mask))
            if (layer->setFlags(s.flags, s.mask))
                flags |= eTraversalNeeded;
                flags |= eTraversalNeeded;
        }
        }