summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp45
1 files changed, 33 insertions, 12 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e9613cce80..4acdb826e0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -166,7 +166,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;
}
@@ -2529,14 +2534,7 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
- Mutex::Autolock _l(mStateLock);
- sp<Layer> layer = weakLayer.promote();
- if (layer == nullptr) {
- // The layer has already been removed, carry on
- return NO_ERROR;
- }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
const auto& p = layer->getParent();
const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
mCurrentState.layersSortedByZ.remove(layer);
@@ -2798,7 +2796,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
}
@@ -2807,6 +2817,9 @@ uint32_t SurfaceFlinger::setClientStateLocked(
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
+ if (what & layer_state_t::eDetachChildren) {
+ layer->detachChildren();
+ }
if (what & layer_state_t::eOverrideScalingModeChanged) {
layer->setOverrideScalingMode(s.overrideScalingMode);
// We don't trigger a traversal here because if no other state is
@@ -2903,7 +2916,7 @@ status_t SurfaceFlinger::createDimLayer(const sp<Client>& client,
status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
{
- // called by the window manager when it wants to remove a Layer
+ // called by a client when it wants to remove a Layer
status_t err = NO_ERROR;
sp<Layer> l(client->getLayerUser(handle));
if (l != NULL) {
@@ -2919,7 +2932,15 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- return removeLayer(layer);
+ sp<Layer> l = layer.promote();
+ if (l == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ } if (l->getParent() != nullptr) {
+ // If we have a parent, then we can continue to live as long as it does.
+ return NO_ERROR;
+ }
+ return removeLayer(l);
}
// ---------------------------------------------------------------------------