summaryrefslogtreecommitdiffstats
path: root/libs/surfaceflinger
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2010-06-08 19:54:15 -0700
committerMathias Agopian <mathias@google.com>2010-06-08 20:10:02 -0700
commit579b3f88d03d06b897b778bd11818f5104677d1d (patch)
treefcdb35e14852bd834d1d702aa94f07e2f3405942 /libs/surfaceflinger
parent53503a97a9afa9e876b1e95ca7e3b46c76aa4f15 (diff)
downloadframeworks_native-579b3f88d03d06b897b778bd11818f5104677d1d.zip
frameworks_native-579b3f88d03d06b897b778bd11818f5104677d1d.tar.gz
frameworks_native-579b3f88d03d06b897b778bd11818f5104677d1d.tar.bz2
allow re-targetting of surfaces
Surfaces can now be parcelized and sent to remote processes. When a surface crosses a process boundary, it looses its connection with the current process and gets attached to the new one. Change-Id: I39c7b055bcd3ea1162ef2718d3d4b866bf7c81c0
Diffstat (limited to 'libs/surfaceflinger')
-rw-r--r--libs/surfaceflinger/Layer.cpp48
-rw-r--r--libs/surfaceflinger/Layer.h11
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp19
3 files changed, 56 insertions, 22 deletions
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index a94fdd4..e7247bd 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -76,15 +76,18 @@ Layer::~Layer()
status_t Layer::setToken(const sp<UserClient>& userClient,
SharedClient* sharedClient, int32_t token)
{
- SharedBufferServer* lcblk = new SharedBufferServer(
+ sp<SharedBufferServer> lcblk = new SharedBufferServer(
sharedClient, token, mBufferManager.getDefaultBufferCount(),
getIdentity());
status_t err = mUserClientRef.setToken(userClient, lcblk, token);
- if (err != NO_ERROR) {
- LOGE("ClientRef::setToken(%p, %p, %u) failed",
- userClient.get(), lcblk, token);
- delete lcblk;
+
+ LOGE_IF(err != NO_ERROR,
+ "ClientRef::setToken(%p, %p, %u) failed",
+ userClient.get(), lcblk.get(), token);
+
+ if (err == NO_ERROR) {
+ // we need to free the buffers associated with this surface
}
return err;
@@ -95,6 +98,11 @@ int32_t Layer::getToken() const
return mUserClientRef.getToken();
}
+sp<UserClient> Layer::getClient() const
+{
+ return mUserClientRef.getClient();
+}
+
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// in the purgatory list
void Layer::onRemoved()
@@ -626,11 +634,10 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
// ---------------------------------------------------------------------------
Layer::ClientRef::ClientRef()
- : mToken(-1) {
+ : mControlBlock(0), mToken(-1) {
}
Layer::ClientRef::~ClientRef() {
- delete lcblk;
}
int32_t Layer::ClientRef::getToken() const {
@@ -638,14 +645,25 @@ int32_t Layer::ClientRef::getToken() const {
return mToken;
}
+sp<UserClient> Layer::ClientRef::getClient() const {
+ Mutex::Autolock _l(mLock);
+ return mUserClient.promote();
+}
+
status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
- SharedBufferServer* sharedClient, int32_t token) {
+ const sp<SharedBufferServer>& sharedClient, int32_t token) {
Mutex::Autolock _l(mLock);
- if (mToken >= 0)
- return INVALID_OPERATION;
+
+ { // scope for strong mUserClient reference
+ sp<UserClient> userClient(mUserClient.promote());
+ if (mUserClient != 0 && mControlBlock != 0) {
+ mControlBlock->setStatus(NO_INIT);
+ }
+ }
+
mUserClient = uc;
mToken = token;
- lcblk = sharedClient;
+ mControlBlock = sharedClient;
return NO_ERROR;
}
@@ -657,12 +675,16 @@ sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
// it makes sure the UserClient (and its associated shared memory)
// won't go away while we're accessing it.
Layer::ClientRef::Access::Access(const ClientRef& ref)
- : lcblk(0)
+ : mControlBlock(0)
{
Mutex::Autolock _l(ref.mLock);
mUserClientStrongRef = ref.mUserClient.promote();
if (mUserClientStrongRef != 0)
- lcblk = ref.lcblk;
+ mControlBlock = ref.mControlBlock;
+}
+
+Layer::ClientRef::Access::~Access()
+{
}
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
index d396ecf..dcb27a0 100644
--- a/libs/surfaceflinger/Layer.h
+++ b/libs/surfaceflinger/Layer.h
@@ -60,6 +60,7 @@ public:
// associate a UserClient to this Layer
status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
int32_t getToken() const;
+ sp<UserClient> getClient() const;
// Set this Layer's buffers size
void setBufferSize(uint32_t w, uint32_t h);
@@ -119,24 +120,26 @@ private:
ClientRef& operator = (const ClientRef& rhs);
mutable Mutex mLock;
// binder thread, page-flip thread
- SharedBufferServer* lcblk;
+ sp<SharedBufferServer> mControlBlock;
wp<UserClient> mUserClient;
int32_t mToken;
public:
ClientRef();
~ClientRef();
int32_t getToken() const;
+ sp<UserClient> getClient() const;
status_t setToken(const sp<UserClient>& uc,
- SharedBufferServer* sharedClient, int32_t token);
+ const sp<SharedBufferServer>& sharedClient, int32_t token);
sp<UserClient> getUserClientUnsafe() const;
class Access {
Access(const Access& rhs);
Access& operator = (const Access& rhs);
sp<UserClient> mUserClientStrongRef;
- SharedBufferServer* lcblk;
+ sp<SharedBufferServer> mControlBlock;
public:
Access(const ClientRef& ref);
- inline SharedBufferServer* get() const { return lcblk; }
+ ~Access();
+ inline SharedBufferServer* get() const { return mControlBlock.get(); }
};
friend class Access;
};
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 4926858..4dea62f 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1718,7 +1718,10 @@ void UserClient::detachLayer(const Layer* layer)
{
int32_t name = layer->getToken();
if (name >= 0) {
- android_atomic_and(~(1LU<<name), &mBitmap);
+ int32_t mask = 1LU<<name;
+ if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
+ LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
+ }
}
}
@@ -1732,17 +1735,23 @@ ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
sp<Layer> layer(mFlinger->getLayer(sur));
if (layer == 0) return name;
- // this layer already has a token, just return it
- // FIXME: we should check that this token is for the same client
+ // if this layer already has a token, just return it
name = layer->getToken();
- if (name >= 0) return name;
+ if ((name >= 0) && (layer->getClient() == this))
+ return name;
name = 0;
do {
int32_t mask = 1LU<<name;
if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
// we found and locked that name
- layer->setToken(const_cast<UserClient*>(this), ctrlblk, name);
+ status_t err = layer->setToken(
+ const_cast<UserClient*>(this), ctrlblk, name);
+ if (err != NO_ERROR) {
+ // free the name
+ android_atomic_and(~mask, &mBitmap);
+ name = err;
+ }
break;
}
if (++name > 31)