summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-11-21 16:02:13 -0800
committerMathias Agopian <mathias@google.com>2012-11-21 16:03:52 -0800
commit8430095879d2fa6878e68f8f12da4e704815ac09 (patch)
tree9e390872accbfdfd1e6d16b9c9e9e537d024ae78 /services/surfaceflinger/SurfaceFlinger.cpp
parent764c197c6fc2bf10b038c33b320a4e95594d52d8 (diff)
downloadframeworks_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.cpp69
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
*/