diff options
-rw-r--r-- | core/jni/android_view_Surface.cpp | 6 | ||||
-rw-r--r-- | include/surfaceflinger/Surface.h | 10 | ||||
-rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 35 |
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() |