GraphicsJNI.h revision afde46ed008f150e45e1b0d7e1dc588fc047b74f
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 virtual void globalRef(); 96 virtual void globalUnref(); 97 98private: 99 JavaVM* fVM; 100 bool fOnJavaHeap; // If true, the memory was allocated on the Java heap 101 102 jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store 103 bool fHasGlobalRef; // If true, fStorageObj holds a JNI global ref 104 105 mutable int32_t fGlobalRefCnt; 106}; 107 108/** A helper class for accessing Java-heap-allocated bitmaps. 109 * This should be used when calling into a JNI method that retains a 110 * reference to the bitmap longer than the lifetime of the Java Bitmap. 111 * 112 * After creating an instance of this class, a call to 113 * AndroidPixelRef::globalRef() will allocate a JNI global reference 114 * to the backing buffer object. 115 */ 116class JavaHeapBitmapRef { 117public: 118 119 JavaHeapBitmapRef(JNIEnv *env, SkBitmap* nativeBitmap, jbyteArray buffer); 120 ~JavaHeapBitmapRef(); 121 122private: 123 JNIEnv* fEnv; 124 SkBitmap* fNativeBitmap; 125 jbyteArray fBuffer; 126}; 127 128/** Allocator which allocates the backing buffer in the Java heap. 129 * Instances can only be used to perform a single allocation, which helps 130 * ensure that the allocated buffer is properly accounted for with a 131 * reference in the heap (or a JNI global reference). 132 */ 133class JavaPixelAllocator : public SkBitmap::Allocator { 134public: 135 JavaPixelAllocator(JNIEnv* env, bool allocateInJavaHeap=true); 136 // overrides 137 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); 138 139 /** Return the Java array object created for the last allocation. 140 * This returns a local JNI reference which the caller is responsible 141 * for storing appropriately (usually by passing it to the Bitmap 142 * constructor). 143 */ 144 jbyteArray getStorageObj() { return fStorageObj; } 145 146 /** Same as getStorageObj(), but also resets the allocator so that it 147 * can allocate again. 148 */ 149 jbyteArray getStorageObjAndReset() { 150 jbyteArray result = fStorageObj; 151 fStorageObj = NULL; 152 fAllocCount = 0; 153 return result; 154 }; 155 156private: 157 JavaVM* fVM; 158 bool fAllocateInJavaHeap; 159 jbyteArray fStorageObj; 160 int fAllocCount; 161}; 162 163class JavaMemoryUsageReporter : public SkVMMemoryReporter { 164public: 165 JavaMemoryUsageReporter(JNIEnv* env); 166 virtual ~JavaMemoryUsageReporter(); 167 // overrides 168 virtual bool reportMemory(size_t memorySize); 169 170private: 171 JavaVM* fVM; 172 size_t fTotalSize; 173}; 174 175enum JNIAccess { 176 kRO_JNIAccess, 177 kRW_JNIAccess 178}; 179 180class AutoJavaFloatArray { 181public: 182 AutoJavaFloatArray(JNIEnv* env, jfloatArray array, 183 int minLength = 0, JNIAccess = kRW_JNIAccess); 184 ~AutoJavaFloatArray(); 185 186 float* ptr() const { return fPtr; } 187 int length() const { return fLen; } 188 189private: 190 JNIEnv* fEnv; 191 jfloatArray fArray; 192 float* fPtr; 193 int fLen; 194 int fReleaseMode; 195}; 196 197class AutoJavaIntArray { 198public: 199 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0); 200 ~AutoJavaIntArray(); 201 202 jint* ptr() const { return fPtr; } 203 int length() const { return fLen; } 204 205private: 206 JNIEnv* fEnv; 207 jintArray fArray; 208 jint* fPtr; 209 int fLen; 210}; 211 212class AutoJavaShortArray { 213public: 214 AutoJavaShortArray(JNIEnv* env, jshortArray array, 215 int minLength = 0, JNIAccess = kRW_JNIAccess); 216 ~AutoJavaShortArray(); 217 218 jshort* ptr() const { return fPtr; } 219 int length() const { return fLen; } 220 221private: 222 JNIEnv* fEnv; 223 jshortArray fArray; 224 jshort* fPtr; 225 int fLen; 226 int fReleaseMode; 227}; 228 229class AutoJavaByteArray { 230public: 231 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0); 232 ~AutoJavaByteArray(); 233 234 jbyte* ptr() const { return fPtr; } 235 int length() const { return fLen; } 236 237private: 238 JNIEnv* fEnv; 239 jbyteArray fArray; 240 jbyte* fPtr; 241 int fLen; 242}; 243 244void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL); 245void doThrowNPE(JNIEnv* env); 246void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception 247void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument 248void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime 249void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State 250void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory 251void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception 252 253#define NPE_CHECK_RETURN_ZERO(env, object) \ 254 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0) 255 256#define NPE_CHECK_RETURN_VOID(env, object) \ 257 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0) 258 259#endif 260