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

Merge commit 'c8c79a654d4ae8e3a883854e19cc2df757f72d82' into gingerbread-plus-aosp

* commit 'c8c79a654d4ae8e3a883854e19cc2df757f72d82':
  Re-use existing Surface objects when reading them from parcels.
This commit is contained in:
Jamie Gennis 2010-07-16 15:17:59 -07:00 committed by Android Git Automerger
commit 4760482810
2 changed files with 36 additions and 9 deletions

View File

@ -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

View File

@ -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()