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 "SkBRDAllocator.h"
      7 #include "SkCodec.h"
      8 #include "SkPixelRef.h"
      9 #include "SkMallocPixelRef.h"
     10 #include "SkPoint.h"
     11 #include "SkRect.h"
     12 #include "SkColorSpace.h"
     13 #include "SkMatrix44.h"
     14 #include <jni.h>
     15 #include <hwui/Canvas.h>
     16 #include <hwui/Bitmap.h>
     17 
     18 class SkBitmapRegionDecoder;
     19 class SkCanvas;
     20 
     21 namespace android {
     22 class Paint;
     23 struct Typeface;
     24 }
     25 
     26 class GraphicsJNI {
     27 public:
     28     // This enum must keep these int values, to match the int values
     29     // in the java Bitmap.Config enum.
     30     enum LegacyBitmapConfig {
     31         kNo_LegacyBitmapConfig          = 0,
     32         kA8_LegacyBitmapConfig          = 1,
     33         kIndex8_LegacyBitmapConfig      = 2,
     34         kRGB_565_LegacyBitmapConfig     = 3,
     35         kARGB_4444_LegacyBitmapConfig   = 4,
     36         kARGB_8888_LegacyBitmapConfig   = 5,
     37         kRGBA_16F_LegacyBitmapConfig    = 6,
     38         kHardware_LegacyBitmapConfig    = 7,
     39 
     40         kLastEnum_LegacyBitmapConfig = kHardware_LegacyBitmapConfig
     41     };
     42 
     43     // returns true if an exception is set (and dumps it out to the Log)
     44     static bool hasException(JNIEnv*);
     45 
     46     static void get_jrect(JNIEnv*, jobject jrect, int* L, int* T, int* R, int* B);
     47     static void set_jrect(JNIEnv*, jobject jrect, int L, int T, int R, int B);
     48 
     49     static SkIRect* jrect_to_irect(JNIEnv*, jobject jrect, SkIRect*);
     50     static void irect_to_jrect(const SkIRect&, JNIEnv*, jobject jrect);
     51 
     52     static SkRect* jrectf_to_rect(JNIEnv*, jobject jrectf, SkRect*);
     53     static SkRect* jrect_to_rect(JNIEnv*, jobject jrect, SkRect*);
     54     static void rect_to_jrectf(const SkRect&, JNIEnv*, jobject jrectf);
     55 
     56     static void set_jpoint(JNIEnv*, jobject jrect, int x, int y);
     57 
     58     static SkIPoint* jpoint_to_ipoint(JNIEnv*, jobject jpoint, SkIPoint* point);
     59     static void ipoint_to_jpoint(const SkIPoint& point, JNIEnv*, jobject jpoint);
     60 
     61     static SkPoint* jpointf_to_point(JNIEnv*, jobject jpointf, SkPoint* point);
     62     static void point_to_jpointf(const SkPoint& point, JNIEnv*, jobject jpointf);
     63 
     64     static android::Canvas* getNativeCanvas(JNIEnv*, jobject canvas);
     65     static void getSkBitmap(JNIEnv*, jobject bitmap, SkBitmap* outBitmap);
     66     static SkPixelRef* refSkPixelRef(JNIEnv*, jobject bitmap);
     67     static SkRegion* getNativeRegion(JNIEnv*, jobject region);
     68 
     69     // Given the 'native' long held by the Rasterizer.java object, return a
     70     // ref to its SkRasterizer* (or NULL).
     71     static sk_sp<SkRasterizer> refNativeRasterizer(jlong rasterizerHandle);
     72 
     73     /*
     74      *  LegacyBitmapConfig is the old enum in Skia that matched the enum int values
     75      *  in Bitmap.Config. Skia no longer supports this config, but has replaced it
     76      *  with SkColorType. These routines convert between the two.
     77      */
     78     static SkColorType legacyBitmapConfigToColorType(jint legacyConfig);
     79     static jint colorTypeToLegacyBitmapConfig(SkColorType colorType);
     80 
     81     /** Return the corresponding native colorType from the java Config enum,
     82         or kUnknown_SkColorType if the java object is null.
     83     */
     84     static SkColorType getNativeBitmapColorType(JNIEnv*, jobject jconfig);
     85 
     86     static bool isHardwareConfig(JNIEnv* env, jobject jconfig);
     87     static jint hardwareLegacyBitmapConfig();
     88 
     89     static jobject createRegion(JNIEnv* env, SkRegion* region);
     90 
     91     static jobject createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap);
     92 
     93     static android::Bitmap* mapAshmemBitmap(JNIEnv* env, SkBitmap* bitmap,
     94             SkColorTable* ctable, int fd, void* addr, size_t size, bool readOnly);
     95 
     96     /**
     97      * Given a bitmap we natively allocate a memory block to store the contents
     98      * of that bitmap.  The memory is then attached to the bitmap via an
     99      * SkPixelRef, which ensures that upon deletion the appropriate caches
    100      * are notified.
    101      */
    102     static bool allocatePixels(JNIEnv* env, SkBitmap* bitmap, SkColorTable* ctable);
    103 
    104     /** Copy the colors in colors[] to the bitmap, convert to the correct
    105         format along the way.
    106         Whether to use premultiplied pixels is determined by dstBitmap's alphaType.
    107     */
    108     static bool SetPixels(JNIEnv* env, jintArray colors, int srcOffset,
    109             int srcStride, int x, int y, int width, int height,
    110             const SkBitmap& dstBitmap);
    111 
    112     static sk_sp<SkColorSpace> defaultColorSpace();
    113     static sk_sp<SkColorSpace> linearColorSpace();
    114     static sk_sp<SkColorSpace> colorSpaceForType(SkColorType type);
    115     static bool isColorSpaceSRGB(SkColorSpace* colorSpace);
    116 
    117     static SkColorSpaceTransferFn getNativeTransferParameters(JNIEnv* env, jobject transferParams);
    118     static SkMatrix44 getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50);
    119     static sk_sp<SkColorSpace> getNativeColorSpace(JNIEnv* env, jobject colorSpace);
    120 
    121     static jobject getColorSpace(JNIEnv* env, sk_sp<SkColorSpace>& decodeColorSpace,
    122             SkColorType decodeColorType);
    123 };
    124 
    125 class HeapAllocator : public SkBRDAllocator {
    126 public:
    127    HeapAllocator() { };
    128     ~HeapAllocator() { };
    129 
    130     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
    131 
    132     /**
    133      * Fetches the backing allocation object. Must be called!
    134      */
    135     android::Bitmap* getStorageObjAndReset() {
    136         return mStorage.release();
    137     };
    138 
    139     SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kYes_ZeroInitialized; }
    140 private:
    141     sk_sp<android::Bitmap> mStorage;
    142 };
    143 
    144 /**
    145  *  Allocator to handle reusing bitmaps for BitmapRegionDecoder.
    146  *
    147  *  The BitmapRegionDecoder documentation states that, if it is
    148  *  provided, the recycled bitmap will always be reused, clipping
    149  *  the decoded output to fit in the recycled bitmap if necessary.
    150  *  This allocator implements that behavior.
    151  *
    152  *  Skia's SkBitmapRegionDecoder expects the memory that
    153  *  is allocated to be large enough to decode the entire region
    154  *  that is requested.  It will decode directly into the memory
    155  *  that is provided.
    156  *
    157  *  FIXME: BUG:25465958
    158  *  If the recycled bitmap is not large enough for the decode
    159  *  requested, meaning that a clip is required, we will allocate
    160  *  enough memory for Skia to perform the decode, and then copy
    161  *  from the decoded output into the recycled bitmap.
    162  *
    163  *  If the recycled bitmap is large enough for the decode requested,
    164  *  we will provide that memory for Skia to decode directly into.
    165  *
    166  *  This allocator should only be used for a single allocation.
    167  *  After we reuse the recycledBitmap once, it is dangerous to
    168  *  reuse it again, given that it still may be in use from our
    169  *  first allocation.
    170  */
    171 class RecyclingClippingPixelAllocator : public SkBRDAllocator {
    172 public:
    173 
    174     RecyclingClippingPixelAllocator(android::Bitmap* recycledBitmap,
    175             size_t recycledBytes);
    176 
    177     ~RecyclingClippingPixelAllocator();
    178 
    179     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) override;
    180 
    181     /**
    182      *  Must be called!
    183      *
    184      *  In the event that the recycled bitmap is not large enough for
    185      *  the allocation requested, we will allocate memory on the heap
    186      *  instead.  As a final step, once we are done using this memory,
    187      *  we will copy the contents of the heap memory into the recycled
    188      *  bitmap's memory, clipping as necessary.
    189      */
    190     void copyIfNecessary();
    191 
    192     /**
    193      *  Indicates that this allocator does not allocate zero initialized
    194      *  memory.
    195      */
    196     SkCodec::ZeroInitialized zeroInit() const override { return SkCodec::kNo_ZeroInitialized; }
    197 
    198 private:
    199     android::Bitmap* mRecycledBitmap;
    200     const size_t     mRecycledBytes;
    201     SkBitmap*        mSkiaBitmap;
    202     bool             mNeedsCopy;
    203 };
    204 
    205 class AshmemPixelAllocator : public SkBitmap::Allocator {
    206 public:
    207     explicit AshmemPixelAllocator(JNIEnv* env);
    208     ~AshmemPixelAllocator() { };
    209     virtual bool allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable);
    210     android::Bitmap* getStorageObjAndReset() {
    211         return mStorage.release();
    212     };
    213 
    214 private:
    215     JavaVM* mJavaVM;
    216     sk_sp<android::Bitmap> mStorage;
    217 };
    218 
    219 
    220 enum JNIAccess {
    221     kRO_JNIAccess,
    222     kRW_JNIAccess
    223 };
    224 
    225 class AutoJavaFloatArray {
    226 public:
    227     AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
    228                        int minLength = 0, JNIAccess = kRW_JNIAccess);
    229     ~AutoJavaFloatArray();
    230 
    231     float* ptr() const { return fPtr; }
    232     int    length() const { return fLen; }
    233 
    234 private:
    235     JNIEnv*     fEnv;
    236     jfloatArray fArray;
    237     float*      fPtr;
    238     int         fLen;
    239     int         fReleaseMode;
    240 };
    241 
    242 class AutoJavaIntArray {
    243 public:
    244     AutoJavaIntArray(JNIEnv* env, jintArray array, int minLength = 0);
    245     ~AutoJavaIntArray();
    246 
    247     jint* ptr() const { return fPtr; }
    248     int    length() const { return fLen; }
    249 
    250 private:
    251     JNIEnv*     fEnv;
    252     jintArray fArray;
    253     jint*      fPtr;
    254     int         fLen;
    255 };
    256 
    257 class AutoJavaShortArray {
    258 public:
    259     AutoJavaShortArray(JNIEnv* env, jshortArray array,
    260                        int minLength = 0, JNIAccess = kRW_JNIAccess);
    261     ~AutoJavaShortArray();
    262 
    263     jshort* ptr() const { return fPtr; }
    264     int    length() const { return fLen; }
    265 
    266 private:
    267     JNIEnv*     fEnv;
    268     jshortArray fArray;
    269     jshort*      fPtr;
    270     int         fLen;
    271     int         fReleaseMode;
    272 };
    273 
    274 class AutoJavaByteArray {
    275 public:
    276     AutoJavaByteArray(JNIEnv* env, jbyteArray array, int minLength = 0);
    277     ~AutoJavaByteArray();
    278 
    279     jbyte* ptr() const { return fPtr; }
    280     int    length() const { return fLen; }
    281 
    282 private:
    283     JNIEnv*     fEnv;
    284     jbyteArray fArray;
    285     jbyte*      fPtr;
    286     int         fLen;
    287 };
    288 
    289 void doThrowNPE(JNIEnv* env);
    290 void doThrowAIOOBE(JNIEnv* env); // Array Index Out Of Bounds Exception
    291 void doThrowIAE(JNIEnv* env, const char* msg = NULL);   // Illegal Argument
    292 void doThrowRE(JNIEnv* env, const char* msg = NULL);   // Runtime
    293 void doThrowISE(JNIEnv* env, const char* msg = NULL);   // Illegal State
    294 void doThrowOOME(JNIEnv* env, const char* msg = NULL);   // Out of memory
    295 void doThrowIOE(JNIEnv* env, const char* msg = NULL);   // IO Exception
    296 
    297 #define NPE_CHECK_RETURN_ZERO(env, object)    \
    298     do { if (NULL == (object)) { doThrowNPE(env); return 0; } } while (0)
    299 
    300 #define NPE_CHECK_RETURN_VOID(env, object)    \
    301     do { if (NULL == (object)) { doThrowNPE(env); return; } } while (0)
    302 
    303 #endif  // _ANDROID_GRAPHICS_GRAPHICS_JNI_H_
    304