Graphics.cpp revision 69a017bc1d1649350f830dfada5c6ed5eac0b770
1fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#define LOG_TAG "GraphicsJNI"
2fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
3fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "jni.h"
4fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "JNIHelp.h"
5fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "GraphicsJNI.h"
6fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
7fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "SkCanvas.h"
8fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "SkDevice.h"
9fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "SkPicture.h"
10fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include "SkRegion.h"
11fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber#include <android_runtime/AndroidRuntime.h>
12fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
13fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowNPE(JNIEnv* env) {
14fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowNullPointerException(env, NULL);
15fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
16fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
17fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowAIOOBE(JNIEnv* env) {
18fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
19fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
20fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
21fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowRE(JNIEnv* env, const char* msg) {
22fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowRuntimeException(env, msg);
23fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
24fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
25fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowIAE(JNIEnv* env, const char* msg) {
26fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
27fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
28fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
29fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowISE(JNIEnv* env, const char* msg) {
30fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowException(env, "java/lang/IllegalStateException", msg);
31fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
32fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
33fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowOOME(JNIEnv* env, const char* msg) {
34fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowException(env, "java/lang/OutOfMemoryError", msg);
35fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
36fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
37fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid doThrowIOE(JNIEnv* env, const char* msg) {
38fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jniThrowException(env, "java/io/IOException", msg);
39fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
40fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
41fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberbool GraphicsJNI::hasException(JNIEnv *env) {
42fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (env->ExceptionCheck() != 0) {
43fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        LOGE("*** Uncaught exception returned from Java call!\n");
44fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        env->ExceptionDescribe();
45fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        return true;
46fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
47fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return false;
48fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
49fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
50fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////
51fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
52fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaFloatArray::AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
53fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                       int minLength, JNIAccess access)
54fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
55fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
56fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (array) {
57fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fLen = env->GetArrayLength(array);
58fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fLen < minLength) {
59fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
60fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
61fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fPtr = env->GetFloatArrayElements(array, NULL);
62fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
63fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
64fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
65fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
66fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaFloatArray::~AutoJavaFloatArray() {
67fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fPtr) {
68fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fEnv->ReleaseFloatArrayElements(fArray, fPtr, fReleaseMode);
69fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
70fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
71fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
72fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaIntArray::AutoJavaIntArray(JNIEnv* env, jintArray array,
73fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                       int minLength)
74fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
75fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
76fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (array) {
77fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fLen = env->GetArrayLength(array);
78fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fLen < minLength) {
79fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
80fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
81fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fPtr = env->GetIntArrayElements(array, NULL);
82fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
83fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
84fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
85fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaIntArray::~AutoJavaIntArray() {
86fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fPtr) {
87fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fEnv->ReleaseIntArrayElements(fArray, fPtr, 0);
88fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
89fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
90fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
91fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaShortArray::AutoJavaShortArray(JNIEnv* env, jshortArray array,
92fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                       int minLength, JNIAccess access)
93fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
94fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
95fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (array) {
96fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fLen = env->GetArrayLength(array);
97fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fLen < minLength) {
98fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
99fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
100fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fPtr = env->GetShortArrayElements(array, NULL);
101fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
102fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
103fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
104fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
105fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaShortArray::~AutoJavaShortArray() {
106fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fPtr) {
107fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fEnv->ReleaseShortArrayElements(fArray, fPtr, fReleaseMode);
108fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
109fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
110fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
111fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaByteArray::AutoJavaByteArray(JNIEnv* env, jbyteArray array,
112fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                       int minLength)
113fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
114fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
115fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (array) {
116fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fLen = env->GetArrayLength(array);
117fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fLen < minLength) {
118fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
119fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
120fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fPtr = env->GetByteArrayElements(array, NULL);
121fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
122fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
123fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
124fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAutoJavaByteArray::~AutoJavaByteArray() {
125fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fPtr) {
126fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fEnv->ReleaseByteArrayElements(fArray, fPtr, 0);
127fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
128fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
129fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
130fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////
131fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
132fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gRect_class;
133fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRect_leftFieldID;
134fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRect_topFieldID;
135fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRect_rightFieldID;
136fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRect_bottomFieldID;
137fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
138fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gRectF_class;
139fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRectF_leftFieldID;
140fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRectF_topFieldID;
141fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRectF_rightFieldID;
142fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRectF_bottomFieldID;
143fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
144fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gPoint_class;
145fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gPoint_xFieldID;
146fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gPoint_yFieldID;
147fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
148fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gPointF_class;
149fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gPointF_xFieldID;
150fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gPointF_yFieldID;
151fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
152fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gBitmap_class;
153fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gBitmap_nativeInstanceID;
154fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jmethodID gBitmap_constructorMethodID;
155fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
156fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gBitmapConfig_class;
157fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gBitmapConfig_nativeInstanceID;
158fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
159fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gBitmapRegionDecoder_class;
160fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jmethodID gBitmapRegionDecoder_constructorMethodID;
161fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
162fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gCanvas_class;
163fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gCanvas_nativeInstanceID;
164fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
165fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gPaint_class;
166fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gPaint_nativeInstanceID;
167fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
168fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gPicture_class;
169fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gPicture_nativeInstanceID;
170fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
171fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass   gRegion_class;
172fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID gRegion_nativeInstanceID;
173fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jmethodID gRegion_constructorMethodID;
174fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
175fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////
176fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
177fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
178fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
179fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRect_class));
180fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
181fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    *L = env->GetIntField(obj, gRect_leftFieldID);
182fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    *T = env->GetIntField(obj, gRect_topFieldID);
183fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    *R = env->GetIntField(obj, gRect_rightFieldID);
184fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    *B = env->GetIntField(obj, gRect_bottomFieldID);
185fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
186fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
187fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid GraphicsJNI::set_jrect(JNIEnv* env, jobject obj, int L, int T, int R, int B)
188fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
189fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRect_class));
190fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
191fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_leftFieldID, L);
192fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_topFieldID, T);
193fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_rightFieldID, R);
194fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_bottomFieldID, B);
195fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
196fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
197fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkIRect* GraphicsJNI::jrect_to_irect(JNIEnv* env, jobject obj, SkIRect* ir)
198fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
199fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRect_class));
200fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
201fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    ir->set(env->GetIntField(obj, gRect_leftFieldID),
202fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            env->GetIntField(obj, gRect_topFieldID),
203fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            env->GetIntField(obj, gRect_rightFieldID),
204fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            env->GetIntField(obj, gRect_bottomFieldID));
205fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return ir;
206fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
207fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
208fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid GraphicsJNI::irect_to_jrect(const SkIRect& ir, JNIEnv* env, jobject obj)
209fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
210fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRect_class));
211fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
212fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_leftFieldID, ir.fLeft);
213fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_topFieldID, ir.fTop);
214fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_rightFieldID, ir.fRight);
215fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gRect_bottomFieldID, ir.fBottom);
216fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
217fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
218fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkRect* GraphicsJNI::jrectf_to_rect(JNIEnv* env, jobject obj, SkRect* r)
219fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
220fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRectF_class));
221fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
222fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    r->set(SkFloatToScalar(env->GetFloatField(obj, gRectF_leftFieldID)),
223fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber           SkFloatToScalar(env->GetFloatField(obj, gRectF_topFieldID)),
224fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber           SkFloatToScalar(env->GetFloatField(obj, gRectF_rightFieldID)),
225fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber           SkFloatToScalar(env->GetFloatField(obj, gRectF_bottomFieldID)));
226fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return r;
227fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
228fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
229fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkRect* GraphicsJNI::jrect_to_rect(JNIEnv* env, jobject obj, SkRect* r)
230fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
231fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRect_class));
232fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
233fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    r->set(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
234fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber           SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
235fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber           SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
236fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber           SkIntToScalar(env->GetIntField(obj, gRect_bottomFieldID)));
237fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return r;
238fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
239fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
240fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid GraphicsJNI::rect_to_jrectf(const SkRect& r, JNIEnv* env, jobject obj)
241fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
242fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gRectF_class));
243fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
244fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetFloatField(obj, gRectF_leftFieldID, SkScalarToFloat(r.fLeft));
245fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetFloatField(obj, gRectF_topFieldID, SkScalarToFloat(r.fTop));
246fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetFloatField(obj, gRectF_rightFieldID, SkScalarToFloat(r.fRight));
247fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetFloatField(obj, gRectF_bottomFieldID, SkScalarToFloat(r.fBottom));
248fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
249fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
250fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkIPoint* GraphicsJNI::jpoint_to_ipoint(JNIEnv* env, jobject obj, SkIPoint* point)
251fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
252fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gPoint_class));
253fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
254fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    point->set(env->GetIntField(obj, gPoint_xFieldID),
255fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber               env->GetIntField(obj, gPoint_yFieldID));
256fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return point;
257fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
258fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
259fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid GraphicsJNI::ipoint_to_jpoint(const SkIPoint& ir, JNIEnv* env, jobject obj)
260fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
261fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gPoint_class));
262fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
263fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gPoint_xFieldID, ir.fX);
264fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetIntField(obj, gPoint_yFieldID, ir.fY);
265fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
266fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
267fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkPoint* GraphicsJNI::jpointf_to_point(JNIEnv* env, jobject obj, SkPoint* point)
268fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
269fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gPointF_class));
270fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
271fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    point->set(SkFloatToScalar(env->GetIntField(obj, gPointF_xFieldID)),
272fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber               SkFloatToScalar(env->GetIntField(obj, gPointF_yFieldID)));
273fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return point;
274fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
275fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
276fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid GraphicsJNI::point_to_jpointf(const SkPoint& r, JNIEnv* env, jobject obj)
277fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
278fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(obj, gPointF_class));
279fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
280fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetFloatField(obj, gPointF_xFieldID, SkScalarToFloat(r.fX));
281fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    env->SetFloatField(obj, gPointF_yFieldID, SkScalarToFloat(r.fY));
282fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
283fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
284fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkBitmap* GraphicsJNI::getNativeBitmap(JNIEnv* env, jobject bitmap) {
285fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
286fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(bitmap);
287fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
288fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkBitmap* b = (SkBitmap*)env->GetIntField(bitmap, gBitmap_nativeInstanceID);
289fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(b);
290fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return b;
291fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
292fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
293fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkBitmap::Config GraphicsJNI::getNativeBitmapConfig(JNIEnv* env,
294fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                                    jobject jconfig) {
295fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
296fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (NULL == jconfig) {
297fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        return SkBitmap::kNo_Config;
298fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
299fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(jconfig, gBitmapConfig_class));
300fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
301fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (c < 0 || c >= SkBitmap::kConfigCount) {
302fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        c = SkBitmap::kNo_Config;
303fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
304fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return static_cast<SkBitmap::Config>(c);
305fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
306fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
307fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkCanvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
308fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
309fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(canvas);
310fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(canvas, gCanvas_class));
311fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkCanvas* c = (SkCanvas*)env->GetIntField(canvas, gCanvas_nativeInstanceID);
312fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(c);
313fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return c;
314fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
315fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
316fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkPaint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
317fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
318fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(paint);
319fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(paint, gPaint_class));
320fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkPaint* p = (SkPaint*)env->GetIntField(paint, gPaint_nativeInstanceID);
321fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(p);
322fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return p;
323fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
324fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
325fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkPicture* GraphicsJNI::getNativePicture(JNIEnv* env, jobject picture)
326fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
327fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
328fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(picture);
329fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(picture, gPicture_class));
330fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkPicture* p = (SkPicture*)env->GetIntField(picture, gPicture_nativeInstanceID);
331fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(p);
332fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return p;
333fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
334fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
335fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberSkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
336fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
337fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
338fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(region);
339fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env->IsInstanceOf(region, gRegion_class));
340fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkRegion* r = (SkRegion*)env->GetIntField(region, gRegion_nativeInstanceID);
341fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(r);
342fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return r;
343fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
344fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
345fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////////////////
346fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
347fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberjobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
348fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                  bool isMutable, jbyteArray ninepatch, int density)
349fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
350fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(bitmap);
351fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(bitmap->pixelRef());
352fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
353fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jobject obj = env->AllocObject(gBitmap_class);
354fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (obj) {
355fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        env->CallVoidMethod(obj, gBitmap_constructorMethodID,
356fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                            (jint)bitmap, buffer, isMutable, ninepatch, density);
357fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (hasException(env)) {
358fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            obj = NULL;
359fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
360fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
361fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return obj;
362fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
363fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
364fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberjobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
365fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                            jbyteArray ninepatch, int density)
366fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
367fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return createBitmap(env, bitmap, NULL, isMutable, ninepatch, density);
368fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
369fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
370fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
371fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberjobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap)
372fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
373fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(bitmap != NULL);
374fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
375fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jobject obj = env->AllocObject(gBitmapRegionDecoder_class);
376fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (hasException(env)) {
377fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        obj = NULL;
378fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        return obj;
379fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
380fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (obj) {
381fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        env->CallVoidMethod(obj, gBitmapRegionDecoder_constructorMethodID, (jint)bitmap);
382fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (hasException(env)) {
383fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            obj = NULL;
384fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
385fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
386fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return obj;
387fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
388fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
389fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberjobject GraphicsJNI::createRegion(JNIEnv* env, SkRegion* region)
390fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
391fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(region != NULL);
392fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jobject obj = env->AllocObject(gRegion_class);
393fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (obj) {
394fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        env->CallVoidMethod(obj, gRegion_constructorMethodID, (jint)region, 0);
395fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (hasException(env)) {
396fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            obj = NULL;
397fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
398fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
399fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return obj;
400fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
401fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
402fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic JNIEnv* vm2env(JavaVM* vm)
403fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
404fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    JNIEnv* env = NULL;
405fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || NULL == env)
406fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    {
407fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        SkDebugf("------- [%p] vm->GetEnv() failed\n", vm);
408fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        sk_throw();
409fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
410fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return env;
411fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
412fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
413fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////
414fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
415fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAndroidPixelRef::AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj,
416fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable) {
417fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(storage);
418fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(env);
419fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
420fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (env->GetJavaVM(&fVM) != JNI_OK) {
421fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        SkDebugf("------ [%p] env->GetJavaVM failed\n", env);
422fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        sk_throw();
423fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
424fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fStorageObj = storageObj;
425fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fHasGlobalRef = false;
426fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fGlobalRefCnt = 0;
427fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
428fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    // If storageObj is NULL, the memory was NOT allocated on the Java heap
429fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fOnJavaHeap = (storageObj != NULL);
430fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
431fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
432fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
433fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberAndroidPixelRef::~AndroidPixelRef() {
434fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fOnJavaHeap) {
435fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        JNIEnv* env = vm2env(fVM);
436fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
437fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fStorageObj && fHasGlobalRef) {
438fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            env->DeleteGlobalRef(fStorageObj);
439fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
440fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fStorageObj = NULL;
441fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
442fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        // Set this to NULL to prevent the SkMallocPixelRef destructor
443fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        // from freeing the memory.
444fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fStorage = NULL;
445fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
446fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
447fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
448fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid AndroidPixelRef::setLocalJNIRef(jbyteArray arr) {
449fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (!fHasGlobalRef) {
450fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fStorageObj = arr;
451fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
452fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
453fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
454fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid AndroidPixelRef::globalRef(void* localref) {
455fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fOnJavaHeap && sk_atomic_inc(&fGlobalRefCnt) == 0) {
456fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        JNIEnv *env = vm2env(fVM);
457fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
458fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        // If JNI ref was passed, it is always used
459fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (localref) fStorageObj = (jbyteArray) localref;
460fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
461fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fStorageObj == NULL) {
462fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            SkDebugf("No valid local ref to create a JNI global ref\n");
463fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
464fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
465fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (fHasGlobalRef) {
466fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            // This should never happen
467fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            SkDebugf("Already holding a JNI global ref");
468fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
469fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
470fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
471fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fStorageObj = (jbyteArray) env->NewGlobalRef(fStorageObj);
472fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        // TODO: Check for failure here
473fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fHasGlobalRef = true;
474fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
475fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    ref();
476fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
477fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
478fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Hubervoid AndroidPixelRef::globalUnref() {
479fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fOnJavaHeap && sk_atomic_dec(&fGlobalRefCnt) == 1) {
480fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        JNIEnv *env = vm2env(fVM);
481fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (!fHasGlobalRef) {
482fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            SkDebugf("We don't have a global ref!");
483fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            sk_throw();
484fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
485fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        env->DeleteGlobalRef(fStorageObj);
486fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fStorageObj = NULL;
487fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        fHasGlobalRef = false;
488fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
489fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    unref();
490fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
491fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
492fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////
493fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
494fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberextern "C" jbyte* jniGetNonMovableArrayElements(C_JNIEnv* env, jarray arrayObj);
495fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
496fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberjbyteArray GraphicsJNI::allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
497fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                             SkColorTable* ctable) {
498fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    Sk64 size64 = bitmap->getSize64();
499fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (size64.isNeg() || !size64.is32()) {
500fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        jniThrowException(env, "java/lang/IllegalArgumentException",
501fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                          "bitmap size exceeds 32bits");
502fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        return NULL;
503fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
504fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
505fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    size_t size = size64.get32();
506fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jbyteArray arrayObj = env->NewByteArray(size);
507fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (arrayObj) {
508fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        // TODO: make this work without jniGetNonMovableArrayElements
509fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        jbyte* addr = jniGetNonMovableArrayElements(&env->functions, arrayObj);
510fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        if (addr) {
511fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            SkPixelRef* pr = new AndroidPixelRef(env, (void*) addr, size, arrayObj, ctable);
512fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            bitmap->setPixelRef(pr)->unref();
513fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            // since we're already allocated, we lockPixels right away
514fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            // HeapAllocator behaves this way too
515fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber            bitmap->lockPixels();
516fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        }
517fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
518fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
519fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return arrayObj;
520fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
521fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
522fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber///////////////////////////////////////////////////////////////////////////////
523fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
524fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberJavaPixelAllocator::JavaPixelAllocator(JNIEnv* env)
525fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    : fStorageObj(NULL),
526fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber      fAllocCount(0) {
527fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (env->GetJavaVM(&fVM) != JNI_OK) {
528fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        SkDebugf("------ [%p] env->GetJavaVM failed\n", env);
529fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        sk_throw();
530fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
531fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
532fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
533fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberbool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
534fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    JNIEnv* env = vm2env(fVM);
535fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
536fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    // If allocating in the Java heap, only allow a single object to be
537fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    // allocated for the lifetime of this object.
538fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fStorageObj != NULL) {
539fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        SkDebugf("WARNING: One-shot allocator has already allocated (alloc count = %d)\n", fAllocCount);
540fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber//        sk_throw();
541fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
542fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fStorageObj = GraphicsJNI::allocateJavaPixelRef(env, bitmap, ctable);
543fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fAllocCount += 1;
544fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return fStorageObj != NULL;
545fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
546fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
547fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber////////////////////////////////////////////////////////////////////////////////
548fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
549fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberJavaHeapBitmapRef::JavaHeapBitmapRef(JNIEnv* env, SkBitmap* nativeBitmap, jbyteArray buffer) {
550fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fEnv = env;
551fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fNativeBitmap = nativeBitmap;
552fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    fBuffer = buffer;
553fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
554fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    // If the buffer is NULL, the backing memory wasn't allocated on the Java heap
555fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fBuffer) {
556fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        ((AndroidPixelRef*) fNativeBitmap->pixelRef())->setLocalJNIRef(fBuffer);
557fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
558fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
559fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
560fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas HuberJavaHeapBitmapRef::~JavaHeapBitmapRef() {
561fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    if (fBuffer) {
562fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        ((AndroidPixelRef*) fNativeBitmap->pixelRef())->setLocalJNIRef(NULL);
563fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    }
564fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
565fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
566fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber////////////////////////////////////////////////////////////////////////////////
567fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
568fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jclass make_globalref(JNIEnv* env, const char classname[])
569fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
570fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jclass c = env->FindClass(classname);
571fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(c);
572fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return (jclass)env->NewGlobalRef(c);
573fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
574fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
575fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberstatic jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
576fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                const char fieldname[], const char type[])
577fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
578fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jfieldID id = env->GetFieldID(clazz, fieldname, type);
579fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    SkASSERT(id);
580fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return id;
581fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
582fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
583fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huberint register_android_graphics_Graphics(JNIEnv* env)
584fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber{
585fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jmethodID m;
586fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    jclass c;
587fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
588fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRect_class = make_globalref(env, "android/graphics/Rect");
589fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRect_leftFieldID = getFieldIDCheck(env, gRect_class, "left", "I");
590fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRect_topFieldID = getFieldIDCheck(env, gRect_class, "top", "I");
591fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRect_rightFieldID = getFieldIDCheck(env, gRect_class, "right", "I");
592fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRect_bottomFieldID = getFieldIDCheck(env, gRect_class, "bottom", "I");
593fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
594fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRectF_class = make_globalref(env, "android/graphics/RectF");
595fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRectF_leftFieldID = getFieldIDCheck(env, gRectF_class, "left", "F");
596fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRectF_topFieldID = getFieldIDCheck(env, gRectF_class, "top", "F");
597fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRectF_rightFieldID = getFieldIDCheck(env, gRectF_class, "right", "F");
598fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRectF_bottomFieldID = getFieldIDCheck(env, gRectF_class, "bottom", "F");
599fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
600fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPoint_class = make_globalref(env, "android/graphics/Point");
601fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPoint_xFieldID = getFieldIDCheck(env, gPoint_class, "x", "I");
602fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPoint_yFieldID = getFieldIDCheck(env, gPoint_class, "y", "I");
603fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
604fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPointF_class = make_globalref(env, "android/graphics/PointF");
605fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPointF_xFieldID = getFieldIDCheck(env, gPointF_class, "x", "F");
606fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPointF_yFieldID = getFieldIDCheck(env, gPointF_class, "y", "F");
607fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
608fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
609fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmap_nativeInstanceID = getFieldIDCheck(env, gBitmap_class, "mNativeBitmap", "I");
610fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
611fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                            "(I[BZ[BI)V");
612fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmapRegionDecoder_class = make_globalref(env, "android/graphics/BitmapRegionDecoder");
613fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmapRegionDecoder_constructorMethodID = env->GetMethodID(gBitmapRegionDecoder_class, "<init>", "(I)V");
614fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
615fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmapConfig_class = make_globalref(env, "android/graphics/Bitmap$Config");
616fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gBitmapConfig_nativeInstanceID = getFieldIDCheck(env, gBitmapConfig_class,
617fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber                                                     "nativeInt", "I");
618fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
619fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gCanvas_class = make_globalref(env, "android/graphics/Canvas");
620fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gCanvas_nativeInstanceID = getFieldIDCheck(env, gCanvas_class, "mNativeCanvas", "I");
621fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
622fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPaint_class = make_globalref(env, "android/graphics/Paint");
623fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPaint_nativeInstanceID = getFieldIDCheck(env, gPaint_class, "mNativePaint", "I");
624fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
625fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPicture_class = make_globalref(env, "android/graphics/Picture");
626fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gPicture_nativeInstanceID = getFieldIDCheck(env, gPicture_class, "mNativePicture", "I");
627fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
628fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRegion_class = make_globalref(env, "android/graphics/Region");
629fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRegion_nativeInstanceID = getFieldIDCheck(env, gRegion_class, "mNativeRegion", "I");
630fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    gRegion_constructorMethodID = env->GetMethodID(gRegion_class, "<init>",
631fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber        "(II)V");
632fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber
633fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber    return 0;
634fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber}
635fbe9d81ff5fbdc5aecdcdd13e4a5d7f019824f96Andreas Huber