GraphicsJNI.h revision c02977e3bbfaaedcb1b1d67e1692becc7dddd59b
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* getNativeBitmap(JNIEnv*, jobject bitmap); 52 static SkRegion* getNativeRegion(JNIEnv*, jobject region); 53 54 // Given the 'native' long held by the Rasterizer.java object, return a 55 // ref to its SkRasterizer* (or NULL). 56 static SkRasterizer* refNativeRasterizer(jlong rasterizerHandle); 57 58 /* 59 * LegacyBitmapConfig is the old enum in Skia that matched the enum int values 60 * in Bitmap.Config. Skia no longer supports this config, but has replaced it 61 * with SkColorType. These routines convert between the two. 62 */ 63 static SkColorType legacyBitmapConfigToColorType(jint legacyConfig); 64 static jint colorTypeToLegacyBitmapConfig(SkColorType colorType); 65 66 /** Return the corresponding native colorType from the java Config enum, 67 or kUnknown_SkColorType if the java object is null. 68 */ 69 static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig); 70 71 /** Create a java Bitmap object given the native bitmap (required) and optional 72 storage array (may be null). 73 bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. 74 */ 75 static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer, 76 int bitmapCreateFlags, jbyteArray ninePatch, jobject ninePatchInsets, int density = -1); 77 78 static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags, 79 jbyteArray ninePatch, int density = -1) { 80 return createBitmap(env, bitmap, NULL, bitmapCreateFlags, ninePatch, NULL, density); 81 } 82 83 /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in 84 sync with isPremultiplied 85 */ 86 static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap, 87 bool isPremultiplied); 88 89 static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap); 90 91 static jobject createRegion(JNIEnv* env, SkRegion* region); 92 93 static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap); 94 95 static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, 96 SkColorTable* ctable); 97 98 /** 99 * Given a bitmap we natively allocate a memory block to store the contents 100 * of that bitmap. The memory is then attached to the bitmap via an 101 * SkPixelRef, which ensures that upon deletion the appropriate caches 102 * are notified. 103 */ 104 static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable); 105 106 /** Copy the colors in colors[] to the bitmap, convert to the correct 107 format along the way. 108 Whether to use premultiplied pixels is determined by dstBitmap's alphaType. 109 */ 110 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset, 111 int srcStride, int x, int y, int width, int height, 112 const SkBitmap& dstBitmap); 113 114 static jbyteArray getBitmapStorageObj(SkPixelRef *pixref); 115}; 116 117class AndroidPixelRef : public SkMallocPixelRef { 118public: 119 AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes, 120 jbyteArray storageObj, SkColorTable* ctable); 121 122 /** 123 * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share 124 * the same storage and java byte array refcounting, yet have a different 125 * color table. 126 */ 127 AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info, 128 size_t rowBytes, SkColorTable* ctable); 129 130 virtual ~AndroidPixelRef(); 131 132private: 133 AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this 134 135 JavaVM* fVM; 136 jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store 137}; 138 139/** Allocator which allocates the backing buffer in the Java heap. 140 * Instances can only be used to perform a single allocation, which helps 141 * ensure that the allocated buffer is properly accounted for with a 142 * reference in the heap (or a JNI global reference). 143 */ 144class JavaPixelAllocator : public SkBitmap::Allocator { 145public: 146 JavaPixelAllocator(JNIEnv* env); 147 // overrides 148 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); 149 150 /** Return the Java array object created for the last allocation. 151 * This returns a local JNI reference which the caller is responsible 152 * for storing appropriately (usually by passing it to the Bitmap 153 * constructor). 154 */ 155 jbyteArray getStorageObj() { return fStorageObj; } 156 157 /** Same as getStorageObj(), but also resets the allocator so that it 158 * can allocate again. 159 */ 160 jbyteArray getStorageObjAndReset() { 161 jbyteArray result = fStorageObj; 162 fStorageObj = NULL; 163 fAllocCount = 0; 164 return result; 165 }; 166 167private: 168 JavaVM* fVM; 169 jbyteArray fStorageObj; 170 int fAllocCount; 171}; 172 173enum JNIAccess { 174 kRO_JNIAccess, 175 kRW_JNIAccess 176}; 177 178class AutoJavaFloatArray { 179public: 180 AutoJavaFloatArray(JNIEnv* env, jfloatArray array, 181 int minLength = 0, JNIAccess = kRW_JNIAccess); 182 ~AutoJavaFloatArray(); 183 184 float* ptr() const { return fPtr; } 185 int length() const { return fLen; } 186 187private: 188 JNIEnv* fEnv; 189 jfloatArray fArray; 190 float* fPtr; 191 int fLen; 192 int fReleaseMode; 193}; 194 195class AutoJavaIntArray { 196public: 197 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0); 198 ~AutoJavaIntArray(); 199 200 jint* ptr() const { return fPtr; } 201 int length() const { return fLen; } 202 203private: 204 JNIEnv* fEnv; 205 jintArray fArray; 206 jint* fPtr; 207 int fLen; 208}; 209 210class AutoJavaShortArray { 211public: 212 AutoJavaShortArray(JNIEnv* env, jshortArray array, 213 int minLength = 0, JNIAccess = kRW_JNIAccess); 214 ~AutoJavaShortArray(); 215 216 jshort* ptr() const { return fPtr; } 217 int length() const { return fLen; } 218 219private: 220 JNIEnv* fEnv; 221 jshortArray fArray; 222 jshort* fPtr; 223 int fLen; 224 int fReleaseMode; 225}; 226 227class AutoJavaByteArray { 228public: 229 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0); 230 ~AutoJavaByteArray(); 231 232 jbyte* ptr() const { return fPtr; } 233 int length() const { return fLen; } 234 235private: 236 JNIEnv* fEnv; 237 jbyteArray fArray; 238 jbyte* fPtr; 239 int fLen; 240}; 241 242void doThrowNPE(JNIEnv* env); 243void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception 244void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument 245void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime 246void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State 247void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory 248void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception 249 250#define NPE_CHECK_RETURN_ZERO(env, object) \ 251 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0) 252 253#define NPE_CHECK_RETURN_VOID(env, object) \ 254 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0) 255 256#endif // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 257