* commit '98cbec81be1d39223e33abde9ac35e43b62918bf': make transform hint multi-display aware
This commit is contained in:
commit
a7da0dda39
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -1076,7 +1076,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;
|
||||
|
||||
@ -1149,18 +1149,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1209,6 +1197,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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user