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