diff options
author | Mathias Agopian <mathias@google.com> | 2010-06-04 18:26:32 -0700 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2010-06-04 18:57:41 -0700 |
commit | fae5cb2b356a1fef172b43066180a7ab4c32dbac (patch) | |
tree | 55e73b81c3a666ab1165603238e7ca43495ff99c | |
parent | 7623da435e45c7c03ef6a00a43675deb6645f070 (diff) | |
download | frameworks_base-fae5cb2b356a1fef172b43066180a7ab4c32dbac.zip frameworks_base-fae5cb2b356a1fef172b43066180a7ab4c32dbac.tar.gz frameworks_base-fae5cb2b356a1fef172b43066180a7ab4c32dbac.tar.bz2 |
optimize Surface.readFromParcel()
this is called for each relayout() and used to create a full Surface (cpp)
which in turn did some heavy work (including an IPC with surfaceflinger),
most of the time to destroy it immediatelly when the returned surface
(the one in the parcel) was the same.
we now more intelligentely read from the parcel and construct the new
object only if needed.
Change-Id: Idfd40d9ac96ffc6d4ae5fd99bcc0773e131e2267
-rw-r--r-- | core/jni/android_view_Surface.cpp | 19 | ||||
-rw-r--r-- | include/surfaceflinger/Surface.h | 7 | ||||
-rw-r--r-- | libs/surfaceflinger_client/Surface.cpp | 21 |
3 files changed, 25 insertions, 22 deletions
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 838ef22..06fa84b 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "Surface" + #include <stdio.h> #include "android_util_Binder.h" @@ -226,8 +228,9 @@ static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel) doThrow(env, "java/lang/NullPointerException", NULL); return; } - sp<Surface> rhs = new Surface(*parcel); - setSurface(env, clazz, rhs); + + sp<Surface> sur(Surface::readFromParcel(*parcel, 0)); + setSurface(env, clazz, sur); } static jint Surface_getIdentity(JNIEnv* env, jobject clazz) @@ -586,7 +589,7 @@ static void Surface_copyFrom( * a Surface and is necessary for returning the Surface reference to * the caller. At this point, we should only have a SurfaceControl. */ - + const sp<SurfaceControl>& surface = getSurfaceControl(env, clazz); const sp<SurfaceControl>& rhs = getSurfaceControl(env, other); if (!SurfaceControl::isSameSurface(surface, rhs)) { @@ -605,13 +608,9 @@ static void Surface_readFromParcel( return; } - const sp<Surface>& control(getSurface(env, clazz)); - sp<Surface> rhs = new Surface(*parcel); - if (!Surface::isSameSurface(control, rhs)) { - // we reassign the surface only if it's a different one - // otherwise we would loose our client-side state. - setSurface(env, clazz, rhs); - } + const sp<Surface>& curr(getSurface(env, clazz)); + sp<Surface> sur(Surface::readFromParcel(*parcel, curr)); + setSurface(env, clazz, sur); } static void Surface_writeToParcel( diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 67dc693..ac01ce5 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -145,15 +145,13 @@ public: uint32_t reserved[2]; }; - Surface(const Parcel& data); + static sp<Surface> readFromParcel( + const Parcel& data, const sp<Surface>& other); static bool isValid(const sp<Surface>& surface) { return (surface != 0) && surface->isValid(); } - static bool isSameSurface( - const sp<Surface>& lhs, const sp<Surface>& rhs); - bool isValid(); SurfaceID ID() const { return mToken; } uint32_t getFlags() const { return mFlags; } @@ -191,6 +189,7 @@ private: Surface(const Surface& rhs); Surface(const sp<SurfaceControl>& control); + Surface(const Parcel& data, const sp<IBinder>& ref); ~Surface(); diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp index 01420fe..6fe4c4a 100644 --- a/libs/surfaceflinger_client/Surface.cpp +++ b/libs/surfaceflinger_client/Surface.cpp @@ -334,13 +334,13 @@ Surface::Surface(const sp<SurfaceControl>& surface) init(); } -Surface::Surface(const Parcel& parcel) +Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref) : mBufferMapper(GraphicBufferMapper::get()), mClient(SurfaceClient::getInstance()), mSharedBufferClient(NULL), mInitCheck(NO_INIT) { - mSurface = interface_cast<ISurface>(parcel.readStrongBinder()); + mSurface = interface_cast<ISurface>(ref); mIdentity = parcel.readInt32(); mWidth = parcel.readInt32(); mHeight = parcel.readInt32(); @@ -349,6 +349,17 @@ Surface::Surface(const Parcel& parcel) init(); } +sp<Surface> Surface::readFromParcel( + const Parcel& data, const sp<Surface>& other) +{ + sp<Surface> result(other); + sp<IBinder> binder(data.readStrongBinder()); + if (other==0 || binder != other->mSurface->asBinder()) { + result = new Surface(data, binder); + } + return result; +} + void Surface::init() { android_native_window_t::setSwapInterval = setSwapInterval; @@ -443,12 +454,6 @@ status_t Surface::validate() const return NO_ERROR; } -bool Surface::isSameSurface(const sp<Surface>& lhs, const sp<Surface>& rhs) { - if (lhs == 0 || rhs == 0) - return false; - return lhs->mSurface->asBinder() == rhs->mSurface->asBinder(); -} - sp<ISurface> Surface::getISurface() const { return mSurface; } |