GraphicsJNI.h revision e4ac2d6b5723c95e648c489b187ddde449452c13
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    jbyteArray getStorageObj() { return fStorageObj; };
140
141private:
142    JavaVM* fVM;
143    bool fAllocateInJavaHeap;
144    jbyteArray fStorageObj;
145};
146
147class JavaMemoryUsageReporter : public SkVMMemoryReporter {
148public:
149    JavaMemoryUsageReporter(JNIEnv* env);
150    virtual ~JavaMemoryUsageReporter();
151    // overrides
152    virtual bool reportMemory(size_t memorySize);
153
154private:
155    JavaVM* fVM;
156    size_t fTotalSize;
157};
158
159enum JNIAccess {
160    kRO_JNIAccess,
161    kRW_JNIAccess
162};
163
164class AutoJavaFloatArray {
165public:
166    AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
167                       int minLength = 0, JNIAccess = kRW_JNIAccess);
168    ~AutoJavaFloatArray();
169
170    float* ptr() const { return fPtr; }
171    int    length() const { return fLen; }
172
173private:
174    JNIEnv*     fEnv;
175    jfloatArray fArray;
176    float*      fPtr;
177    int         fLen;
178    int         fReleaseMode;
179};
180
181class AutoJavaIntArray {
182public:
183    AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
184    ~AutoJavaIntArray();
185
186    jint* ptr() const { return fPtr; }
187    int    length() const { return fLen; }
188
189private:
190    JNIEnv*     fEnv;
191    jintArray fArray;
192    jint*      fPtr;
193    int         fLen;
194};
195
196class AutoJavaShortArray {
197public:
198    AutoJavaShortArray(JNIEnv* env, jshortArray array,
199                       int minLength = 0, JNIAccess = kRW_JNIAccess);
200    ~AutoJavaShortArray();
201
202    jshort* ptr() const { return fPtr; }
203    int    length() const { return fLen; }
204
205private:
206    JNIEnv*     fEnv;
207    jshortArray fArray;
208    jshort*      fPtr;
209    int         fLen;
210    int         fReleaseMode;
211};
212
213class AutoJavaByteArray {
214public:
215    AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
216    ~AutoJavaByteArray();
217
218    jbyte* ptr() const { return fPtr; }
219    int    length() const { return fLen; }
220
221private:
222    JNIEnv*     fEnv;
223    jbyteArray fArray;
224    jbyte*      fPtr;
225    int         fLen;
226};
227
228void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL);
229void doThrowNPE(JNIEnv* env);
230void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
231void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
232void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
233void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
234void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
235void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception
236
237#define NPE_CHECK_RETURN_ZERO(env, object)    \
238    do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
239
240#define NPE_CHECK_RETURN_VOID(env, object)    \
241    do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
242
243#endif
244