diff options
| -rw-r--r-- | include/gui/SurfaceComposerClient.h | 2 | ||||
| -rw-r--r-- | include/gui/SurfaceControl.h | 5 | ||||
| -rw-r--r-- | include/private/gui/LayerState.h | 3 | ||||
| -rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 19 | ||||
| -rw-r--r-- | libs/gui/SurfaceControl.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 31 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 5 |
9 files changed, 65 insertions, 13 deletions
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 73f923c237..312e02f1dc 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -140,6 +140,8 @@ public: const sp<IBinder>& handle, uint64_t frameNumber); status_t setOverrideScalingMode(const sp<IBinder>& id, int32_t overrideScalingMode); + status_t setPositionAppliesWithResize(const sp<IBinder>& id); + status_t destroySurface(const sp<IBinder>& id); status_t clearLayerFrameStats(const sp<IBinder>& token) const; diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index bedebb6051..fafd1948fe 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -73,6 +73,11 @@ public: status_t setCrop(const Rect& crop); status_t setFinalCrop(const Rect& crop); + // If the size changes in this transaction, position updates specified + // in this transaction will not complete until a buffer of the new size + // arrives. + status_t setPositionAppliesWithResize(); + // Defers applying any changes made in this transaction until the Layer // identified by handle reaches the given frameNumber status_t deferTransactionUntil(sp<IBinder> handle, uint64_t frameNumber); diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index 92d31d1012..4885e05d04 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -54,7 +54,8 @@ struct layer_state_t { eCropChanged = 0x00000100, eDeferTransaction = 0x00000200, eFinalCropChanged = 0x00000400, - eOverrideScalingModeChanged = 0x00000800 + eOverrideScalingModeChanged = 0x00000800, + ePositionAppliesWithResize = 0x00001000, }; layer_state_t() diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index e33cc37b24..92ae41eec8 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -165,6 +165,8 @@ public: uint64_t frameNumber); status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, int32_t overrideScalingMode); + status_t setPositionAppliesWithResize(const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id); void setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); @@ -443,6 +445,18 @@ status_t Composer::setOverrideScalingMode( return NO_ERROR; } +status_t Composer::setPositionAppliesWithResize( + const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id) { + Mutex::Autolock lock(mLock); + layer_state_t* s = getLayerStateLocked(client, id); + if (!s) { + return BAD_INDEX; + } + s->what |= layer_state_t::ePositionAppliesWithResize; + return NO_ERROR; +} + // --------------------------------------------------------------------------- DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) { @@ -685,6 +699,11 @@ status_t SurfaceComposerClient::setOverrideScalingMode( this, id, overrideScalingMode); } +status_t SurfaceComposerClient::setPositionAppliesWithResize( + const sp<IBinder>& id) { + return getComposer().setPositionAppliesWithResize(this, id); +} + // ---------------------------------------------------------------------------- void SurfaceComposerClient::setDisplaySurface(const sp<IBinder>& token, diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 314d83a209..4671e505aa 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -112,6 +112,11 @@ status_t SurfaceControl::setPosition(float x, float y) { if (err < 0) return err; return mClient->setPosition(mHandle, x, y); } +status_t SurfaceControl::setPositionAppliesWithResize() { + status_t err = validate(); + if (err < 0) return err; + return mClient->setPositionAppliesWithResize(mHandle); +} status_t SurfaceControl::setSize(uint32_t w, uint32_t h) { status_t err = validate(); if (err < 0) return err; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index b5d3262056..02477239b7 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -95,7 +95,8 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mQueueItems(), mLastFrameNumberReceived(0), mUpdateTexImageFailed(false), - mAutoRefresh(false) + mAutoRefresh(false), + mFreezePositionUpdates(false) { #ifdef USE_HWC2 ALOGV("Creating Layer %s", name.string()); @@ -1415,11 +1416,9 @@ uint32_t Layer::doTransaction(uint32_t flags) { c.requested.w, c.requested.h); } + const bool resizePending = (c.requested.w != c.active.w) || + (c.requested.h != c.active.h); if (!isFixedSize()) { - - const bool resizePending = (c.requested.w != c.active.w) || - (c.requested.h != c.active.h); - if (resizePending && mSidebandStream == NULL) { // don't let Layer::doTransaction update the drawing state // if we have a pending resize, unless we are in fixed-size mode. @@ -1443,8 +1442,16 @@ uint32_t Layer::doTransaction(uint32_t flags) { if (flags & eDontUpdateGeometryState) { } else { Layer::State& editCurrentState(getCurrentState()); - editCurrentState.active = editCurrentState.requested; - c.active = c.requested; + if (mFreezePositionUpdates) { + float tx = c.active.transform.tx(); + float ty = c.active.transform.ty(); + c.active = c.requested; + c.active.transform.set(tx, ty); + editCurrentState.active = c.active; + } else { + editCurrentState.active = editCurrentState.requested; + c.active = c.requested; + } } if (s.active != c.active) { @@ -1491,7 +1498,7 @@ uint32_t Layer::setTransactionFlags(uint32_t flags) { return android_atomic_or(flags, &mTransactionFlags); } -bool Layer::setPosition(float x, float y) { +bool Layer::setPosition(float x, float y, bool immediate) { if (mCurrentState.requested.transform.tx() == x && mCurrentState.requested.transform.ty() == y) return false; mCurrentState.sequence++; @@ -1500,12 +1507,16 @@ bool Layer::setPosition(float x, float y) { // we want to apply the position portion of the transform matrix immediately, // but still delay scaling when resizing a SCALING_MODE_FREEZE layer. mCurrentState.requested.transform.set(x, y); - mCurrentState.active.transform.set(x, y); + if (immediate && !mFreezePositionUpdates) { + mCurrentState.active.transform.set(x, y); + } + mFreezePositionUpdates = mFreezePositionUpdates || !immediate; mCurrentState.modified = true; setTransactionFlags(eTransactionNeeded); return true; } + bool Layer::setLayer(uint32_t z) { if (mCurrentState.z == z) return false; @@ -1585,6 +1596,7 @@ bool Layer::setOverrideScalingMode(int32_t scalingMode) { if (scalingMode == mOverrideScalingMode) return false; mOverrideScalingMode = scalingMode; + setTransactionFlags(eTransactionNeeded); return true; } @@ -2004,6 +2016,7 @@ Region Layer::latchBuffer(bool& recomputeVisibleRegions) if (bufWidth != uint32_t(oldActiveBuffer->width) || bufHeight != uint32_t(oldActiveBuffer->height)) { recomputeVisibleRegions = true; + mFreezePositionUpdates = false; } } diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 7d085a479a..ba7184f8e7 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -145,7 +145,7 @@ public: status_t setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags); // modify current state - bool setPosition(float x, float y); + bool setPosition(float x, float y, bool immediate); bool setLayer(uint32_t z); bool setSize(uint32_t w, uint32_t h); #ifdef USE_HWC2 @@ -596,6 +596,7 @@ private: bool mUpdateTexImageFailed; // This is only modified from the main thread bool mAutoRefresh; + bool mFreezePositionUpdates; }; // --------------------------------------------------------------------------- diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 80b4d75fb1..a10a8138e3 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2251,9 +2251,12 @@ uint32_t SurfaceFlinger::setClientStateLocked( sp<Layer> layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; + bool positionAppliesWithResize = + what & layer_state_t::ePositionAppliesWithResize; if (what & layer_state_t::ePositionChanged) { - if (layer->setPosition(s.x, s.y)) + if (layer->setPosition(s.x, s.y, !positionAppliesWithResize)) { flags |= eTraversalNeeded; + } } if (what & layer_state_t::eLayerChanged) { // NOTE: index needs to be calculated before we update the state diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index 5721db7dce..7f3b269f0e 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -2267,9 +2267,12 @@ uint32_t SurfaceFlinger::setClientStateLocked( sp<Layer> layer(client->getLayerUser(s.surface)); if (layer != 0) { const uint32_t what = s.what; + bool positionAppliesWithResize = + what & layer_state_t::ePositionAppliesWithResize; if (what & layer_state_t::ePositionChanged) { - if (layer->setPosition(s.x, s.y)) + if (layer->setPosition(s.x, s.y, !positionAppliesWithResize)) { flags |= eTraversalNeeded; + } } if (what & layer_state_t::eLayerChanged) { // NOTE: index needs to be calculated before we update the state |