Loading include/surfaceflinger/Surface.h +8 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <stdint.h> #include <sys/types.h> #include <utils/KeyedVector.h> #include <utils/RefBase.h> #include <utils/threads.h> Loading Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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 Loading libs/surfaceflinger_client/Surface.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -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() Loading Loading
include/surfaceflinger/Surface.h +8 −2 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <stdint.h> #include <sys/types.h> #include <utils/KeyedVector.h> #include <utils/RefBase.h> #include <utils/threads.h> Loading Loading @@ -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(); Loading Loading @@ -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; Loading Loading @@ -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 Loading
libs/surfaceflinger_client/Surface.cpp +28 −7 Original line number Diff line number Diff line Loading @@ -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() Loading