GraphicsJNI.h revision a771b9861d11671c780092d35c0062eeefcf37c0
1#ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 2#define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 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 "SkImageDecoder.h" 11#include <jni.h> 12 13class SkBitmapRegionDecoder; 14class SkCanvas; 15 16namespace android { 17class Paint; 18struct TypefaceImpl; 19} 20 21class GraphicsJNI { 22public: 23 enum BitmapCreateFlags { 24 kBitmapCreateFlag_None = 0x0, 25 kBitmapCreateFlag_Mutable = 0x1, 26 kBitmapCreateFlag_Premultiplied = 0x2, 27 }; 28 29 // returns true if an exception is set (and dumps it out to the Log) 30 static bool hasException(JNIEnv*); 31 32 static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B); 33 static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B); 34 35 static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*); 36 static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect); 37 38 static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*); 39 static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*); 40 static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf); 41 42 static void set_jpoint(JNIEnv*, jobject jrect, int x, int y); 43 44 static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point); 45 static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint); 46 47 static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point); 48 static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf); 49 50 static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas); 51 static SkBitmap* getSkBitmapDeprecated(JNIEnv*, jobject bitmap); 52 static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap); 53 static SkPixelRef* getSkPixelRef(JNIEnv*, jobject bitmap); 54 static SkRegion* getNativeRegion(JNIEnv*, jobject region); 55 56 // Given the 'native' long held by the Rasterizer.java object, return a 57 // ref to its SkRasterizer* (or NULL). 58 static SkRasterizer* refNativeRasterizer(jlong rasterizerHandle); 59 60 /* 61 * LegacyBitmapConfig is the old enum in Skia that matched the enum int values 62 * in Bitmap.Config. Skia no longer supports this config, but has replaced it 63 * with SkColorType. These routines convert between the two. 64 */ 65 static SkColorType legacyBitmapConfigToColorType(jint legacyConfig); 66 static jint colorTypeToLegacyBitmapConfig(SkColorType colorType); 67 68 /** Return the corresponding native colorType from the java Config enum, 69 or kUnknown_SkColorType if the java object is null. 70 */ 71 static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig); 72 73 /** Create a java Bitmap object given the native bitmap (required) and optional 74 storage array (may be null). 75 bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. 76 */ 77 static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, 78 int bitmapCreateFlags, jbyteArray ninePatch, jobject ninePatchInsets, int density = -1); 79 80 static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags, 81 jbyteArray ninePatch, int density = -1) { 82 return createBitmap(env, bitmap, NULL, bitmapCreateFlags, ninePatch, NULL, density); 83 } 84 85 /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in 86 sync with isPremultiplied 87 */ 88 static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, 89 bool isPremultiplied); 90 91 static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap); 92 93 static jobject createRegion(JNIEnv* env, SkRegion* region); 94 95 static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap); 96 97 static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, 98 SkColorTable* ctable); 99 100 /** 101 * Given a bitmap we natively allocate a memory block to store the contents 102 * of that bitmap. The memory is then attached to the bitmap via an 103 * SkPixelRef, which ensures that upon deletion the appropriate caches 104 * are notified. 105 */ 106 static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable); 107 108 /** Copy the colors in colors[] to the bitmap, convert to the correct 109 format along the way. 110 Whether to use premultiplied pixels is determined by dstBitmap's alphaType. 111 */ 112 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset, 113 int srcStride, int x, int y, int width, int height, 114 const SkBitmap& dstBitmap); 115 116 static jbyteArray getBitmapStorageObj(SkPixelRef *pixref); 117}; 118 119class AndroidPixelRef : public SkMallocPixelRef { 120public: 121 AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, 122 jbyteArray storageObj, SkColorTable* ctable); 123 124 /** 125 * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share 126 * the same storage and java byte array refcounting, yet have a different 127 * color table. 128 */ 129 AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, 130 size_t rowBytes, SkColorTable* ctable); 131 132 virtual ~AndroidPixelRef(); 133 134private: 135 AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this 136 137 JavaVM* fVM; 138 jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store 139}; 140 141/** Allocator which allocates the backing buffer in the Java heap. 142 * Instances can only be used to perform a single allocation, which helps 143 * ensure that the allocated buffer is properly accounted for with a 144 * reference in the heap (or a JNI global reference). 145 */ 146class JavaPixelAllocator : public SkBitmap::Allocator { 147public: 148 JavaPixelAllocator(JNIEnv* env); 149 // overrides 150 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); 151 152 /** Return the Java array object created for the last allocation. 153 * This returns a local JNI reference which the caller is responsible 154 * for storing appropriately (usually by passing it to the Bitmap 155 * constructor). 156 */ 157 jbyteArray getStorageObj() { return fStorageObj; } 158 159 /** Same as getStorageObj(), but also resets the allocator so that it 160 * can allocate again. 161 */ 162 jbyteArray getStorageObjAndReset() { 163 jbyteArray result = fStorageObj; 164 fStorageObj = NULL; 165 fAllocCount = 0; 166 return result; 167 }; 168 169private: 170 JavaVM* fVM; 171 jbyteArray fStorageObj; 172 int fAllocCount; 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 doThrowNPE(JNIEnv* env); 245void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception 246void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument 247void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime 248void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State 249void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory 250void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception 251 252#define NPE_CHECK_RETURN_ZERO(env, object) \ 253 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0) 254 255#define NPE_CHECK_RETURN_VOID(env, object) \ 256 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0) 257 258#endif // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 259