Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 874da6e4 authored by Jamie Gennis's avatar Jamie Gennis Committed by Android (Google) Code Review
Browse files

Merge "Re-use existing Surface objects when reading them from parcels." into gingerbread

parents 3cf1c9b8 aca4e228
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -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
+28 −7
Original line number Diff line number Diff line
@@ -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()