11a9c27c312ba20b2ceafcde18ce451724782d2a5Ficus Kirkpatrick#define LOG_TAG "GraphicsJNI"
21a9c27c312ba20b2ceafcde18ce451724782d2a5Ficus Kirkpatrick
339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <unistd.h>
439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <sys/mman.h>
539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h"
78451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes#include "JNIHelp.h"
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "GraphicsJNI.h"
995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy#include "core_jni_helpers.h"
10e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy
11e4ac2d6b5723c95e648c489b187ddde449452c13Patrick Dubroy#include "SkCanvas.h"
1246cb9bdbf56b27cbf2ab878b41d21e30896a4feaLeon Scroggins#include "SkMath.h"
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SkRegion.h"
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h>
1539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews#include <cutils/ashmem.h>
16dccca44ffda4836b56a21da95a046c9708ffd49csergeyv#include <hwui/Canvas.h>
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
183d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger#include <Caches.h>
193d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger#include <TextureCache.h>
203d4eed7f1aa99401dabe2e45b82f98fb4fc2d754Derek Sollenberger
2195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guyusing namespace android;
2295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid doThrowNPE(JNIEnv* env) {
2469a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    jniThrowNullPointerException(env, NULL);
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid doThrowAIOOBE(JNIEnv* env) {
288451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid doThrowRE(JNIEnv* env, const char* msg) {
3269a017bc1d1649350f830dfada5c6ed5eac0b770Elliott Hughes    jniThrowRuntimeException(env, msg);
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid doThrowIAE(JNIEnv* env, const char* msg) {
368451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    jniThrowException(env, "java/lang/IllegalArgumentException", msg);
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid doThrowISE(JNIEnv* env, const char* msg) {
408451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    jniThrowException(env, "java/lang/IllegalStateException", msg);
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid doThrowOOME(JNIEnv* env, const char* msg) {
448451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    jniThrowException(env, "java/lang/OutOfMemoryError", msg);
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
47f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wenvoid doThrowIOE(JNIEnv* env, const char* msg) {
488451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes    jniThrowException(env, "java/io/IOException", msg);
49f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen}
50f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool GraphicsJNI::hasException(JNIEnv *env) {
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (env->ExceptionCheck() != 0) {
533762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("*** Uncaught exception returned from Java call!\n");
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        env->ExceptionDescribe();
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaFloatArray::AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
63c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed                                       int minLength, JNIAccess access)
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (array) {
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fLen = env->GetArrayLength(array);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fLen < minLength) {
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sk_throw();
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fPtr = env->GetFloatArrayElements(array, NULL);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
73c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed    fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaFloatArray::~AutoJavaFloatArray() {
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fPtr) {
78c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed        fEnv->ReleaseFloatArrayElements(fArray, fPtr, fReleaseMode);
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaIntArray::AutoJavaIntArray(JNIEnv* env, jintArray array,
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       int minLength)
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (array) {
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fLen = env->GetArrayLength(array);
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fLen < minLength) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sk_throw();
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fPtr = env->GetIntArrayElements(array, NULL);
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaIntArray::~AutoJavaIntArray() {
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fPtr) {
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fEnv->ReleaseIntArrayElements(fArray, fPtr, 0);
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaShortArray::AutoJavaShortArray(JNIEnv* env, jshortArray array,
102c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed                                       int minLength, JNIAccess access)
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (array) {
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fLen = env->GetArrayLength(array);
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fLen < minLength) {
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sk_throw();
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fPtr = env->GetShortArrayElements(array, NULL);
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
112c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed    fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaShortArray::~AutoJavaShortArray() {
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fPtr) {
117c04851fd0af87f44a7d7351e0c17442fa1d3fc28Mike Reed        fEnv->ReleaseShortArrayElements(fArray, fPtr, fReleaseMode);
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaByteArray::AutoJavaByteArray(JNIEnv* env, jbyteArray array,
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       int minLength)
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project: fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (array) {
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fLen = env->GetArrayLength(array);
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fLen < minLength) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sk_throw();
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fPtr = env->GetByteArrayElements(array, NULL);
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectAutoJavaByteArray::~AutoJavaByteArray() {
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (fPtr) {
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fEnv->ReleaseByteArrayElements(fArray, fPtr, 0);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gRect_class;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRect_leftFieldID;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRect_topFieldID;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRect_rightFieldID;
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRect_bottomFieldID;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gRectF_class;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRectF_leftFieldID;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRectF_topFieldID;
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRectF_rightFieldID;
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRectF_bottomFieldID;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gPoint_class;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gPoint_xFieldID;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gPoint_yFieldID;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gPointF_class;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gPointF_xFieldID;
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gPointF_yFieldID;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gBitmapConfig_class;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gBitmapConfig_nativeInstanceID;
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1656b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jclass   gBitmapRegionDecoder_class;
1666b849e2123be98eb2a1a25b8abf0b13a279ce952Wei-Ta Chenstatic jmethodID gBitmapRegionDecoder_constructorMethodID;
167f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gCanvas_class;
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gCanvas_nativeInstanceID;
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gPicture_class;
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gPicture_nativeInstanceID;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jclass   gRegion_class;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jfieldID gRegion_nativeInstanceID;
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jmethodID gRegion_constructorMethodID;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1787384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartierstatic jclass    gByte_class;
1797384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartierstatic jobject   gVMRuntime;
1807384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartierstatic jclass    gVMRuntime_class;
1817384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartierstatic jmethodID gVMRuntime_newNonMovableArray;
1827384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartierstatic jmethodID gVMRuntime_addressOf;
1837384b428c445f07540fd6a80a21727d03be65d96Mathieu Chartier
18495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_aFieldID;
18595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_bFieldID;
18695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_cFieldID;
18795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_dFieldID;
18895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_eFieldID;
18995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_fFieldID;
19095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gTransferParams_gFieldID;
19195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
19295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jclass gColorSpace_class;
19395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gColorSpace_IlluminantD50FieldID;
19495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gColorSpace_adaptMethodID;
19595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gColorSpace_getMethodID;
19695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gColorSpace_matchMethodID;
19795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
19895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jclass gColorSpaceRGB_class;
19995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gColorSpaceRGB_getTransferParametersMethodID;
20095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gColorSpaceRGB_getTransformMethodID;
20195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gColorSpaceRGB_constructorMethodID;
20295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
20395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jclass gColorSpace_Named_class;
20495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gColorSpace_Named_sRGBFieldID;
20595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jfieldID gColorSpace_Named_LinearExtendedSRGBFieldID;
20695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
20795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jclass gTransferParameters_class;
20895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guystatic jmethodID gTransferParameters_constructorMethodID;
20995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRect_class));
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *L = env->GetIntField(obj, gRect_leftFieldID);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *T = env->GetIntField(obj, gRect_topFieldID);
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *R = env->GetIntField(obj, gRect_rightFieldID);
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *B = env->GetIntField(obj, gRect_bottomFieldID);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid GraphicsJNI::set_jrect(JNIEnv* env, jobject obj, int L, int T, int R, int B)
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRect_class));
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_leftFieldID, L);
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_topFieldID, T);
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_rightFieldID, R);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_bottomFieldID, B);
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkIRect* GraphicsJNI::jrect_to_irect(JNIEnv* env, jobject obj, SkIRect* ir)
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRect_class));
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ir->set(env->GetIntField(obj, gRect_leftFieldID),
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetIntField(obj, gRect_topFieldID),
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetIntField(obj, gRect_rightFieldID),
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            env->GetIntField(obj, gRect_bottomFieldID));
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return ir;
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid GraphicsJNI::irect_to_jrect(const SkIRect& ir, JNIEnv* env, jobject obj)
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRect_class));
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_leftFieldID, ir.fLeft);
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_topFieldID, ir.fTop);
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_rightFieldID, ir.fRight);
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gRect_bottomFieldID, ir.fBottom);
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkRect* GraphicsJNI::jrectf_to_rect(JNIEnv* env, jobject obj, SkRect* r)
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRectF_class));
2568451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
2572e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III    r->set(env->GetFloatField(obj, gRectF_leftFieldID),
2582e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III           env->GetFloatField(obj, gRectF_topFieldID),
2592e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III           env->GetFloatField(obj, gRectF_rightFieldID),
2602e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III           env->GetFloatField(obj, gRectF_bottomFieldID));
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return r;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkRect* GraphicsJNI::jrect_to_rect(JNIEnv* env, jobject obj, SkRect* r)
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRect_class));
2678451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    r->set(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project           SkIntToScalar(env->GetIntField(obj, gRect_bottomFieldID)));
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return r;
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid GraphicsJNI::rect_to_jrectf(const SkRect& r, JNIEnv* env, jobject obj)
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gRectF_class));
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetFloatField(obj, gRectF_leftFieldID, SkScalarToFloat(r.fLeft));
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetFloatField(obj, gRectF_topFieldID, SkScalarToFloat(r.fTop));
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetFloatField(obj, gRectF_rightFieldID, SkScalarToFloat(r.fRight));
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetFloatField(obj, gRectF_bottomFieldID, SkScalarToFloat(r.fBottom));
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkIPoint* GraphicsJNI::jpoint_to_ipoint(JNIEnv* env, jobject obj, SkIPoint* point)
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gPoint_class));
2888451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    point->set(env->GetIntField(obj, gPoint_xFieldID),
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project               env->GetIntField(obj, gPoint_yFieldID));
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return point;
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid GraphicsJNI::ipoint_to_jpoint(const SkIPoint& ir, JNIEnv* env, jobject obj)
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gPoint_class));
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gPoint_xFieldID, ir.fX);
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetIntField(obj, gPoint_yFieldID, ir.fY);
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkPoint* GraphicsJNI::jpointf_to_point(JNIEnv* env, jobject obj, SkPoint* point)
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gPointF_class));
3058451b25a4422656bbd6657a5855e69c0f4d53c74Elliott Hughes
3062e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III    point->set(env->GetIntField(obj, gPointF_xFieldID),
3072e0103eb340822f9d580c1aa8492bae8394b8243Leon Scroggins III               env->GetIntField(obj, gPointF_yFieldID));
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return point;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid GraphicsJNI::point_to_jpointf(const SkPoint& r, JNIEnv* env, jobject obj)
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(obj, gPointF_class));
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetFloatField(obj, gPointF_xFieldID, SkScalarToFloat(r.fX));
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    env->SetFloatField(obj, gPointF_yFieldID, SkScalarToFloat(r.fY));
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319e8d2ebb5c29efb996179f9a4b62c78e4d3037e14Romain Guy// See enum values in GraphicsJNI.h
3201103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reedjint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) {
3211103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    switch (colorType) {
3229505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        case kRGBA_F16_SkColorType:
3239505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            return kRGBA_16F_LegacyBitmapConfig;
3241103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kN32_SkColorType:
3251103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed            return kARGB_8888_LegacyBitmapConfig;
3261103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kARGB_4444_SkColorType:
3271103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed            return kARGB_4444_LegacyBitmapConfig;
3281103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kRGB_565_SkColorType:
3291103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed            return kRGB_565_LegacyBitmapConfig;
3301103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kIndex_8_SkColorType:
3311103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed            return kIndex8_LegacyBitmapConfig;
3321103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kAlpha_8_SkColorType:
3331103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed            return kA8_LegacyBitmapConfig;
3341103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        case kUnknown_SkColorType:
3351103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        default:
3361103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed            break;
3371103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    }
3381103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return kNo_LegacyBitmapConfig;
3391103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed}
3401103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed
3411103b3255945d2eb2fa9c191e84e2270b343cca9Mike ReedSkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
3421103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    const uint8_t gConfig2ColorType[] = {
3431103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        kUnknown_SkColorType,
3441103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        kAlpha_8_SkColorType,
3451103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        kIndex_8_SkColorType,
3461103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        kRGB_565_SkColorType,
3471103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        kARGB_4444_SkColorType,
348da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv        kN32_SkColorType,
3499505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        kRGBA_F16_SkColorType,
3501103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        kN32_SkColorType
3511103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    };
3521103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed
3531103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    if (legacyConfig < 0 || legacyConfig > kLastEnum_LegacyBitmapConfig) {
3541103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed        legacyConfig = kNo_LegacyBitmapConfig;
3551103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    }
3561103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return static_cast<SkColorType>(gConfig2ColorType[legacyConfig]);
3571103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed}
3581103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed
359ed207b92747234eac88dd3664ecfb535e45d8ed1John Reckvoid GraphicsJNI::getSkBitmap(JNIEnv* env, jobject bitmap, SkBitmap* outBitmap) {
36095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    bitmap::toBitmap(env, bitmap).getSkBitmap(outBitmap);
361ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck}
362ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck
363aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyvSkPixelRef* GraphicsJNI::refSkPixelRef(JNIEnv* env, jobject jbitmap) {
364aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    android::Bitmap& bitmap = android::bitmap::toBitmap(env, jbitmap);
365aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    bitmap.ref();
366aed7f58fb05a25ce2112829e77c0eb5dd268e8a7sergeyv    return &bitmap;
367ed207b92747234eac88dd3664ecfb535e45d8ed1John Reck}
36842a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike ReedSkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) {
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == jconfig) {
37142a1d08df7d417fd4e67eabc91ff05ee77fd9995Mike Reed        return kUnknown_SkColorType;
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(jconfig, gBitmapConfig_class));
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
3751103b3255945d2eb2fa9c191e84e2270b343cca9Mike Reed    return legacyBitmapConfigToColorType(c);
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
378da6c8ffcc594493c3936f83255efccdbf964cd21sergeyvbool GraphicsJNI::isHardwareConfig(JNIEnv* env, jobject jconfig) {
379da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv    SkASSERT(env);
380da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv    if (NULL == jconfig) {
381da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv        return false;
382da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv    }
383da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv    int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
384da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv    return c == kHardware_LegacyBitmapConfig;
385da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv}
386da6c8ffcc594493c3936f83255efccdbf964cd21sergeyv
38719b4b019169424d62bf3edc40b9560984206cf80sergeyvjint GraphicsJNI::hardwareLegacyBitmapConfig() {
38819b4b019169424d62bf3edc40b9560984206cf80sergeyv    return kHardware_LegacyBitmapConfig;
38919b4b019169424d62bf3edc40b9560984206cf80sergeyv}
39019b4b019169424d62bf3edc40b9560984206cf80sergeyv
391c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reckandroid::Canvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(canvas);
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(canvas, gCanvas_class));
39536bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    jlong canvasHandle = env->GetLongField(canvas, gCanvas_nativeInstanceID);
396de92f4c72be8537d2efff6024390b9ab706286e1Bo Liu    if (!canvasHandle) {
397de92f4c72be8537d2efff6024390b9ab706286e1Bo Liu        return NULL;
398de92f4c72be8537d2efff6024390b9ab706286e1Bo Liu    }
399c1b33d665c8caf5760f68c45c6ca0baa649b832aJohn Reck    return reinterpret_cast<android::Canvas*>(canvasHandle);
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env);
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(region);
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(env->IsInstanceOf(region, gRegion_class));
40736bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    jlong regionHandle = env->GetLongField(region, gRegion_nativeInstanceID);
40836bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat    SkRegion* r = reinterpret_cast<SkRegion*>(regionHandle);
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(r);
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return r;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///////////////////////////////////////////////////////////////////////////////////////////
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4151f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarettjobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, SkBitmapRegionDecoder* bitmap)
416f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen{
417f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    SkASSERT(bitmap != NULL);
418f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
419cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes    jobject obj = env->NewObject(gBitmapRegionDecoder_class,
420cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes            gBitmapRegionDecoder_constructorMethodID,
421b091d47a2e31a30581aa210419ff09bcc8715cdfAshok Bhat            reinterpret_cast<jlong>(bitmap));
422cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes    hasException(env); // For the side effect of logging.
423f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen    return obj;
424f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen}
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjobject GraphicsJNI::createRegion(JNIEnv* env, SkRegion* region)
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    SkASSERT(region != NULL);
429cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes    jobject obj = env->NewObject(gRegion_class, gRegion_constructorMethodID,
43036bef0bf30d6bae48cf3837df351075ca4fce654Ashok Bhat                                 reinterpret_cast<jlong>(region), 0);
431cf6f7a0f006c0fcf59bb634cbe79f2a8500fd92aElliott Hughes    hasException(env); // For the side effect of logging.
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return obj;
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
437c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyvandroid::Bitmap* GraphicsJNI::mapAshmemBitmap(JNIEnv* env, SkBitmap* bitmap,
438003bdee0b6680b8ab0d1fa07451e50e8c3555160John Reck        SkColorTable* ctable, int fd, void* addr, size_t size, bool readOnly) {
43939d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    const SkImageInfo& info = bitmap->info();
440f35b989d26bb98900f6c5fa2e586326b30b6e161Leon Scroggins III    if (info.colorType() == kUnknown_SkColorType) {
44139d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews        doThrowIAE(env, "unknown bitmap configuration");
44239d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews        return nullptr;
44339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    }
44439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews
445a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown    if (!addr) {
446a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown        // Map existing ashmem region if not already mapped.
447a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown        int flags = readOnly ? (PROT_READ) : (PROT_READ | PROT_WRITE);
448003bdee0b6680b8ab0d1fa07451e50e8c3555160John Reck        size = ashmem_get_size_region(fd);
449003bdee0b6680b8ab0d1fa07451e50e8c3555160John Reck        addr = mmap(NULL, size, flags, MAP_SHARED, fd, 0);
450a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown        if (addr == MAP_FAILED) {
451a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown            return nullptr;
452a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown        }
45339d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    }
45439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews
45539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    // we must respect the rowBytes value already set on the bitmap instead of
45639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    // attempting to compute our own.
45739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    const size_t rowBytes = bitmap->rowBytes();
45839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews
459c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    auto wrapper = new android::Bitmap(addr, fd, size, info, rowBytes, ctable);
46039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    wrapper->getSkBitmap(bitmap);
461a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown    if (readOnly) {
462a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown        bitmap->pixelRef()->setImmutable();
463a316c5dfbc6355f536d765959cacb06bbfed76adJeff Brown    }
46439d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    // since we're already allocated, we lockPixels right away
46539d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    // HeapAllocator behaves this way too
46639d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    bitmap->lockPixels();
46739d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews
46839d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews    return wrapper;
46939d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews}
47039d7f30ebe490c1d6aee76b0b61e3e67dec13e34Riley Andrews
471253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guysk_sp<SkColorSpace> GraphicsJNI::defaultColorSpace() {
472253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy#ifdef ANDROID_ENABLE_LINEAR_BLENDING
47389ddb1f1644e0b47de060d2c9aaf6d5387c38f2fMatt Sarett    return SkColorSpace::MakeSRGB();
474253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy#else
475253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy    return nullptr;
476253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy#endif
477253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy}
478253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy
4799505a6552764461c22ce48f1ac13d025d23e1579Romain Guysk_sp<SkColorSpace> GraphicsJNI::linearColorSpace() {
48089ddb1f1644e0b47de060d2c9aaf6d5387c38f2fMatt Sarett    return SkColorSpace::MakeSRGBLinear();
4819505a6552764461c22ce48f1ac13d025d23e1579Romain Guy}
4829505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
4839505a6552764461c22ce48f1ac13d025d23e1579Romain Guysk_sp<SkColorSpace> GraphicsJNI::colorSpaceForType(SkColorType type) {
4849505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    switch (type) {
4859505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        case kRGBA_F16_SkColorType:
4869505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            return linearColorSpace();
4879505a6552764461c22ce48f1ac13d025d23e1579Romain Guy        default:
4889505a6552764461c22ce48f1ac13d025d23e1579Romain Guy            return defaultColorSpace();
4899505a6552764461c22ce48f1ac13d025d23e1579Romain Guy    }
4909505a6552764461c22ce48f1ac13d025d23e1579Romain Guy}
4919505a6552764461c22ce48f1ac13d025d23e1579Romain Guy
492ce217faddb4b40c1b3e698944da1951027080427Romain Guybool GraphicsJNI::isColorSpaceSRGB(SkColorSpace* colorSpace) {
4932ecdfc2a331ee38d4494377330721d93e9f77cedMatt Sarett    return colorSpace == nullptr || colorSpace->isSRGB();
494ce217faddb4b40c1b3e698944da1951027080427Romain Guy}
495ce217faddb4b40c1b3e698944da1951027080427Romain Guy
49695648b8a590995e57948ff2fd57d234bdbf30be0Romain GuySkColorSpaceTransferFn GraphicsJNI::getNativeTransferParameters(JNIEnv* env, jobject transferParams) {
49795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    SkColorSpaceTransferFn p;
49895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fA = (float) env->GetDoubleField(transferParams, gTransferParams_aFieldID);
49995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fB = (float) env->GetDoubleField(transferParams, gTransferParams_bFieldID);
50095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fC = (float) env->GetDoubleField(transferParams, gTransferParams_cFieldID);
50195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fD = (float) env->GetDoubleField(transferParams, gTransferParams_dFieldID);
50295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fE = (float) env->GetDoubleField(transferParams, gTransferParams_eFieldID);
50395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fF = (float) env->GetDoubleField(transferParams, gTransferParams_fFieldID);
50495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    p.fG = (float) env->GetDoubleField(transferParams, gTransferParams_gFieldID);
50595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    return p;
50695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy}
50795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
50895648b8a590995e57948ff2fd57d234bdbf30be0Romain GuySkMatrix44 GraphicsJNI::getNativeXYZMatrix(JNIEnv* env, jfloatArray xyzD50) {
50995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    SkMatrix44 xyzMatrix(SkMatrix44::kIdentity_Constructor);
51095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    jfloat* array = env->GetFloatArrayElements(xyzD50, NULL);
51195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(0, 0, array[0]);
51295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(1, 0, array[1]);
51395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(2, 0, array[2]);
51495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(0, 1, array[3]);
51595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(1, 1, array[4]);
51695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(2, 1, array[5]);
51795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(0, 2, array[6]);
51895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(1, 2, array[7]);
51995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    xyzMatrix.setFloat(2, 2, array[8]);
52095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    env->ReleaseFloatArrayElements(xyzD50, array, 0);
52195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    return xyzMatrix;
52295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy}
52395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
52495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guysk_sp<SkColorSpace> GraphicsJNI::getNativeColorSpace(JNIEnv* env, jobject colorSpace) {
52595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    if (colorSpace == nullptr) return nullptr;
52695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    if (!env->IsInstanceOf(colorSpace, gColorSpaceRGB_class)) {
52795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        doThrowIAE(env, "The color space must be an RGB color space");
52895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    }
52995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
53095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    jobject transferParams = env->CallObjectMethod(colorSpace,
53195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            gColorSpaceRGB_getTransferParametersMethodID);
53295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    if (transferParams == nullptr) {
53395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        doThrowIAE(env, "The color space must use an ICC parametric transfer function");
53495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    }
53595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
53695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    jfloatArray illuminantD50 = (jfloatArray) env->GetStaticObjectField(gColorSpace_class,
53795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            gColorSpace_IlluminantD50FieldID);
53895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    jobject colorSpaceD50 = env->CallStaticObjectMethod(gColorSpace_class,
53995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            gColorSpace_adaptMethodID, colorSpace, illuminantD50);
54095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
54195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    jfloatArray xyzD50 = (jfloatArray) env->CallObjectMethod(colorSpaceD50,
54295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            gColorSpaceRGB_getTransformMethodID);
54395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
54495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    SkMatrix44 xyzMatrix = getNativeXYZMatrix(env, xyzD50);
54595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    SkColorSpaceTransferFn transferFunction = getNativeTransferParameters(env, transferParams);
54695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
54795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    return SkColorSpace::MakeRGB(transferFunction, xyzMatrix);
54895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy}
54995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
55095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
55195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guyjobject GraphicsJNI::getColorSpace(JNIEnv* env, sk_sp<SkColorSpace>& decodeColorSpace,
55295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        SkColorType decodeColorType) {
55395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    jobject colorSpace = nullptr;
55495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
55595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    // No need to match, we know what the output color space will be
55695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    if (decodeColorType == kRGBA_F16_SkColorType) {
55795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        jobject linearExtendedSRGB = env->GetStaticObjectField(
55895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                gColorSpace_Named_class, gColorSpace_Named_LinearExtendedSRGBFieldID);
55995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
56095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                gColorSpace_getMethodID, linearExtendedSRGB);
56195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    } else {
56295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        // Same here, no need to match
56395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        if (decodeColorSpace->isSRGB()) {
56495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            jobject sRGB = env->GetStaticObjectField(
56595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    gColorSpace_Named_class, gColorSpace_Named_sRGBFieldID);
56695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
56795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    gColorSpace_getMethodID, sRGB);
56895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        } else if (decodeColorSpace.get() != nullptr) {
56995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            // Try to match against known RGB color spaces using the CIE XYZ D50
57095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            // conversion matrix and numerical transfer function parameters
57195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor);
57295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            LOG_ALWAYS_FATAL_IF(!decodeColorSpace->toXYZD50(&xyzMatrix));
57395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
57495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            SkColorSpaceTransferFn transferParams;
57595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            // We can only handle numerical transfer functions at the moment
57695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            LOG_ALWAYS_FATAL_IF(!decodeColorSpace->isNumericalTransferFn(&transferParams));
57795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
57895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            jobject params = env->NewObject(gTransferParameters_class,
57995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    gTransferParameters_constructorMethodID,
58095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    transferParams.fA, transferParams.fB, transferParams.fC,
58195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    transferParams.fD, transferParams.fE, transferParams.fF,
58295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    transferParams.fG);
58395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
58495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            jfloatArray xyzArray = env->NewFloatArray(9);
58595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            jfloat xyz[9] = {
58695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(0, 0),
58795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(1, 0),
58895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(2, 0),
58995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(0, 1),
59095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(1, 1),
59195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(2, 1),
59295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(0, 2),
59395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(1, 2),
59495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    xyzMatrix.getFloat(2, 2)
59595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            };
59695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            env->SetFloatArrayRegion(xyzArray, 0, 9, xyz);
59795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
59895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
59995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                    gColorSpace_matchMethodID, xyzArray, params);
60095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
60195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            if (colorSpace == nullptr) {
60295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                // We couldn't find an exact match, let's create a new color space
60395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                // instance with the 3x3 conversion matrix and transfer function
60495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                colorSpace = env->NewObject(gColorSpaceRGB_class,
60595648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                        gColorSpaceRGB_constructorMethodID,
60695648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy                        env->NewStringUTF("Unknown"), xyzArray, params);
60795648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            }
60895648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
60995648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy            env->DeleteLocalRef(xyzArray);
61095648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy        }
61195648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    }
61295648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy    return colorSpace;
61395648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy}
61495648b8a590995e57948ff2fd57d234bdbf30be0Romain Guy
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project///////////////////////////////////////////////////////////////////////////////
6164508218850faedea95371188da587b6734f5f3dasergeyvbool HeapAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
617c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv    mStorage = android::Bitmap::allocateHeapBitmap(bitmap, ctable);
618c69853c8b72540e5031d28e03cbce5a390c6959fsergeyv    return !!mStorage;
619f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen}
620f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
621f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen////////////////////////////////////////////////////////////////////////////////
622f1f48bc7f200f54c76b22d845d8ba8419879b375Joseph Wen
6231f979639c168ebdf77ad8d7771786fc321ce8234Matt SarettRecyclingClippingPixelAllocator::RecyclingClippingPixelAllocator(
624c1c54062f8cc9d47bdea820ae5ab6aef260b4488sergeyv        android::Bitmap* recycledBitmap, size_t recycledBytes)
6251f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    : mRecycledBitmap(recycledBitmap)
6261f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    , mRecycledBytes(recycledBytes)
6271f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    , mSkiaBitmap(nullptr)
6281f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    , mNeedsCopy(false)
6291f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett{}
6301f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
6311f979639c168ebdf77ad8d7771786fc321ce8234Matt SarettRecyclingClippingPixelAllocator::~RecyclingClippingPixelAllocator() {}
6321f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
6331f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarettbool RecyclingClippingPixelAllocator::allocPixelRef(SkBitmap* bitmap, SkColorTable* ctable) {
6341f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // Ensure that the caller did not pass in a NULL bitmap to the constructor or this
6351f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // function.
6361f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    LOG_ALWAYS_FATAL_IF(!mRecycledBitmap);
6371f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    LOG_ALWAYS_FATAL_IF(!bitmap);
6381f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    mSkiaBitmap = bitmap;
6391f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
6401f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // This behaves differently than the RecyclingPixelAllocator.  For backwards
6411f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // compatibility, the original color type of the recycled bitmap must be maintained.
6421f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    if (mRecycledBitmap->info().colorType() != bitmap->colorType()) {
6431f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett        return false;
6441f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    }
6451f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett
6461f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // The Skia bitmap specifies the width and height needed by the decoder.
6471f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // mRecycledBitmap specifies the width and height of the bitmap that we
6481f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // want to reuse.  Neither can be changed.  We will try to find a way
6491f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    // to reuse the memory.
6501f979639c168ebdf77ad8d7771786fc321ce8234Matt Sarett    const int maxWidth = SkTMax(bitmap->width(), mRecycledBitmap->info().width());
651