blob: 7fbea2589730ca983cf0d094e021b7afe7c2a0b5 [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 "SkPixelRef.h"
9#include "SkMallocPixelRef.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010#include "SkPoint.h"
11#include "SkRect.h"
Romain Guy253f2c22016-09-28 17:34:42 -070012#include "SkColorSpace.h"
Romain Guy95648b82017-04-13 18:43:42 -070013#include "SkMatrix44.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>
sergeyvc1c54062016-10-19 18:47:26 -070016#include <hwui/Bitmap.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080017
Matt Sarett1f979632015-10-27 10:33:20 -040018class SkBitmapRegionDecoder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080019class SkCanvas;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
Raph Levien3d528c402014-06-26 09:04:54 -070021namespace android {
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040022class Paint;
sergeyvbad99182016-03-17 11:24:22 -070023struct Typeface;
Raph Levien3d528c402014-06-26 09:04:54 -070024}
25
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026class GraphicsJNI {
27public:
Romain Guye8d2ebb2017-02-09 18:38:47 -080028 // This enum must keep these int values, to match the int values
29 // in the java Bitmap.Config enum.
30 enum LegacyBitmapConfig {
31 kNo_LegacyBitmapConfig = 0,
32 kA8_LegacyBitmapConfig = 1,
33 kIndex8_LegacyBitmapConfig = 2,
34 kRGB_565_LegacyBitmapConfig = 3,
35 kARGB_4444_LegacyBitmapConfig = 4,
36 kARGB_8888_LegacyBitmapConfig = 5,
37 kRGBA_16F_LegacyBitmapConfig = 6,
38 kHardware_LegacyBitmapConfig = 7,
39
40 kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig
41 };
42
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 // returns true if an exception is set (and dumps it out to the Log)
44 static bool hasException(JNIEnv*);
45
46 static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
47 static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
48
49 static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
50 static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
51
52 static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
53 static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
54 static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
Elliott Hughes8451b252011-04-07 19:17:57 -070055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
Elliott Hughes8451b252011-04-07 19:17:57 -070057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
59 static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
Elliott Hughes8451b252011-04-07 19:17:57 -070060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061 static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
62 static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
Elliott Hughes8451b252011-04-07 19:17:57 -070063
John Reckc1b33d62015-04-22 09:04:45 -070064 static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
John Recked207b92015-04-10 13:52:57 -070065 static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
John Reckae2e8b42015-05-06 14:55:05 -070066 static SkPixelRef* refSkPixelRef(JNIEnv*, jobject bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067 static SkRegion* getNativeRegion(JNIEnv*, jobject region);
Elliott Hughes8451b252011-04-07 19:17:57 -070068
Mike Reed4c9355c2014-05-07 11:48:37 -040069 // Given the 'native' long held by the Rasterizer.java object, return a
70 // ref to its SkRasterizer* (or NULL).
Mike Reed260ab722016-10-07 15:59:20 -040071 static sk_sp<SkRasterizer> refNativeRasterizer(jlong rasterizerHandle);
Mike Reed4c9355c2014-05-07 11:48:37 -040072
Mike Reed1103b322014-07-08 12:36:44 -040073 /*
74 * LegacyBitmapConfig is the old enum in Skia that matched the enum int values
75 * in Bitmap.Config. Skia no longer supports this config, but has replaced it
76 * with SkColorType. These routines convert between the two.
77 */
78 static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
79 static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);
80
Mike Reed42a1d082014-07-07 18:06:18 -040081 /** Return the corresponding native colorType from the java Config enum,
82 or kUnknown_SkColorType if the java object is null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083 */
Mike Reed42a1d082014-07-07 18:06:18 -040084 static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
Elliott Hughes8451b252011-04-07 19:17:57 -070085
sergeyvda6c8ffc2016-11-22 18:28:54 -080086 static bool isHardwareConfig(JNIEnv* env, jobject jconfig);
sergeyv19b4b012016-12-13 16:06:00 -080087 static jint hardwareLegacyBitmapConfig();
sergeyvda6c8ffc2016-11-22 18:28:54 -080088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 static jobject createRegion(JNIEnv* env, SkRegion* region);
90
Matt Sarett1f979632015-10-27 10:33:20 -040091 static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
Joseph Wenf1f48bc2010-07-19 16:59:51 +080092
sergeyvc1c54062016-10-19 18:47:26 -070093 static android::Bitmap* mapAshmemBitmap(JNIEnv* env, SkBitmap* bitmap,
John Reck003bdee2016-09-12 10:43:35 -070094 SkColorTable* ctable, int fd, void* addr, size_t size, bool readOnly);
Riley Andrews39d7f302014-11-13 17:43:25 -080095
Derek Sollenberger3d4eed72014-12-04 15:20:29 -050096 /**
97 * Given a bitmap we natively allocate a memory block to store the contents
98 * of that bitmap. The memory is then attached to the bitmap via an
99 * SkPixelRef, which ensures that upon deletion the appropriate caches
100 * are notified.
101 */
102 static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable);
103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104 /** Copy the colors in colors[] to the bitmap, convert to the correct
105 format along the way.
Leon Scroggins III57ee6202014-06-04 18:51:07 -0400106 Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 */
108 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
Chris Craik1abf5d62013-08-16 12:47:03 -0700109 int srcStride, int x, int y, int width, int height,
Leon Scroggins III57ee6202014-06-04 18:51:07 -0400110 const SkBitmap& dstBitmap);
Romain Guy253f2c22016-09-28 17:34:42 -0700111
112 static sk_sp<SkColorSpace> defaultColorSpace();
Romain Guy9505a652016-12-14 09:43:50 -0800113 static sk_sp<SkColorSpace> linearColorSpace();
114 static sk_sp<SkColorSpace> colorSpaceForType(SkColorType type);
Romain Guyce217fa2017-03-08 15:58:06 -0800115 static bool isColorSpaceSRGB(SkColorSpace* colorSpace);
Romain Guy95648b82017-04-13 18:43:42 -0700116
117 static SkColorSpaceTransferFn getNativeTransferParameters(JNIEnv* env, jobject transferParams);
118 static SkMatrix44 getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50);
119 static sk_sp<SkColorSpace> getNativeColorSpace(JNIEnv* env, jobject colorSpace);
120
121 static jobject getColorSpace(JNIEnv* env, sk_sp<SkColorSpace>& decodeColorSpace,
122 SkColorType decodeColorType);
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800123};
124
sergeyv45082182016-09-29 18:25:40 -0700125class HeapAllocator : public SkBRDAllocator {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126public:
sergeyvc69853c2016-10-07 14:14:09 -0700127 HeapAllocator() { };
128 ~HeapAllocator() { };
Elliott Hughes8451b252011-04-07 19:17:57 -0700129
John Reckf29ed282015-04-07 07:32:03 -0700130 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800131
John Reckf29ed282015-04-07 07:32:03 -0700132 /**
133 * Fetches the backing allocation object. Must be called!
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800134 */
sergeyvc1c54062016-10-19 18:47:26 -0700135 android::Bitmap* getStorageObjAndReset() {
sergeyvc69853c2016-10-07 14:14:09 -0700136 return mStorage.release();
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800137 };
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800138
Matt Sarett1f979632015-10-27 10:33:20 -0400139 SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140private:
sergeyvc1c54062016-10-19 18:47:26 -0700141 sk_sp<android::Bitmap> mStorage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142};
143
Matt Sarett1f979632015-10-27 10:33:20 -0400144/**
145 * Allocator to handle reusing bitmaps for BitmapRegionDecoder.
146 *
147 * The BitmapRegionDecoder documentation states that, if it is
148 * provided, the recycled bitmap will always be reused, clipping
149 * the decoded output to fit in the recycled bitmap if necessary.
150 * This allocator implements that behavior.
151 *
152 * Skia's SkBitmapRegionDecoder expects the memory that
153 * is allocated to be large enough to decode the entire region
154 * that is requested. It will decode directly into the memory
155 * that is provided.
156 *
157 * FIXME: BUG:25465958
158 * If the recycled bitmap is not large enough for the decode
159 * requested, meaning that a clip is required, we will allocate
160 * enough memory for Skia to perform the decode, and then copy
161 * from the decoded output into the recycled bitmap.
162 *
163 * If the recycled bitmap is large enough for the decode requested,
164 * we will provide that memory for Skia to decode directly into.
165 *
166 * This allocator should only be used for a single allocation.
167 * After we reuse the recycledBitmap once, it is dangerous to
168 * reuse it again, given that it still may be in use from our
169 * first allocation.
170 */
171class RecyclingClippingPixelAllocator : public SkBRDAllocator {
172public:
173
sergeyvc1c54062016-10-19 18:47:26 -0700174 RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
Matt Sarett1f979632015-10-27 10:33:20 -0400175 size_t recycledBytes);
176
177 ~RecyclingClippingPixelAllocator();
178
179 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
180
181 /**
182 * Must be called!
183 *
184 * In the event that the recycled bitmap is not large enough for
185 * the allocation requested, we will allocate memory on the heap
186 * instead. As a final step, once we are done using this memory,
187 * we will copy the contents of the heap memory into the recycled
188 * bitmap's memory, clipping as necessary.
189 */
190 void copyIfNecessary();
191
192 /**
193 * Indicates that this allocator does not allocate zero initialized
194 * memory.
195 */
196 SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kNo_ZeroInitialized; }
197
198private:
sergeyvc1c54062016-10-19 18:47:26 -0700199 android::Bitmap* mRecycledBitmap;
Matt Sarett1f979632015-10-27 10:33:20 -0400200 const size_t mRecycledBytes;
201 SkBitmap* mSkiaBitmap;
202 bool mNeedsCopy;
203};
204
Riley Andrews721ae5f2015-05-11 16:08:22 -0700205class AshmemPixelAllocator : public SkBitmap::Allocator {
206public:
Chih-Hung Hsieha6543282016-08-29 14:46:35 -0700207 explicit AshmemPixelAllocator(JNIEnv* env);
sergeyvc69853c2016-10-07 14:14:09 -0700208 ~AshmemPixelAllocator() { };
Riley Andrews721ae5f2015-05-11 16:08:22 -0700209 virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
sergeyvc1c54062016-10-19 18:47:26 -0700210 android::Bitmap* getStorageObjAndReset() {
sergeyvc69853c2016-10-07 14:14:09 -0700211 return mStorage.release();
Riley Andrews721ae5f2015-05-11 16:08:22 -0700212 };
213
214private:
215 JavaVM* mJavaVM;
sergeyvc1c54062016-10-19 18:47:26 -0700216 sk_sp<android::Bitmap> mStorage;
Riley Andrews721ae5f2015-05-11 16:08:22 -0700217};
218
219
Mike Reedc04851f2009-10-28 15:09:45 -0400220enum JNIAccess {
221 kRO_JNIAccess,
222 kRW_JNIAccess
223};
224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225class AutoJavaFloatArray {
226public:
Mike Reedc04851f2009-10-28 15:09:45 -0400227 AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
228 int minLength = 0, JNIAccess = kRW_JNIAccess);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800229 ~AutoJavaFloatArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700230
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231 float* ptr() const { return fPtr; }
232 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700233
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800234private:
235 JNIEnv* fEnv;
236 jfloatArray fArray;
237 float* fPtr;
238 int fLen;
Mike Reedc04851f2009-10-28 15:09:45 -0400239 int fReleaseMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240};
241
242class AutoJavaIntArray {
243public:
244 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
245 ~AutoJavaIntArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 jint* ptr() const { return fPtr; }
248 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250private:
251 JNIEnv* fEnv;
252 jintArray fArray;
253 jint* fPtr;
254 int fLen;
255};
256
257class AutoJavaShortArray {
258public:
Mike Reedc04851f2009-10-28 15:09:45 -0400259 AutoJavaShortArray(JNIEnv* env, jshortArray array,
260 int minLength = 0, JNIAccess = kRW_JNIAccess);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 ~AutoJavaShortArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 jshort* ptr() const { return fPtr; }
264 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266private:
267 JNIEnv* fEnv;
268 jshortArray fArray;
269 jshort* fPtr;
270 int fLen;
Mike Reedc04851f2009-10-28 15:09:45 -0400271 int fReleaseMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272};
273
274class AutoJavaByteArray {
275public:
276 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
277 ~AutoJavaByteArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 jbyte* ptr() const { return fPtr; }
280 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800282private:
283 JNIEnv* fEnv;
284 jbyteArray fArray;
285 jbyte* fPtr;
286 int fLen;
287};
288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289void doThrowNPE(JNIEnv* env);
290void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
291void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument
292void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime
293void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State
294void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory
Joseph Wenf1f48bc2010-07-19 16:59:51 +0800295void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296
297#define NPE_CHECK_RETURN_ZERO(env, object) \
298 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
299
300#define NPE_CHECK_RETURN_VOID(env, object) \
301 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
302
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800303#endif // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_