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

Commit c677675e authored by Florin Malita's avatar Florin Malita
Browse files

Encapsulate Canvas.mNativeCanvas

Currently, the native canvas is accessed/manipulated from several
unrelated classes.

In order to facilitate SaveFlags emulation, this CL encapsulates
the field and refactors its external users.

Two main changes:

* new getNativeCanvas() getter for use in Java-level clients.
* JNI canvas swappers (GraphicsBuffers, Surface, TextureView &
  AssetAtlasService) are refactored based on the exising/equivalent
  safeCanvasSwap() Canvas method.

Change-Id: I966bd4898f0838fb3699e226d3d3d51e0224ea97
parent ae949571
Loading
Loading
Loading
Loading
+4 −23
Original line number Diff line number Diff line
@@ -74,15 +74,10 @@ static struct {
} gRectClassInfo;

static struct {
    jfieldID mFinalizer;
    jfieldID mNativeCanvas;
    jfieldID mSurfaceFormat;
    jmethodID safeCanvasSwap;
} gCanvasClassInfo;

static struct {
    jfieldID mNativeCanvas;
} gCanvasFinalizerClassInfo;

#define GET_INT(object, field) \
    env->GetIntField(object, field)

@@ -146,15 +141,6 @@ static void android_view_GraphiceBuffer_destroy(JNIEnv* env, jobject clazz,
// Canvas management
// ----------------------------------------------------------------------------

static inline void swapCanvasPtr(JNIEnv* env, jobject canvasObj, SkCanvas* newCanvas) {
    jobject canvasFinalizerObj = env->GetObjectField(canvasObj, gCanvasClassInfo.mFinalizer);
    SkCanvas* previousCanvas = reinterpret_cast<SkCanvas*>(
            GET_LONG(canvasObj, gCanvasClassInfo.mNativeCanvas));
    SET_LONG(canvasObj, gCanvasClassInfo.mNativeCanvas, (long) newCanvas);
    SET_LONG(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (long) newCanvas);
    SkSafeUnref(previousCanvas);
}

static inline SkBitmap::Config convertPixelFormat(int32_t format) {
    switch (format) {
        case PIXEL_FORMAT_RGBA_8888:
@@ -213,7 +199,7 @@ static jboolean android_view_GraphicBuffer_lockCanvas(JNIEnv* env, jobject,
    SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer->getPixelFormat());

    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
    swapCanvasPtr(env, canvas, nativeCanvas);
    INVOKEV(canvas, gCanvasClassInfo.safeCanvasSwap, (jlong)nativeCanvas, false);

    SkRect clipRect;
    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
@@ -233,7 +219,7 @@ static jboolean android_view_GraphicBuffer_unlockCanvasAndPost(JNIEnv* env, jobj
    GraphicBufferWrapper* wrapper =
                reinterpret_cast<GraphicBufferWrapper*>(wrapperHandle);
    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
    swapCanvasPtr(env, canvas, nativeCanvas);
    INVOKEV(canvas, gCanvasClassInfo.safeCanvasSwap, (jlong)nativeCanvas, false);

    if (wrapper) {
        status_t status = wrapper->buffer->unlock();
@@ -332,13 +318,8 @@ int register_android_view_GraphicBuffer(JNIEnv* env) {
    GET_FIELD_ID(gRectClassInfo.bottom, clazz, "bottom", "I");

    FIND_CLASS(clazz, "android/graphics/Canvas");
    GET_FIELD_ID(gCanvasClassInfo.mFinalizer, clazz, "mFinalizer",
            "Landroid/graphics/Canvas$CanvasFinalizer;");
    GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "J");
    GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");

    FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
    GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "J");
    GET_METHOD_ID(gCanvasClassInfo.safeCanvasSwap, clazz, "safeCanvasSwap", "(JZ)V");

    return AndroidRuntime::registerNativeMethods(env, kClassPathName, gMethods, NELEM(gMethods));
}
+4 −22
Original line number Diff line number Diff line
@@ -69,15 +69,10 @@ static struct {
} gRectClassInfo;

static struct {
    jfieldID mFinalizer;
    jfieldID mNativeCanvas;
    jfieldID mSurfaceFormat;
    jmethodID safeCanvasSwap;
} gCanvasClassInfo;

static struct {
    jfieldID mNativeCanvas;
} gCanvasFinalizerClassInfo;

// ----------------------------------------------------------------------------

// this is just a pointer we use to pass to inc/decStrong
@@ -191,15 +186,6 @@ 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->GetLongField(canvasObj, gCanvasClassInfo.mNativeCanvas));
  env->SetLongField(canvasObj, gCanvasClassInfo.mNativeCanvas, (jlong)newCanvas);
  env->SetLongField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (jlong)newCanvas);
  SkSafeUnref(previousCanvas);
}

