summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-11-27 16:07:04 -0800
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-11-27 16:07:04 -0800
commitefd614b869e952792b009db4ab54f3bb4375d198 (patch)
tree50a7d7f3597c67374e4eff4dd8451f82d9816b5b
parent762a6d86de63ad319884ab6e666be6ad0d75996e (diff)
parent8430095879d2fa6878e68f8f12da4e704815ac09 (diff)
downloadframeworks_native-efd614b869e952792b009db4ab54f3bb4375d198.zip
frameworks_native-efd614b869e952792b009db4ab54f3bb4375d198.tar.gz
frameworks_native-efd614b869e952792b009db4ab54f3bb4375d198.tar.bz2
Merge "make transform hint multi-display aware" into jb-mr1.1-dev
-rw-r--r--services/surfaceflinger/Layer.cpp12
-rw-r--r--services/surfaceflinger/Layer.h4
-rw-r--r--services/surfaceflinger/LayerBase.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp69
4 files changed, 64 insertions, 23 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 064f689..7edbdc5 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -110,7 +110,8 @@ void Layer::onFirstRef()
mSurfaceTexture->setDefaultMaxBufferCount(3);
#endif
- updateTransformHint();
+ const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
+ updateTransformHint(hw);
}
Layer::~Layer()
@@ -767,15 +768,12 @@ uint32_t Layer::getEffectiveUsage(uint32_t usage) const
return usage;
}
-void Layer::updateTransformHint() const {
+void Layer::updateTransformHint(const sp<const DisplayDevice>& hw) const {
uint32_t orientation = 0;
if (!mFlinger->mDebugDisableTransformHint) {
- // The transform hint is used to improve performance on the main
- // display -- we can only have a single transform hint, it cannot
+ // The transform hint is used to improve performance, but we can
+ // only have a single transform hint, it cannot
// apply to all displays.
- // This is why we use the default display here. This is not an
- // oversight.
- sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
const Transform& planeTransform(hw->getTransform());
orientation = planeTransform.getOrientation();
if (orientation & Transform::ROT_INVALID) {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 6f75d8c..c5eb26b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -91,8 +91,8 @@ public:
inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
// Updates the transform hint in our SurfaceTexture to match
- // the current orientation of the default display device.
- virtual void updateTransformHint() const;
+ // the current orientation of the display device.
+ virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const;
protected:
virtual void onFirstRef();
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 00c4ffe..4d5a5b0 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -246,7 +246,7 @@ public:
* Updates the SurfaceTexture's transform hint, for layers that have
* a SurfaceTexture.
*/
- virtual void updateTransformHint() const { }
+ virtual void updateTransformHint(const sp<const DisplayDevice>& hw) const { }
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
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
*/