diff options
author | Mathias Agopian <mathias@google.com> | 2010-03-16 16:41:46 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2010-03-16 17:54:27 -0700 |
commit | ab02873e8f4e235b0db800521dd0c969ed38c0b9 (patch) | |
tree | 54754cb5af99ddd885337a16410f180648b10728 /libs/surfaceflinger | |
parent | b7f853e57b3ba884a9e5390baf004415c2556e61 (diff) | |
download | frameworks_native-ab02873e8f4e235b0db800521dd0c969ed38c0b9.zip frameworks_native-ab02873e8f4e235b0db800521dd0c969ed38c0b9.tar.gz frameworks_native-ab02873e8f4e235b0db800521dd0c969ed38c0b9.tar.bz2 |
fix [2511580] Window poop on screen - drop down list left some residual when it resized
Change-Id: Ib9a3622e7a568ba26717a93b5bfa4a191651f4d0
Diffstat (limited to 'libs/surfaceflinger')
-rw-r--r-- | libs/surfaceflinger/LayerBase.cpp | 1 | ||||
-rw-r--r-- | libs/surfaceflinger/LayerBase.h | 4 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 72 |
3 files changed, 57 insertions, 20 deletions
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp index 140f10c..efbc77a 100644 --- a/libs/surfaceflinger/LayerBase.cpp +++ b/libs/surfaceflinger/LayerBase.cpp @@ -214,7 +214,6 @@ uint32_t LayerBase::doTransaction(uint32_t flags) if ((front.w != temp.w) || (front.h != temp.h)) { // invalidate and recompute the visible regions if needed flags |= Layer::eVisibleRegion; - this->contentDirty = true; } if (temp.sequence != front.sequence) { diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h index a6e5644..62ec839 100644 --- a/libs/surfaceflinger/LayerBase.h +++ b/libs/surfaceflinger/LayerBase.h @@ -157,11 +157,11 @@ public: /** * setCoveredRegion - called when the covered region changes. The covered - * region correspond to any area of the surface that is covered + * region corresponds to any area of the surface that is covered * (transparently or not) by another surface. */ virtual void setCoveredRegion(const Region& coveredRegion); - + /** * validateVisibility - cache a bunch of things */ diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index 26ee285..0722fda 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -674,6 +674,8 @@ void SurfaceFlinger::computeVisibleRegions( { const GraphicPlane& plane(graphicPlane(0)); const Transform& planeTransform(plane.transform()); + const DisplayHardware& hw(plane.displayHardware()); + const Region screenRegion(hw.bounds()); Region aboveOpaqueLayers; Region aboveCoveredLayers; @@ -689,31 +691,56 @@ void SurfaceFlinger::computeVisibleRegions( // start with the whole surface at its current location const Layer::State& s(layer->drawingState()); - // handle hidden surfaces by setting the visible region to empty + /* + * opaqueRegion: area of a surface that is fully opaque. + */ Region opaqueRegion; + + /* + * visibleRegion: area of a surface that is visible on screen + * and not fully transparent. This is essentially the layer's + * footprint minus the opaque regions above it. + * Areas covered by a translucent surface are considered visible. + */ Region visibleRegion; + + /* + * coveredRegion: area of a surface that is covered by all + * visible regions above it (which includes the translucent areas). + */ Region coveredRegion; + + + // handle hidden surfaces by setting the visible region to empty if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { const bool translucent = layer->needsBlending(); const Rect bounds(layer->visibleBounds()); visibleRegion.set(bounds); - coveredRegion = visibleRegion; - - // Remove the transparent area from the visible region - if (translucent) { - visibleRegion.subtractSelf(layer->transparentRegionScreen); - } + visibleRegion.andSelf(screenRegion); + if (!visibleRegion.isEmpty()) { + // Remove the transparent area from the visible region + if (translucent) { + visibleRegion.subtractSelf(layer->transparentRegionScreen); + } - // compute the opaque region - if (s.alpha==255 && !translucent && layer->getOrientation()>=0) { - // the opaque region is the visible region - opaqueRegion = visibleRegion; + // compute the opaque region + const int32_t layerOrientation = layer->getOrientation(); + if (s.alpha==255 && !translucent && + ((layerOrientation & Transform::ROT_INVALID) == false)) { + // the opaque region is the layer's footprint + opaqueRegion = visibleRegion; + } } } + // Clip the covered region to the visible region + coveredRegion = aboveCoveredLayers.intersect(visibleRegion); + + // Update aboveCoveredLayers for next (lower) layer + aboveCoveredLayers.orSelf(visibleRegion); + // subtract the opaque region covered by the layers above us visibleRegion.subtractSelf(aboveOpaqueLayers); - coveredRegion.andSelf(aboveCoveredLayers); // compute this layer's dirty region if (layer->contentDirty) { @@ -724,19 +751,30 @@ void SurfaceFlinger::computeVisibleRegions( layer->contentDirty = false; } else { /* compute the exposed region: - * exposed = what's VISIBLE and NOT COVERED now - * but was COVERED before + * the exposed region consists of two components: + * 1) what's VISIBLE now and was COVERED before + * 2) what's EXPOSED now less what was EXPOSED before + * + * note that (1) is conservative, we start with the whole + * visible region but only keep what used to be covered by + * something -- which mean it may have been exposed. + * + * (2) handles areas that were not covered by anything but got + * exposed because of a resize. */ - dirty = (visibleRegion - coveredRegion) & layer->coveredRegionScreen; + const Region newExposed = visibleRegion - coveredRegion; + const Region oldVisibleRegion = layer->visibleRegionScreen; + const Region oldCoveredRegion = layer->coveredRegionScreen; + const Region oldExposed = oldVisibleRegion - oldCoveredRegion; + dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed); } dirty.subtractSelf(aboveOpaqueLayers); // accumulate to the screen dirty region dirtyRegion.orSelf(dirty); - // Update aboveOpaqueLayers/aboveCoveredLayers for next (lower) layer + // Update aboveOpaqueLayers for next (lower) layer aboveOpaqueLayers.orSelf(opaqueRegion); - aboveCoveredLayers.orSelf(visibleRegion); // Store the visible region is screen space layer->setVisibleRegion(visibleRegion); |