summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2016-08-09 22:25:37 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2016-08-09 22:25:38 +0000
commit1ff2b85b032f1088263700470aa7bcaa385e9091 (patch)
treedbc062c70df35a9770b66c93f134c0c981d1d0b1
parent27f9c827300e0d18742803f67fcd80b5c314129b (diff)
parent92cd24e5f648175944deef5899258981807a9ca4 (diff)
downloadnative-1ff2b85b032f1088263700470aa7bcaa385e9091.tar.gz
Merge "SF: Fix a couple of Layer ref count issues" into nyc-mr1-dev
-rw-r--r--services/surfaceflinger/Client.cpp5
-rw-r--r--services/surfaceflinger/Layer.cpp11
-rw-r--r--services/surfaceflinger/Layer.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp17
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger_hwc1.cpp17
6 files changed, 27 insertions, 27 deletions
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 415bdcae2e..e14a59b46d 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -43,10 +43,7 @@ Client::~Client()
{
const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) {
- sp<Layer> layer(mLayers.valueAt(i).promote());
- if (layer != 0) {
- mFlinger->removeLayer(layer);
- }
+ mFlinger->removeLayer(mLayers.valueAt(i));
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2b899398be..785df1a288 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1331,9 +1331,14 @@ 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<Handle> handle = static_cast<Handle*>(mCurrentState.handle.get());
- sp<Layer> handleLayer = handle->owner.promote();
- if (handleLayer == 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 we can't promote the layer we are intended to wait on,
// then it is expired or otherwise invalid. Allow this transaction
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c070539da8..65339530b4 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -128,7 +128,7 @@ public:
// If set, defers this state update until the Layer identified by handle
// receives a frame with the given frameNumber
- sp<IBinder> handle;
+ wp<IBinder> handle;
uint64_t frameNumber;
// the transparentRegion hint is a bit special, it's latched only
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 820c332a9c..d6d23a832a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2203,8 +2203,14 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+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;
+ }
+
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersPendingRemoval.push(layer);
@@ -2545,14 +2551,7 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- status_t err = NO_ERROR;
- sp<Layer> l(layer.promote());
- if (l != NULL) {
- err = removeLayer(l);
- ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
- }
- return err;
+ return removeLayer(layer);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f50f9e7918..b99acfcee6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -324,7 +324,7 @@ private:
status_t onLayerDestroyed(const wp<Layer>& layer);
// remove a layer from SurfaceFlinger immediately
- status_t removeLayer(const sp<Layer>& layer);
+ status_t removeLayer(const wp<Layer>& layer);
// add a layer to SurfaceFlinger
status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 34240b4dd3..2ade006a52 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -2120,8 +2120,14 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
+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;
+ }
+
ssize_t index = mCurrentState.layersSortedByZ.remove(layer);
if (index >= 0) {
mLayersPendingRemoval.push(layer);
@@ -2462,14 +2468,7 @@ status_t SurfaceFlinger::onLayerDestroyed(const wp<Layer>& layer)
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- status_t err = NO_ERROR;
- sp<Layer> l(layer.promote());
- if (l != NULL) {
- err = removeLayer(l);
- ALOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
- }
- return err;
+ return removeLayer(layer);
}
// ---------------------------------------------------------------------------