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