diff options
author | Mathias Agopian <mathias@google.com> | 2012-11-21 16:02:13 -0800 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2012-11-21 16:03:52 -0800 |
commit | 8430095879d2fa6878e68f8f12da4e704815ac09 (patch) | |
tree | 9e390872accbfdfd1e6d16b9c9e9e537d024ae78 /services/surfaceflinger/SurfaceFlinger.cpp | |
parent | 764c197c6fc2bf10b038c33b320a4e95594d52d8 (diff) | |
download | frameworks_native-8430095879d2fa6878e68f8f12da4e704815ac09.zip frameworks_native-8430095879d2fa6878e68f8f12da4e704815ac09.tar.gz frameworks_native-8430095879d2fa6878e68f8f12da4e704815ac09.tar.bz2 |
make transform hint multi-display aware
if a layer is not mirrored, we now use its display
as the source for the transfrom hint calculation
instead of always using the default (main) display.
this change does two thing:
1) we make updateTransformHint take a DisplayDevice
as a parameter instead of hard-coding the
main display.
2) each time we do a transaction that could change
the hint, we go through all layers and
figure out which display should be used for their
transform hint.
Bug: 7599344
Change-Id: I9b04a95e6c372dd770bacf81d8ef6f8e31b87b83
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index ce10c78..842471f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1069,7 +1069,7 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) if (transactionFlags & eTraversalNeeded) { for (size_t i=0 ; i<count ; i++) { - const sp<LayerBase>& layer = currentLayers[i]; + const sp<LayerBase>& layer(currentLayers[i]); uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); if (!trFlags) continue; @@ -1142,18 +1142,6 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) disp->setProjection(state.orientation, state.viewport, state.frame); } - - // Walk through all the layers in currentLayers, - // and update their transform hint. - // - // TODO: we could be much more clever about which - // layers we touch and how often we do these updates - // (e.g. only touch the layers associated with this - // display, and only on a rotation). - for (size_t i = 0; i < count; i++) { - const sp<LayerBase>& layerBase = currentLayers[i]; - layerBase->updateTransformHint(); - } } } } @@ -1208,6 +1196,61 @@ void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) } } + if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { + // The transform hint might have changed for some layers + // (either because a display has changed, or because a layer + // as changed). + // + // Walk through all the layers in currentLayers, + // and update their transform hint. + // + // If a layer is visible only on a single display, then that + // display is used to calculate the hint, otherwise we use the + // default display. + // + // NOTE: we do this here, rather than in rebuildLayerStacks() so that + // the hint is set before we acquire a buffer from the surface texture. + // + // NOTE: layer transactions have taken place already, so we use their + // drawing state. However, SurfaceFlinger's own transaction has not + // happened yet, so we must use the current state layer list + // (soon to become the drawing state list). + // + sp<const DisplayDevice> disp; + uint32_t currentlayerStack = 0; + for (size_t i=0; i<count; i++) { + // NOTE: we rely on the fact that layers are sorted by + // layerStack first (so we don't have to traverse the list + // of displays for every layer). + const sp<LayerBase>& layerBase(currentLayers[i]); + uint32_t layerStack = layerBase->drawingState().layerStack; + if (i==0 || currentlayerStack != layerStack) { + currentlayerStack = layerStack; + // figure out if this layerstack is mirrored + // (more than one display) if so, pick the default display, + // if not, pick the only display it's on. + disp.clear(); + for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) { + sp<const DisplayDevice> hw(mDisplays[dpy]); + if (hw->getLayerStack() == currentlayerStack) { + if (disp == NULL) { + disp = hw; + } else { + disp = getDefaultDisplayDevice(); + break; + } + } + } + } + if (disp != NULL) { + // presumably this means this layer is using a layerStack + // that is not visible on any display + layerBase->updateTransformHint(disp); + } + } + } + + /* * Perform our own transaction if needed */ |