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 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()
|
||||||
|
@ -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;
|
||||||
|
@ -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],
|
||||||
|
@ -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;
|
||||||
|
@ -1380,7 +1380,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()) {
|
||||||
@ -1629,7 +1629,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
|
||||||
@ -1873,7 +1873,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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user