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