SurfaceFlinger: fix a layer occlusion bug

This change fixes a bug where the window visibility would be computed
before any buffers were available, causing the window to be treated as
non-opaque.  When the first buffer arrived, if both mCurrentOpacity and
the opacity determined by the buffer's format were 'opaque', a
recomputation of the opacity would not be done, and the window would
continue to be treated as non-opaque.  SurfaceFlinger could then
unnecessarily draw fully occluded layers.

Change-Id: I2b95da2f4b50e68d50fc5afd8b772e26e62f58d6
Bug: 5057122
This commit is contained in:
Jamie Gennis 2011-07-28 14:54:07 -07:00
parent 96e108271b
commit db5230f444

View File

@ -326,8 +326,9 @@ bool Layer::isOpaque() const
{
// if we don't have a buffer yet, we're translucent regardless of the
// layer's opaque flag.
if (mActiveBuffer == 0)
if (mActiveBuffer == 0) {
return false;
}
// if the layer has the opaque flag, then we're always opaque,
// otherwise we use the current buffer's format.
@ -411,6 +412,8 @@ bool Layer::isCropped() const {
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
if (mQueuedFrames > 0) {
const bool oldOpacity = isOpaque();
// signal another event if we have more frames pending
if (android_atomic_dec(&mQueuedFrames) > 1) {
mFlinger->signalEvent();
@ -438,9 +441,8 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions)
mFlinger->invalidateHwcGeometry();
}
const bool opacity(getOpacityForFormat(mActiveBuffer->format));
if (opacity != mCurrentOpacity) {
mCurrentOpacity = opacity;
mCurrentOpacity = getOpacityForFormat(mActiveBuffer->format);
if (oldOpacity != isOpaque()) {
recomputeVisibleRegions = true;
}