1 #ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 2 #define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 3 4 #include "Bitmap.h" 5 #include "SkBitmap.h" 6 #include "SkDevice.h" 7 #include "SkPixelRef.h" 8 #include "SkMallocPixelRef.h" 9 #include "SkPoint.h" 10 #include "SkRect.h" 11 #include "SkImageDecoder.h" 12 #include <Canvas.h> 13 #include <jni.h> 14 15 class SkBitmapRegionDecoder; 16 class SkCanvas; 17 18 namespace android { 19 class Paint; 20 struct TypefaceImpl; 21 } 22 23 class GraphicsJNI { 24 public: 25 enum BitmapCreateFlags { 26 kBitmapCreateFlag_None = 0x0, 27 kBitmapCreateFlag_Mutable = 0x1, 28 kBitmapCreateFlag_Premultiplied = 0x2, 29 }; 30 31 // returns true if an exception is set (and dumps it out to the Log) 32 static bool hasException(JNIEnv*); 33 34 static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B); 35 static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B); 36 37 static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*); 38 static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect); 39 40 static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*); 41 static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*); 42 static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf); 43 44 static void set_jpoint(JNIEnv*, jobject jrect, int x, int y); 45 46 static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point); 47 static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint); 48 49 static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point); 50 static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf); 51 52 static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas); 53 static android::Bitmap* getBitmap(JNIEnv*, jobject bitmap); 54 static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap); 55 static SkPixelRef* refSkPixelRef(JNIEnv*, jobject bitmap); 56 static SkRegion* getNativeRegion(JNIEnv*, jobject region); 57 58 // Given the 'native' long held by the Rasterizer.java object, return a 59 // ref to its SkRasterizer* (or NULL). 60 static SkRasterizer* refNativeRasterizer(jlong rasterizerHandle); 61 62 /* 63 * LegacyBitmapConfig is the old enum in Skia that matched the enum int values 64 * in Bitmap.Config. Skia no longer supports this config, but has replaced it 65 * with SkColorType. These routines convert between the two. 66 */ 67 static SkColorType legacyBitmapConfigToColorType(jint legacyConfig); 68 static jint colorTypeToLegacyBitmapConfig(SkColorType colorType); 69 70 /** Return the corresponding native colorType from the java Config enum, 71 or kUnknown_SkColorType if the java object is null. 72 */ 73 static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig); 74 75 /* 76 * Create a java Bitmap object given the native bitmap 77 * bitmap's SkAlphaType must already be in sync with bitmapCreateFlags. 78 */ 79 static jobject createBitmap(JNIEnv* env, android::Bitmap* bitmap, 80 int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL, 81 jobject ninePatchInsets = NULL, int density = -1); 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, const SkImageInfo& info, 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 android::Bitmap* allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap, 96 SkColorTable* ctable); 97 98 static android::Bitmap* allocateAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap, 99 SkColorTable* ctable); 100 101 static android::Bitmap* mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap, 102 SkColorTable* ctable, int fd, void* addr, bool readOnly); 103 104 /** 105 * Given a bitmap we natively allocate a memory block to store the contents 106 * of that bitmap. The memory is then attached to the bitmap via an 107 * SkPixelRef, which ensures that upon deletion the appropriate caches 108 * are notified. 109 */ 110 static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable); 111 112 /** Copy the colors in colors[] to the bitmap, convert to the correct 113 format along the way. 114 Whether to use premultiplied pixels is determined by dstBitmap's alphaType. 115 */ 116 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset, 117 int srcStride, int x, int y, int width, int height, 118 const SkBitmap& dstBitmap); 119 }; 120 121 /** Allocator which allocates the backing buffer in the Java heap. 122 * Instances can only be used to perform a single allocation, which helps 123 * ensure that the allocated buffer is properly accounted for with a 124 * reference in the heap (or a JNI global reference). 125 */ 126 class JavaPixelAllocator : public SkBitmap::Allocator { 127 public: 128 JavaPixelAllocator(JNIEnv* env); 129 ~JavaPixelAllocator(); 130 131 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override; 132 133 /** 134 * Fetches the backing allocation object. Must be called! 135 */ getStorageObjAndReset()136 android::Bitmap* getStorageObjAndReset() { 137 android::Bitmap* result = mStorage; 138 mStorage = NULL; 139 return result; 140 }; 141 142 private: 143 JavaVM* mJavaVM; 144 android::Bitmap* mStorage = nullptr; 145 }; 146 147 class AshmemPixelAllocator : public SkBitmap::Allocator { 148 public: 149 AshmemPixelAllocator(JNIEnv* env); 150 ~AshmemPixelAllocator(); 151 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable); getStorageObjAndReset()152 android::Bitmap* getStorageObjAndReset() { 153 android::Bitmap* result = mStorage; 154 mStorage = NULL; 155 return result; 156 }; 157 158 private: 159 JavaVM* mJavaVM; 160 android::Bitmap* mStorage = nullptr; 161 }; 162 163 164 enum JNIAccess { 165 kRO_JNIAccess, 166 kRW_JNIAccess 167 }; 168 169 class AutoJavaFloatArray { 170 public: 171 AutoJavaFloatArray(JNIEnv* env, jfloatArray array, 172 int minLength = 0, JNIAccess = kRW_JNIAccess); 173 ~AutoJavaFloatArray(); 174 ptr()175 float* ptr() const { return fPtr; } length()176 int length() const { return fLen; } 177 178 private: 179 JNIEnv* fEnv; 180 jfloatArray fArray; 181 float* fPtr; 182 int fLen; 183 int fReleaseMode; 184 }; 185 186 class AutoJavaIntArray { 187 public: 188 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0); 189 ~AutoJavaIntArray(); 190 ptr()191 jint* ptr() const { return fPtr; } length()192 int length() const { return fLen; } 193 194 private: 195 JNIEnv* fEnv; 196 jintArray fArray; 197 jint* fPtr; 198 int fLen; 199 }; 200 201 class AutoJavaShortArray { 202 public: 203 AutoJavaShortArray(JNIEnv* env, jshortArray array, 204 int minLength = 0, JNIAccess = kRW_JNIAccess); 205 ~AutoJavaShortArray(); 206 ptr()207 jshort* ptr() const { return fPtr; } length()208 int length() const { return fLen; } 209 210 private: 211 JNIEnv* fEnv; 212 jshortArray fArray; 213 jshort* fPtr; 214 int fLen; 215 int fReleaseMode; 216 }; 217 218 class AutoJavaByteArray { 219 public: 220 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0); 221 ~AutoJavaByteArray(); 222 ptr()223 jbyte* ptr() const { return fPtr; } length()224 int length() const { return fLen; } 225 226 private: 227 JNIEnv* fEnv; 228 jbyteArray fArray; 229 jbyte* fPtr; 230 int fLen; 231 }; 232 233 void doThrowNPE(JNIEnv* env); 234 void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception 235 void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument 236 void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime 237 void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State 238 void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory 239 void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception 240 241 #define NPE_CHECK_RETURN_ZERO(env, object) \ 242 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0) 243 244 #define NPE_CHECK_RETURN_VOID(env, object) \ 245 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0) 246 247 #endif // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_ 248