GraphicsJNI.h revision e4ac2d6b5723c95e648c489b187ddde449452c13
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 jbyteArray getStorageObj() { return fStorageObj; }; 140 141private: 142 JavaVM* fVM; 143 bool fAllocateInJavaHeap; 144 jbyteArray fStorageObj; 145}; 146 147class JavaMemoryUsageReporter : public SkVMMemoryReporter { 148public: 149 JavaMemoryUsageReporter(JNIEnv* env); 150 virtual ~JavaMemoryUsageReporter(); 151 // overrides 152 virtual bool reportMemory(size_t memorySize); 153 154private: 155 JavaVM* fVM; 156 size_t fTotalSize; 157}; 158 159enum JNIAccess { 160 kRO_JNIAccess, 161 kRW_JNIAccess 162}; 163 164class AutoJavaFloatArray { 165public: 166 AutoJavaFloatArray(JNIEnv* env, jfloatArray array, 167 int minLength = 0, JNIAccess = kRW_JNIAccess); 168 ~AutoJavaFloatArray(); 169 170 float* ptr() const { return fPtr; } 171 int length() const { return fLen; } 172 173private: 174 JNIEnv* fEnv; 175 jfloatArray fArray; 176 float* fPtr; 177 int fLen; 178 int fReleaseMode; 179}; 180 181class AutoJavaIntArray { 182public: 183 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0); 184 ~AutoJavaIntArray(); 185 186 jint* ptr() const { return fPtr; } 187 int length() const { return fLen; } 188 189private: 190 JNIEnv* fEnv; 191 jintArray fArray; 192 jint* fPtr; 193 int fLen; 194}; 195 196class AutoJavaShortArray { 197public: 198 AutoJavaShortArray(JNIEnv* env, jshortArray array, 199 int minLength = 0, JNIAccess = kRW_JNIAccess); 200 ~AutoJavaShortArray(); 201 202 jshort* ptr() const { return fPtr; } 203 int length() const { return fLen; } 204 205private: 206 JNIEnv* fEnv; 207 jshortArray fArray; 208 jshort* fPtr; 209 int fLen; 210 int fReleaseMode; 211}; 212 213class AutoJavaByteArray { 214public: 215 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0); 216 ~AutoJavaByteArray(); 217 218 jbyte* ptr() const { return fPtr; } 219 int length() const { return fLen; } 220 221private: 222 JNIEnv* fEnv; 223 jbyteArray fArray; 224 jbyte* fPtr; 225 int fLen; 226}; 227 228void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL); 229void doThrowNPE(JNIEnv* env); 230void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception 231void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument 232void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime 233void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State 234void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory 235void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception 236 237#define NPE_CHECK_RETURN_ZERO(env, object) \ 238 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0) 239 240#define NPE_CHECK_RETURN_VOID(env, object) \ 241 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0) 242 243#endif 244