blob: ba407f2164deca3462498b9df793606b5dce1f46 [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
Derek Sollenberger2173ea22020-02-19 15:37:29 -05004#include <cutils/compiler.h>
5
John Reckf29ed282015-04-07 07:32:03 -07006#include "Bitmap.h"
Leon Scroggins III23ac0362020-05-04 15:38:58 -04007#include "BRDAllocator.h"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -08008#include "SkBitmap.h"
Matt Sarett1f979632015-10-27 10:33:20 -04009#include "SkCodec.h"
Patrick Dubroye4ac2d62010-12-01 11:23:13 -080010#include "SkPixelRef.h"
11#include "SkMallocPixelRef.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012#include "SkPoint.h"
13#include "SkRect.h"
Romain Guy253f2c22016-09-28 17:34:42 -070014#include "SkColorSpace.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
Derek Sollenbergerc5882c42019-10-25 11:11:32 -040018#include "graphics_jni_helpers.h"
19
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020class SkCanvas;
Seigo Nonaka1ed4f642020-09-10 17:19:34 -070021struct SkFontMetrics;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
Raph Levien3d528c402014-06-26 09:04:54 -070023namespace android {
Leon Scroggins III23ac0362020-05-04 15:38:58 -040024namespace skia {
25 class BitmapRegionDecoder;
26}
John Reckbe671952021-01-13 22:39:32 -050027class Canvas;
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040028class Paint;
sergeyvbad99182016-03-17 11:24:22 -070029struct Typeface;
Raph Levien3d528c402014-06-26 09:04:54 -070030}
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032class GraphicsJNI {
33public:
Romain Guye8d2ebb2017-02-09 18:38:47 -080034 // This enum must keep these int values, to match the int values
35 // in the java Bitmap.Config enum.
36 enum LegacyBitmapConfig {
37 kNo_LegacyBitmapConfig = 0,
38 kA8_LegacyBitmapConfig = 1,
39 kIndex8_LegacyBitmapConfig = 2,
40 kRGB_565_LegacyBitmapConfig = 3,
41 kARGB_4444_LegacyBitmapConfig = 4,
42 kARGB_8888_LegacyBitmapConfig = 5,
43 kRGBA_16F_LegacyBitmapConfig = 6,
44 kHardware_LegacyBitmapConfig = 7,
45
46 kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig
47 };
48
Derek Sollenbergerc5882c42019-10-25 11:11:32 -040049 static void setJavaVM(JavaVM* javaVM);
50
51 /** returns a pointer to the JavaVM provided when we initialized the module */
52 static JavaVM* getJavaVM() { return mJavaVM; }
53
54 /** return a pointer to the JNIEnv for this thread */
55 static JNIEnv* getJNIEnv();
56
57 /** create a JNIEnv* for this thread or assert if one already exists */
58 static JNIEnv* attachJNIEnv(const char* envName);
59
60 /** detach the current thread from the JavaVM */
61 static void detachJNIEnv();
62
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 // returns true if an exception is set (and dumps it out to the Log)
64 static bool hasException(JNIEnv*);
65
66 static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
67 static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
68
69 static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
70 static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
71
72 static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
73 static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
74 static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
Elliott Hughes8451b252011-04-07 19:17:57 -070075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
Elliott Hughes8451b252011-04-07 19:17:57 -070077
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
79 static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
Elliott Hughes8451b252011-04-07 19:17:57 -070080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081 static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
82 static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
Elliott Hughes8451b252011-04-07 19:17:57 -070083
Derek Sollenberger2173ea22020-02-19 15:37:29 -050084 ANDROID_API static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
Derek Sollenberger6c41ab12019-11-08 08:50:58 -050085 static android::Bitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
Leon Scroggins III84a2afc2020-01-19 19:27:16 -050086 static SkImageInfo getBitmapInfo(JNIEnv*, jobject bitmap, uint32_t* outRowBytes,
87 bool* isHardware);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 static SkRegion* getNativeRegion(JNIEnv*, jobject region);
Elliott Hughes8451b252011-04-07 19:17:57 -070089
Seigo Nonaka1ed4f642020-09-10 17:19:34 -070090 /**
91 * Set SkFontMetrics to Java Paint.FontMetrics.
92 * Do nothing if metrics is nullptr.
93 */
94 static void set_metrics(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);
95 /**
96 * Set SkFontMetrics to Java Paint.FontMetricsInt and return recommended interline space.
97 * Do nothing if metrics is nullptr.
98 */
99 static int set_metrics_int(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);
100
Mike Reed1103b322014-07-08 12:36:44 -0400101 /*
102 * LegacyBitmapConfig is the old enum in Skia that matched the enum int values
103 * in Bitmap.Config. Skia no longer supports this config, but has replaced it
104 * with SkColorType. These routines convert between the two.
105 */
106 static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
107 static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);
108
Mike Reed42a1d082014-07-07 18:06:18 -0400109 /** Return the corresponding native colorType from the java Config enum,
110 or kUnknown_SkColorType if the java object is null.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 */
Mike Reed42a1d082014-07-07 18:06:18 -0400112 static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
Derek Sollenberger213daca2019-10-25 14:17:32 -0400113 static AndroidBitmapFormat getFormatFromConfig(JNIEnv* env, jobject jconfig);
114 static jobject getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
Elliott Hughes8451b252011-04-07 19:17:57 -0700115
sergeyvda6c8ffc2016-11-22 18:28:54 -0800116 static bool isHardwareConfig(JNIEnv* env, jobject jconfig);
sergeyv19b4b012016-12-13 16:06:00 -0800117 static jint hardwareLegacyBitmapConfig();
sergeyvda6c8ffc2016-11-22 18:28:54 -0800118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 static jobject createRegion(JNIEnv* env, SkRegion* region);
120
Leon Scroggins III23ac0362020-05-04 15:38:58 -0400121 static jobject createBitmapRegionDecoder(JNIEnv* env,
122 android::skia::BitmapRegionDecoder* bitmap);
Joseph Wenf1f48bc2010-07-19 16:59:51 +0800123
Derek Sollenberger3d4eed72014-12-04 15:20:29 -0500124 /**
125 * Given a bitmap we natively allocate a memory block to store the contents
126 * of that bitmap. The memory is then attached to the bitmap via an
127 * SkPixelRef, which ensures that upon deletion the appropriate caches
128 * are notified.
129 */
Mike Reed81397c42017-07-18 17:04:16 -0400130 static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap);
Derek Sollenberger3d4eed72014-12-04 15:20:29 -0500131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 /** Copy the colors in colors[] to the bitmap, convert to the correct
133 format along the way.
Leon Scroggins III57ee6202014-06-04 18:51:07 -0400134 Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 */
136 static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
Chris Craik1abf5d62013-08-16 12:47:03 -0700137 int srcStride, int x, int y, int width, int height,
Brian Osman91c9c282018-08-17 16:57:15 -0400138 SkBitmap* dstBitmap);
Romain Guy253f2c22016-09-28 17:34:42 -0700139
Leon Scroggins III0e443d12018-12-19 11:38:35 -0500140 /**
141 * Convert the native SkColorSpace retrieved from ColorSpace.Rgb.getNativeInstance().
142 *
143 * This will never throw an Exception. If the ColorSpace is one that Skia cannot
144 * use, ColorSpace.Rgb.getNativeInstance() would have thrown an Exception. It may,
145 * however, be nullptr, which may be acceptable.
146 */
147 static sk_sp<SkColorSpace> getNativeColorSpace(jlong colorSpaceHandle);
Romain Guy95648b82017-04-13 18:43:42 -0700148
Derek Sollenbergerbf3e4642019-01-30 11:28:27 -0500149 /**
150 * Return the android.graphics.ColorSpace Java object that corresponds to decodeColorSpace
151 * and decodeColorType.
152 *
153 * This may create a new object if none of the Named ColorSpaces match.
154 */
155 static jobject getColorSpace(JNIEnv* env, SkColorSpace* decodeColorSpace,
Romain Guy95648b82017-04-13 18:43:42 -0700156 SkColorType decodeColorType);
Leon Scroggins III94ba1002019-01-17 13:34:51 -0500157
158 /**
159 * Convert from a Java @ColorLong to an SkColor4f that Skia can use directly.
160 *
161 * This ignores the encoded ColorSpace, besides checking to see if it is sRGB,
162 * which is encoded differently. The color space should be passed down separately
163 * via ColorSpace#getNativeInstance(), and converted with getNativeColorSpace(),
164 * above.
165 */
166 static SkColor4f convertColorLong(jlong color);
Derek Sollenbergerc5882c42019-10-25 11:11:32 -0400167
168private:
169 /* JNI JavaVM pointer */
170 static JavaVM* mJavaVM;
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800171};
172
Leon Scroggins III23ac0362020-05-04 15:38:58 -0400173class HeapAllocator : public android::skia::BRDAllocator {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174public:
sergeyvc69853c2016-10-07 14:14:09 -0700175 HeapAllocator() { };
176 ~HeapAllocator() { };
Elliott Hughes8451b252011-04-07 19:17:57 -0700177
Mike Reed81397c42017-07-18 17:04:16 -0400178 virtual bool allocPixelRef(SkBitmap* bitmap) override;
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800179
John Reckf29ed282015-04-07 07:32:03 -0700180 /**
181 * Fetches the backing allocation object. Must be called!
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800182 */
sergeyvc1c54062016-10-19 18:47:26 -0700183 android::Bitmap* getStorageObjAndReset() {
sergeyvc69853c2016-10-07 14:14:09 -0700184 return mStorage.release();
Patrick Dubroyafde46e2010-12-15 11:52:01 -0800185 };
Patrick Dubroye4ac2d62010-12-01 11:23:13 -0800186
Matt Sarett1f979632015-10-27 10:33:20 -0400187 SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188private:
sergeyvc1c54062016-10-19 18:47:26 -0700189 sk_sp<android::Bitmap> mStorage;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190};
191
Matt Sarett1f979632015-10-27 10:33:20 -0400192/**
193 * Allocator to handle reusing bitmaps for BitmapRegionDecoder.
194 *
195 * The BitmapRegionDecoder documentation states that, if it is
196 * provided, the recycled bitmap will always be reused, clipping
197 * the decoded output to fit in the recycled bitmap if necessary.
198 * This allocator implements that behavior.
199 *
Leon Scroggins III23ac0362020-05-04 15:38:58 -0400200 * Skia's BitmapRegionDecoder expects the memory that
Matt Sarett1f979632015-10-27 10:33:20 -0400201 * is allocated to be large enough to decode the entire region
202 * that is requested. It will decode directly into the memory
203 * that is provided.
204 *
205 * FIXME: BUG:25465958
206 * If the recycled bitmap is not large enough for the decode
207 * requested, meaning that a clip is required, we will allocate
208 * enough memory for Skia to perform the decode, and then copy
209 * from the decoded output into the recycled bitmap.
210 *
211 * If the recycled bitmap is large enough for the decode requested,
212 * we will provide that memory for Skia to decode directly into.
213 *
214 * This allocator should only be used for a single allocation.
215 * After we reuse the recycledBitmap once, it is dangerous to
216 * reuse it again, given that it still may be in use from our
217 * first allocation.
218 */
Leon Scroggins III23ac0362020-05-04 15:38:58 -0400219class RecyclingClippingPixelAllocator : public android::skia::BRDAllocator {
Matt Sarett1f979632015-10-27 10:33:20 -0400220public:
221
sergeyvc1c54062016-10-19 18:47:26 -0700222 RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
Matt Sarett1f979632015-10-27 10:33:20 -0400223 size_t recycledBytes);
224
225 ~RecyclingClippingPixelAllocator();
226
Mike Reed81397c42017-07-18 17:04:16 -0400227 virtual bool allocPixelRef(SkBitmap* bitmap) override;
Matt Sarett1f979632015-10-27 10:33:20 -0400228
229 /**
230 * Must be called!
231 *
232 * In the event that the recycled bitmap is not large enough for
233 * the allocation requested, we will allocate memory on the heap
234 * instead. As a final step, once we are done using this memory,
235 * we will copy the contents of the heap memory into the recycled
236 * bitmap's memory, clipping as necessary.
237 */
238 void copyIfNecessary();
239
240 /**
241 * Indicates that this allocator does not allocate zero initialized
242 * memory.
243 */
244 SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kNo_ZeroInitialized; }
245
246private:
sergeyvc1c54062016-10-19 18:47:26 -0700247 android::Bitmap* mRecycledBitmap;
Matt Sarett1f979632015-10-27 10:33:20 -0400248 const size_t mRecycledBytes;
249 SkBitmap* mSkiaBitmap;
250 bool mNeedsCopy;
251};
252
Riley Andrews721ae5f2015-05-11 16:08:22 -0700253class AshmemPixelAllocator : public SkBitmap::Allocator {
254public:
Chih-Hung Hsieha6543282016-08-29 14:46:35 -0700255 explicit AshmemPixelAllocator(JNIEnv* env);
sergeyvc69853c2016-10-07 14:14:09 -0700256 ~AshmemPixelAllocator() { };
Mike Reed81397c42017-07-18 17:04:16 -0400257 virtual bool allocPixelRef(SkBitmap* bitmap);
sergeyvc1c54062016-10-19 18:47:26 -0700258 android::Bitmap* getStorageObjAndReset() {
sergeyvc69853c2016-10-07 14:14:09 -0700259 return mStorage.release();
Riley Andrews721ae5f2015-05-11 16:08:22 -0700260 };
261
262private:
263 JavaVM* mJavaVM;
sergeyvc1c54062016-10-19 18:47:26 -0700264 sk_sp<android::Bitmap> mStorage;
Riley Andrews721ae5f2015-05-11 16:08:22 -0700265};
266
267
Mike Reedc04851f2009-10-28 15:09:45 -0400268enum JNIAccess {
269 kRO_JNIAccess,
270 kRW_JNIAccess
271};
272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273class AutoJavaFloatArray {
274public:
Mike Reedc04851f2009-10-28 15:09:45 -0400275 AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
276 int minLength = 0, JNIAccess = kRW_JNIAccess);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 ~AutoJavaFloatArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 float* 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 jfloatArray fArray;
285 float* fPtr;
286 int fLen;
Mike Reedc04851f2009-10-28 15:09:45 -0400287 int fReleaseMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288};
289
290class AutoJavaIntArray {
291public:
292 AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
293 ~AutoJavaIntArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700294
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800295 jint* ptr() const { return fPtr; }
296 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298private:
299 JNIEnv* fEnv;
300 jintArray fArray;
301 jint* fPtr;
302 int fLen;
303};
304
305class AutoJavaShortArray {
306public:
Mike Reedc04851f2009-10-28 15:09:45 -0400307 AutoJavaShortArray(JNIEnv* env, jshortArray array,
308 int minLength = 0, JNIAccess = kRW_JNIAccess);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 ~AutoJavaShortArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 jshort* ptr() const { return fPtr; }
312 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314private:
315 JNIEnv* fEnv;
316 jshortArray fArray;
317 jshort* fPtr;
318 int fLen;
Mike Reedc04851f2009-10-28 15:09:45 -0400319 int fReleaseMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320};
321
322class AutoJavaByteArray {
323public:
324 AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
325 ~AutoJavaByteArray();
Elliott Hughes8451b252011-04-07 19:17:57 -0700326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 jbyte* ptr() const { return fPtr; }
328 int length() const { return fLen; }
Elliott Hughes8451b252011-04-07 19:17:57 -0700329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330private:
331 JNIEnv* fEnv;
332 jbyteArray fArray;
333 jbyte* fPtr;
334 int fLen;
335};
336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337void doThrowNPE(JNIEnv* env);
338void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
339void doThrowIAE(JNIEnv* env, const char* msg = NULL); // Illegal Argument
340void doThrowRE(JNIEnv* env, const char* msg = NULL); // Runtime
341void doThrowISE(JNIEnv* env, const char* msg = NULL); // Illegal State
342void doThrowOOME(JNIEnv* env, const char* msg = NULL); // Out of memory
Joseph Wenf1f48bc2010-07-19 16:59:51 +0800343void doThrowIOE(JNIEnv* env, const char* msg = NULL); // IO Exception
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344
345#define NPE_CHECK_RETURN_ZERO(env, object) \
346 do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
347
348#define NPE_CHECK_RETURN_VOID(env, object) \
349 do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
350
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800351#endif // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_