blob: 5659ba2f353f87dba77d4bdb03a21f664e090218 [file] [log] [blame]
Ficus Kirkpatrick1a9c27c2010-03-05 17:05:08 -08001#define LOG_TAG "GraphicsJNI"
2
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003#include "jni.h"
4#include "GraphicsJNI.h"
5#include "NIOBuffer.h"
6#include "SkPicture.h"
7#include "SkRegion.h"
8#include <android_runtime/AndroidRuntime.h>
9
Mike Reed1b22b972009-07-17 11:21:47 -040010//#define REPORT_SIZE_TO_JVM
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011//#define TRACK_LOCK_COUNT
12
13void doThrow(JNIEnv* env, const char* exc, const char* msg) {
14 // don't throw a new exception if we already have one pending
15 if (env->ExceptionCheck() == JNI_FALSE) {
16 jclass npeClazz;
17
18 npeClazz = env->FindClass(exc);
19 LOG_FATAL_IF(npeClazz == NULL, "Unable to find class %s", exc);
20
21 env->ThrowNew(npeClazz, msg);
22 }
23}
24
25void doThrowNPE(JNIEnv* env) {
26 doThrow(env, "java/lang/NullPointerException");
27}
28
29void doThrowAIOOBE(JNIEnv* env) {
30 doThrow(env, "java/lang/ArrayIndexOutOfBoundsException");
31}
32
33void doThrowRE(JNIEnv* env, const char* msg) {
34 doThrow(env, "java/lang/RuntimeException", msg);
35}
36
37void doThrowIAE(JNIEnv* env, const char* msg) {
38 doThrow(env, "java/lang/IllegalArgumentException", msg);
39}
40
41void doThrowISE(JNIEnv* env, const char* msg) {
42 doThrow(env, "java/lang/IllegalStateException", msg);
43}
44
45void doThrowOOME(JNIEnv* env, const char* msg) {
46 doThrow(env, "java/lang/OutOfMemoryError", msg);
47}
48
49bool GraphicsJNI::hasException(JNIEnv *env) {
50 if (env->ExceptionCheck() != 0) {
51 LOGE("*** Uncaught exception returned from Java call!\n");
52 env->ExceptionDescribe();
53 return true;
54 }
55 return false;
56}
57
58///////////////////////////////////////////////////////////////////////////////
59
60AutoJavaFloatArray::AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
Mike Reedc04851f2009-10-28 15:09:45 -040061 int minLength, JNIAccess access)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
63 SkASSERT(env);
64 if (array) {
65 fLen = env->GetArrayLength(array);
66 if (fLen < minLength) {
67 sk_throw();
68 }
69 fPtr = env->GetFloatArrayElements(array, NULL);
70 }
Mike Reedc04851f2009-10-28 15:09:45 -040071 fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072}
73
74AutoJavaFloatArray::~AutoJavaFloatArray() {
75 if (fPtr) {
Mike Reedc04851f2009-10-28 15:09:45 -040076 fEnv->ReleaseFloatArrayElements(fArray, fPtr, fReleaseMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077 }
78}
79
80AutoJavaIntArray::AutoJavaIntArray(JNIEnv* env, jintArray array,
81 int minLength)
82: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
83 SkASSERT(env);
84 if (array) {
85 fLen = env->GetArrayLength(array);
86 if (fLen < minLength) {
87 sk_throw();
88 }
89 fPtr = env->GetIntArrayElements(array, NULL);
90 }
91}
92
93AutoJavaIntArray::~AutoJavaIntArray() {
94 if (fPtr) {
95 fEnv->ReleaseIntArrayElements(fArray, fPtr, 0);
96 }
97}
98
99AutoJavaShortArray::AutoJavaShortArray(JNIEnv* env, jshortArray array,
Mike Reedc04851f2009-10-28 15:09:45 -0400100 int minLength, JNIAccess access)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
102 SkASSERT(env);
103 if (array) {
104 fLen = env->GetArrayLength(array);
105 if (fLen < minLength) {
106 sk_throw();
107 }
108 fPtr = env->GetShortArrayElements(array, NULL);
109 }
Mike Reedc04851f2009-10-28 15:09:45 -0400110 fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111}
112
113AutoJavaShortArray::~AutoJavaShortArray() {
114 if (fPtr) {
Mike Reedc04851f2009-10-28 15:09:45 -0400115 fEnv->ReleaseShortArrayElements(fArray, fPtr, fReleaseMode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 }
117}
118
119AutoJavaByteArray::AutoJavaByteArray(JNIEnv* env, jbyteArray array,
120 int minLength)
121: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
122 SkASSERT(env);
123 if (array) {
124 fLen = env->GetArrayLength(array);
125 if (fLen < minLength) {
126 sk_throw();
127 }
128 fPtr = env->GetByteArrayElements(array, NULL);
129 }
130}
131
132AutoJavaByteArray::~AutoJavaByteArray() {
133 if (fPtr) {
134 fEnv->ReleaseByteArrayElements(fArray, fPtr, 0);
135 }
136}
137
138///////////////////////////////////////////////////////////////////////////////
139
140static jclass gRect_class;
141static jfieldID gRect_leftFieldID;
142static jfieldID gRect_topFieldID;
143static jfieldID gRect_rightFieldID;
144static jfieldID gRect_bottomFieldID;
145
146static jclass gRectF_class;
147static jfieldID gRectF_leftFieldID;
148static jfieldID gRectF_topFieldID;
149static jfieldID gRectF_rightFieldID;
150static jfieldID gRectF_bottomFieldID;
151
152static jclass gPoint_class;
153static jfieldID gPoint_xFieldID;
154static jfieldID gPoint_yFieldID;
155
156static jclass gPointF_class;
157static jfieldID gPointF_xFieldID;
158static jfieldID gPointF_yFieldID;
159
160static jclass gBitmap_class;
161static jfieldID gBitmap_nativeInstanceID;
162static jmethodID gBitmap_constructorMethodID;
163static jmethodID gBitmap_allocBufferMethodID;
164
165static jclass gBitmapConfig_class;
166static jfieldID gBitmapConfig_nativeInstanceID;
167
168static jclass gCanvas_class;
169static jfieldID gCanvas_nativeInstanceID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170
171static jclass gPaint_class;
172static jfieldID gPaint_nativeInstanceID;
173
174static jclass gPicture_class;
175static jfieldID gPicture_nativeInstanceID;
176
177static jclass gRegion_class;
178static jfieldID gRegion_nativeInstanceID;
179static jmethodID gRegion_constructorMethodID;
180
181static jobject gVMRuntime_singleton;
182static jmethodID gVMRuntime_trackExternalAllocationMethodID;
183static jmethodID gVMRuntime_trackExternalFreeMethodID;
184
185///////////////////////////////////////////////////////////////////////////////
186
187void GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
188{
189 SkASSERT(env->IsInstanceOf(obj, gRect_class));
190
191 *L = env->GetIntField(obj, gRect_leftFieldID);
192 *T = env->GetIntField(obj, gRect_topFieldID);
193 *R = env->GetIntField(obj, gRect_rightFieldID);
194 *B = env->GetIntField(obj, gRect_bottomFieldID);
195}
196
197void GraphicsJNI::set_jrect(JNIEnv* env, jobject obj, int L, int T, int R, int B)
198{
199 SkASSERT(env->IsInstanceOf(obj, gRect_class));
200
201 env->SetIntField(obj, gRect_leftFieldID, L);
202 env->SetIntField(obj, gRect_topFieldID, T);
203 env->SetIntField(obj, gRect_rightFieldID, R);
204 env->SetIntField(obj, gRect_bottomFieldID, B);
205}
206
207SkIRect* GraphicsJNI::jrect_to_irect(JNIEnv* env, jobject obj, SkIRect* ir)
208{
209 SkASSERT(env->IsInstanceOf(obj, gRect_class));
210
211 ir->set(env->GetIntField(obj, gRect_leftFieldID),
212 env->GetIntField(obj, gRect_topFieldID),
213 env->GetIntField(obj, gRect_rightFieldID),
214 env->GetIntField(obj, gRect_bottomFieldID));
215 return ir;
216}
217
218void GraphicsJNI::irect_to_jrect(const SkIRect& ir, JNIEnv* env, jobject obj)
219{
220 SkASSERT(env->IsInstanceOf(obj, gRect_class));
221
222 env->SetIntField(obj, gRect_leftFieldID, ir.fLeft);
223 env->SetIntField(obj, gRect_topFieldID, ir.fTop);
224 env->SetIntField(obj, gRect_rightFieldID, ir.fRight);
225 env->SetIntField(obj, gRect_bottomFieldID, ir.fBottom);
226}
227
228SkRect* GraphicsJNI::jrectf_to_rect(JNIEnv* env, jobject obj, SkRect* r)
229{
230 SkASSERT(env->IsInstanceOf(obj, gRectF_class));
231
232 r->set(SkFloatToScalar(env->GetFloatField(obj, gRectF_leftFieldID)),
233 SkFloatToScalar(env->GetFloatField(obj, gRectF_topFieldID)),
234 SkFloatToScalar(env->GetFloatField(obj, gRectF_rightFieldID)),
235 SkFloatToScalar(env->GetFloatField(obj, gRectF_bottomFieldID)));
236 return r;
237}
238
239SkRect* GraphicsJNI::jrect_to_rect(JNIEnv* env, jobject obj, SkRect* r)
240{
241 SkASSERT(env->IsInstanceOf(obj, gRect_class));
242
243 r->set(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
244 SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
245 SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
246 SkIntToScalar(env->GetIntField(obj, gRect_bottomFieldID)));
247 return r;
248}
249
250void GraphicsJNI::rect_to_jrectf(const SkRect& r, JNIEnv* env, jobject obj)
251{
252 SkASSERT(env->IsInstanceOf(obj, gRectF_class));
253
254 env->SetFloatField(obj, gRectF_leftFieldID, SkScalarToFloat(r.fLeft));
255 env->SetFloatField(obj, gRectF_topFieldID, SkScalarToFloat(r.fTop));
256 env->SetFloatField(obj, gRectF_rightFieldID, SkScalarToFloat(r.fRight));
257 env->SetFloatField(obj, gRectF_bottomFieldID, SkScalarToFloat(r.fBottom));
258}
259
260SkIPoint* GraphicsJNI::jpoint_to_ipoint(JNIEnv* env, jobject obj, SkIPoint* point)
261{
262 SkASSERT(env->IsInstanceOf(obj, gPoint_class));
263
264 point->set(env->GetIntField(obj, gPoint_xFieldID),
265 env->GetIntField(obj, gPoint_yFieldID));
266 return point;
267}
268
269void GraphicsJNI::ipoint_to_jpoint(const SkIPoint& ir, JNIEnv* env, jobject obj)
270{
271 SkASSERT(env->IsInstanceOf(obj, gPoint_class));
272
273 env->SetIntField(obj, gPoint_xFieldID, ir.fX);
274 env->SetIntField(obj, gPoint_yFieldID, ir.fY);
275}
276
277SkPoint* GraphicsJNI::jpointf_to_point(JNIEnv* env, jobject obj, SkPoint* point)
278{
279 SkASSERT(env->IsInstanceOf(obj, gPointF_class));
280
281 point->set(SkFloatToScalar(env->GetIntField(obj, gPointF_xFieldID)),
282 SkFloatToScalar(env->GetIntField(obj, gPointF_yFieldID)));
283 return point;
284}
285
286void GraphicsJNI::point_to_jpointf(const SkPoint& r, JNIEnv* env, jobject obj)
287{
288 SkASSERT(env->IsInstanceOf(obj, gPointF_class));
289
290 env->SetFloatField(obj, gPointF_xFieldID, SkScalarToFloat(r.fX));
291 env->SetFloatField(obj, gPointF_yFieldID, SkScalarToFloat(r.fY));
292}
293
294SkBitmap* GraphicsJNI::getNativeBitmap(JNIEnv* env, jobject bitmap) {
295 SkASSERT(env);
296 SkASSERT(bitmap);
297 SkASSERT(env->IsInstanceOf(bitmap, gBitmap_class));
298 SkBitmap* b = (SkBitmap*)env->GetIntField(bitmap, gBitmap_nativeInstanceID);
299 SkASSERT(b);
300 return b;
301}
302
303SkBitmap::Config GraphicsJNI::getNativeBitmapConfig(JNIEnv* env,
304 jobject jconfig) {
305 SkASSERT(env);
306 if (NULL == jconfig) {
307 return SkBitmap::kNo_Config;
308 }
309 SkASSERT(env->IsInstanceOf(jconfig, gBitmapConfig_class));
310 int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
311 if (c < 0 || c >= SkBitmap::kConfigCount) {
312 c = SkBitmap::kNo_Config;
313 }
314 return static_cast<SkBitmap::Config>(c);
315}
316
317SkCanvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
318 SkASSERT(env);
319 SkASSERT(canvas);
320 SkASSERT(env->IsInstanceOf(canvas, gCanvas_class));
321 SkCanvas* c = (SkCanvas*)env->GetIntField(canvas, gCanvas_nativeInstanceID);
322 SkASSERT(c);
323 return c;
324}
325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326SkPaint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
327 SkASSERT(env);
328 SkASSERT(paint);
329 SkASSERT(env->IsInstanceOf(paint, gPaint_class));
330 SkPaint* p = (SkPaint*)env->GetIntField(paint, gPaint_nativeInstanceID);
331 SkASSERT(p);
332 return p;
333}
334
335SkPicture* GraphicsJNI::getNativePicture(JNIEnv* env, jobject picture)
336{
337 SkASSERT(env);
338 SkASSERT(picture);
339 SkASSERT(env->IsInstanceOf(picture, gPicture_class));
340 SkPicture* p = (SkPicture*)env->GetIntField(picture, gPicture_nativeInstanceID);
341 SkASSERT(p);
342 return p;
343}
344
345SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
346{
347 SkASSERT(env);
348 SkASSERT(region);
349 SkASSERT(env->IsInstanceOf(region, gRegion_class));
350 SkRegion* r = (SkRegion*)env->GetIntField(region, gRegion_nativeInstanceID);
351 SkASSERT(r);
352 return r;
353}
354
355///////////////////////////////////////////////////////////////////////////////////////////
356
357jobject GraphicsJNI::createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable,
Dianne Hackbornde0dfb72009-09-23 14:09:34 -0700358 jbyteArray ninepatch, int density)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359{
360 SkASSERT(bitmap != NULL);
361 SkASSERT(NULL != bitmap->pixelRef());
362
363 jobject obj = env->AllocObject(gBitmap_class);
364 if (obj) {
365 env->CallVoidMethod(obj, gBitmap_constructorMethodID,
Dianne Hackbornde0dfb72009-09-23 14:09:34 -0700366 (jint)bitmap, isMutable, ninepatch, density);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 if (hasException(env)) {
368 obj = NULL;
369 }
370 }
371 return obj;
372}
373
374jobject GraphicsJNI::createRegion(JNIEnv* env, SkRegion* region)
375{
376 SkASSERT(region != NULL);
377 jobject obj = env->AllocObject(gRegion_class);
378 if (obj) {
379 env->CallVoidMethod(obj, gRegion_constructorMethodID, (jint)region, 0);
380 if (hasException(env)) {
381 obj = NULL;
382 }
383 }
384 return obj;
385}
386
387#include "SkPixelRef.h"
388
389static JNIEnv* vm2env(JavaVM* vm)
390{
391 JNIEnv* env = NULL;
392 if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK || NULL == env)
393 {
394 SkDebugf("------- [%p] vm->GetEnv() failed\n", vm);
395 sk_throw();
396 }
397 return env;
398}
399
400#ifdef TRACK_LOCK_COUNT
401 static int gLockCount;
402#endif
403
404///////////////////////////////////////////////////////////////////////////////
405
406#include "SkMallocPixelRef.h"
407
408/* Extend SkMallocPixelRef to inform the VM when we free up the storage
409*/
410class AndroidPixelRef : public SkMallocPixelRef {
411public:
412 /** Allocate the specified buffer for pixels. The memory is freed when the
413 last owner of this pixelref is gone. Our caller has already informed
414 the VM of our allocation.
415 */
416 AndroidPixelRef(JNIEnv* env, void* storage, size_t size,
417 SkColorTable* ctable) : SkMallocPixelRef(storage, size, ctable) {
418 SkASSERT(storage);
419 SkASSERT(env);
420
421 if (env->GetJavaVM(&fVM) != JNI_OK) {
422 SkDebugf("------ [%p] env->GetJavaVM failed\n", env);
423 sk_throw();
424 }
425 }
426
427 virtual ~AndroidPixelRef() {
428 JNIEnv* env = vm2env(fVM);
429// SkDebugf("-------------- inform VM we're releasing %d bytes\n", this->getSize());
430 jlong jsize = this->getSize(); // the VM wants longs for the size
431 env->CallVoidMethod(gVMRuntime_singleton,
432 gVMRuntime_trackExternalFreeMethodID,
433 jsize);
434 if (GraphicsJNI::hasException(env)) {
435 env->ExceptionClear();
436 }
437 }
438
439private:
440 JavaVM* fVM;
441};
442
443bool GraphicsJNI::setJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
Mike Reed1b22b972009-07-17 11:21:47 -0400444 SkColorTable* ctable, bool reportSizeToVM) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800445 Sk64 size64 = bitmap->getSize64();
446 if (size64.isNeg() || !size64.is32()) {
447 doThrow(env, "java/lang/IllegalArgumentException",
448 "bitmap size exceeds 32bits");
449 return false;
450 }
451
452 size_t size = size64.get32();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800453 jlong jsize = size; // the VM wants longs for the size
Mike Reed1b22b972009-07-17 11:21:47 -0400454 if (reportSizeToVM) {
455 // SkDebugf("-------------- inform VM we've allocated %d bytes\n", size);
456 bool r = env->CallBooleanMethod(gVMRuntime_singleton,
457 gVMRuntime_trackExternalAllocationMethodID,
458 jsize);
459 if (GraphicsJNI::hasException(env)) {
460 return false;
461 }
462 if (!r) {
463 LOGE("VM won't let us allocate %zd bytes\n", size);
464 doThrowOOME(env, "bitmap size exceeds VM budget");
465 return false;
466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 // call the version of malloc that returns null on failure
469 void* addr = sk_malloc_flags(size, 0);
470 if (NULL == addr) {
Mike Reed1b22b972009-07-17 11:21:47 -0400471 if (reportSizeToVM) {
472 // SkDebugf("-------------- inform VM we're releasing %d bytes which we couldn't allocate\n", size);
473 // we didn't actually allocate it, so inform the VM
474 env->CallVoidMethod(gVMRuntime_singleton,
475 gVMRuntime_trackExternalFreeMethodID,
476 jsize);
477 if (!GraphicsJNI::hasException(env)) {
478 doThrowOOME(env, "bitmap size too large for malloc");
479 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 }
481 return false;
482 }
483
Mike Reed1b22b972009-07-17 11:21:47 -0400484 SkPixelRef* pr = reportSizeToVM ?
485 new AndroidPixelRef(env, addr, size, ctable) :
486 new SkMallocPixelRef(addr, size, ctable);
487 bitmap->setPixelRef(pr)->unref();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800488 // since we're already allocated, we lockPixels right away
489 // HeapAllocator behaves this way too
490 bitmap->lockPixels();
491 return true;
492}
493
494///////////////////////////////////////////////////////////////////////////////
495
Mike Reed1b22b972009-07-17 11:21:47 -0400496JavaPixelAllocator::JavaPixelAllocator(JNIEnv* env, bool reportSizeToVM)
497 : fEnv(env), fReportSizeToVM(reportSizeToVM) {}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498
499bool JavaPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
Mike Reed1b22b972009-07-17 11:21:47 -0400500 return GraphicsJNI::setJavaPixelRef(fEnv, bitmap, ctable, fReportSizeToVM);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501}
502
503////////////////////////////////////////////////////////////////////////////////
504
505static jclass make_globalref(JNIEnv* env, const char classname[])
506{
507 jclass c = env->FindClass(classname);
508 SkASSERT(c);
509 return (jclass)env->NewGlobalRef(c);
510}
511
512static jfieldID getFieldIDCheck(JNIEnv* env, jclass clazz,
513 const char fieldname[], const char type[])
514{
515 jfieldID id = env->GetFieldID(clazz, fieldname, type);
516 SkASSERT(id);
517 return id;
518}
519
520int register_android_graphics_Graphics(JNIEnv* env)
521{
522 jmethodID m;
523 jclass c;
524
525 gRect_class = make_globalref(env, "android/graphics/Rect");
526 gRect_leftFieldID = getFieldIDCheck(env, gRect_class, "left", "I");
527 gRect_topFieldID = getFieldIDCheck(env, gRect_class, "top", "I");
528 gRect_rightFieldID = getFieldIDCheck(env, gRect_class, "right", "I");
529 gRect_bottomFieldID = getFieldIDCheck(env, gRect_class, "bottom", "I");
530
531 gRectF_class = make_globalref(env, "android/graphics/RectF");
532 gRectF_leftFieldID = getFieldIDCheck(env, gRectF_class, "left", "F");
533 gRectF_topFieldID = getFieldIDCheck(env, gRectF_class, "top", "F");
534 gRectF_rightFieldID = getFieldIDCheck(env, gRectF_class, "right", "F");
535 gRectF_bottomFieldID = getFieldIDCheck(env, gRectF_class, "bottom", "F");
536
537 gPoint_class = make_globalref(env, "android/graphics/Point");
538 gPoint_xFieldID = getFieldIDCheck(env, gPoint_class, "x", "I");
539 gPoint_yFieldID = getFieldIDCheck(env, gPoint_class, "y", "I");
540
541 gPointF_class = make_globalref(env, "android/graphics/PointF");
542 gPointF_xFieldID = getFieldIDCheck(env, gPointF_class, "x", "F");
543 gPointF_yFieldID = getFieldIDCheck(env, gPointF_class, "y", "F");
544
545 gBitmap_class = make_globalref(env, "android/graphics/Bitmap");
546 gBitmap_nativeInstanceID = getFieldIDCheck(env, gBitmap_class, "mNativeBitmap", "I");
547 gBitmap_constructorMethodID = env->GetMethodID(gBitmap_class, "<init>",
Dianne Hackbornde0dfb72009-09-23 14:09:34 -0700548 "(IZ[BI)V");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549
550 gBitmapConfig_class = make_globalref(env, "android/graphics/Bitmap$Config");
551 gBitmapConfig_nativeInstanceID = getFieldIDCheck(env, gBitmapConfig_class,
552 "nativeInt", "I");
553
554 gCanvas_class = make_globalref(env, "android/graphics/Canvas");
555 gCanvas_nativeInstanceID = getFieldIDCheck(env, gCanvas_class, "mNativeCanvas", "I");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556
557 gPaint_class = make_globalref(env, "android/graphics/Paint");
558 gPaint_nativeInstanceID = getFieldIDCheck(env, gPaint_class, "mNativePaint", "I");
559
560 gPicture_class = make_globalref(env, "android/graphics/Picture");
561 gPicture_nativeInstanceID = getFieldIDCheck(env, gPicture_class, "mNativePicture", "I");
562
563 gRegion_class = make_globalref(env, "android/graphics/Region");
564 gRegion_nativeInstanceID = getFieldIDCheck(env, gRegion_class, "mNativeRegion", "I");
565 gRegion_constructorMethodID = env->GetMethodID(gRegion_class, "<init>",
566 "(II)V");
567
568 // Get the VMRuntime class.
569 c = env->FindClass("dalvik/system/VMRuntime");
570 SkASSERT(c);
571 // Look up VMRuntime.getRuntime().
572 m = env->GetStaticMethodID(c, "getRuntime", "()Ldalvik/system/VMRuntime;");
573 SkASSERT(m);
574 // Call VMRuntime.getRuntime() and hold onto its result.
575 gVMRuntime_singleton = env->CallStaticObjectMethod(c, m);
576 SkASSERT(gVMRuntime_singleton);
577 gVMRuntime_singleton = (jobject)env->NewGlobalRef(gVMRuntime_singleton);
578 // Look up the VMRuntime methods we'll be using.
579 gVMRuntime_trackExternalAllocationMethodID =
580 env->GetMethodID(c, "trackExternalAllocation", "(J)Z");
581 gVMRuntime_trackExternalFreeMethodID =
582 env->GetMethodID(c, "trackExternalFree", "(J)V");
583
584 NIOBuffer::RegisterJNI(env);
585
586 return 0;
587}
588