GraphicsJNI.h revision a2f0e2d6b7f9dff3a52dd78d6db307070a71e9b2
1#ifndef GraphicsJNI_DEFINED 2#define GraphicsJNI_DEFINED 3 4#include "SkBitmap.h" 5#include "SkDevice.h" 6#include "SkPixelRef.h" 7#include "SkMallocPixelRef.h" 8#include "SkPoint.h" 9#include "SkRect.h" 10#include "../images/SkBitmapRegionDecoder.h" 11#include "../images/SkImageDecoder.h" 12#include <jni.h> 13 14class SkCanvas; 15class SkPaint; 16class SkPicture; 17 18class GraphicsJNI { 19public: 20 // returns true if an exception is set (and dumps it out to the Log) 21 static bool hasException(JNIEnv*); 22 23 static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B); 24 static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B); 25 26 static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*); 27 static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect); 28 29 static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*); 30 static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*); 31 static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf); 32 33 static void set_jpoint(JNIEnv*, jobject jrect, int x, int y); 34 35 static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point); 36 static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint); 37 38 static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point); 39 static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf); 40 41 static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas); 42 static SkPaint* getNativePaint(JNIEnv*, jobject paint); 43 static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap); 44 static SkPicture* getNativePicture(JNIEnv*, jobject picture); 45 static SkRegion* getNativeRegion(JNIEnv*, jobject region); 46 47 /** Return the corresponding native config from the java Config enum, 48 or kNo_Config if the java object is null. 49 */ 50 static SkBitmap::Config getNativeBitmapConfig(JNIEnv*, jobject jconfig); 51 52 /** Create a java Bitmap object given the native bitmap (required) and optional 53 storage array (may be null). 54 */ 55 static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, 56 bool isMutable, jbyteArray ninepatch, int density = -1); 57 58 static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, bool isMutable, 59 jbyteArray ninepatch, int density = -1); 60 61 static jobject createRegion(JNIEnv* env, SkRegion* region); 62 63 static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap); 64 65 static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, 66 SkColorTable* ctable); 67 68 /** Set a pixelref for the bitmap (needs setConfig to already be called) 69 Returns true on success. If it returns false, then it failed, and the 70 appropriate exception will have been raised. 71 */ 72 static bool mallocPixelRef(JNIEnv*, SkBitmap*, SkColorTable* ctable); 73 74 /** Copy the colors in colors[] to the bitmap, convert to the correct 75 format along the way. 76 */ 77 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset, 78 int srcStride, int x, int y, int width, int height, 79 const SkBitmap& dstBitmap); 80 81 static jbyteArray getBitmapStorageObj(SkPixelRef *pixref); 82}; 83 84class AndroidPixelRef : public SkMallocPixelRef { 85public: 86 AndroidPixelRef(JNIEnv* env, void* storage, size_t size, jbyteArray storageObj, 87 SkColorTable* ctable); 88 89 virtual ~AndroidPixelRef(); 90 91 jbyteArray getStorageObj() { return fStorageObj; } 92 93 void setLocalJNIRef(jbyteArray arr); 94 95 /** Used to hold a ref to the pixels when the Java bitmap may be collected. 96 * If specified, 'localref' is a valid JNI local reference to the byte array 97 * containing the pixel data. 98 * 99 * 'localref' may only be NULL if setLocalJNIRef() was already called with 100 * a JNI local ref that is still valid. 101 */ 102 virtual void globalRef(void* localref=NULL); 103 104 /** Release a ref that was acquired using globalRef(). */ 105 virtual void globalUnref(); 106 107private: 108 JavaVM* fVM; 109 bool fOnJavaHeap; // If true, the memory was allocated on the Java heap 110 111 jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store 112 bool fHasGlobalRef; // If true, fStorageObj holds a JNI global ref 113 114 mutable int32_t fGlobalRefCnt; 115}; 116 117/** A helper class for accessing Java-heap-allocated bitmaps. 118 * This should be used when calling into a JNI method that retains a 119 * reference to the bitmap longer than the lifetime of the Java Bitmap. 120 * 121 * After creating an instance of this class, a call to 122 * AndroidPixelRef::globalRef() will allocate a JNI global reference 123 * to the backing buffer object. 124 */ 125class JavaHeapBitmapRef { 126public: 127 128 JavaHeapBitmapRef(JNIEnv *env, SkBitmap* nativeBitmap, jbyteArray buffer); 129 ~JavaHeapBitmapRef(); 130 131private: 132 JNIEnv* fEnv; 133 SkBitmap* fNativeBitmap; 134 jbyteArray fBuffer; 135}; 136 137/** Allocator which allocates the backing buffer in the Java heap. 138 * Instances can only be used to perform a single allocation, which helps 139 * ensure that the allocated buffer is properly accounted for with a 140 * reference in the heap (or a JNI global reference). 141 */ 142class JavaPixelAllocator : public SkBitmap::Allocator { 143public: 144 JavaPixelAllocator(JNIEnv* env, bool allocateInJavaHeap=true); 145 // overrides 146 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); 147 148 /** Return the Java array object created for the last allocation. 149 * This returns a local JNI reference which the caller is responsible 150 * for storing appropriately (usually by passing it to the Bitmap 151 * constructor). 152 */ 153 jbyteArray getStorageObj() { return fStorageObj; } 154 155 /** Same as getStorageObj(), but also resets the allocator so that it 156 * can allocate again. 157 */ 158 jbyteArray getStorageObjAndReset() { 159 jbyteArray result = fStorageObj; 160 fStorageObj = NULL; 161 fAllocCount = 0; 162 return result; 163 }; 164 165private: 166 JavaVM* fVM; 167 bool fAllocateInJavaHeap; 168 jbyteArray fStorageObj; 169 int fAllocCount; 170}; 171 172class JavaMemoryUsageReporter : public SkVMMemoryReporter { 173public: 174 JavaMemoryUsageReporter(JNIEnv* env); 175 virtual ~JavaMemoryUsageReporter(); 176 // overrides 177 virtual bool reportMemory(size_t memorySize); 178 179private: 180 JavaVM* fVM; 181 size_t fTotalSize; 182}; 183 184enum JNIAccess { 185 kRO_JNIAccess, 186 kRW_JNIAccess 187}; 188 189class AutoJavaFloatArray { 190public: 191 AutoJavaFloatArray(JNIEnv* env, jfloatArray array, 192 int minLength = 0, JNIAccess = kRW_JNIAccess); 193 ~AutoJavaFloatArray(); 194 195 float* ptr() const { return fPtr; } 196 int length() const { return fLen; } 197 198private: 199 JNIEnv* fEnv; 200 jfloatArray fArray; 201 float* fPtr; 202 int fLen; 203 int fReleaseMode; 204}; 205 206class AutoJavaIntArray { 207public: 208 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0); 209 ~AutoJavaIntArray(); 210 211 jint* ptr() const { return fPtr; } 212 int length() const { return fLen; } 213 214private: 215 JNIEnv* fEnv; 216 jintArray fArray; 217 jint* fPtr; 218 int fLen; 219}; 220 221class AutoJavaShortArray { 222public: 223 AutoJavaShortArray(JNIEnv* env, jshortArray array, 224 int minLength = 0, JNIAccess = kRW_JNIAccess); 225 ~AutoJavaShortArray(); 226 227 jshort* ptr() const { return fPtr; } 228 int length() const { return fLen; } 229 230private: 231 JNIEnv* fEnv; 232 jshortArray fArray; 233 jshort* fPtr; 234 int fLen; 235 int fReleaseMode; 236}; 237 238class AutoJavaByteArray { 239public: 240 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0); 241 ~AutoJavaByteArray(); 242 243 jbyte* ptr() const { return fPtr; } 244 int length() const { return fLen; } 245 246private: 247 JNIEnv* fEnv; 248 jbyteArray fArray; 249 jbyte* fPtr; 250 int fLen; 251}; 252 253void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL); 254void doThrowNPE(JNIEnv* env); 255void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception 256void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument 257void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime 258void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State 259void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory 260void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception 261 262#define NPE_CHECK_RETURN_ZERO(env, object) \ 263 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0) 264 265#define NPE_CHECK_RETURN_VOID(env, object) \ 266 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0) 267 268#endif 269