Loading core/java/android/view/Surface.java +29 −6 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public class Surface implements Parcelable { throws OutOfResourcesException; private static native int nativeCreateFromSurfaceControl(int surfaceControlNativeObject); private static native void nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty) private static native int nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty) throws OutOfResourcesException; private static native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas); Loading Loading @@ -72,6 +72,7 @@ public class Surface implements Parcelable { final Object mLock = new Object(); // protects the native state private String mName; int mNativeObject; // package scope only for SurfaceControl access private int mLockedObject; private int mGenerationId; // incremented each time mNativeObject changes private final Canvas mCanvas = new CompatibleCanvas(); Loading Loading @@ -233,7 +234,14 @@ public class Surface implements Parcelable { throws OutOfResourcesException, IllegalArgumentException { synchronized (mLock) { checkNotReleasedLocked(); nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); if (mLockedObject != 0) { // Ideally, nativeLockCanvas() would throw in this situation and prevent the // double-lock, but that won't happen if mNativeObject was updated. We can't // abandon the old mLockedObject because it might still be in use, so instead // we just refuse to re-lock the Surface. throw new RuntimeException("Surface was already locked"); } mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); return mCanvas; } } Loading @@ -252,7 +260,17 @@ public class Surface implements Parcelable { synchronized (mLock) { checkNotReleasedLocked(); nativeUnlockCanvasAndPost(mNativeObject, canvas); if (mNativeObject != mLockedObject) { Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + Integer.toHexString(mNativeObject) + ") != mLockedObject (0x" + Integer.toHexString(mLockedObject) +")"); } if (mLockedObject == 0) { throw new RuntimeException("Surface was not locked"); } nativeUnlockCanvasAndPost(mLockedObject, canvas); nativeRelease(mLockedObject); mLockedObject = 0; } } Loading Loading @@ -343,6 +361,10 @@ public class Surface implements Parcelable { } synchronized (mLock) { // nativeReadFromParcel() will either return mNativeObject, or // create a new native Surface and return it after reducing // the reference count on mNativeObject. Either way, it is // not necessary to call nativeRelease() here. mName = source.readString(); setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); } Loading @@ -365,7 +387,8 @@ public class Surface implements Parcelable { @Override public String toString() { synchronized (mLock) { return "Surface(name=" + mName + ")"; return "Surface(name=" + mName + ")/@0x" + Integer.toHexString(System.identityHashCode(this)); } } Loading core/jni/android_view_Surface.cpp +11 −4 Original line number Diff line number Diff line Loading @@ -196,13 +196,13 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa SkSafeUnref(previousCanvas); } static void nativeLockCanvas(JNIEnv* env, jclass clazz, static jint nativeLockCanvas(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObj, jobject dirtyRectObj) { sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); if (!isSurfaceValid(surface)) { doThrowIAE(env); return; return 0; } Rect dirtyRect; Loading @@ -223,7 +223,7 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, OutOfResourcesException : "java/lang/IllegalArgumentException"; jniThrowException(env, exception, NULL); return; return 0; } // Associate a SkCanvas object to this surface Loading Loading @@ -255,6 +255,13 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right); env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom); } // Create another reference to the surface and return it. This reference // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject, // because the latter could be replaced while the surface is locked. sp<Surface> lockedSurface(surface); lockedSurface->incStrong(&sRefBaseOwner); return (int) lockedSurface.get(); } static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, Loading Loading @@ -351,7 +358,7 @@ static JNINativeMethod gSurfaceMethods[] = { (void*)nativeIsValid }, {"nativeIsConsumerRunningBehind", "(I)Z", (void*)nativeIsConsumerRunningBehind }, {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V", {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)I", (void*)nativeLockCanvas }, {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V", (void*)nativeUnlockCanvasAndPost }, Loading Loading
core/java/android/view/Surface.java +29 −6 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ public class Surface implements Parcelable { throws OutOfResourcesException; private static native int nativeCreateFromSurfaceControl(int surfaceControlNativeObject); private static native void nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty) private static native int nativeLockCanvas(int nativeObject, Canvas canvas, Rect dirty) throws OutOfResourcesException; private static native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas); Loading Loading @@ -72,6 +72,7 @@ public class Surface implements Parcelable { final Object mLock = new Object(); // protects the native state private String mName; int mNativeObject; // package scope only for SurfaceControl access private int mLockedObject; private int mGenerationId; // incremented each time mNativeObject changes private final Canvas mCanvas = new CompatibleCanvas(); Loading Loading @@ -233,7 +234,14 @@ public class Surface implements Parcelable { throws OutOfResourcesException, IllegalArgumentException { synchronized (mLock) { checkNotReleasedLocked(); nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); if (mLockedObject != 0) { // Ideally, nativeLockCanvas() would throw in this situation and prevent the // double-lock, but that won't happen if mNativeObject was updated. We can't // abandon the old mLockedObject because it might still be in use, so instead // we just refuse to re-lock the Surface. throw new RuntimeException("Surface was already locked"); } mLockedObject = nativeLockCanvas(mNativeObject, mCanvas, inOutDirty); return mCanvas; } } Loading @@ -252,7 +260,17 @@ public class Surface implements Parcelable { synchronized (mLock) { checkNotReleasedLocked(); nativeUnlockCanvasAndPost(mNativeObject, canvas); if (mNativeObject != mLockedObject) { Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + Integer.toHexString(mNativeObject) + ") != mLockedObject (0x" + Integer.toHexString(mLockedObject) +")"); } if (mLockedObject == 0) { throw new RuntimeException("Surface was not locked"); } nativeUnlockCanvasAndPost(mLockedObject, canvas); nativeRelease(mLockedObject); mLockedObject = 0; } } Loading Loading @@ -343,6 +361,10 @@ public class Surface implements Parcelable { } synchronized (mLock) { // nativeReadFromParcel() will either return mNativeObject, or // create a new native Surface and return it after reducing // the reference count on mNativeObject. Either way, it is // not necessary to call nativeRelease() here. mName = source.readString(); setNativeObjectLocked(nativeReadFromParcel(mNativeObject, source)); } Loading @@ -365,7 +387,8 @@ public class Surface implements Parcelable { @Override public String toString() { synchronized (mLock) { return "Surface(name=" + mName + ")"; return "Surface(name=" + mName + ")/@0x" + Integer.toHexString(System.identityHashCode(this)); } } Loading
core/jni/android_view_Surface.cpp +11 −4 Original line number Diff line number Diff line Loading @@ -196,13 +196,13 @@ static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCa SkSafeUnref(previousCanvas); } static void nativeLockCanvas(JNIEnv* env, jclass clazz, static jint nativeLockCanvas(JNIEnv* env, jclass clazz, jint nativeObject, jobject canvasObj, jobject dirtyRectObj) { sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); if (!isSurfaceValid(surface)) { doThrowIAE(env); return; return 0; } Rect dirtyRect; Loading @@ -223,7 +223,7 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, OutOfResourcesException : "java/lang/IllegalArgumentException"; jniThrowException(env, exception, NULL); return; return 0; } // Associate a SkCanvas object to this surface Loading Loading @@ -255,6 +255,13 @@ static void nativeLockCanvas(JNIEnv* env, jclass clazz, env->SetIntField(dirtyRectObj, gRectClassInfo.right, dirtyRect.right); env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, dirtyRect.bottom); } // Create another reference to the surface and return it. This reference // should be passed to nativeUnlockCanvasAndPost in place of mNativeObject, // because the latter could be replaced while the surface is locked. sp<Surface> lockedSurface(surface); lockedSurface->incStrong(&sRefBaseOwner); return (int) lockedSurface.get(); } static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz, Loading Loading @@ -351,7 +358,7 @@ static JNINativeMethod gSurfaceMethods[] = { (void*)nativeIsValid }, {"nativeIsConsumerRunningBehind", "(I)Z", (void*)nativeIsConsumerRunningBehind }, {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)V", {"nativeLockCanvas", "(ILandroid/graphics/Canvas;Landroid/graphics/Rect;)I", (void*)nativeLockCanvas }, {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V", (void*)nativeUnlockCanvasAndPost }, Loading