diff options
author | 2012-12-20 14:39:57 -0500 | |
---|---|---|
committer | 2013-01-08 10:00:54 -0500 | |
commit | fc615a0f643408956fc0dc1b997871e2b27cee7e (patch) | |
tree | 4365ec88e252096d312fc4c6b0b529b9876eed95 | |
parent | 82f2cc312e50f54d289783d67eca5c55a158917b (diff) |
Remove calls to SkCanvas::setBitmapDevice()
Change-Id: Ib0aa2f65b77802b105c0e8a9d7cdde2e863d3673
-rw-r--r-- | core/java/android/view/Surface.java | 1 | ||||
-rw-r--r-- | core/jni/android/graphics/Canvas.cpp | 9 | ||||
-rw-r--r-- | core/jni/android_view_Surface.cpp | 38 | ||||
-rw-r--r-- | core/jni/android_view_TextureView.cpp | 37 | ||||
-rw-r--r-- | graphics/java/android/graphics/Canvas.java | 34 | ||||
-rw-r--r-- | services/input/SpriteController.cpp | 3 |
6 files changed, 75 insertions, 47 deletions
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index a972b750743e..c10f28742888 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -215,7 +215,6 @@ public class Surface implements Parcelable { private int mNativeSurfaceControl; // SurfaceControl* private int mGenerationId; // incremented each time mNativeSurface changes private final Canvas mCanvas = new CompatibleCanvas(); - private int mCanvasSaveCount; // Canvas save count at time of lockCanvas() // The Translator for density compatibility mode. This is used for scaling // the canvas to perform the appropriate density transformation. diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp index ef9b96ead991..7208c570f391 100644 --- a/core/jni/android/graphics/Canvas.cpp +++ b/core/jni/android/graphics/Canvas.cpp @@ -93,14 +93,6 @@ public: return canvas->getDevice()->accessBitmap(false).height(); } - static void setBitmap(JNIEnv* env, jobject, SkCanvas* canvas, SkBitmap* bitmap) { - if (bitmap) { - canvas->setBitmapDevice(*bitmap); - } else { - canvas->setDevice(NULL); - } - } - static int saveAll(JNIEnv* env, jobject jcanvas) { NPE_CHECK_RETURN_ZERO(env, jcanvas); return GraphicsJNI::getNativeCanvas(env, jcanvas)->save(); @@ -967,7 +959,6 @@ static JNINativeMethod gCanvasMethods[] = { {"isOpaque","()Z", (void*) SkCanvasGlue::isOpaque}, {"getWidth","()I", (void*) SkCanvasGlue::getWidth}, {"getHeight","()I", (void*) SkCanvasGlue::getHeight}, - {"native_setBitmap","(II)V", (void*) SkCanvasGlue::setBitmap}, {"save","()I", (void*) SkCanvasGlue::saveAll}, {"save","(I)I", (void*) SkCanvasGlue::save}, {"native_saveLayer","(ILandroid/graphics/RectF;II)I", diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index bef751b69608..ed92e43c9ddb 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -66,7 +66,6 @@ static struct { jfieldID mNativeSurfaceControl; jfieldID mGenerationId; jfieldID mCanvas; - jfieldID mCanvasSaveCount; jmethodID ctor; } gSurfaceClassInfo; @@ -78,11 +77,16 @@ static struct { } gRectClassInfo; static struct { + jfieldID mFinalizer; jfieldID mNativeCanvas; jfieldID mSurfaceFormat; } gCanvasClassInfo; static struct { + jfieldID mNativeCanvas; +} gCanvasFinalizerClassInfo; + +static struct { jfieldID width; jfieldID height; jfieldID refreshRate; @@ -374,6 +378,15 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { } } +static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { + jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); + SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( + env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); + env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas); + env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas); + SkSafeUnref(previousCanvas); +} + static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRectObj) { sp<Surface> surface(getSurface(env, surfaceObj)); if (!Surface::isValid(surface)) { @@ -410,8 +423,6 @@ static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRe jobject canvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas); env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat, info.format); - SkCanvas* nativeCanvas = reinterpret_cast<SkCanvas*>( - env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); SkBitmap bitmap; ssize_t bpr = info.s * bytesPerPixel(info.format); bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr); @@ -424,7 +435,9 @@ static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRe // be safe with an empty bitmap. bitmap.setPixels(NULL); } - nativeCanvas->setBitmapDevice(bitmap); + + SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap)); + swapCanvasPtr(env, canvasObj, nativeCanvas); SkRegion clipReg; if (dirtyRegion.isRect()) { // very common case @@ -441,9 +454,6 @@ static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRe nativeCanvas->clipRegion(clipReg); - int saveCount = nativeCanvas->save(); - env->SetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount, saveCount); - if (dirtyRectObj) { const Rect& bounds(dirtyRegion.getBounds()); env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left); @@ -468,12 +478,8 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject c } // detach the canvas from the surface - SkCanvas* nativeCanvas = reinterpret_cast<SkCanvas*>( - env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); - int saveCount = env->GetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount); - nativeCanvas->restoreToCount(saveCount); - nativeCanvas->setBitmapDevice(SkBitmap()); - env->SetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount, 0); + SkCanvas* nativeCanvas = SkNEW(SkCanvas); + swapCanvasPtr(env, canvasObj, nativeCanvas); // unlock surface status_t err = surface->unlockAndPost(); @@ -889,14 +895,16 @@ int register_android_view_Surface(JNIEnv* env) env->GetFieldID(gSurfaceClassInfo.clazz, "mGenerationId", "I"); gSurfaceClassInfo.mCanvas = env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvas", "Landroid/graphics/Canvas;"); - gSurfaceClassInfo.mCanvasSaveCount = - env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvasSaveCount", "I"); gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "()V"); clazz = env->FindClass("android/graphics/Canvas"); + gCanvasClassInfo.mFinalizer = env->GetFieldID(clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;"); gCanvasClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I"); gCanvasClassInfo.mSurfaceFormat = env->GetFieldID(clazz, "mSurfaceFormat", "I"); + clazz = env->FindClass("android/graphics/Canvas$CanvasFinalizer"); + gCanvasFinalizerClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I"); + clazz = env->FindClass("android/graphics/Rect"); gRectClassInfo.left = env->GetFieldID(clazz, "left", "I"); gRectClassInfo.top = env->GetFieldID(clazz, "top", "I"); diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp index 87b312f4cbfe..64cbda3091a4 100644 --- a/core/jni/android_view_TextureView.cpp +++ b/core/jni/android_view_TextureView.cpp @@ -43,11 +43,16 @@ static struct { } gRectClassInfo; static struct { - jfieldID nativeCanvas; - jfieldID surfaceFormat; + jfieldID mFinalizer; + jfieldID mNativeCanvas; + jfieldID mSurfaceFormat; } gCanvasClassInfo; static struct { + jfieldID mNativeCanvas; +} gCanvasFinalizerClassInfo; + +static struct { jfieldID nativeWindow; } gTextureViewClassInfo; @@ -120,6 +125,15 @@ static void android_view_TextureView_destroyNativeWindow(JNIEnv* env, jobject te } } +static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) { + jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer); + SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>( + env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); + env->SetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas, (int)newCanvas); + env->SetIntField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (int)newCanvas); + SkSafeUnref(previousCanvas); +} + static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, jint nativeWindow, jobject canvas, jobject dirtyRect) { @@ -157,9 +171,10 @@ static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, bitmap.setPixels(NULL); } - SET_INT(canvas, gCanvasClassInfo.surfaceFormat, buffer.format); - SkCanvas* nativeCanvas = (SkCanvas*) GET_INT(canvas, gCanvasClassInfo.nativeCanvas); - nativeCanvas->setBitmapDevice(bitmap); + SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer.format); + + SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap)); + swapCanvasPtr(env, canvas, nativeCanvas); SkRect clipRect; clipRect.set(rect.left, rect.top, rect.right, rect.bottom); @@ -174,8 +189,8 @@ static void android_view_TextureView_lockCanvas(JNIEnv* env, jobject, static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject, jint nativeWindow, jobject canvas) { - SkCanvas* nativeCanvas = (SkCanvas*) GET_INT(canvas, gCanvasClassInfo.nativeCanvas); - nativeCanvas->setBitmapDevice(SkBitmap()); + SkCanvas* nativeCanvas = SkNEW(SkCanvas); + swapCanvasPtr(env, canvas, nativeCanvas); if (nativeWindow) { sp<ANativeWindow> window((ANativeWindow*) nativeWindow); @@ -226,8 +241,12 @@ int register_android_view_TextureView(JNIEnv* env) { GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I"); FIND_CLASS(clazz, "android/graphics/Canvas"); - GET_FIELD_ID(gCanvasClassInfo.nativeCanvas, clazz, "mNativeCanvas", "I"); - GET_FIELD_ID(gCanvasClassInfo.surfaceFormat, clazz, "mSurfaceFormat", "I"); + GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;"); + GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); + GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I"); + + FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer"); + GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "I"); FIND_CLASS(clazz, "android/view/TextureView"); GET_FIELD_ID(gTextureViewClassInfo.nativeWindow, clazz, "mNativeWindow", "I"); diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index d8cac4163dcd..483d11afb8f3 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -37,8 +37,8 @@ import javax.microedition.khronos.opengles.GL; * Canvas and Drawables</a> developer guide.</p></div> */ public class Canvas { - // assigned in constructors, freed in finalizer - final int mNativeCanvas; + // assigned in constructors or setBitmap, freed in finalizer + int mNativeCanvas; // may be null private Bitmap mBitmap; @@ -83,7 +83,7 @@ public class Canvas { private final CanvasFinalizer mFinalizer; private static class CanvasFinalizer { - private final int mNativeCanvas; + private int mNativeCanvas; public CanvasFinalizer(int nativeCanvas) { mNativeCanvas = nativeCanvas; @@ -143,6 +143,17 @@ public class Canvas { } /** + * Replace existing canvas while ensuring that the swap has occurred before + * the previous native canvas is unreferenced. + */ + private void safeCanvasSwap(int nativeCanvas) { + final int oldCanvas = mNativeCanvas; + mNativeCanvas = nativeCanvas; + mFinalizer.mNativeCanvas = nativeCanvas; + finalizer(oldCanvas); + } + + /** * Returns null. * * @deprecated This method is not supported and should not be invoked. @@ -168,11 +179,11 @@ public class Canvas { } /** - * Specify a bitmap for the canvas to draw into. As a side-effect, also - * updates the canvas's target density to match that of the bitmap. + * Specify a bitmap for the canvas to draw into. As a side-effect, the + * canvas' target density is updated to match that of the bitmap while all + * other state such as the layers, filters, matrix, and clip are reset. * * @param bitmap Specifies a mutable bitmap for the canvas to draw into. - * * @see #setDensity(int) * @see #getDensity() */ @@ -181,17 +192,19 @@ public class Canvas { throw new RuntimeException("Can't set a bitmap device on a GL canvas"); } - int pointer = 0; - if (bitmap != null) { + if (bitmap == null) { + safeCanvasSwap(initRaster(0)); + mDensity = Bitmap.DENSITY_NONE; + } else { if (!bitmap.isMutable()) { throw new IllegalStateException(); } throwIfRecycled(bitmap); + + safeCanvasSwap(initRaster(bitmap.ni())); mDensity = bitmap.mDensity; - pointer = bitmap.ni(); } - native_setBitmap(mNativeCanvas, pointer); mBitmap = bitmap; } @@ -1625,7 +1638,6 @@ public class Canvas { public static native void freeTextLayoutCaches(); private static native int initRaster(int nativeBitmapOrZero); - private static native void native_setBitmap(int nativeCanvas, int bitmap); private static native int native_saveLayer(int nativeCanvas, RectF bounds, int paint, int layerFlags); private static native int native_saveLayer(int nativeCanvas, float l, diff --git a/services/input/SpriteController.cpp b/services/input/SpriteController.cpp index 1f3d2cf2fdf0..8163ea0aa1fc 100644 --- a/services/input/SpriteController.cpp +++ b/services/input/SpriteController.cpp @@ -208,8 +208,7 @@ void SpriteController::doUpdateSprites() { surfaceInfo.w, surfaceInfo.h, bpr); surfaceBitmap.setPixels(surfaceInfo.bits); - SkCanvas surfaceCanvas; - surfaceCanvas.setBitmapDevice(surfaceBitmap); + SkCanvas surfaceCanvas(surfaceBitmap); SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); |