summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/jni/android_view_Surface.cpp6
-rw-r--r--include/surfaceflinger/Surface.h10
-rw-r--r--libs/surfaceflinger_client/Surface.cpp35
3 files changed, 38 insertions, 13 deletions
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 7305032..c4d6d1b 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -237,7 +237,7 @@ static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel)
return;
}
- sp<Surface> sur(Surface::readFromParcel(*parcel, 0));
+ sp<Surface> sur(Surface::readFromParcel(*parcel));
setSurface(env, clazz, sur);
}
@@ -616,8 +616,7 @@ static void Surface_readFromParcel(
return;
}
- const sp<Surface>& curr(getSurface(env, clazz));
- sp<Surface> sur(Surface::readFromParcel(*parcel, curr));
+ sp<Surface> sur(Surface::readFromParcel(*parcel));
setSurface(env, clazz, sur);
}
@@ -729,4 +728,3 @@ int register_android_view_Surface(JNIEnv* env)
}
};
-
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 4fd0681..294c867 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -147,8 +148,7 @@ public:
static status_t writeToParcel(
const sp<Surface>& control, Parcel* parcel);
- static sp<Surface> readFromParcel(
- const Parcel& data, const sp<Surface>& other);
+ static sp<Surface> readFromParcel(const Parcel& data);
static bool isValid(const sp<Surface>& surface) {
return (surface != 0) && surface->isValid();
@@ -244,6 +244,8 @@ private:
uint32_t *pWidth, uint32_t *pHeight,
uint32_t *pFormat, uint32_t *pUsage) const;
+ static void cleanCachedSurfaces();
+
class BufferInfo {
uint32_t mWidth;
uint32_t mHeight;
@@ -298,6 +300,10 @@ private:
// Inherently thread-safe
mutable Mutex mSurfaceLock;
mutable Mutex mApiLock;
+
+ // A cache of Surface objects that have been deserialized into this process.
+ static Mutex sCachedSurfacesLock;
+ static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces;
};
}; // namespace android
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index dc6332c..1de3a4f 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -374,15 +374,36 @@ status_t Surface::writeToParcel(
}
-sp<Surface> Surface::readFromParcel(
- const Parcel& data, const sp<Surface>& other)
-{
- sp<Surface> result(other);
+
+Mutex Surface::sCachedSurfacesLock;
+DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
+
+sp<Surface> Surface::readFromParcel(const Parcel& data) {
+ Mutex::Autolock _l(sCachedSurfacesLock);
sp<IBinder> binder(data.readStrongBinder());
- if (other==0 || binder != other->mSurface->asBinder()) {
- result = new Surface(data, binder);
+ sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
+ if (surface == 0) {
+ surface = new Surface(data, binder);
+ sCachedSurfaces.add(binder, surface);
+ } else {
+ LOGW("Reusing surface!");
+ }
+ if (surface->mSurface == 0) {
+ surface = 0;
+ }
+ cleanCachedSurfaces();
+ return surface;
+}
+
+// Remove the stale entries from the surface cache. This should only be called
+// with sCachedSurfacesLock held.
+void Surface::cleanCachedSurfaces() {
+ for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
+ wp<Surface> s(sCachedSurfaces.valueAt(i));
+ if (s == 0 || s.promote() == 0) {
+ sCachedSurfaces.removeItemsAt(i);
+ }
}
- return result;
}
void Surface::init()