static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
        jlong nativeObject, jobject canvasObj, jobject dirtyRectObj) {
    sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
@@ -247,7 +233,7 @@ static jlong nativeLockCanvas(JNIEnv* env, jclass clazz,
    }

    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
    swapCanvasPtr(env, canvasObj, nativeCanvas);
    env->CallVoidMethod(canvasObj, gCanvasClassInfo.safeCanvasSwap, (jlong)nativeCanvas, false);

    if (dirtyRectPtr) {
        nativeCanvas->clipRect( SkRect::Make(reinterpret_cast<const SkIRect&>(dirtyRect)) );
@@ -277,7 +263,7 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jclass clazz,

    // detach the canvas from the surface
    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
    swapCanvasPtr(env, canvasObj, nativeCanvas);
    env->CallVoidMethod(canvasObj, gCanvasClassInfo.safeCanvasSwap, (jlong)nativeCanvas, false);

    // unlock surface
    status_t err = surface->unlockAndPost();
@@ -388,12 +374,8 @@ int register_android_view_Surface(JNIEnv* env)
    gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(J)V");

    clazz = env->FindClass("android/graphics/Canvas");
    gCanvasClassInfo.mFinalizer = env->GetFieldID(clazz, "mFinalizer", "Landroid/graphics/Canvas$CanvasFinalizer;");
    gCanvasClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "J");
    gCanvasClassInfo.mSurfaceFormat = env->GetFieldID(clazz, "mSurfaceFormat", "I");

    clazz = env->FindClass("android/graphics/Canvas$CanvasFinalizer");
    gCanvasFinalizerClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "J");
    gCanvasClassInfo.safeCanvasSwap = env->GetMethodID(clazz, "safeCanvasSwap", "(JZ)V");

    clazz = env->FindClass("android/graphics/Rect");
    gRectClassInfo.left = env->GetFieldID(clazz, "left", "I");
+4 −23
Original line number Diff line number Diff line
@@ -44,15 +44,10 @@ static struct {
} gRectClassInfo;

static struct {
    jfieldID mFinalizer;
    jfieldID mNativeCanvas;
    jfieldID mSurfaceFormat;
    jmethodID safeCanvasSwap;
} gCanvasClassInfo;

static struct {
    jfieldID mNativeCanvas;
} gCanvasFinalizerClassInfo;

static struct {
    jfieldID nativeWindow;
} gTextureViewClassInfo;
@@ -125,15 +120,6 @@ 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->GetLongField(canvasObj, gCanvasClassInfo.mNativeCanvas));
    env->SetLongField(canvasObj, gCanvasClassInfo.mNativeCanvas, (jlong)newCanvas);
    env->SetLongField(canvasFinalizerObj, gCanvasFinalizerClassInfo.mNativeCanvas, (jlong)newCanvas);
    SkSafeUnref(previousCanvas);
}

static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
        jlong nativeWindow, jobject canvas, jobject dirtyRect) {

@@ -175,7 +161,7 @@ static jboolean android_view_TextureView_lockCanvas(JNIEnv* env, jobject,
    SET_INT(canvas, gCanvasClassInfo.mSurfaceFormat, buffer.format);

    SkCanvas* nativeCanvas = SkNEW_ARGS(SkCanvas, (bitmap));
    swapCanvasPtr(env, canvas, nativeCanvas);
    INVOKEV(canvas, gCanvasClassInfo.safeCanvasSwap, (jlong)nativeCanvas, false);

    SkRect clipRect;
    clipRect.set(rect.left, rect.top, rect.right, rect.bottom);
@@ -193,7 +179,7 @@ static void android_view_TextureView_unlockCanvasAndPost(JNIEnv* env, jobject,
        jlong nativeWindow, jobject canvas) {

    SkCanvas* nativeCanvas = SkNEW(SkCanvas);
    swapCanvasPtr(env, canvas, nativeCanvas);
    INVOKEV(canvas, gCanvasClassInfo.safeCanvasSwap, (jlong)nativeCanvas, false);

    if (nativeWindow) {
        sp<ANativeWindow> window((ANativeWindow*) nativeWindow);
@@ -241,13 +227,8 @@ 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.mFinalizer, clazz, "mFinalizer",
            "Landroid/graphics/Canvas$CanvasFinalizer;");
    GET_FIELD_ID(gCanvasClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "J");
    GET_FIELD_ID(gCanvasClassInfo.mSurfaceFormat, clazz, "mSurfaceFormat", "I");

    FIND_CLASS(clazz, "android/graphics/Canvas$CanvasFinalizer");
    GET_FIELD_ID(gCanvasFinalizerClassInfo.mNativeCanvas, clazz, "mNativeCanvas", "J");
    GET_METHOD_ID(gCanvasClassInfo.safeCanvasSwap, clazz, "safeCanvasSwap", "(JZ)V");

    FIND_CLASS(clazz, "android/view/TextureView");
    GET_FIELD_ID(gTextureViewClassInfo.nativeWindow, clazz, "mNativeWindow", "J");
+1 −1
Original line number Diff line number Diff line
@@ -154,7 +154,7 @@ public class Camera {
            getMatrix(mMatrix);
            canvas.concat(mMatrix);
        } else {
            nativeApplyToCanvas(canvas.mNativeCanvas);
            nativeApplyToCanvas(canvas.getNativeCanvas());
        }
    }

+5 −1
Original line number Diff line number Diff line
@@ -39,8 +39,12 @@ import javax.microedition.khronos.opengles.GL;
public class Canvas {

    // assigned in constructors or setBitmap, freed in finalizer
    private long mNativeCanvas;

    /** @hide */
    public long mNativeCanvas;
    public long getNativeCanvas() {
        return mNativeCanvas;
    }

    // may be null
    private Bitmap mBitmap;
Loading