summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Mathias Agopian <mathias@google.com> 2010-12-13 16:49:05 -0800
committer Mathias Agopian <mathias@google.com> 2010-12-13 16:49:05 -0800
commit5747bbc20690f2a9d0a70725f9d510647db38ae2 (patch)
treee9fe775f5f7c2519363bdba8e659cdd7f236212d
parent06f9ebf4f6178d6b6970cace263ee180d4b61d36 (diff)
fix [3176642] Camera preview turns completely black for multiple toggles between camera and camcorder app
There was a leak of Surface tokens when a surface was detached from a UserClient. We now always detach a surface from its client before attaching to the new one, this guarantees that its token is freed. Change-Id: Icfad0b16286ed58155bdfafdf36ab161440aa485
-rw-r--r--services/surfaceflinger/Layer.cpp22
1 files changed, 21 insertions, 1 deletions
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 80aef5fcc2c5..2b2f557d3a3c 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -83,8 +83,28 @@ status_t Layer::setToken(const sp<UserClient>& userClient,
sharedClient, token, mBufferManager.getDefaultBufferCount(),
getIdentity());
- status_t err = mUserClientRef.setToken(userClient, lcblk, token);
+ sp<UserClient> ourClient(mUserClientRef.getClient());
+
+ /*
+ * Here it is guaranteed that userClient != ourClient
+ * (see UserClient::getTokenForSurface()).
+ *
+ * We release the token used by this surface in ourClient below.
+ * This should be safe to do so now, since this layer won't be attached
+ * to this client, it should be okay to reuse that id.
+ *
+ * If this causes problems, an other solution would be to keep a list
+ * of all the {UserClient, token} ever used and release them when the
+ * Layer is destroyed.
+ *
+ */
+
+ if (ourClient != 0) {
+ ourClient->detachLayer(this);
+ }
+
+ status_t err = mUserClientRef.setToken(userClient, lcblk, token);
LOGE_IF(err != NO_ERROR,
"ClientRef::setToken(%p, %p, %u) failed",
userClient.get(), lcblk.get(), token);