Home | History | Annotate | Download | only in graphics
      1 #ifndef GraphicsJNI_DEFINED
      2 #define GraphicsJNI_DEFINED
      3 
      4 #include "SkBitmap.h"
      5 #include "SkDevice.h"
      6 #include "SkPixelRef.h"
      7 #include "SkMallocPixelRef.h"
      8 #include "SkPoint.h"
      9 #include "SkRect.h"
     10 #include "SkImageDecoder.h"
     11 #include <jni.h>
     12 
     13 class SkBitmapRegionDecoder;
     14 class SkCanvas;
     15 class SkPaint;
     16 class SkPicture;
     17 
     18 class GraphicsJNI {
     19 public:
     20     enum BitmapCreateFlags {
     21         kBitmapCreateFlag_None = 0x0,
     22         kBitmapCreateFlag_Mutable = 0x1,
     23         kBitmapCreateFlag_Premultiplied = 0x2,
     24     };
     25 
     26     // returns true if an exception is set (and dumps it out to the Log)
     27     static bool hasException(JNIEnv*);
     28 
     29     static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
     30     static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
     31 
     32     static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
     33     static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
     34 
     35     static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
     36     static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
     37     static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
     38 
     39     static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
     40 
     41     static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
     42     static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
     43 
     44     static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
     45     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
     46 
     47     static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
     48     static SkPaint*  getNativePaint(JNIEnv*, jobject paint);
     49     static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
     50     static SkPicture* getNativePicture(JNIEnv*, jobject picture);
     51     static SkRegion* getNativeRegion(JNIEnv*, jobject region);
     52 
     53     /** Return the corresponding native config from the java Config enum,
     54         or kNo_Config if the java object is null.
     55     */
     56     static SkBitmap::Config getNativeBitmapConfig(JNIEnv*, jobject jconfig);
     57 
     58     /** Create a java Bitmap object given the native bitmap (required) and optional
     59         storage array (may be null).
     60         bitmap's SkAlphaType must already be in sync with bitmapCreateFlags.
     61     */
     62     static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, jbyteArray buffer,
     63             int bitmapCreateFlags, jbyteArray ninepatch, jintArray layoutbounds, int density = -1);
     64 
     65     static jobject createBitmap(JNIEnv* env, SkBitmap* bitmap, int bitmapCreateFlags,
     66             jbyteArray ninepatch, int density = -1);
     67 
     68     /** Reinitialize a bitmap. bitmap must already have its SkAlphaType set in
     69         sync with isPremultiplied
     70     */
     71     static void reinitBitmap(JNIEnv* env, jobject javaBitmap, SkBitmap* bitmap,
     72             bool isPremultiplied);
     73 
     74     static int getBitmapAllocationByteCount(JNIEnv* env, jobject javaBitmap);
     75 
     76     static jobject createRegion(JNIEnv* env, SkRegion* region);
     77 
     78     static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
     79 
     80     static jbyteArray allocateJavaPixelRef(JNIEnv* env, SkBitmap* bitmap,
     81             SkColorTable* ctable);
     82 
     83     /** Copy the colors in colors[] to the bitmap, convert to the correct
     84         format along the way.
     85     */
     86     static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
     87             int srcStride, int x, int y, int width, int height,
     88             const SkBitmap& dstBitmap, bool isPremultiplied);
     89 
     90     static jbyteArray getBitmapStorageObj(SkPixelRef *pixref);
     91 };
     92 
     93 class AndroidPixelRef : public SkMallocPixelRef {
     94 public:
     95     AndroidPixelRef(JNIEnv* env, const SkImageInfo& info, void* storage, size_t rowBytes,
     96             jbyteArray storageObj, SkColorTable* ctable);
     97 
     98     /**
     99      * Creates an AndroidPixelRef that wraps (and refs) another to reuse/share
    100      * the same storage and java byte array refcounting, yet have a different
    101      * color table.
    102      */
    103     AndroidPixelRef(AndroidPixelRef& wrappedPixelRef, const SkImageInfo& info,
    104             size_t rowBytes, SkColorTable* ctable);
    105 
    106     virtual ~AndroidPixelRef();
    107 
    108     jbyteArray getStorageObj();
    109 
    110     void setLocalJNIRef(jbyteArray arr);
    111 
    112     /** Used to hold a ref to the pixels when the Java bitmap may be collected.
    113      *  If specified, 'localref' is a valid JNI local reference to the byte array
    114      *  containing the pixel data.
    115      *
    116      *  'localref' may only be NULL if setLocalJNIRef() was already called with
    117      *  a JNI local ref that is still valid.
    118      */
    119     virtual void globalRef(void* localref=NULL);
    120 
    121     /** Release a ref that was acquired using globalRef(). */
    122     virtual void globalUnref();
    123 
    124 private:
    125     AndroidPixelRef* const fWrappedPixelRef; // if set, delegate memory management calls to this
    126 
    127     JavaVM* fVM;
    128     bool fOnJavaHeap; // If true, the memory was allocated on the Java heap
    129 
    130     jbyteArray fStorageObj; // The Java byte[] object used as the bitmap backing store
    131     bool fHasGlobalRef; // If true, fStorageObj holds a JNI global ref
    132 
    133     mutable int32_t fGlobalRefCnt;
    134 };
    135 
    136 /** A helper class for accessing Java-heap-allocated bitmaps.
    137  *  This should be used when calling into a JNI method that retains a
    138  *  reference to the bitmap longer than the lifetime of the Java Bitmap.
    139  *
    140  *  After creating an instance of this class, a call to
    141  *  AndroidPixelRef::globalRef() will allocate a JNI global reference
    142  *  to the backing buffer object.
    143  */
    144 class JavaHeapBitmapRef {
    145 public:
    146 
    147     JavaHeapBitmapRef(JNIEnv *env, SkBitmap* nativeBitmap, jbyteArray buffer);
    148     ~JavaHeapBitmapRef();
    149 
    150 private:
    151     JNIEnv* fEnv;
    152     SkBitmap* fNativeBitmap;
    153     jbyteArray fBuffer;
    154 };
    155 
    156 /** Allocator which allocates the backing buffer in the Java heap.
    157  *  Instances can only be used to perform a single allocation, which helps
    158  *  ensure that the allocated buffer is properly accounted for with a
    159  *  reference in the heap (or a JNI global reference).
    160  */
    161 class JavaPixelAllocator : public SkBitmap::Allocator {
    162 public:
    163     JavaPixelAllocator(JNIEnv* env);
    164     // overrides
    165     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
    166 
    167     /** Return the Java array object created for the last allocation.
    168      *  This returns a local JNI reference which the caller is responsible
    169      *  for storing appropriately (usually by passing it to the Bitmap
    170      *  constructor).
    171      */
    172     jbyteArray getStorageObj() { return fStorageObj; }
    173 
    174     /** Same as getStorageObj(), but also resets the allocator so that it
    175      *  can allocate again.
    176      */
    177     jbyteArray getStorageObjAndReset() {
    178         jbyteArray result = fStorageObj;
    179         fStorageObj = NULL;
    180         fAllocCount = 0;
    181         return result;
    182     };
    183 
    184 private:
    185     JavaVM* fVM;
    186     bool fAllocateInJavaHeap;
    187     jbyteArray fStorageObj;
    188     int fAllocCount;
    189 };
    190 
    191 enum JNIAccess {
    192     kRO_JNIAccess,
    193     kRW_JNIAccess
    194 };
    195 
    196 class AutoJavaFloatArray {
    197 public:
    198     AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
    199                        int minLength = 0, JNIAccess = kRW_JNIAccess);
    200     ~AutoJavaFloatArray();
    201 
    202     float* ptr() const { return fPtr; }
    203     int    length() const { return fLen; }
    204 
    205 private:
    206     JNIEnv*     fEnv;
    207     jfloatArray fArray;
    208     float*      fPtr;
    209     int         fLen;
    210     int         fReleaseMode;
    211 };
    212 
    213 class AutoJavaIntArray {
    214 public:
    215     AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
    216     ~AutoJavaIntArray();
    217 
    218     jint* ptr() const { return fPtr; }
    219     int    length() const { return fLen; }
    220 
    221 private:
    222     JNIEnv*     fEnv;
    223     jintArray fArray;
    224     jint*      fPtr;
    225     int         fLen;
    226 };
    227 
    228 class AutoJavaShortArray {
    229 public:
    230     AutoJavaShortArray(JNIEnv* env, jshortArray array,
    231                        int minLength = 0, JNIAccess = kRW_JNIAccess);
    232     ~AutoJavaShortArray();
    233 
    234     jshort* ptr() const { return fPtr; }
    235     int    length() const { return fLen; }
    236 
    237 private:
    238     JNIEnv*     fEnv;
    239     jshortArray fArray;
    240     jshort*      fPtr;
    241     int         fLen;
    242     int         fReleaseMode;
    243 };
    244 
    245 class AutoJavaByteArray {
    246 public:
    247     AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
    248     ~AutoJavaByteArray();
    249 
    250     jbyte* ptr() const { return fPtr; }
    251     int    length() const { return fLen; }
    252 
    253 private:
    254     JNIEnv*     fEnv;
    255     jbyteArray fArray;
    256     jbyte*      fPtr;
    257     int         fLen;
    258 };
    259 
    260 void doThrowNPE(JNIEnv* env);
    261 void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
    262 void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
    263 void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
    264 void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
    265 void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
    266 void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception
    267 
    268 #define NPE_CHECK_RETURN_ZERO(env, object)    \
    269     do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
    270 
    271 #define NPE_CHECK_RETURN_VOID(env, object)    \
    272     do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
    273 
    274 #endif
    275