GraphicsJNI.h revision afde46ed008f150e45e1b0d7e1dc588fc047b74f
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    /** Return the Java array object created for the last allocation.
140     *  This returns a local JNI reference which the caller is responsible
141     *  for storing appropriately (usually by passing it to the Bitmap
142     *  constructor).
143     */
144    jbyteArray getStorageObj() { return fStorageObj; }
145
146    /** Same as getStorageObj(), but also resets the allocator so that it
147     *  can allocate again.
148     */
149    jbyteArray getStorageObjAndReset() {
150        jbyteArray result = fStorageObj;
151        fStorageObj = NULL;
152        fAllocCount = 0;
153        return result;
154    };
155
156private:
157    JavaVM* fVM;
158    bool fAllocateInJavaHeap;
159    jbyteArray fStorageObj;
160    int fAllocCount;
161};
162
163class JavaMemoryUsageReporter : public SkVMMemoryReporter {
164public:
165    JavaMemoryUsageReporter(JNIEnv* env);
166    virtual ~JavaMemoryUsageReporter();
167    // overrides
168    virtual bool reportMemory(size_t memorySize);
169
170private:
171    JavaVM* fVM;
172    size_t fTotalSize;
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 doThrow(JNIEnv* env, const char* exc, const char* msg = NULL);
245void doThrowNPE(JNIEnv* env);
246void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
247void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
248void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
249void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
250void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
251void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception
252
253#define NPE_CHECK_RETURN_ZERO(env, object)    \
254    do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
255
256#define NPE_CHECK_RETURN_VOID(env, object)    \
257    do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
258
259#endif
260