Home | History | Annotate | Download | only in graphics
      1 #ifndef _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
      2 #define _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
      3 
      4 #include "Bitmap.h"
      5 #include "SkBitmap.h"
      6 #include "SkDevice.h"
      7 #include "SkPixelRef.h"
      8 #include "SkMallocPixelRef.h"
      9 #include "SkPoint.h"
     10 #include "SkRect.h"
     11 #include "SkImageDecoder.h"
     12 #include <Canvas.h>
     13 #include <jni.h>
     14 
     15 class SkBitmapRegionDecoder;
     16 class SkCanvas;
     17 
     18 namespace android {
     19 class Paint;
     20 struct TypefaceImpl;
     21 }
     22 
     23 class GraphicsJNI {
     24 public:
     25     enum BitmapCreateFlags {
     26         kBitmapCreateFlag_None = 0x0,
     27         kBitmapCreateFlag_Mutable = 0x1,
     28         kBitmapCreateFlag_Premultiplied = 0x2,
     29     };
     30 
     31     // returns true if an exception is set (and dumps it out to the Log)
     32     static bool hasException(JNIEnv*);
     33 
     34     static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
     35     static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
     36 
     37     static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
     38     static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
     39 
     40     static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
     41     static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
     42     static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
     43 
     44     static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
     45 
     46     static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
     47     static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
     48 
     49     static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
     50     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
     51 
     52     static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
     53     static android::Bitmap* getBitmap(JNIEnv*, jobject bitmap);
     54     static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
     55     static SkPixelRef* refSkPixelRef(JNIEnv*, jobject bitmap);
     56     static SkRegion* getNativeRegion(JNIEnv*, jobject region);
     57 
     58     // Given the 'native' long held by the Rasterizer.java object, return a
     59     // ref to its SkRasterizer* (or NULL).
     60     static SkRasterizer* refNativeRasterizer(jlong rasterizerHandle);
     61 
     62     /*
     63      *  LegacyBitmapConfig is the old enum in Skia that matched the enum int values
     64      *  in Bitmap.Config. Skia no longer supports this config, but has replaced it
     65      *  with SkColorType. These routines convert between the two.
     66      */
     67     static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
     68     static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);
     69 
     70     /** Return the corresponding native colorType from the java Config enum,
     71         or kUnknown_SkColorType if the java object is null.
     72     */
     73     static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
     74 
     75     /*
     76      * Create a java Bitmap object given the native bitmap
     77      * bitmap's SkAlphaType must already be in sync with bitmapCreateFlags.
     78     */
     79     static jobject createBitmap(JNIEnv* env, android::Bitmap* bitmap,
     80             int bitmapCreateFlags, jbyteArray ninePatchChunk = NULL,
     81             jobject ninePatchInsets = NULL, int density = -1);
     82 
     83     /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
     84         sync with isPremultiplied
     85     */
     86     static void reinitBitmap(JNIEnv* env, jobject javaBitmap, const SkImageInfo& info,
     87             bool isPremultiplied);
     88 
     89     static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap);
     90 
     91     static jobject createRegion(JNIEnv* env, SkRegion* region);
     92 
     93     static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
     94 
     95     static android::Bitmap* allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
     96             SkColorTable* ctable);
     97 
     98     static android::Bitmap* allocateAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
     99             SkColorTable* ctable);
    100 
    101     static android::Bitmap* mapAshmemPixelRef(JNIEnv* env, SkBitmap* bitmap,
    102             SkColorTable* ctable, int fd, void* addr, bool readOnly);
    103 
    104     /**
    105      * Given a bitmap we natively allocate a memory block to store the contents
    106      * of that bitmap.  The memory is then attached to the bitmap via an
    107      * SkPixelRef, which ensures that upon deletion the appropriate caches
    108      * are notified.
    109      */
    110     static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable);
    111 
    112     /** Copy the colors in colors[] to the bitmap, convert to the correct
    113         format along the way.
    114         Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
    115     */
    116     static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
    117             int srcStride, int x, int y, int width, int height,
    118             const SkBitmap& dstBitmap);
    119 };
    120 
    121 /** Allocator which allocates the backing buffer in the Java heap.
    122  *  Instances can only be used to perform a single allocation, which helps
    123  *  ensure that the allocated buffer is properly accounted for with a
    124  *  reference in the heap (or a JNI global reference).
    125  */
    126 class JavaPixelAllocator : public SkBitmap::Allocator {
    127 public:
    128     JavaPixelAllocator(JNIEnv* env);
    129     ~JavaPixelAllocator();
    130 
    131     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
    132 
    133     /**
    134      * Fetches the backing allocation object. Must be called!
    135      */
    136     android::Bitmap* getStorageObjAndReset() {
    137         android::Bitmap* result = mStorage;
    138         mStorage = NULL;
    139         return result;
    140     };
    141 
    142 private:
    143     JavaVM* mJavaVM;
    144     android::Bitmap* mStorage = nullptr;
    145 };
    146 
    147 class AshmemPixelAllocator : public SkBitmap::Allocator {
    148 public:
    149     AshmemPixelAllocator(JNIEnv* env);
    150     ~AshmemPixelAllocator();
    151     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
    152     android::Bitmap* getStorageObjAndReset() {
    153         android::Bitmap* result = mStorage;
    154         mStorage = NULL;
    155         return result;
    156     };
    157 
    158 private:
    159     JavaVM* mJavaVM;
    160     android::Bitmap* mStorage = nullptr;
    161 };
    162 
    163 
    164 enum JNIAccess {
    165     kRO_JNIAccess,
    166     kRW_JNIAccess
    167 };
    168 
    169 class AutoJavaFloatArray {
    170 public:
    171     AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
    172                        int minLength = 0, JNIAccess = kRW_JNIAccess);
    173     ~AutoJavaFloatArray();
    174 
    175     float* ptr() const { return fPtr; }
    176     int    length() const { return fLen; }
    177 
    178 private:
    179     JNIEnv*     fEnv;
    180     jfloatArray fArray;
    181     float*      fPtr;
    182     int         fLen;
    183     int         fReleaseMode;
    184 };
    185 
    186 class AutoJavaIntArray {
    187 public:
    188     AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
    189     ~AutoJavaIntArray();
    190 
    191     jint* ptr() const { return fPtr; }
    192     int    length() const { return fLen; }
    193 
    194 private:
    195     JNIEnv*     fEnv;
    196     jintArray fArray;
    197     jint*      fPtr;
    198     int         fLen;
    199 };
    200 
    201 class AutoJavaShortArray {
    202 public:
    203     AutoJavaShortArray(JNIEnv* env, jshortArray array,
    204                        int minLength = 0, JNIAccess = kRW_JNIAccess);
    205     ~AutoJavaShortArray();
    206 
    207     jshort* ptr() const { return fPtr; }
    208     int    length() const { return fLen; }
    209 
    210 private:
    211     JNIEnv*     fEnv;
    212     jshortArray fArray;
    213     jshort*      fPtr;
    214     int         fLen;
    215     int         fReleaseMode;
    216 };
    217 
    218 class AutoJavaByteArray {
    219 public:
    220     AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
    221     ~AutoJavaByteArray();
    222 
    223     jbyte* ptr() const { return fPtr; }
    224     int    length() const { return fLen; }
    225 
    226 private:
    227     JNIEnv*     fEnv;
    228     jbyteArray fArray;
    229     jbyte*      fPtr;
    230     int         fLen;
    231 };
    232 
    233 void doThrowNPE(JNIEnv* env);
    234 void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
    235 void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
    236 void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
    237 void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
    238 void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
    239 void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception
    240 
    241 #define NPE_CHECK_RETURN_ZERO(env, object)    \
    242     do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
    243 
    244 #define NPE_CHECK_RETURN_VOID(env, object)    \
    245     do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
    246 
    247 #endif  // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
    248