xref: /aosp_15_r20/frameworks/base/libs/hwui/jni/GraphicsJNI.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker #ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
2*d57664e9SAndroid Build Coastguard Worker #define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
3*d57664e9SAndroid Build Coastguard Worker 
4*d57664e9SAndroid Build Coastguard Worker #include <cutils/compiler.h>
5*d57664e9SAndroid Build Coastguard Worker #include <hwui/Bitmap.h>
6*d57664e9SAndroid Build Coastguard Worker #include <hwui/Canvas.h>
7*d57664e9SAndroid Build Coastguard Worker 
8*d57664e9SAndroid Build Coastguard Worker #include "BRDAllocator.h"
9*d57664e9SAndroid Build Coastguard Worker #include "Bitmap.h"
10*d57664e9SAndroid Build Coastguard Worker #include "SkBitmap.h"
11*d57664e9SAndroid Build Coastguard Worker #include "SkCodec.h"
12*d57664e9SAndroid Build Coastguard Worker #include "SkColorSpace.h"
13*d57664e9SAndroid Build Coastguard Worker #include "SkMallocPixelRef.h"
14*d57664e9SAndroid Build Coastguard Worker #include "SkPixelRef.h"
15*d57664e9SAndroid Build Coastguard Worker #include "SkPoint.h"
16*d57664e9SAndroid Build Coastguard Worker #include "SkRect.h"
17*d57664e9SAndroid Build Coastguard Worker #include "graphics_jni_helpers.h"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker class SkCanvas;
20*d57664e9SAndroid Build Coastguard Worker struct SkFontMetrics;
21*d57664e9SAndroid Build Coastguard Worker 
22*d57664e9SAndroid Build Coastguard Worker namespace android {
23*d57664e9SAndroid Build Coastguard Worker class BitmapRegionDecoderWrapper;
24*d57664e9SAndroid Build Coastguard Worker class Canvas;
25*d57664e9SAndroid Build Coastguard Worker class Paint;
26*d57664e9SAndroid Build Coastguard Worker struct Typeface;
27*d57664e9SAndroid Build Coastguard Worker }
28*d57664e9SAndroid Build Coastguard Worker 
29*d57664e9SAndroid Build Coastguard Worker class GraphicsJNI {
30*d57664e9SAndroid Build Coastguard Worker public:
31*d57664e9SAndroid Build Coastguard Worker     // This enum must keep these int values, to match the int values
32*d57664e9SAndroid Build Coastguard Worker     // in the java Bitmap.Config enum.
33*d57664e9SAndroid Build Coastguard Worker     enum LegacyBitmapConfig {
34*d57664e9SAndroid Build Coastguard Worker         kNo_LegacyBitmapConfig = 0,
35*d57664e9SAndroid Build Coastguard Worker         kA8_LegacyBitmapConfig = 1,
36*d57664e9SAndroid Build Coastguard Worker         kIndex8_LegacyBitmapConfig = 2,
37*d57664e9SAndroid Build Coastguard Worker         kRGB_565_LegacyBitmapConfig = 3,
38*d57664e9SAndroid Build Coastguard Worker         kARGB_4444_LegacyBitmapConfig = 4,
39*d57664e9SAndroid Build Coastguard Worker         kARGB_8888_LegacyBitmapConfig = 5,
40*d57664e9SAndroid Build Coastguard Worker         kRGBA_16F_LegacyBitmapConfig = 6,
41*d57664e9SAndroid Build Coastguard Worker         kHardware_LegacyBitmapConfig = 7,
42*d57664e9SAndroid Build Coastguard Worker         kRGBA_1010102_LegacyBitmapConfig = 8,
43*d57664e9SAndroid Build Coastguard Worker 
44*d57664e9SAndroid Build Coastguard Worker         kLastEnum_LegacyBitmapConfig = kRGBA_1010102_LegacyBitmapConfig
45*d57664e9SAndroid Build Coastguard Worker     };
46*d57664e9SAndroid Build Coastguard Worker 
47*d57664e9SAndroid Build Coastguard Worker     static void setJavaVM(JavaVM* javaVM);
48*d57664e9SAndroid Build Coastguard Worker 
49*d57664e9SAndroid Build Coastguard Worker     /**
50*d57664e9SAndroid Build Coastguard Worker      * returns a pointer to the JavaVM provided when we initialized the module
51*d57664e9SAndroid Build Coastguard Worker      * DEPRECATED: Objects should know the JavaVM that created them
52*d57664e9SAndroid Build Coastguard Worker      */
getJavaVM()53*d57664e9SAndroid Build Coastguard Worker     static JavaVM* getJavaVM() { return mJavaVM; }
54*d57664e9SAndroid Build Coastguard Worker 
55*d57664e9SAndroid Build Coastguard Worker     /**
56*d57664e9SAndroid Build Coastguard Worker      * return a pointer to the JNIEnv for this thread
57*d57664e9SAndroid Build Coastguard Worker      * DEPRECATED: Objects should know the JavaVM that created them
58*d57664e9SAndroid Build Coastguard Worker      */
59*d57664e9SAndroid Build Coastguard Worker     static JNIEnv* getJNIEnv();
60*d57664e9SAndroid Build Coastguard Worker 
61*d57664e9SAndroid Build Coastguard Worker     /** create a JNIEnv* for this thread or assert if one already exists */
62*d57664e9SAndroid Build Coastguard Worker     static JNIEnv* attachJNIEnv(const char* envName);
63*d57664e9SAndroid Build Coastguard Worker 
64*d57664e9SAndroid Build Coastguard Worker     /** detach the current thread from the JavaVM */
65*d57664e9SAndroid Build Coastguard Worker     static void detachJNIEnv();
66*d57664e9SAndroid Build Coastguard Worker 
67*d57664e9SAndroid Build Coastguard Worker     // returns true if an exception is set (and dumps it out to the Log)
68*d57664e9SAndroid Build Coastguard Worker     static bool hasException(JNIEnv*);
69*d57664e9SAndroid Build Coastguard Worker 
70*d57664e9SAndroid Build Coastguard Worker     static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
71*d57664e9SAndroid Build Coastguard Worker     static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
72*d57664e9SAndroid Build Coastguard Worker 
73*d57664e9SAndroid Build Coastguard Worker     static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
74*d57664e9SAndroid Build Coastguard Worker     static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
75*d57664e9SAndroid Build Coastguard Worker 
76*d57664e9SAndroid Build Coastguard Worker     static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
77*d57664e9SAndroid Build Coastguard Worker     static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
78*d57664e9SAndroid Build Coastguard Worker     static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
79*d57664e9SAndroid Build Coastguard Worker 
80*d57664e9SAndroid Build Coastguard Worker     static void set_cluster_count_to_run_info(JNIEnv* env, jobject runInfo, jint clusterCount);
81*d57664e9SAndroid Build Coastguard Worker 
82*d57664e9SAndroid Build Coastguard Worker     static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
83*d57664e9SAndroid Build Coastguard Worker 
84*d57664e9SAndroid Build Coastguard Worker     static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
85*d57664e9SAndroid Build Coastguard Worker     static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
86*d57664e9SAndroid Build Coastguard Worker 
87*d57664e9SAndroid Build Coastguard Worker     static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
88*d57664e9SAndroid Build Coastguard Worker     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
89*d57664e9SAndroid Build Coastguard Worker 
90*d57664e9SAndroid Build Coastguard Worker     ANDROID_API static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
91*d57664e9SAndroid Build Coastguard Worker     static android::Bitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
92*d57664e9SAndroid Build Coastguard Worker     static SkImageInfo getBitmapInfo(JNIEnv*, jobject bitmap, uint32_t* outRowBytes,
93*d57664e9SAndroid Build Coastguard Worker                                      bool* isHardware);
94*d57664e9SAndroid Build Coastguard Worker     static SkRegion* getNativeRegion(JNIEnv*, jobject region);
95*d57664e9SAndroid Build Coastguard Worker 
96*d57664e9SAndroid Build Coastguard Worker     /**
97*d57664e9SAndroid Build Coastguard Worker      * Set SkFontMetrics to Java Paint.FontMetrics.
98*d57664e9SAndroid Build Coastguard Worker      * Do nothing if metrics is nullptr.
99*d57664e9SAndroid Build Coastguard Worker      */
100*d57664e9SAndroid Build Coastguard Worker     static void set_metrics(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);
101*d57664e9SAndroid Build Coastguard Worker     /**
102*d57664e9SAndroid Build Coastguard Worker      * Set SkFontMetrics to Java Paint.FontMetricsInt and return recommended interline space.
103*d57664e9SAndroid Build Coastguard Worker      * Do nothing if metrics is nullptr.
104*d57664e9SAndroid Build Coastguard Worker      */
105*d57664e9SAndroid Build Coastguard Worker     static int set_metrics_int(JNIEnv*, jobject metrics, const SkFontMetrics& skmetrics);
106*d57664e9SAndroid Build Coastguard Worker 
107*d57664e9SAndroid Build Coastguard Worker     /*
108*d57664e9SAndroid Build Coastguard Worker      *  LegacyBitmapConfig is the old enum in Skia that matched the enum int values
109*d57664e9SAndroid Build Coastguard Worker      *  in Bitmap.Config. Skia no longer supports this config, but has replaced it
110*d57664e9SAndroid Build Coastguard Worker      *  with SkColorType. These routines convert between the two.
111*d57664e9SAndroid Build Coastguard Worker      */
112*d57664e9SAndroid Build Coastguard Worker     static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
113*d57664e9SAndroid Build Coastguard Worker     static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);
114*d57664e9SAndroid Build Coastguard Worker 
115*d57664e9SAndroid Build Coastguard Worker     /** Return the corresponding native colorType from the java Config enum,
116*d57664e9SAndroid Build Coastguard Worker         or kUnknown_SkColorType if the java object is null.
117*d57664e9SAndroid Build Coastguard Worker     */
118*d57664e9SAndroid Build Coastguard Worker     static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
119*d57664e9SAndroid Build Coastguard Worker     static AndroidBitmapFormat getFormatFromConfig(JNIEnv* env, jobject jconfig);
120*d57664e9SAndroid Build Coastguard Worker     static jobject getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format);
121*d57664e9SAndroid Build Coastguard Worker 
122*d57664e9SAndroid Build Coastguard Worker     static bool isHardwareConfig(JNIEnv* env, jobject jconfig);
123*d57664e9SAndroid Build Coastguard Worker     static jint hardwareLegacyBitmapConfig();
124*d57664e9SAndroid Build Coastguard Worker 
125*d57664e9SAndroid Build Coastguard Worker     static jobject createRegion(JNIEnv* env, SkRegion* region);
126*d57664e9SAndroid Build Coastguard Worker 
127*d57664e9SAndroid Build Coastguard Worker     static jobject createBitmapRegionDecoder(JNIEnv* env,
128*d57664e9SAndroid Build Coastguard Worker                                              android::BitmapRegionDecoderWrapper* bitmap);
129*d57664e9SAndroid Build Coastguard Worker 
130*d57664e9SAndroid Build Coastguard Worker     /** Copy the colors in colors[] to the bitmap, convert to the correct
131*d57664e9SAndroid Build Coastguard Worker         format along the way.
132*d57664e9SAndroid Build Coastguard Worker         Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
133*d57664e9SAndroid Build Coastguard Worker     */
134*d57664e9SAndroid Build Coastguard Worker     static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
135*d57664e9SAndroid Build Coastguard Worker             int srcStride, int x, int y, int width, int height,
136*d57664e9SAndroid Build Coastguard Worker             SkBitmap* dstBitmap);
137*d57664e9SAndroid Build Coastguard Worker 
138*d57664e9SAndroid Build Coastguard Worker     /**
139*d57664e9SAndroid Build Coastguard Worker      * Convert the native SkColorSpace retrieved from ColorSpace.Rgb.getNativeInstance().
140*d57664e9SAndroid Build Coastguard Worker      *
141*d57664e9SAndroid Build Coastguard Worker      * This will never throw an Exception. If the ColorSpace is one that Skia cannot
142*d57664e9SAndroid Build Coastguard Worker      * use, ColorSpace.Rgb.getNativeInstance() would have thrown an Exception. It may,
143*d57664e9SAndroid Build Coastguard Worker      * however, be nullptr, which may be acceptable.
144*d57664e9SAndroid Build Coastguard Worker      */
145*d57664e9SAndroid Build Coastguard Worker     static sk_sp<SkColorSpace> getNativeColorSpace(jlong colorSpaceHandle);
146*d57664e9SAndroid Build Coastguard Worker 
147*d57664e9SAndroid Build Coastguard Worker     /**
148*d57664e9SAndroid Build Coastguard Worker      * Return the android.graphics.ColorSpace Java object that corresponds to decodeColorSpace
149*d57664e9SAndroid Build Coastguard Worker      * and decodeColorType.
150*d57664e9SAndroid Build Coastguard Worker      *
151*d57664e9SAndroid Build Coastguard Worker      * This may create a new object if none of the Named ColorSpaces match.
152*d57664e9SAndroid Build Coastguard Worker      */
153*d57664e9SAndroid Build Coastguard Worker     static jobject getColorSpace(JNIEnv* env, SkColorSpace* decodeColorSpace,
154*d57664e9SAndroid Build Coastguard Worker             SkColorType decodeColorType);
155*d57664e9SAndroid Build Coastguard Worker 
156*d57664e9SAndroid Build Coastguard Worker     /**
157*d57664e9SAndroid Build Coastguard Worker      * Convert from a Java @ColorLong to an SkColor4f that Skia can use directly.
158*d57664e9SAndroid Build Coastguard Worker      *
159*d57664e9SAndroid Build Coastguard Worker      * This ignores the encoded ColorSpace, besides checking to see if it is sRGB,
160*d57664e9SAndroid Build Coastguard Worker      * which is encoded differently. The color space should be passed down separately
161*d57664e9SAndroid Build Coastguard Worker      * via ColorSpace#getNativeInstance(), and converted with getNativeColorSpace(),
162*d57664e9SAndroid Build Coastguard Worker      * above.
163*d57664e9SAndroid Build Coastguard Worker      */
164*d57664e9SAndroid Build Coastguard Worker     static SkColor4f convertColorLong(jlong color);
165*d57664e9SAndroid Build Coastguard Worker 
166*d57664e9SAndroid Build Coastguard Worker private:
167*d57664e9SAndroid Build Coastguard Worker     /* JNI JavaVM pointer */
168*d57664e9SAndroid Build Coastguard Worker     static JavaVM* mJavaVM;
169*d57664e9SAndroid Build Coastguard Worker };
170*d57664e9SAndroid Build Coastguard Worker 
171*d57664e9SAndroid Build Coastguard Worker class HeapAllocator : public android::skia::BRDAllocator {
172*d57664e9SAndroid Build Coastguard Worker public:
HeapAllocator()173*d57664e9SAndroid Build Coastguard Worker    HeapAllocator() { };
~HeapAllocator()174*d57664e9SAndroid Build Coastguard Worker     ~HeapAllocator() { };
175*d57664e9SAndroid Build Coastguard Worker 
176*d57664e9SAndroid Build Coastguard Worker     virtual bool allocPixelRef(SkBitmap* bitmap) override;
177*d57664e9SAndroid Build Coastguard Worker 
178*d57664e9SAndroid Build Coastguard Worker     /**
179*d57664e9SAndroid Build Coastguard Worker      * Fetches the backing allocation object. Must be called!
180*d57664e9SAndroid Build Coastguard Worker      */
getStorageObjAndReset()181*d57664e9SAndroid Build Coastguard Worker     android::Bitmap* getStorageObjAndReset() {
182*d57664e9SAndroid Build Coastguard Worker         return mStorage.release();
183*d57664e9SAndroid Build Coastguard Worker     };
184*d57664e9SAndroid Build Coastguard Worker 
zeroInit()185*d57664e9SAndroid Build Coastguard Worker     SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
186*d57664e9SAndroid Build Coastguard Worker private:
187*d57664e9SAndroid Build Coastguard Worker     sk_sp<android::Bitmap> mStorage;
188*d57664e9SAndroid Build Coastguard Worker };
189*d57664e9SAndroid Build Coastguard Worker 
190*d57664e9SAndroid Build Coastguard Worker /**
191*d57664e9SAndroid Build Coastguard Worker  *  Allocator to handle reusing bitmaps for BitmapRegionDecoder.
192*d57664e9SAndroid Build Coastguard Worker  *
193*d57664e9SAndroid Build Coastguard Worker  *  The BitmapRegionDecoder documentation states that, if it is
194*d57664e9SAndroid Build Coastguard Worker  *  provided, the recycled bitmap will always be reused, clipping
195*d57664e9SAndroid Build Coastguard Worker  *  the decoded output to fit in the recycled bitmap if necessary.
196*d57664e9SAndroid Build Coastguard Worker  *  This allocator implements that behavior.
197*d57664e9SAndroid Build Coastguard Worker  *
198*d57664e9SAndroid Build Coastguard Worker  *  Skia's BitmapRegionDecoder expects the memory that
199*d57664e9SAndroid Build Coastguard Worker  *  is allocated to be large enough to decode the entire region
200*d57664e9SAndroid Build Coastguard Worker  *  that is requested.  It will decode directly into the memory
201*d57664e9SAndroid Build Coastguard Worker  *  that is provided.
202*d57664e9SAndroid Build Coastguard Worker  *
203*d57664e9SAndroid Build Coastguard Worker  *  FIXME: BUG:25465958
204*d57664e9SAndroid Build Coastguard Worker  *  If the recycled bitmap is not large enough for the decode
205*d57664e9SAndroid Build Coastguard Worker  *  requested, meaning that a clip is required, we will allocate
206*d57664e9SAndroid Build Coastguard Worker  *  enough memory for Skia to perform the decode, and then copy
207*d57664e9SAndroid Build Coastguard Worker  *  from the decoded output into the recycled bitmap.
208*d57664e9SAndroid Build Coastguard Worker  *
209*d57664e9SAndroid Build Coastguard Worker  *  If the recycled bitmap is large enough for the decode requested,
210*d57664e9SAndroid Build Coastguard Worker  *  we will provide that memory for Skia to decode directly into.
211*d57664e9SAndroid Build Coastguard Worker  *
212*d57664e9SAndroid Build Coastguard Worker  *  This allocator should only be used for a single allocation.
213*d57664e9SAndroid Build Coastguard Worker  *  After we reuse the recycledBitmap once, it is dangerous to
214*d57664e9SAndroid Build Coastguard Worker  *  reuse it again, given that it still may be in use from our
215*d57664e9SAndroid Build Coastguard Worker  *  first allocation.
216*d57664e9SAndroid Build Coastguard Worker  */
217*d57664e9SAndroid Build Coastguard Worker class RecyclingClippingPixelAllocator : public android::skia::BRDAllocator {
218*d57664e9SAndroid Build Coastguard Worker public:
219*d57664e9SAndroid Build Coastguard Worker     RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap, bool mustMatchColorType = true,
220*d57664e9SAndroid Build Coastguard Worker                                     std::optional<SkRect> desiredSubset = std::nullopt);
221*d57664e9SAndroid Build Coastguard Worker 
222*d57664e9SAndroid Build Coastguard Worker     ~RecyclingClippingPixelAllocator();
223*d57664e9SAndroid Build Coastguard Worker 
224*d57664e9SAndroid Build Coastguard Worker     virtual bool allocPixelRef(SkBitmap* bitmap) override;
225*d57664e9SAndroid Build Coastguard Worker 
226*d57664e9SAndroid Build Coastguard Worker     /**
227*d57664e9SAndroid Build Coastguard Worker      *  Must be called!
228*d57664e9SAndroid Build Coastguard Worker      *
229*d57664e9SAndroid Build Coastguard Worker      *  In the event that the recycled bitmap is not large enough for
230*d57664e9SAndroid Build Coastguard Worker      *  the allocation requested, we will allocate memory on the heap
231*d57664e9SAndroid Build Coastguard Worker      *  instead.  As a final step, once we are done using this memory,
232*d57664e9SAndroid Build Coastguard Worker      *  we will copy the contents of the heap memory into the recycled
233*d57664e9SAndroid Build Coastguard Worker      *  bitmap's memory, clipping as necessary.
234*d57664e9SAndroid Build Coastguard Worker      */
235*d57664e9SAndroid Build Coastguard Worker     void copyIfNecessary();
236*d57664e9SAndroid Build Coastguard Worker 
237*d57664e9SAndroid Build Coastguard Worker     /**
238*d57664e9SAndroid Build Coastguard Worker      *  Indicates that this allocator does not allocate zero initialized
239*d57664e9SAndroid Build Coastguard Worker      *  memory.
240*d57664e9SAndroid Build Coastguard Worker      */
zeroInit()241*d57664e9SAndroid Build Coastguard Worker     SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kNo_ZeroInitialized; }
242*d57664e9SAndroid Build Coastguard Worker 
243*d57664e9SAndroid Build Coastguard Worker private:
244*d57664e9SAndroid Build Coastguard Worker     /**
245*d57664e9SAndroid Build Coastguard Worker      *  Optionally returns a subset rectangle that we need to upsample from.
246*d57664e9SAndroid Build Coastguard Worker      *  E.g., a gainmap subset may be decoded in a slightly larger rectangle
247*d57664e9SAndroid Build Coastguard Worker      *  than is needed (in order to correctly preserve gainmap alignment when
248*d57664e9SAndroid Build Coastguard Worker      *  rendering at display time), so we need to re-sample the "intended"
249*d57664e9SAndroid Build Coastguard Worker      *  gainmap back up to the bitmap dimensions.
250*d57664e9SAndroid Build Coastguard Worker      *
251*d57664e9SAndroid Build Coastguard Worker      *  If we don't need to upsample from a subregion, then returns an empty
252*d57664e9SAndroid Build Coastguard Worker      *  optional
253*d57664e9SAndroid Build Coastguard Worker      */
254*d57664e9SAndroid Build Coastguard Worker     static std::optional<SkRect> getSourceBoundsForUpsample(std::optional<SkRect> subset);
255*d57664e9SAndroid Build Coastguard Worker 
256*d57664e9SAndroid Build Coastguard Worker     android::Bitmap* mRecycledBitmap;
257*d57664e9SAndroid Build Coastguard Worker     const size_t     mRecycledBytes;
258*d57664e9SAndroid Build Coastguard Worker     SkBitmap*        mSkiaBitmap;
259*d57664e9SAndroid Build Coastguard Worker     bool             mNeedsCopy;
260*d57664e9SAndroid Build Coastguard Worker     const bool mMustMatchColorType;
261*d57664e9SAndroid Build Coastguard Worker     const std::optional<SkRect> mDesiredSubset;
262*d57664e9SAndroid Build Coastguard Worker };
263*d57664e9SAndroid Build Coastguard Worker 
264*d57664e9SAndroid Build Coastguard Worker class AshmemPixelAllocator : public SkBitmap::Allocator {
265*d57664e9SAndroid Build Coastguard Worker public:
266*d57664e9SAndroid Build Coastguard Worker     explicit AshmemPixelAllocator(JNIEnv* env);
~AshmemPixelAllocator()267*d57664e9SAndroid Build Coastguard Worker     ~AshmemPixelAllocator() { };
268*d57664e9SAndroid Build Coastguard Worker     virtual bool allocPixelRef(SkBitmap* bitmap);
getStorageObjAndReset()269*d57664e9SAndroid Build Coastguard Worker     android::Bitmap* getStorageObjAndReset() {
270*d57664e9SAndroid Build Coastguard Worker         return mStorage.release();
271*d57664e9SAndroid Build Coastguard Worker     };
272*d57664e9SAndroid Build Coastguard Worker 
273*d57664e9SAndroid Build Coastguard Worker private:
274*d57664e9SAndroid Build Coastguard Worker     JavaVM* mJavaVM;
275*d57664e9SAndroid Build Coastguard Worker     sk_sp<android::Bitmap> mStorage;
276*d57664e9SAndroid Build Coastguard Worker };
277*d57664e9SAndroid Build Coastguard Worker 
278*d57664e9SAndroid Build Coastguard Worker 
279*d57664e9SAndroid Build Coastguard Worker enum JNIAccess {
280*d57664e9SAndroid Build Coastguard Worker     kRO_JNIAccess,
281*d57664e9SAndroid Build Coastguard Worker     kRW_JNIAccess
282*d57664e9SAndroid Build Coastguard Worker };
283*d57664e9SAndroid Build Coastguard Worker 
284*d57664e9SAndroid Build Coastguard Worker class AutoJavaFloatArray {
285*d57664e9SAndroid Build Coastguard Worker public:
286*d57664e9SAndroid Build Coastguard Worker     AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
287*d57664e9SAndroid Build Coastguard Worker                        int minLength = 0, JNIAccess = kRW_JNIAccess);
288*d57664e9SAndroid Build Coastguard Worker     ~AutoJavaFloatArray();
289*d57664e9SAndroid Build Coastguard Worker 
ptr()290*d57664e9SAndroid Build Coastguard Worker     float* ptr() const { return fPtr; }
length()291*d57664e9SAndroid Build Coastguard Worker     int    length() const { return fLen; }
292*d57664e9SAndroid Build Coastguard Worker 
293*d57664e9SAndroid Build Coastguard Worker private:
294*d57664e9SAndroid Build Coastguard Worker     JNIEnv*     fEnv;
295*d57664e9SAndroid Build Coastguard Worker     jfloatArray fArray;
296*d57664e9SAndroid Build Coastguard Worker     float*      fPtr;
297*d57664e9SAndroid Build Coastguard Worker     int         fLen;
298*d57664e9SAndroid Build Coastguard Worker     int         fReleaseMode;
299*d57664e9SAndroid Build Coastguard Worker };
300*d57664e9SAndroid Build Coastguard Worker 
301*d57664e9SAndroid Build Coastguard Worker class AutoJavaIntArray {
302*d57664e9SAndroid Build Coastguard Worker public:
303*d57664e9SAndroid Build Coastguard Worker     AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
304*d57664e9SAndroid Build Coastguard Worker     ~AutoJavaIntArray();
305*d57664e9SAndroid Build Coastguard Worker 
ptr()306*d57664e9SAndroid Build Coastguard Worker     jint* ptr() const { return fPtr; }
length()307*d57664e9SAndroid Build Coastguard Worker     int    length() const { return fLen; }
308*d57664e9SAndroid Build Coastguard Worker 
309*d57664e9SAndroid Build Coastguard Worker private:
310*d57664e9SAndroid Build Coastguard Worker     JNIEnv*     fEnv;
311*d57664e9SAndroid Build Coastguard Worker     jintArray fArray;
312*d57664e9SAndroid Build Coastguard Worker     jint*      fPtr;
313*d57664e9SAndroid Build Coastguard Worker     int         fLen;
314*d57664e9SAndroid Build Coastguard Worker };
315*d57664e9SAndroid Build Coastguard Worker 
316*d57664e9SAndroid Build Coastguard Worker class AutoJavaShortArray {
317*d57664e9SAndroid Build Coastguard Worker public:
318*d57664e9SAndroid Build Coastguard Worker     AutoJavaShortArray(JNIEnv* env, jshortArray array,
319*d57664e9SAndroid Build Coastguard Worker                        int minLength = 0, JNIAccess = kRW_JNIAccess);
320*d57664e9SAndroid Build Coastguard Worker     ~AutoJavaShortArray();
321*d57664e9SAndroid Build Coastguard Worker 
ptr()322*d57664e9SAndroid Build Coastguard Worker     jshort* ptr() const { return fPtr; }
length()323*d57664e9SAndroid Build Coastguard Worker     int    length() const { return fLen; }
324*d57664e9SAndroid Build Coastguard Worker 
325*d57664e9SAndroid Build Coastguard Worker private:
326*d57664e9SAndroid Build Coastguard Worker     JNIEnv*     fEnv;
327*d57664e9SAndroid Build Coastguard Worker     jshortArray fArray;
328*d57664e9SAndroid Build Coastguard Worker     jshort*      fPtr;
329*d57664e9SAndroid Build Coastguard Worker     int         fLen;
330*d57664e9SAndroid Build Coastguard Worker     int         fReleaseMode;
331*d57664e9SAndroid Build Coastguard Worker };
332*d57664e9SAndroid Build Coastguard Worker 
333*d57664e9SAndroid Build Coastguard Worker class AutoJavaByteArray {
334*d57664e9SAndroid Build Coastguard Worker public:
335*d57664e9SAndroid Build Coastguard Worker     AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
336*d57664e9SAndroid Build Coastguard Worker     ~AutoJavaByteArray();
337*d57664e9SAndroid Build Coastguard Worker 
ptr()338*d57664e9SAndroid Build Coastguard Worker     jbyte* ptr() const { return fPtr; }
length()339*d57664e9SAndroid Build Coastguard Worker     int    length() const { return fLen; }
340*d57664e9SAndroid Build Coastguard Worker 
341*d57664e9SAndroid Build Coastguard Worker private:
342*d57664e9SAndroid Build Coastguard Worker     JNIEnv*     fEnv;
343*d57664e9SAndroid Build Coastguard Worker     jbyteArray fArray;
344*d57664e9SAndroid Build Coastguard Worker     jbyte*      fPtr;
345*d57664e9SAndroid Build Coastguard Worker     int         fLen;
346*d57664e9SAndroid Build Coastguard Worker };
347*d57664e9SAndroid Build Coastguard Worker 
348*d57664e9SAndroid Build Coastguard Worker class JGlobalRefHolder {
349*d57664e9SAndroid Build Coastguard Worker public:
JGlobalRefHolder(JavaVM * vm,jobject object)350*d57664e9SAndroid Build Coastguard Worker     JGlobalRefHolder(JavaVM* vm, jobject object) : mVm(vm), mObject(object) {}
351*d57664e9SAndroid Build Coastguard Worker 
~JGlobalRefHolder()352*d57664e9SAndroid Build Coastguard Worker     virtual ~JGlobalRefHolder() {
353*d57664e9SAndroid Build Coastguard Worker         env()->DeleteGlobalRef(mObject);
354*d57664e9SAndroid Build Coastguard Worker         mObject = nullptr;
355*d57664e9SAndroid Build Coastguard Worker     }
356*d57664e9SAndroid Build Coastguard Worker 
object()357*d57664e9SAndroid Build Coastguard Worker     jobject object() { return mObject; }
vm()358*d57664e9SAndroid Build Coastguard Worker     JavaVM* vm() { return mVm; }
359*d57664e9SAndroid Build Coastguard Worker 
env()360*d57664e9SAndroid Build Coastguard Worker     JNIEnv* env() {
361*d57664e9SAndroid Build Coastguard Worker         JNIEnv* env;
362*d57664e9SAndroid Build Coastguard Worker         if (mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
363*d57664e9SAndroid Build Coastguard Worker             LOG_ALWAYS_FATAL("Failed to get JNIEnv for JavaVM: %p", mVm);
364*d57664e9SAndroid Build Coastguard Worker         }
365*d57664e9SAndroid Build Coastguard Worker         return env;
366*d57664e9SAndroid Build Coastguard Worker     }
367*d57664e9SAndroid Build Coastguard Worker 
368*d57664e9SAndroid Build Coastguard Worker private:
369*d57664e9SAndroid Build Coastguard Worker     JGlobalRefHolder(const JGlobalRefHolder&) = delete;
370*d57664e9SAndroid Build Coastguard Worker     void operator=(const JGlobalRefHolder&) = delete;
371*d57664e9SAndroid Build Coastguard Worker 
372*d57664e9SAndroid Build Coastguard Worker     JavaVM* mVm;
373*d57664e9SAndroid Build Coastguard Worker     jobject mObject;
374*d57664e9SAndroid Build Coastguard Worker };
375*d57664e9SAndroid Build Coastguard Worker 
376*d57664e9SAndroid Build Coastguard Worker void doThrowNPE(JNIEnv* env);
377*d57664e9SAndroid Build Coastguard Worker void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
378*d57664e9SAndroid Build Coastguard Worker void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
379*d57664e9SAndroid Build Coastguard Worker void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
380*d57664e9SAndroid Build Coastguard Worker void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
381*d57664e9SAndroid Build Coastguard Worker void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
382*d57664e9SAndroid Build Coastguard Worker void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception
383*d57664e9SAndroid Build Coastguard Worker 
384*d57664e9SAndroid Build Coastguard Worker #define NPE_CHECK_RETURN_ZERO(env, object)    \
385*d57664e9SAndroid Build Coastguard Worker     do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
386*d57664e9SAndroid Build Coastguard Worker 
387*d57664e9SAndroid Build Coastguard Worker #define NPE_CHECK_RETURN_VOID(env, object)    \
388*d57664e9SAndroid Build Coastguard Worker     do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
389*d57664e9SAndroid Build Coastguard Worker 
390*d57664e9SAndroid Build Coastguard Worker #endif  // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
391