Allow "opaque" flag to be updated
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
This commit is contained in:
parent
a9d5701b03
commit
4125a4ffaf
@ -30,11 +30,15 @@ namespace android {
|
||||
class Parcel;
|
||||
class ISurfaceComposerClient;
|
||||
|
||||
/*
|
||||
* Used to communicate layer information between SurfaceFlinger and its clients.
|
||||
*/
|
||||
struct layer_state_t {
|
||||
|
||||
|
||||
enum {
|
||||
eLayerHidden = 0x01,
|
||||
eLayerHidden = 0x01, // SURFACE_HIDDEN in SurfaceControl.java
|
||||
eLayerOpaque = 0x02, // SURFACE_OPAQUE
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -47,6 +51,7 @@ struct layer_state_t {
|
||||
eVisibilityChanged = 0x00000040,
|
||||
eLayerStackChanged = 0x00000080,
|
||||
eCropChanged = 0x00000100,
|
||||
eOpacityChanged = 0x00000200,
|
||||
};
|
||||
|
||||
layer_state_t()
|
||||
|
@ -309,7 +309,12 @@ status_t Composer::setFlags(const sp<SurfaceComposerClient>& client,
|
||||
layer_state_t* s = getLayerStateLocked(client, id);
|
||||
if (!s)
|
||||
return BAD_INDEX;
|
||||
s->what |= layer_state_t::eVisibilityChanged;
|
||||
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->flags &= ~mask;
|
||||
s->flags |= (flags & mask);
|
||||
s->mask |= mask;
|
||||
|
@ -64,7 +64,6 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||
mName("unnamed"),
|
||||
mDebug(false),
|
||||
mFormat(PIXEL_FORMAT_NONE),
|
||||
mOpaqueLayer(true),
|
||||
mTransactionFlags(0),
|
||||
mQueuedFrames(0),
|
||||
mCurrentTransform(0),
|
||||
@ -86,7 +85,9 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client,
|
||||
|
||||
uint32_t layerFlags = 0;
|
||||
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)
|
||||
mPremultipliedAlpha = false;
|
||||
@ -189,7 +190,6 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
||||
|
||||
mSecure = (flags & ISurfaceComposerClient::eSecure) ? true : false;
|
||||
mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
|
||||
mOpaqueLayer = (flags & ISurfaceComposerClient::eOpaque);
|
||||
mCurrentOpacity = getOpacityForFormat(format);
|
||||
|
||||
mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
|
||||
@ -352,7 +352,7 @@ void Layer::setGeometry(
|
||||
|
||||
// this gives us only the "orientation" component of the transform
|
||||
const State& s(getDrawingState());
|
||||
if (!isOpaque() || s.alpha != 0xFF) {
|
||||
if (!isOpaque(s) || s.alpha != 0xFF) {
|
||||
layer.setBlending(mPremultipliedAlpha ?
|
||||
HWC_BLENDING_PREMULT :
|
||||
HWC_BLENDING_COVERAGE);
|
||||
@ -596,7 +596,7 @@ void Layer::drawWithOpenGL(
|
||||
texCoords[3] = vec2(right, 1.0f - top);
|
||||
|
||||
RenderEngine& engine(mFlinger->getRenderEngine());
|
||||
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(), s.alpha);
|
||||
engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), s.alpha);
|
||||
engine.drawMesh(mMesh);
|
||||
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
|
||||
// layer's opaque flag.
|
||||
@ -666,7 +666,7 @@ bool Layer::isOpaque() const
|
||||
|
||||
// if the layer has the opaque flag, then we're always opaque,
|
||||
// otherwise we use the current buffer's format.
|
||||
return mOpaqueLayer || mCurrentOpacity;
|
||||
return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
|
||||
}
|
||||
|
||||
bool Layer::isProtected() const
|
||||
@ -954,7 +954,8 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
struct Reject : public SurfaceFlingerConsumer::BufferRejecter {
|
||||
@ -1122,12 +1123,11 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions)
|
||||
}
|
||||
|
||||
mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
|
||||
if (oldOpacity != isOpaque()) {
|
||||
if (oldOpacity != isOpaque(s)) {
|
||||
recomputeVisibleRegions = true;
|
||||
}
|
||||
|
||||
// FIXME: postedRegion should be dirty & bounds
|
||||
const Layer::State& s(getDrawingState());
|
||||
Region dirtyRegion(Rect(s.active.w, s.active.h));
|
||||
|
||||
// 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.active.crop.left, s.active.crop.top,
|
||||
s.active.crop.right, s.active.crop.bottom,
|
||||
isOpaque(), contentDirty,
|
||||
isOpaque(s), contentDirty,
|
||||
s.alpha, s.flags,
|
||||
s.transform[0][0], s.transform[0][1],
|
||||
s.transform[1][0], s.transform[1][1],
|
||||
|
@ -149,8 +149,12 @@ public:
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -335,7 +339,6 @@ private:
|
||||
String8 mName;
|
||||
mutable bool mDebug;
|
||||
PixelFormat mFormat;
|
||||
bool mOpaqueLayer;
|
||||
|
||||
// these are protected by an external lock
|
||||
State mCurrentState;
|
||||
|
@ -1380,7 +1380,7 @@ void SurfaceFlinger::computeVisibleRegions(
|
||||
|
||||
// handle hidden surfaces by setting the visible region to empty
|
||||
if (CC_LIKELY(layer->isVisible())) {
|
||||
const bool translucent = !layer->isOpaque();
|
||||
const bool translucent = !layer->isOpaque(s);
|
||||
Rect bounds(s.transform.transform(layer->computeBounds()));
|
||||
visibleRegion.set(bounds);
|
||||
if (!visibleRegion.isEmpty()) {
|
||||
@ -1629,7 +1629,7 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
|
||||
const Layer::State& state(layer->getDrawingState());
|
||||
if ((cur->getHints() & HWC_HINT_CLEAR_FB)
|
||||
&& i
|
||||
&& layer->isOpaque() && (state.alpha == 0xFF)
|
||||
&& layer->isOpaque(state) && (state.alpha == 0xFF)
|
||||
&& hasGlesComposition) {
|
||||
// never clear the very first layer since we're
|
||||
// guaranteed the FB is already cleared
|
||||
@ -1873,7 +1873,9 @@ uint32_t SurfaceFlinger::setClientStateLocked(
|
||||
if (layer->setTransparentRegionHint(s.transparentRegion))
|
||||
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))
|
||||
flags |= eTraversalNeeded;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user