diff options
author | 2017-01-10 16:42:54 -0800 | |
---|---|---|
committer | 2017-02-27 10:20:10 -0800 | |
commit | 0d48072f6047140119ff194c1194ce402fca2c0b (patch) | |
tree | 3db72861fcac7b9a1622d3f7d75d54bcba2e22b3 | |
parent | e7f1979d8180ff9ab10422da2020e77fafe8d7d6 (diff) |
Add deferTransaction variant taking GraphicBufferProducer.
For SurfaceView using child layers, the client framework
will not have access to the Handle* for the parent surface,
but still needs a way to defer transactions to it's frames.
Test: Tested with corresponding SurfaceView modifications and existing tests.
Change-Id: I6f01c360e85a95ff0ab08db406741221152e5d5c
-rw-r--r-- | include/gui/SurfaceComposerClient.h | 2 | ||||
-rw-r--r-- | include/gui/SurfaceControl.h | 10 | ||||
-rw-r--r-- | include/private/gui/LayerState.h | 6 | ||||
-rw-r--r-- | libs/gui/LayerState.cpp | 7 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 25 | ||||
-rw-r--r-- | libs/gui/SurfaceControl.cpp | 7 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 35 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 7 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 21 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 3 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger_hwc1.cpp | 21 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceInterceptor.cpp | 25 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceInterceptor.h | 5 |
13 files changed, 139 insertions, 35 deletions
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index 830216079f..df73ff61ee 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -156,6 +156,8 @@ public: status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); status_t deferTransactionUntil(const sp<IBinder>& id, const sp<IBinder>& handle, uint64_t frameNumber); + status_t deferTransactionUntil(const sp<IBinder>& id, + const sp<Surface>& handle, uint64_t frameNumber); status_t reparentChildren(const sp<IBinder>& id, const sp<IBinder>& newParentHandle); status_t setOverrideScalingMode(const sp<IBinder>& id, diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index 54c8fa9dd2..8d338f98a8 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -80,8 +80,16 @@ public: status_t setGeometryAppliesWithResize(); // Defers applying any changes made in this transaction until the Layer - // identified by handle reaches the given frameNumber + // identified by handle reaches the given frameNumber. If the Layer identified + // by handle is removed, then we will apply this transaction regardless of + // what frame number has been reached. status_t deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); + + // A variant of deferTransactionUntil which identifies the Layer we wait for by + // Surface instead of Handle. Useful for clients which may not have the + // SurfaceControl for some of their Surfaces. Otherwise behaves identically. + status_t deferTransactionUntil(const sp<Surface>& barrier, uint64_t frameNumber); + // Reparents all children of this layer to the new parent handle. status_t reparentChildren(const sp<IBinder>& newParentHandle); diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h index 2a1801b4dd..fac5d2cb75 100644 --- a/include/private/gui/LayerState.h +++ b/include/private/gui/LayerState.h @@ -24,6 +24,7 @@ #include <ui/Region.h> #include <ui/Rect.h> +#include <gui/IGraphicBufferProducer.h> namespace android { @@ -95,10 +96,13 @@ struct layer_state_t { matrix22_t matrix; Rect crop; Rect finalCrop; - sp<IBinder> handle; + sp<IBinder> barrierHandle; sp<IBinder> reparentHandle; uint64_t frameNumber; int32_t overrideScalingMode; + + sp<IGraphicBufferProducer> barrierGbp; + // non POD must be last. see write/read Region transparentRegion; }; diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp index bb552aa67c..2461cba152 100644 --- a/libs/gui/LayerState.cpp +++ b/libs/gui/LayerState.cpp @@ -39,10 +39,11 @@ status_t layer_state_t::write(Parcel& output) const output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix; output.write(crop); output.write(finalCrop); - output.writeStrongBinder(handle); + output.writeStrongBinder(barrierHandle); output.writeStrongBinder(reparentHandle); output.writeUint64(frameNumber); output.writeInt32(overrideScalingMode); + output.writeStrongBinder(IInterface::asBinder(barrierGbp)); output.write(transparentRegion); return NO_ERROR; } @@ -68,10 +69,12 @@ status_t layer_state_t::read(const Parcel& input) } input.read(crop); input.read(finalCrop); - handle = input.readStrongBinder(); + barrierHandle = input.readStrongBinder(); reparentHandle = input.readStrongBinder(); frameNumber = input.readUint64(); overrideScalingMode = input.readInt32(); + barrierGbp = + interface_cast<IGraphicBufferProducer>(input.readStrongBinder()); input.read(transparentRegion); return NO_ERROR; } diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index ae81c8fbd1..fd277f1beb 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -38,6 +38,7 @@ #include <gui/IGraphicBufferProducer.h> #include <gui/ISurfaceComposer.h> #include <gui/ISurfaceComposerClient.h> +#include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> #include <private/gui/ComposerService.h> @@ -168,6 +169,9 @@ public: status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const sp<IBinder>& handle, uint64_t frameNumber); + status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client, + const sp<IBinder>& id, const sp<Surface>& barrierSurface, + uint64_t frameNumber); status_t reparentChildren(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, const sp<IBinder>& newParentHandle); @@ -439,7 +443,21 @@ status_t Composer::deferTransactionUntil( return BAD_INDEX; } s->what |= layer_state_t::eDeferTransaction; - s->handle = handle; + s->barrierHandle = handle; + s->frameNumber = frameNumber; + return NO_ERROR; +} + +status_t Composer::deferTransactionUntil( + const sp<SurfaceComposerClient>& client, const sp<IBinder>& id, + const sp<Surface>& barrierSurface, uint64_t frameNumber) { + Mutex::Autolock lock(mLock); + layer_state_t* s = getLayerStateLocked(client, id); + if (!s) { + return BAD_INDEX; + } + s->what |= layer_state_t::eDeferTransaction; + s->barrierGbp = barrierSurface->getIGraphicBufferProducer(); s->frameNumber = frameNumber; return NO_ERROR; } @@ -777,6 +795,11 @@ status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id, return getComposer().deferTransactionUntil(this, id, handle, frameNumber); } +status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id, + const sp<Surface>& barrierSurface, uint64_t frameNumber) { + return getComposer().deferTransactionUntil(this, id, barrierSurface, frameNumber); +} + status_t SurfaceComposerClient::reparentChildren(const sp<IBinder>& id, const sp<IBinder>& newParentHandle) { return getComposer().reparentChildren(this, id, newParentHandle); diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index 0362216258..94094e5a51 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -170,6 +170,13 @@ status_t SurfaceControl::deferTransactionUntil(const sp<IBinder>& handle, return mClient->deferTransactionUntil(mHandle, handle, frameNumber); } +status_t SurfaceControl::deferTransactionUntil(const sp<Surface>& handle, + uint64_t frameNumber) { + status_t err = validate(); + if (err < 0) return err; + return mClient->deferTransactionUntil(mHandle, handle, frameNumber); +} + status_t SurfaceControl::reparentChildren(const sp<IBinder>& newParentHandle) { status_t err = validate(); if (err < 0) return err; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 2f83c0e946..6908c883fd 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1436,29 +1436,23 @@ void Layer::pushPendingState() { // If this transaction is waiting on the receipt of a frame, generate a sync // point and send it to the remote layer. - if (mCurrentState.handle != nullptr) { - sp<IBinder> strongBinder = mCurrentState.handle.promote(); - sp<Handle> handle = nullptr; - sp<Layer> handleLayer = nullptr; - if (strongBinder != nullptr) { - handle = static_cast<Handle*>(strongBinder.get()); - handleLayer = handle->owner.promote(); - } - if (strongBinder == nullptr || handleLayer == nullptr) { - ALOGE("[%s] Unable to promote Layer handle", mName.string()); + if (mCurrentState.barrierLayer != nullptr) { + sp<Layer> barrierLayer = mCurrentState.barrierLayer.promote(); + if (barrierLayer == nullptr) { + ALOGE("[%s] Unable to promote barrier Layer.", mName.string()); // If we can't promote the layer we are intended to wait on, // then it is expired or otherwise invalid. Allow this transaction // to be applied as per normal (no synchronization). - mCurrentState.handle = nullptr; + mCurrentState.barrierLayer = nullptr; } else { auto syncPoint = std::make_shared<SyncPoint>( mCurrentState.frameNumber); - if (handleLayer->addSyncPoint(syncPoint)) { + if (barrierLayer->addSyncPoint(syncPoint)) { mRemoteSyncPoints.push_back(std::move(syncPoint)); } else { // We already missed the frame we're supposed to synchronize // on, so go ahead and apply the state update - mCurrentState.handle = nullptr; + mCurrentState.barrierLayer = nullptr; } } @@ -1481,7 +1475,7 @@ void Layer::popPendingState(State* stateToCommit) { bool Layer::applyPendingStates(State* stateToCommit) { bool stateUpdateAvailable = false; while (!mPendingStates.empty()) { - if (mPendingStates[0].handle != nullptr) { + if (mPendingStates[0].barrierLayer != nullptr) { if (mRemoteSyncPoints.empty()) { // If we don't have a sync point for this, apply it anyway. It // will be visually wrong, but it should keep us from getting @@ -1828,17 +1822,24 @@ uint32_t Layer::getLayerStack() const { return p->getLayerStack(); } -void Layer::deferTransactionUntil(const sp<IBinder>& handle, +void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber) { - mCurrentState.handle = handle; + mCurrentState.barrierLayer = barrierLayer; mCurrentState.frameNumber = frameNumber; // We don't set eTransactionNeeded, because just receiving a deferral // request without any other state updates shouldn't actually induce a delay mCurrentState.modified = true; pushPendingState(); - mCurrentState.handle = nullptr; + mCurrentState.barrierLayer = nullptr; mCurrentState.frameNumber = 0; mCurrentState.modified = false; + ALOGE("Deferred transaction"); +} + +void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle, + uint64_t frameNumber) { + sp<Handle> handle = static_cast<Handle*>(barrierHandle.get()); + deferTransactionUntil(handle->owner.promote(), frameNumber); } void Layer::useSurfaceDamage() { diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index c5fea73be4..fc33c99373 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -128,9 +128,9 @@ public: // finalCrop is expressed in display space coordinate. Rect finalCrop; - // If set, defers this state update until the Layer identified by handle + // If set, defers this state update until the identified Layer // receives a frame with the given frameNumber - wp<IBinder> handle; + wp<Layer> barrierLayer; uint64_t frameNumber; // the transparentRegion hint is a bit special, it's latched only @@ -171,7 +171,8 @@ public: bool setLayerStack(uint32_t layerStack); bool setDataSpace(android_dataspace dataSpace); uint32_t getLayerStack() const; - void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); + void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber); + void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber); bool setOverrideScalingMode(int32_t overrideScalingMode); void setInfo(uint32_t type, uint32_t appId); bool reparentChildren(const sp<IBinder>& layer); diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 60c71b3950..7a31a1528c 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -167,7 +167,7 @@ SurfaceFlinger::SurfaceFlinger() mLastTransactionTime(0), mBootFinished(false), mForceFullDamage(false), - mInterceptor(), + mInterceptor(this), mPrimaryDispSync("PrimaryDispSync"), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), @@ -629,6 +629,11 @@ size_t SurfaceFlinger::getMaxViewportDims() const { bool SurfaceFlinger::authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) const { Mutex::Autolock _l(mStateLock); + return authenticateSurfaceTextureLocked(bufferProducer); +} + +bool SurfaceFlinger::authenticateSurfaceTextureLocked( + const sp<IGraphicBufferProducer>& bufferProducer) const { sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; } @@ -2798,7 +2803,19 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } if (what & layer_state_t::eDeferTransaction) { - layer->deferTransactionUntil(s.handle, s.frameNumber); + if (s.barrierHandle != nullptr) { + layer->deferTransactionUntil(s.barrierHandle, s.frameNumber); + } else if (s.barrierGbp != nullptr) { + const sp<IGraphicBufferProducer>& gbp = s.barrierGbp; + if (authenticateSurfaceTextureLocked(gbp)) { + const auto& otherLayer = + (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); + layer->deferTransactionUntil(otherLayer, s.frameNumber); + } else { + ALOGE("Attempt to defer transaction to to an" + " unrecognized GraphicBufferProducer"); + } + } // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index c43786ad04..970a4ef125 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -160,6 +160,9 @@ public: return *mRenderEngine; } + bool authenticateSurfaceTextureLocked( + const sp<IGraphicBufferProducer>& bufferProducer) const; + private: friend class Client; friend class DisplayEventConnection; diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp index 5aaaab1f5e..056d733089 100644 --- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp +++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp @@ -155,7 +155,7 @@ SurfaceFlinger::SurfaceFlinger() mLastTransactionTime(0), mBootFinished(false), mForceFullDamage(false), - mInterceptor(), + mInterceptor(this), mPrimaryDispSync("PrimaryDispSync"), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), @@ -628,6 +628,11 @@ size_t SurfaceFlinger::getMaxViewportDims() const { bool SurfaceFlinger::authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& bufferProducer) const { Mutex::Autolock _l(mStateLock); + return authenticateSurfaceTextureLocked(bufferProducer); +} + +bool SurfaceFlinger::authenticateSurfaceTextureLocked( + const sp<IGraphicBufferProducer>& bufferProducer) const { sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer)); return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0; } @@ -2582,7 +2587,19 @@ uint32_t SurfaceFlinger::setClientStateLocked( } } if (what & layer_state_t::eDeferTransaction) { - layer->deferTransactionUntil(s.handle, s.frameNumber); + if (s.barrierHandle != nullptr) { + layer->deferTransactionUntil(s.barrierHandle, s.frameNumber); + } else if (s.barrierGbp != nullptr) { + const sp<IGraphicBufferProducer>& gbp = s.barrierGbp; + if (authenticateSurfaceTextureLocked(gbp)) { + const auto& otherLayer = + (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); + layer->deferTransactionUntil(otherLayer, s.frameNumber); + } else { + ALOGE("Attempt to defer transaction to to an" + " unrecognized GraphicBufferProducer"); + } + } // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp index 2d6472a8ef..026fe803c0 100644 --- a/services/surfaceflinger/SurfaceInterceptor.cpp +++ b/services/surfaceflinger/SurfaceInterceptor.cpp @@ -31,6 +31,11 @@ namespace android { // ---------------------------------------------------------------------------- +SurfaceInterceptor::SurfaceInterceptor(SurfaceFlinger* flinger) + : mFlinger(flinger) +{ +} + void SurfaceInterceptor::enable(const SortedVector<sp<Layer>>& layers, const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays) { @@ -97,8 +102,8 @@ void SurfaceInterceptor::addInitialSurfaceStateLocked(Increment* increment, addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion); addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack); addCropLocked(transaction, layerId, layer->mCurrentState.crop); - if (layer->mCurrentState.handle != nullptr) { - addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.handle, + if (layer->mCurrentState.barrierLayer != nullptr) { + addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.barrierLayer.promote(), layer->mCurrentState.frameNumber); } addFinalCropLocked(transaction, layerId, layer->mCurrentState.finalCrop); @@ -287,10 +292,9 @@ void SurfaceInterceptor::addFinalCropLocked(Transaction* transaction, int32_t la } void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId, - const wp<const IBinder>& weakHandle, uint64_t frameNumber) + const sp<const Layer>& layer, uint64_t frameNumber) { SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId)); - const sp<const Layer> layer(getLayer(weakHandle)); if (layer == nullptr) { ALOGE("An existing layer could not be retrieved with the handle" " for the deferred transaction"); @@ -349,7 +353,18 @@ void SurfaceInterceptor::addSurfaceChangesLocked(Transaction* transaction, addCropLocked(transaction, layerId, state.crop); } if (state.what & layer_state_t::eDeferTransaction) { - addDeferTransactionLocked(transaction, layerId, state.handle, state.frameNumber); + sp<Layer> otherLayer = nullptr; + if (state.barrierHandle != nullptr) { + otherLayer = static_cast<Layer::Handle*>(state.barrierHandle.get())->owner.promote(); + } else if (state.barrierGbp != nullptr) { + auto const& gbp = state.barrierGbp; + if (mFlinger->authenticateSurfaceTextureLocked(gbp)) { + otherLayer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer(); + } else { + ALOGE("Attempt to defer transaction to to an unrecognized GraphicBufferProducer"); + } + } + addDeferTransactionLocked(transaction, layerId, otherLayer, state.frameNumber); } if (state.what & layer_state_t::eFinalCropChanged) { addFinalCropLocked(transaction, layerId, state.finalCrop); diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h index 9af6e612ec..30ebcc6a1c 100644 --- a/services/surfaceflinger/SurfaceInterceptor.h +++ b/services/surfaceflinger/SurfaceInterceptor.h @@ -28,6 +28,7 @@ namespace android { class BufferItem; class Layer; +class SurfaceFlinger; struct DisplayState; struct layer_state_t; @@ -39,6 +40,7 @@ constexpr auto DEFAULT_FILENAME = "/data/SurfaceTrace.dat"; */ class SurfaceInterceptor { public: + SurfaceInterceptor(SurfaceFlinger* const flinger); // Both vectors are used to capture the current state of SF as the initial snapshot in the trace void enable(const SortedVector<sp<Layer>>& layers, const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays); @@ -102,7 +104,7 @@ private: void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack); void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect); void addDeferTransactionLocked(Transaction* transaction, int32_t layerId, - const wp<const IBinder>& weakHandle, uint64_t frameNumber); + const sp<const Layer>& layer, uint64_t frameNumber); void addFinalCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect); void addOverrideScalingModeLocked(Transaction* transaction, int32_t layerId, int32_t overrideScalingMode); @@ -129,6 +131,7 @@ private: std::string mOutputFileName {DEFAULT_FILENAME}; std::mutex mTraceMutex {}; Trace mTrace {}; + SurfaceFlinger* const mFlinger; }; } |