blob: 5ec41ca1572c1f4ee149620a849469cecef7e707 [file] [log] [blame]
Andreas Gampeed6b9df2014-11-20 22:02:20 -08001#ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
2#define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003
John Reckf29ed282015-04-07 07:32:03 -07004#include "Bitmap.h"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -08005#include "SkBitmap.h"
Matt Sarett1f979632015-10-27 10:33:20 -04006#include "SkBRDAllocator.h"
7#include "SkCodec.h"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -08008#include "SkDevice.h"
9#include "SkPixelRef.h"
10#include "SkMallocPixelRef.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011#include "SkPoint.h"
12#include "SkRect.h"
Derek Sollenberger5827cb52013-07-26 14:58:06 -040013#include "SkImageDecoder.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014#include <jni.h>
sergeyvdccca442016-03-21 15:38:21 -070015#include <hwui/Canvas.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080016
Matt Sarett1f979632015-10-27 10:33:20 -040017class SkBitmapRegionDecoder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018class SkCanvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019
Raph Levien3d528c402014-06-26 09:04:54 -070020namespace android {
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040021class Paint;
sergeyvbad99182016-03-17 11:24:22 -070022struct Typeface;
Raph Levien3d528c402014-06-26 09:04:54 -070023}
24
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025class GraphicsJNI {
26public:
Chris Craik1abf5d62013-08-16 12:47:03 -070027 enum BitmapCreateFlags {
28 kBitmapCreateFlag_None = 0x0,
29 kBitmapCreateFlag_Mutable = 0x1,
30 kBitmapCreateFlag_Premultiplied = 0x2,
31 };
32
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033 // returns true if an exception is set (and dumps it out to the Log)
34 static bool hasException(JNIEnv*);
35
36 static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
37 static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
38
39 static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
40 static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
41
42 static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
43 static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
44 static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
Elliott Hughes8451b252011-04-07 19:17:57 -070045
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046 static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
Elliott Hughes8451b252011-04-07 19:17:57 -070047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048 static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
49 static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
Elliott Hughes8451b252011-04-07 19:17:57 -070050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
52 static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
Elliott Hughes8451b252011-04-07 19:17:57 -070053
John Reckc1b33d62015-04-22 09:04:45 -070054 static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
John Reckf29ed282015-04-07 07:32:03 -070055 static android::Bitmap* getBitmap(JNIEnv*, jobject bitmap);
John Recked207b92015-04-10 13:52:57 -070056 static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
John Reckae2e8b42015-05-06 14:55:05 -070057 static SkPixelRef* refSkPixelRef(JNIEnv*, jobject bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 static SkRegion* getNativeRegion(JNIEnv*, jobject region);
Elliott Hughes8451b252011-04-07 19:17:57 -070059
Mike Reed4c9355c2014-05-07 11:48:37 -040060 // Given the 'native' long held by the Rasterizer.java object, return a
61 // ref to its SkRasterizer* (or NULL).
62 static SkRasterizer* refNativeRasterizer(jlong rasterizerHandle);
63
Mike Reed1103b322014-07-08 12:36:44 -040064 /*
65 * LegacyBitmapConfig is the old enum in Skia that matched the enum int values
66 * in Bitmap.Config. Skia no longer supports this config, but has replaced it
67 * with SkColorType. These routines convert between the two.
68 */
69 static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
70 static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);
71
Mike Reed42a1d082014-07-07 18:06:18 -040072 /** Return the corresponding native colorType from the java Config enum,
73 or kUnknown_SkColorType if the java object is null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 */
Mike Reed42a1d082014-07-07 18:06:18 -040075 static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
Elliott Hughes8451b252011-04-07 19:17:57 -070076
John Reckf29ed282015-04-07 07:32:03 -070077 /*
78 * Create a java Bitmap object given the native bitmap
79 * bitmap's SkAlphaType must already be in sync with bitmapCreateFlags.
Patrick Dubroye4ac2d62010-12-01 11:23:13 -080080 */
John Reckf29ed282015-04-07 07:32:03 -070081 static jobject createBitmap(JNIEnv* env, android::Bitmap* bitmap,
82 int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL,
83 jobject ninePatchInsets = NULL, int density = -1);
Elliott Hughes8451b252011-04-07 19:17:57 -070084
Leon Scroggins III8790be62013-12-03 16:26:51 -050085 /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
86 sync with isPremultiplied
87 */
John Reckf29ed282015-04-07 07:32:03 -070088 static void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
Chris Craik1abf5d62013-08-16 12:47:03 -070089 bool isPremultiplied);
Chris Craik9f583612013-05-20 18:13:47 -070090
91 static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap);
92
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 static jobject createRegion(JNIEnv* env, SkRegion* region);
94
Matt Sarett1f979632015-10-27 10:33:20 -040095 static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
Joseph Wenf1f48bc2010-07-19 16:59:51 +080096
John Reckf29ed282015-04-07 07:32:03 -070097 static android::Bitmap* allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
Chris Craik1abf5d62013-08-16 12:47:03 -070098 SkColorTable* ctable);
Patrick Dubroye4ac2d62010-12-01 11:23:13 -080099
Riley Andrews39d7f302014-11-13 17:43:25 -0800100 static android::Bitmap* allocateAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
101 SkColorTable* ctable);
102
103 static android::Bitmap* mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
John Reckaa394dd2016-09-12 10:43:35 -0700104 SkColorTable* ctable, int fd, void* addr, size_t size, bool readOnly);
Riley Andrews39d7f302014-11-13 17:43:25 -0800105
Derek Sollenberger3d4eed72014-12-04 15:20:29 -0500106 /**
107 * Given a bitmap we natively allocate a memory block to store the contents
108 * of that bitmap. The memory is then attached to the bitmap via an
109 * SkPixelRef, which ensures that upon deletion the appropriate caches
110 * are notified.
111 */
112 static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable);
113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114 /** Copy the colors in colors[] to the bitmap, convert to the correct
115 format along the way.
Leon Scroggins III57ee6202014-06-04 18:51:07 -0400116 Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 */
118 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
Chris Craik1abf5d62013-08-16 12:47:03 -0700119 int srcStride, int x, int y, int width, int height,
Leon Scroggins III57ee6202014-06-04 18:51:07 -0400120 const SkBitmap& dstBitmap);
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800121};
122
123/** Allocator which allocates the backing buffer in the Java heap.
124 * Instances can only be used to perform a single allocation, which helps
125 * ensure that the allocated buffer is properly accounted for with a
126 * reference in the heap (or a JNI global reference).
127 */
Matt Sarett1f979632015-10-27 10:33:20 -0400128class JavaPixelAllocator : public SkBRDAllocator {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129public:
Chih-Hung Hsieha6543282016-08-29 14:46:35 -0700130 explicit JavaPixelAllocator(JNIEnv* env);
John Reckf29ed282015-04-07 07:32:03 -0700131 ~JavaPixelAllocator();
Elliott Hughes8451b252011-04-07 19:17:57 -0700132
John Reckf29ed282015-04-07 07:32:03 -0700133 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800134
John Reckf29ed282015-04-07 07:32:03 -0700135 /**
136 * Fetches the backing allocation object. Must be called!
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800137 */
John Reckf29ed282015-04-07 07:32:03 -0700138 android::Bitmap* getStorageObjAndReset() {
139 android::Bitmap* result = mStorage;
140 mStorage = NULL;
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800141 return result;
142 };
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800143
Matt Sarett1f979632015-10-27 10:33:20 -0400144 /**
145 * Indicates that this allocator allocates zero initialized
146 * memory.
147 */
148 SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150private:
John Reckf29ed282015-04-07 07:32:03 -0700151 JavaVM* mJavaVM;
152 android::Bitmap* mStorage = nullptr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153};
154
Matt Sarett1f979632015-10-27 10:33:20 -0400155/**
156 * Allocator to handle reusing bitmaps for BitmapRegionDecoder.
157 *
158 * The BitmapRegionDecoder documentation states that, if it is
159 * provided, the recycled bitmap will always be reused, clipping
160 * the decoded output to fit in the recycled bitmap if necessary.
161 * This allocator implements that behavior.
162 *
163 * Skia's SkBitmapRegionDecoder expects the memory that
164 * is allocated to be large enough to decode the entire region
165 * that is requested. It will decode directly into the memory
166 * that is provided.
167 *
168 * FIXME: BUG:25465958
169 * If the recycled bitmap is not large enough for the decode
170 * requested, meaning that a clip is required, we will allocate
171 * enough memory for Skia to perform the decode, and then copy
172 * from the decoded output into the recycled bitmap.
173 *
174 * If the recycled bitmap is large enough for the decode requested,
175 * we will provide that memory for Skia to decode directly into.
176 *
177 * This allocator should only be used for a single allocation.
178 * After we reuse the recycledBitmap once, it is dangerous to
179 * reuse it again, given that it still may be in use from our
180 * first allocation.
181 */
182class RecyclingClippingPixelAllocator : public SkBRDAllocator {
183public:
184
185 RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
186 size_t recycledBytes);
187
188 ~RecyclingClippingPixelAllocator();
189
190 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
191
192 /**
193 * Must be called!
194 *
195 * In the event that the recycled bitmap is not large enough for
196 * the allocation requested, we will allocate memory on the heap
197 * instead. As a final step, once we are done using this memory,
198 * we will copy the contents of the heap memory into the recycled
199 * bitmap's memory, clipping as necessary.
200 */
201 void copyIfNecessary();
202
203 /**
204 * Indicates that this allocator does not allocate zero initialized
205 * memory.
206 */
207 SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kNo_ZeroInitialized; }
208
209private:
210 android::Bitmap* mRecycledBitmap;
211 const size_t mRecycledBytes;
212 SkBitmap* mSkiaBitmap;
213 bool mNeedsCopy;
214};
215
Riley Andrews721ae5f2015-05-11 16:08:22 -0700216class AshmemPixelAllocator : public SkBitmap::Allocator {
217public:
Chih-Hung Hsieha6543282016-08-29 14:46:35 -0700218 explicit AshmemPixelAllocator(JNIEnv* env);
Riley Andrews721ae5f2015-05-11 16:08:22 -0700219 ~AshmemPixelAllocator();
220 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
221 android::Bitmap* getStorageObjAndReset() {
222 android::Bitmap* result = mStorage;
223 mStorage = NULL;
224 return result;
225 };
226
227private:
228 JavaVM* mJavaVM;
229 android::Bitmap* mStorage = nullptr;
230};
231
232
Mike Reedc04851f2009-10-28 15:09:45 -0400233enum JNIAccess {
234 kRO_JNIAccess,
235 kRW_JNIAccess
236};
237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238class AutoJavaFloatArray {
239public:
Mike Reedc04851f2009-10-28 15:09:45 -0400240 AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
241 int minLength = 0, JNIAccess = kRW_JNIAccess);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 ~AutoJavaFloatArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 float* ptr() const { return fPtr; }
245 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247private:
248 JNIEnv* fEnv;
249 jfloatArray fArray;
250 float* fPtr;
251 int fLen;
Mike Reedc04851f2009-10-28 15:09:45 -0400252 int fReleaseMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253};
254
255class AutoJavaIntArray {
256public:
257 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
258 ~AutoJavaIntArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 jint* ptr() const { return fPtr; }
261 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263private:
264 JNIEnv* fEnv;
265 jintArray fArray;
266 jint* fPtr;
267 int fLen;
268};
269
270class AutoJavaShortArray {
271public:
Mike Reedc04851f2009-10-28 15:09:45 -0400272 AutoJavaShortArray(JNIEnv* env, jshortArray array,
273 int minLength = 0, JNIAccess = kRW_JNIAccess);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 ~AutoJavaShortArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 jshort* ptr() const { return fPtr; }
277 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279private:
280 JNIEnv* fEnv;
281 jshortArray fArray;
282 jshort* fPtr;
283 int fLen;
Mike Reedc04851f2009-10-28 15:09:45 -0400284 int fReleaseMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285};
286
287class AutoJavaByteArray {
288public:
289 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
290 ~AutoJavaByteArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800292 jbyte* ptr() const { return fPtr; }
293 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295private:
296 JNIEnv* fEnv;
297 jbyteArray fArray;
298 jbyte* fPtr;
299 int fLen;
300};
301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302void doThrowNPE(JNIEnv* env);
303void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
304void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument
305void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime
306void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State
307void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory
Joseph Wenf1f48bc2010-07-19 16:59:51 +0800308void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
310#define NPE_CHECK_RETURN_ZERO(env, object) \
311 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
312
313#define NPE_CHECK_RETURN_VOID(env, object) \
314 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
315
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800316#endif // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_