1*d57664e9SAndroid Build Coastguard Worker #include <assert.h>
2*d57664e9SAndroid Build Coastguard Worker #include <cutils/ashmem.h>
3*d57664e9SAndroid Build Coastguard Worker #include <hwui/Canvas.h>
4*d57664e9SAndroid Build Coastguard Worker #include <log/log.h>
5*d57664e9SAndroid Build Coastguard Worker #include <nativehelper/JNIHelp.h>
6*d57664e9SAndroid Build Coastguard Worker #include <unistd.h>
7*d57664e9SAndroid Build Coastguard Worker
8*d57664e9SAndroid Build Coastguard Worker #include "GraphicsJNI.h"
9*d57664e9SAndroid Build Coastguard Worker #include "SkBitmap.h"
10*d57664e9SAndroid Build Coastguard Worker #include "SkCanvas.h"
11*d57664e9SAndroid Build Coastguard Worker #include "SkColor.h"
12*d57664e9SAndroid Build Coastguard Worker #include "SkColorSpace.h"
13*d57664e9SAndroid Build Coastguard Worker #include "SkFontMetrics.h"
14*d57664e9SAndroid Build Coastguard Worker #include "SkImageInfo.h"
15*d57664e9SAndroid Build Coastguard Worker #include "SkPixelRef.h"
16*d57664e9SAndroid Build Coastguard Worker #include "SkPoint.h"
17*d57664e9SAndroid Build Coastguard Worker #include "SkRect.h"
18*d57664e9SAndroid Build Coastguard Worker #include "SkRegion.h"
19*d57664e9SAndroid Build Coastguard Worker #include "SkSamplingOptions.h"
20*d57664e9SAndroid Build Coastguard Worker #include "SkTypes.h"
21*d57664e9SAndroid Build Coastguard Worker #include "jni.h"
22*d57664e9SAndroid Build Coastguard Worker
23*d57664e9SAndroid Build Coastguard Worker using namespace android;
24*d57664e9SAndroid Build Coastguard Worker
25*d57664e9SAndroid Build Coastguard Worker /*static*/ JavaVM* GraphicsJNI::mJavaVM = nullptr;
26*d57664e9SAndroid Build Coastguard Worker
setJavaVM(JavaVM * javaVM)27*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::setJavaVM(JavaVM* javaVM) {
28*d57664e9SAndroid Build Coastguard Worker mJavaVM = javaVM;
29*d57664e9SAndroid Build Coastguard Worker }
30*d57664e9SAndroid Build Coastguard Worker
31*d57664e9SAndroid Build Coastguard Worker /** return a pointer to the JNIEnv for this thread */
getJNIEnv()32*d57664e9SAndroid Build Coastguard Worker JNIEnv* GraphicsJNI::getJNIEnv() {
33*d57664e9SAndroid Build Coastguard Worker assert(mJavaVM != nullptr);
34*d57664e9SAndroid Build Coastguard Worker JNIEnv* env;
35*d57664e9SAndroid Build Coastguard Worker if (mJavaVM->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
36*d57664e9SAndroid Build Coastguard Worker return nullptr;
37*d57664e9SAndroid Build Coastguard Worker }
38*d57664e9SAndroid Build Coastguard Worker return env;
39*d57664e9SAndroid Build Coastguard Worker }
40*d57664e9SAndroid Build Coastguard Worker
41*d57664e9SAndroid Build Coastguard Worker /** create a JNIEnv* for this thread or assert if one already exists */
attachJNIEnv(const char * envName)42*d57664e9SAndroid Build Coastguard Worker JNIEnv* GraphicsJNI::attachJNIEnv(const char* envName) {
43*d57664e9SAndroid Build Coastguard Worker assert(getJNIEnv() == nullptr);
44*d57664e9SAndroid Build Coastguard Worker JNIEnv* env = nullptr;
45*d57664e9SAndroid Build Coastguard Worker JavaVMAttachArgs args = { JNI_VERSION_1_4, envName, NULL };
46*d57664e9SAndroid Build Coastguard Worker int result = mJavaVM->AttachCurrentThread(&env, (void*) &args);
47*d57664e9SAndroid Build Coastguard Worker if (result != JNI_OK) {
48*d57664e9SAndroid Build Coastguard Worker ALOGE("thread attach failed: %#x", result);
49*d57664e9SAndroid Build Coastguard Worker }
50*d57664e9SAndroid Build Coastguard Worker return env;
51*d57664e9SAndroid Build Coastguard Worker }
52*d57664e9SAndroid Build Coastguard Worker
53*d57664e9SAndroid Build Coastguard Worker /** detach the current thread from the JavaVM */
detachJNIEnv()54*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::detachJNIEnv() {
55*d57664e9SAndroid Build Coastguard Worker assert(mJavaVM != nullptr);
56*d57664e9SAndroid Build Coastguard Worker mJavaVM->DetachCurrentThread();
57*d57664e9SAndroid Build Coastguard Worker }
58*d57664e9SAndroid Build Coastguard Worker
doThrowNPE(JNIEnv * env)59*d57664e9SAndroid Build Coastguard Worker void doThrowNPE(JNIEnv* env) {
60*d57664e9SAndroid Build Coastguard Worker jniThrowNullPointerException(env, NULL);
61*d57664e9SAndroid Build Coastguard Worker }
62*d57664e9SAndroid Build Coastguard Worker
doThrowAIOOBE(JNIEnv * env)63*d57664e9SAndroid Build Coastguard Worker void doThrowAIOOBE(JNIEnv* env) {
64*d57664e9SAndroid Build Coastguard Worker jniThrowException(env, "java/lang/ArrayIndexOutOfBoundsException", NULL);
65*d57664e9SAndroid Build Coastguard Worker }
66*d57664e9SAndroid Build Coastguard Worker
doThrowRE(JNIEnv * env,const char * msg)67*d57664e9SAndroid Build Coastguard Worker void doThrowRE(JNIEnv* env, const char* msg) {
68*d57664e9SAndroid Build Coastguard Worker jniThrowRuntimeException(env, msg);
69*d57664e9SAndroid Build Coastguard Worker }
70*d57664e9SAndroid Build Coastguard Worker
doThrowIAE(JNIEnv * env,const char * msg)71*d57664e9SAndroid Build Coastguard Worker void doThrowIAE(JNIEnv* env, const char* msg) {
72*d57664e9SAndroid Build Coastguard Worker jniThrowException(env, "java/lang/IllegalArgumentException", msg);
73*d57664e9SAndroid Build Coastguard Worker }
74*d57664e9SAndroid Build Coastguard Worker
doThrowISE(JNIEnv * env,const char * msg)75*d57664e9SAndroid Build Coastguard Worker void doThrowISE(JNIEnv* env, const char* msg) {
76*d57664e9SAndroid Build Coastguard Worker jniThrowException(env, "java/lang/IllegalStateException", msg);
77*d57664e9SAndroid Build Coastguard Worker }
78*d57664e9SAndroid Build Coastguard Worker
doThrowOOME(JNIEnv * env,const char * msg)79*d57664e9SAndroid Build Coastguard Worker void doThrowOOME(JNIEnv* env, const char* msg) {
80*d57664e9SAndroid Build Coastguard Worker jniThrowException(env, "java/lang/OutOfMemoryError", msg);
81*d57664e9SAndroid Build Coastguard Worker }
82*d57664e9SAndroid Build Coastguard Worker
doThrowIOE(JNIEnv * env,const char * msg)83*d57664e9SAndroid Build Coastguard Worker void doThrowIOE(JNIEnv* env, const char* msg) {
84*d57664e9SAndroid Build Coastguard Worker jniThrowException(env, "java/io/IOException", msg);
85*d57664e9SAndroid Build Coastguard Worker }
86*d57664e9SAndroid Build Coastguard Worker
hasException(JNIEnv * env)87*d57664e9SAndroid Build Coastguard Worker bool GraphicsJNI::hasException(JNIEnv *env) {
88*d57664e9SAndroid Build Coastguard Worker if (env->ExceptionCheck() != 0) {
89*d57664e9SAndroid Build Coastguard Worker ALOGE("*** Uncaught exception returned from Java call!\n");
90*d57664e9SAndroid Build Coastguard Worker env->ExceptionDescribe();
91*d57664e9SAndroid Build Coastguard Worker return true;
92*d57664e9SAndroid Build Coastguard Worker }
93*d57664e9SAndroid Build Coastguard Worker return false;
94*d57664e9SAndroid Build Coastguard Worker }
95*d57664e9SAndroid Build Coastguard Worker
96*d57664e9SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
97*d57664e9SAndroid Build Coastguard Worker
AutoJavaFloatArray(JNIEnv * env,jfloatArray array,int minLength,JNIAccess access)98*d57664e9SAndroid Build Coastguard Worker AutoJavaFloatArray::AutoJavaFloatArray(JNIEnv* env, jfloatArray array,
99*d57664e9SAndroid Build Coastguard Worker int minLength, JNIAccess access)
100*d57664e9SAndroid Build Coastguard Worker : fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
101*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
102*d57664e9SAndroid Build Coastguard Worker if (array) {
103*d57664e9SAndroid Build Coastguard Worker fLen = env->GetArrayLength(array);
104*d57664e9SAndroid Build Coastguard Worker if (fLen < minLength) {
105*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("bad length");
106*d57664e9SAndroid Build Coastguard Worker }
107*d57664e9SAndroid Build Coastguard Worker fPtr = env->GetFloatArrayElements(array, NULL);
108*d57664e9SAndroid Build Coastguard Worker }
109*d57664e9SAndroid Build Coastguard Worker fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
110*d57664e9SAndroid Build Coastguard Worker }
111*d57664e9SAndroid Build Coastguard Worker
~AutoJavaFloatArray()112*d57664e9SAndroid Build Coastguard Worker AutoJavaFloatArray::~AutoJavaFloatArray() {
113*d57664e9SAndroid Build Coastguard Worker if (fPtr) {
114*d57664e9SAndroid Build Coastguard Worker fEnv->ReleaseFloatArrayElements(fArray, fPtr, fReleaseMode);
115*d57664e9SAndroid Build Coastguard Worker }
116*d57664e9SAndroid Build Coastguard Worker }
117*d57664e9SAndroid Build Coastguard Worker
AutoJavaIntArray(JNIEnv * env,jintArray array,int minLength)118*d57664e9SAndroid Build Coastguard Worker AutoJavaIntArray::AutoJavaIntArray(JNIEnv* env, jintArray array,
119*d57664e9SAndroid Build Coastguard Worker int minLength)
120*d57664e9SAndroid Build Coastguard Worker : fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
121*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
122*d57664e9SAndroid Build Coastguard Worker if (array) {
123*d57664e9SAndroid Build Coastguard Worker fLen = env->GetArrayLength(array);
124*d57664e9SAndroid Build Coastguard Worker if (fLen < minLength) {
125*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("bad length");
126*d57664e9SAndroid Build Coastguard Worker }
127*d57664e9SAndroid Build Coastguard Worker fPtr = env->GetIntArrayElements(array, NULL);
128*d57664e9SAndroid Build Coastguard Worker }
129*d57664e9SAndroid Build Coastguard Worker }
130*d57664e9SAndroid Build Coastguard Worker
~AutoJavaIntArray()131*d57664e9SAndroid Build Coastguard Worker AutoJavaIntArray::~AutoJavaIntArray() {
132*d57664e9SAndroid Build Coastguard Worker if (fPtr) {
133*d57664e9SAndroid Build Coastguard Worker fEnv->ReleaseIntArrayElements(fArray, fPtr, 0);
134*d57664e9SAndroid Build Coastguard Worker }
135*d57664e9SAndroid Build Coastguard Worker }
136*d57664e9SAndroid Build Coastguard Worker
AutoJavaShortArray(JNIEnv * env,jshortArray array,int minLength,JNIAccess access)137*d57664e9SAndroid Build Coastguard Worker AutoJavaShortArray::AutoJavaShortArray(JNIEnv* env, jshortArray array,
138*d57664e9SAndroid Build Coastguard Worker int minLength, JNIAccess access)
139*d57664e9SAndroid Build Coastguard Worker : fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
140*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
141*d57664e9SAndroid Build Coastguard Worker if (array) {
142*d57664e9SAndroid Build Coastguard Worker fLen = env->GetArrayLength(array);
143*d57664e9SAndroid Build Coastguard Worker if (fLen < minLength) {
144*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("bad length");
145*d57664e9SAndroid Build Coastguard Worker }
146*d57664e9SAndroid Build Coastguard Worker fPtr = env->GetShortArrayElements(array, NULL);
147*d57664e9SAndroid Build Coastguard Worker }
148*d57664e9SAndroid Build Coastguard Worker fReleaseMode = (access == kRO_JNIAccess) ? JNI_ABORT : 0;
149*d57664e9SAndroid Build Coastguard Worker }
150*d57664e9SAndroid Build Coastguard Worker
~AutoJavaShortArray()151*d57664e9SAndroid Build Coastguard Worker AutoJavaShortArray::~AutoJavaShortArray() {
152*d57664e9SAndroid Build Coastguard Worker if (fPtr) {
153*d57664e9SAndroid Build Coastguard Worker fEnv->ReleaseShortArrayElements(fArray, fPtr, fReleaseMode);
154*d57664e9SAndroid Build Coastguard Worker }
155*d57664e9SAndroid Build Coastguard Worker }
156*d57664e9SAndroid Build Coastguard Worker
AutoJavaByteArray(JNIEnv * env,jbyteArray array,int minLength)157*d57664e9SAndroid Build Coastguard Worker AutoJavaByteArray::AutoJavaByteArray(JNIEnv* env, jbyteArray array,
158*d57664e9SAndroid Build Coastguard Worker int minLength)
159*d57664e9SAndroid Build Coastguard Worker : fEnv(env), fArray(array), fPtr(NULL), fLen(0) {
160*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
161*d57664e9SAndroid Build Coastguard Worker if (array) {
162*d57664e9SAndroid Build Coastguard Worker fLen = env->GetArrayLength(array);
163*d57664e9SAndroid Build Coastguard Worker if (fLen < minLength) {
164*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL("bad length");
165*d57664e9SAndroid Build Coastguard Worker }
166*d57664e9SAndroid Build Coastguard Worker fPtr = env->GetByteArrayElements(array, NULL);
167*d57664e9SAndroid Build Coastguard Worker }
168*d57664e9SAndroid Build Coastguard Worker }
169*d57664e9SAndroid Build Coastguard Worker
~AutoJavaByteArray()170*d57664e9SAndroid Build Coastguard Worker AutoJavaByteArray::~AutoJavaByteArray() {
171*d57664e9SAndroid Build Coastguard Worker if (fPtr) {
172*d57664e9SAndroid Build Coastguard Worker fEnv->ReleaseByteArrayElements(fArray, fPtr, 0);
173*d57664e9SAndroid Build Coastguard Worker }
174*d57664e9SAndroid Build Coastguard Worker }
175*d57664e9SAndroid Build Coastguard Worker
176*d57664e9SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
177*d57664e9SAndroid Build Coastguard Worker
178*d57664e9SAndroid Build Coastguard Worker static jclass gRect_class;
179*d57664e9SAndroid Build Coastguard Worker static jfieldID gRect_leftFieldID;
180*d57664e9SAndroid Build Coastguard Worker static jfieldID gRect_topFieldID;
181*d57664e9SAndroid Build Coastguard Worker static jfieldID gRect_rightFieldID;
182*d57664e9SAndroid Build Coastguard Worker static jfieldID gRect_bottomFieldID;
183*d57664e9SAndroid Build Coastguard Worker
184*d57664e9SAndroid Build Coastguard Worker static jclass gRectF_class;
185*d57664e9SAndroid Build Coastguard Worker static jfieldID gRectF_leftFieldID;
186*d57664e9SAndroid Build Coastguard Worker static jfieldID gRectF_topFieldID;
187*d57664e9SAndroid Build Coastguard Worker static jfieldID gRectF_rightFieldID;
188*d57664e9SAndroid Build Coastguard Worker static jfieldID gRectF_bottomFieldID;
189*d57664e9SAndroid Build Coastguard Worker
190*d57664e9SAndroid Build Coastguard Worker static jclass gPoint_class;
191*d57664e9SAndroid Build Coastguard Worker static jfieldID gPoint_xFieldID;
192*d57664e9SAndroid Build Coastguard Worker static jfieldID gPoint_yFieldID;
193*d57664e9SAndroid Build Coastguard Worker
194*d57664e9SAndroid Build Coastguard Worker static jclass gPointF_class;
195*d57664e9SAndroid Build Coastguard Worker static jfieldID gPointF_xFieldID;
196*d57664e9SAndroid Build Coastguard Worker static jfieldID gPointF_yFieldID;
197*d57664e9SAndroid Build Coastguard Worker
198*d57664e9SAndroid Build Coastguard Worker static jclass gBitmapConfig_class;
199*d57664e9SAndroid Build Coastguard Worker static jfieldID gBitmapConfig_nativeInstanceID;
200*d57664e9SAndroid Build Coastguard Worker static jmethodID gBitmapConfig_nativeToConfigMethodID;
201*d57664e9SAndroid Build Coastguard Worker
202*d57664e9SAndroid Build Coastguard Worker static jclass gBitmapRegionDecoder_class;
203*d57664e9SAndroid Build Coastguard Worker static jmethodID gBitmapRegionDecoder_constructorMethodID;
204*d57664e9SAndroid Build Coastguard Worker
205*d57664e9SAndroid Build Coastguard Worker static jclass gCanvas_class;
206*d57664e9SAndroid Build Coastguard Worker static jfieldID gCanvas_nativeInstanceID;
207*d57664e9SAndroid Build Coastguard Worker
208*d57664e9SAndroid Build Coastguard Worker static jclass gPicture_class;
209*d57664e9SAndroid Build Coastguard Worker static jfieldID gPicture_nativeInstanceID;
210*d57664e9SAndroid Build Coastguard Worker
211*d57664e9SAndroid Build Coastguard Worker static jclass gRegion_class;
212*d57664e9SAndroid Build Coastguard Worker static jfieldID gRegion_nativeInstanceID;
213*d57664e9SAndroid Build Coastguard Worker static jmethodID gRegion_constructorMethodID;
214*d57664e9SAndroid Build Coastguard Worker
215*d57664e9SAndroid Build Coastguard Worker static jclass gByte_class;
216*d57664e9SAndroid Build Coastguard Worker
217*d57664e9SAndroid Build Coastguard Worker static jclass gColorSpace_class;
218*d57664e9SAndroid Build Coastguard Worker static jmethodID gColorSpace_getMethodID;
219*d57664e9SAndroid Build Coastguard Worker static jmethodID gColorSpace_matchMethodID;
220*d57664e9SAndroid Build Coastguard Worker
221*d57664e9SAndroid Build Coastguard Worker static jclass gColorSpaceRGB_class;
222*d57664e9SAndroid Build Coastguard Worker static jmethodID gColorSpaceRGB_constructorMethodID;
223*d57664e9SAndroid Build Coastguard Worker
224*d57664e9SAndroid Build Coastguard Worker static jclass gColorSpace_Named_class;
225*d57664e9SAndroid Build Coastguard Worker static jfieldID gColorSpace_Named_sRGBFieldID;
226*d57664e9SAndroid Build Coastguard Worker static jfieldID gColorSpace_Named_ExtendedSRGBFieldID;
227*d57664e9SAndroid Build Coastguard Worker static jfieldID gColorSpace_Named_LinearSRGBFieldID;
228*d57664e9SAndroid Build Coastguard Worker static jfieldID gColorSpace_Named_LinearExtendedSRGBFieldID;
229*d57664e9SAndroid Build Coastguard Worker
230*d57664e9SAndroid Build Coastguard Worker static jclass gTransferParameters_class;
231*d57664e9SAndroid Build Coastguard Worker static jmethodID gTransferParameters_constructorMethodID;
232*d57664e9SAndroid Build Coastguard Worker
233*d57664e9SAndroid Build Coastguard Worker static jclass gFontMetrics_class;
234*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetrics_top;
235*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetrics_ascent;
236*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetrics_descent;
237*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetrics_bottom;
238*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetrics_leading;
239*d57664e9SAndroid Build Coastguard Worker
240*d57664e9SAndroid Build Coastguard Worker static jclass gFontMetricsInt_class;
241*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetricsInt_top;
242*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetricsInt_ascent;
243*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetricsInt_descent;
244*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetricsInt_bottom;
245*d57664e9SAndroid Build Coastguard Worker static jfieldID gFontMetricsInt_leading;
246*d57664e9SAndroid Build Coastguard Worker
247*d57664e9SAndroid Build Coastguard Worker static jclass gRunInfo_class;
248*d57664e9SAndroid Build Coastguard Worker static jfieldID gRunInfo_clusterCount;
249*d57664e9SAndroid Build Coastguard Worker
250*d57664e9SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
251*d57664e9SAndroid Build Coastguard Worker
get_jrect(JNIEnv * env,jobject obj,int * L,int * T,int * R,int * B)252*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::get_jrect(JNIEnv* env, jobject obj, int* L, int* T, int* R, int* B)
253*d57664e9SAndroid Build Coastguard Worker {
254*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
255*d57664e9SAndroid Build Coastguard Worker
256*d57664e9SAndroid Build Coastguard Worker *L = env->GetIntField(obj, gRect_leftFieldID);
257*d57664e9SAndroid Build Coastguard Worker *T = env->GetIntField(obj, gRect_topFieldID);
258*d57664e9SAndroid Build Coastguard Worker *R = env->GetIntField(obj, gRect_rightFieldID);
259*d57664e9SAndroid Build Coastguard Worker *B = env->GetIntField(obj, gRect_bottomFieldID);
260*d57664e9SAndroid Build Coastguard Worker }
261*d57664e9SAndroid Build Coastguard Worker
set_jrect(JNIEnv * env,jobject obj,int L,int T,int R,int B)262*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::set_jrect(JNIEnv* env, jobject obj, int L, int T, int R, int B)
263*d57664e9SAndroid Build Coastguard Worker {
264*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
265*d57664e9SAndroid Build Coastguard Worker
266*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_leftFieldID, L);
267*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_topFieldID, T);
268*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_rightFieldID, R);
269*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_bottomFieldID, B);
270*d57664e9SAndroid Build Coastguard Worker }
271*d57664e9SAndroid Build Coastguard Worker
jrect_to_irect(JNIEnv * env,jobject obj,SkIRect * ir)272*d57664e9SAndroid Build Coastguard Worker SkIRect* GraphicsJNI::jrect_to_irect(JNIEnv* env, jobject obj, SkIRect* ir)
273*d57664e9SAndroid Build Coastguard Worker {
274*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
275*d57664e9SAndroid Build Coastguard Worker
276*d57664e9SAndroid Build Coastguard Worker ir->setLTRB(env->GetIntField(obj, gRect_leftFieldID),
277*d57664e9SAndroid Build Coastguard Worker env->GetIntField(obj, gRect_topFieldID),
278*d57664e9SAndroid Build Coastguard Worker env->GetIntField(obj, gRect_rightFieldID),
279*d57664e9SAndroid Build Coastguard Worker env->GetIntField(obj, gRect_bottomFieldID));
280*d57664e9SAndroid Build Coastguard Worker return ir;
281*d57664e9SAndroid Build Coastguard Worker }
282*d57664e9SAndroid Build Coastguard Worker
irect_to_jrect(const SkIRect & ir,JNIEnv * env,jobject obj)283*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::irect_to_jrect(const SkIRect& ir, JNIEnv* env, jobject obj)
284*d57664e9SAndroid Build Coastguard Worker {
285*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
286*d57664e9SAndroid Build Coastguard Worker
287*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_leftFieldID, ir.fLeft);
288*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_topFieldID, ir.fTop);
289*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_rightFieldID, ir.fRight);
290*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gRect_bottomFieldID, ir.fBottom);
291*d57664e9SAndroid Build Coastguard Worker }
292*d57664e9SAndroid Build Coastguard Worker
jrectf_to_rect(JNIEnv * env,jobject obj,SkRect * r)293*d57664e9SAndroid Build Coastguard Worker SkRect* GraphicsJNI::jrectf_to_rect(JNIEnv* env, jobject obj, SkRect* r)
294*d57664e9SAndroid Build Coastguard Worker {
295*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRectF_class));
296*d57664e9SAndroid Build Coastguard Worker
297*d57664e9SAndroid Build Coastguard Worker r->setLTRB(env->GetFloatField(obj, gRectF_leftFieldID),
298*d57664e9SAndroid Build Coastguard Worker env->GetFloatField(obj, gRectF_topFieldID),
299*d57664e9SAndroid Build Coastguard Worker env->GetFloatField(obj, gRectF_rightFieldID),
300*d57664e9SAndroid Build Coastguard Worker env->GetFloatField(obj, gRectF_bottomFieldID));
301*d57664e9SAndroid Build Coastguard Worker return r;
302*d57664e9SAndroid Build Coastguard Worker }
303*d57664e9SAndroid Build Coastguard Worker
jrect_to_rect(JNIEnv * env,jobject obj,SkRect * r)304*d57664e9SAndroid Build Coastguard Worker SkRect* GraphicsJNI::jrect_to_rect(JNIEnv* env, jobject obj, SkRect* r)
305*d57664e9SAndroid Build Coastguard Worker {
306*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRect_class));
307*d57664e9SAndroid Build Coastguard Worker
308*d57664e9SAndroid Build Coastguard Worker r->setLTRB(SkIntToScalar(env->GetIntField(obj, gRect_leftFieldID)),
309*d57664e9SAndroid Build Coastguard Worker SkIntToScalar(env->GetIntField(obj, gRect_topFieldID)),
310*d57664e9SAndroid Build Coastguard Worker SkIntToScalar(env->GetIntField(obj, gRect_rightFieldID)),
311*d57664e9SAndroid Build Coastguard Worker SkIntToScalar(env->GetIntField(obj, gRect_bottomFieldID)));
312*d57664e9SAndroid Build Coastguard Worker return r;
313*d57664e9SAndroid Build Coastguard Worker }
314*d57664e9SAndroid Build Coastguard Worker
rect_to_jrectf(const SkRect & r,JNIEnv * env,jobject obj)315*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::rect_to_jrectf(const SkRect& r, JNIEnv* env, jobject obj)
316*d57664e9SAndroid Build Coastguard Worker {
317*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gRectF_class));
318*d57664e9SAndroid Build Coastguard Worker
319*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(obj, gRectF_leftFieldID, SkScalarToFloat(r.fLeft));
320*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(obj, gRectF_topFieldID, SkScalarToFloat(r.fTop));
321*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(obj, gRectF_rightFieldID, SkScalarToFloat(r.fRight));
322*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(obj, gRectF_bottomFieldID, SkScalarToFloat(r.fBottom));
323*d57664e9SAndroid Build Coastguard Worker }
324*d57664e9SAndroid Build Coastguard Worker
jpoint_to_ipoint(JNIEnv * env,jobject obj,SkIPoint * point)325*d57664e9SAndroid Build Coastguard Worker SkIPoint* GraphicsJNI::jpoint_to_ipoint(JNIEnv* env, jobject obj, SkIPoint* point)
326*d57664e9SAndroid Build Coastguard Worker {
327*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gPoint_class));
328*d57664e9SAndroid Build Coastguard Worker
329*d57664e9SAndroid Build Coastguard Worker point->set(env->GetIntField(obj, gPoint_xFieldID),
330*d57664e9SAndroid Build Coastguard Worker env->GetIntField(obj, gPoint_yFieldID));
331*d57664e9SAndroid Build Coastguard Worker return point;
332*d57664e9SAndroid Build Coastguard Worker }
333*d57664e9SAndroid Build Coastguard Worker
ipoint_to_jpoint(const SkIPoint & ir,JNIEnv * env,jobject obj)334*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::ipoint_to_jpoint(const SkIPoint& ir, JNIEnv* env, jobject obj)
335*d57664e9SAndroid Build Coastguard Worker {
336*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gPoint_class));
337*d57664e9SAndroid Build Coastguard Worker
338*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gPoint_xFieldID, ir.fX);
339*d57664e9SAndroid Build Coastguard Worker env->SetIntField(obj, gPoint_yFieldID, ir.fY);
340*d57664e9SAndroid Build Coastguard Worker }
341*d57664e9SAndroid Build Coastguard Worker
jpointf_to_point(JNIEnv * env,jobject obj,SkPoint * point)342*d57664e9SAndroid Build Coastguard Worker SkPoint* GraphicsJNI::jpointf_to_point(JNIEnv* env, jobject obj, SkPoint* point)
343*d57664e9SAndroid Build Coastguard Worker {
344*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gPointF_class));
345*d57664e9SAndroid Build Coastguard Worker
346*d57664e9SAndroid Build Coastguard Worker point->set(env->GetIntField(obj, gPointF_xFieldID),
347*d57664e9SAndroid Build Coastguard Worker env->GetIntField(obj, gPointF_yFieldID));
348*d57664e9SAndroid Build Coastguard Worker return point;
349*d57664e9SAndroid Build Coastguard Worker }
350*d57664e9SAndroid Build Coastguard Worker
point_to_jpointf(const SkPoint & r,JNIEnv * env,jobject obj)351*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::point_to_jpointf(const SkPoint& r, JNIEnv* env, jobject obj)
352*d57664e9SAndroid Build Coastguard Worker {
353*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(obj, gPointF_class));
354*d57664e9SAndroid Build Coastguard Worker
355*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(obj, gPointF_xFieldID, SkScalarToFloat(r.fX));
356*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(obj, gPointF_yFieldID, SkScalarToFloat(r.fY));
357*d57664e9SAndroid Build Coastguard Worker }
358*d57664e9SAndroid Build Coastguard Worker
359*d57664e9SAndroid Build Coastguard Worker // See enum values in GraphicsJNI.h
colorTypeToLegacyBitmapConfig(SkColorType colorType)360*d57664e9SAndroid Build Coastguard Worker jint GraphicsJNI::colorTypeToLegacyBitmapConfig(SkColorType colorType) {
361*d57664e9SAndroid Build Coastguard Worker switch (colorType) {
362*d57664e9SAndroid Build Coastguard Worker case kRGBA_F16_SkColorType:
363*d57664e9SAndroid Build Coastguard Worker return kRGBA_16F_LegacyBitmapConfig;
364*d57664e9SAndroid Build Coastguard Worker case kN32_SkColorType:
365*d57664e9SAndroid Build Coastguard Worker return kARGB_8888_LegacyBitmapConfig;
366*d57664e9SAndroid Build Coastguard Worker case kARGB_4444_SkColorType:
367*d57664e9SAndroid Build Coastguard Worker return kARGB_4444_LegacyBitmapConfig;
368*d57664e9SAndroid Build Coastguard Worker case kRGB_565_SkColorType:
369*d57664e9SAndroid Build Coastguard Worker return kRGB_565_LegacyBitmapConfig;
370*d57664e9SAndroid Build Coastguard Worker case kAlpha_8_SkColorType:
371*d57664e9SAndroid Build Coastguard Worker return kA8_LegacyBitmapConfig;
372*d57664e9SAndroid Build Coastguard Worker case kRGBA_1010102_SkColorType:
373*d57664e9SAndroid Build Coastguard Worker return kRGBA_1010102_LegacyBitmapConfig;
374*d57664e9SAndroid Build Coastguard Worker case kUnknown_SkColorType:
375*d57664e9SAndroid Build Coastguard Worker default:
376*d57664e9SAndroid Build Coastguard Worker break;
377*d57664e9SAndroid Build Coastguard Worker }
378*d57664e9SAndroid Build Coastguard Worker return kNo_LegacyBitmapConfig;
379*d57664e9SAndroid Build Coastguard Worker }
380*d57664e9SAndroid Build Coastguard Worker
legacyBitmapConfigToColorType(jint legacyConfig)381*d57664e9SAndroid Build Coastguard Worker SkColorType GraphicsJNI::legacyBitmapConfigToColorType(jint legacyConfig) {
382*d57664e9SAndroid Build Coastguard Worker const uint8_t gConfig2ColorType[] = {
383*d57664e9SAndroid Build Coastguard Worker kUnknown_SkColorType, kAlpha_8_SkColorType,
384*d57664e9SAndroid Build Coastguard Worker kUnknown_SkColorType, // Previously kIndex_8_SkColorType,
385*d57664e9SAndroid Build Coastguard Worker kRGB_565_SkColorType, kARGB_4444_SkColorType, kN32_SkColorType,
386*d57664e9SAndroid Build Coastguard Worker kRGBA_F16_SkColorType, kN32_SkColorType, kRGBA_1010102_SkColorType,
387*d57664e9SAndroid Build Coastguard Worker };
388*d57664e9SAndroid Build Coastguard Worker
389*d57664e9SAndroid Build Coastguard Worker if (legacyConfig < 0 || legacyConfig > kLastEnum_LegacyBitmapConfig) {
390*d57664e9SAndroid Build Coastguard Worker legacyConfig = kNo_LegacyBitmapConfig;
391*d57664e9SAndroid Build Coastguard Worker }
392*d57664e9SAndroid Build Coastguard Worker return static_cast<SkColorType>(gConfig2ColorType[legacyConfig]);
393*d57664e9SAndroid Build Coastguard Worker }
394*d57664e9SAndroid Build Coastguard Worker
getFormatFromConfig(JNIEnv * env,jobject jconfig)395*d57664e9SAndroid Build Coastguard Worker AndroidBitmapFormat GraphicsJNI::getFormatFromConfig(JNIEnv* env, jobject jconfig) {
396*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
397*d57664e9SAndroid Build Coastguard Worker if (NULL == jconfig) {
398*d57664e9SAndroid Build Coastguard Worker return ANDROID_BITMAP_FORMAT_NONE;
399*d57664e9SAndroid Build Coastguard Worker }
400*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(jconfig, gBitmapConfig_class));
401*d57664e9SAndroid Build Coastguard Worker jint javaConfigId = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
402*d57664e9SAndroid Build Coastguard Worker
403*d57664e9SAndroid Build Coastguard Worker const AndroidBitmapFormat config2BitmapFormat[] = {
404*d57664e9SAndroid Build Coastguard Worker ANDROID_BITMAP_FORMAT_NONE, ANDROID_BITMAP_FORMAT_A_8,
405*d57664e9SAndroid Build Coastguard Worker ANDROID_BITMAP_FORMAT_NONE, // Previously Config.Index_8
406*d57664e9SAndroid Build Coastguard Worker ANDROID_BITMAP_FORMAT_RGB_565, ANDROID_BITMAP_FORMAT_RGBA_4444,
407*d57664e9SAndroid Build Coastguard Worker ANDROID_BITMAP_FORMAT_RGBA_8888, ANDROID_BITMAP_FORMAT_RGBA_F16,
408*d57664e9SAndroid Build Coastguard Worker ANDROID_BITMAP_FORMAT_NONE, // Congfig.HARDWARE
409*d57664e9SAndroid Build Coastguard Worker ANDROID_BITMAP_FORMAT_RGBA_1010102};
410*d57664e9SAndroid Build Coastguard Worker return config2BitmapFormat[javaConfigId];
411*d57664e9SAndroid Build Coastguard Worker }
412*d57664e9SAndroid Build Coastguard Worker
getConfigFromFormat(JNIEnv * env,AndroidBitmapFormat format)413*d57664e9SAndroid Build Coastguard Worker jobject GraphicsJNI::getConfigFromFormat(JNIEnv* env, AndroidBitmapFormat format) {
414*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
415*d57664e9SAndroid Build Coastguard Worker jint configId = kNo_LegacyBitmapConfig;
416*d57664e9SAndroid Build Coastguard Worker switch (format) {
417*d57664e9SAndroid Build Coastguard Worker case ANDROID_BITMAP_FORMAT_A_8:
418*d57664e9SAndroid Build Coastguard Worker configId = kA8_LegacyBitmapConfig;
419*d57664e9SAndroid Build Coastguard Worker break;
420*d57664e9SAndroid Build Coastguard Worker case ANDROID_BITMAP_FORMAT_RGB_565:
421*d57664e9SAndroid Build Coastguard Worker configId = kRGB_565_LegacyBitmapConfig;
422*d57664e9SAndroid Build Coastguard Worker break;
423*d57664e9SAndroid Build Coastguard Worker case ANDROID_BITMAP_FORMAT_RGBA_4444:
424*d57664e9SAndroid Build Coastguard Worker configId = kARGB_4444_LegacyBitmapConfig;
425*d57664e9SAndroid Build Coastguard Worker break;
426*d57664e9SAndroid Build Coastguard Worker case ANDROID_BITMAP_FORMAT_RGBA_8888:
427*d57664e9SAndroid Build Coastguard Worker configId = kARGB_8888_LegacyBitmapConfig;
428*d57664e9SAndroid Build Coastguard Worker break;
429*d57664e9SAndroid Build Coastguard Worker case ANDROID_BITMAP_FORMAT_RGBA_F16:
430*d57664e9SAndroid Build Coastguard Worker configId = kRGBA_16F_LegacyBitmapConfig;
431*d57664e9SAndroid Build Coastguard Worker break;
432*d57664e9SAndroid Build Coastguard Worker case ANDROID_BITMAP_FORMAT_RGBA_1010102:
433*d57664e9SAndroid Build Coastguard Worker configId = kRGBA_1010102_LegacyBitmapConfig;
434*d57664e9SAndroid Build Coastguard Worker break;
435*d57664e9SAndroid Build Coastguard Worker default:
436*d57664e9SAndroid Build Coastguard Worker break;
437*d57664e9SAndroid Build Coastguard Worker }
438*d57664e9SAndroid Build Coastguard Worker
439*d57664e9SAndroid Build Coastguard Worker return env->CallStaticObjectMethod(gBitmapConfig_class,
440*d57664e9SAndroid Build Coastguard Worker gBitmapConfig_nativeToConfigMethodID, configId);
441*d57664e9SAndroid Build Coastguard Worker }
442*d57664e9SAndroid Build Coastguard Worker
getNativeBitmapColorType(JNIEnv * env,jobject jconfig)443*d57664e9SAndroid Build Coastguard Worker SkColorType GraphicsJNI::getNativeBitmapColorType(JNIEnv* env, jobject jconfig) {
444*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
445*d57664e9SAndroid Build Coastguard Worker if (NULL == jconfig) {
446*d57664e9SAndroid Build Coastguard Worker return kUnknown_SkColorType;
447*d57664e9SAndroid Build Coastguard Worker }
448*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(jconfig, gBitmapConfig_class));
449*d57664e9SAndroid Build Coastguard Worker int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
450*d57664e9SAndroid Build Coastguard Worker return legacyBitmapConfigToColorType(c);
451*d57664e9SAndroid Build Coastguard Worker }
452*d57664e9SAndroid Build Coastguard Worker
isHardwareConfig(JNIEnv * env,jobject jconfig)453*d57664e9SAndroid Build Coastguard Worker bool GraphicsJNI::isHardwareConfig(JNIEnv* env, jobject jconfig) {
454*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
455*d57664e9SAndroid Build Coastguard Worker if (NULL == jconfig) {
456*d57664e9SAndroid Build Coastguard Worker return false;
457*d57664e9SAndroid Build Coastguard Worker }
458*d57664e9SAndroid Build Coastguard Worker int c = env->GetIntField(jconfig, gBitmapConfig_nativeInstanceID);
459*d57664e9SAndroid Build Coastguard Worker return c == kHardware_LegacyBitmapConfig;
460*d57664e9SAndroid Build Coastguard Worker }
461*d57664e9SAndroid Build Coastguard Worker
hardwareLegacyBitmapConfig()462*d57664e9SAndroid Build Coastguard Worker jint GraphicsJNI::hardwareLegacyBitmapConfig() {
463*d57664e9SAndroid Build Coastguard Worker return kHardware_LegacyBitmapConfig;
464*d57664e9SAndroid Build Coastguard Worker }
465*d57664e9SAndroid Build Coastguard Worker
getNativeCanvas(JNIEnv * env,jobject canvas)466*d57664e9SAndroid Build Coastguard Worker android::Canvas* GraphicsJNI::getNativeCanvas(JNIEnv* env, jobject canvas) {
467*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
468*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(canvas);
469*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(canvas, gCanvas_class));
470*d57664e9SAndroid Build Coastguard Worker jlong canvasHandle = env->GetLongField(canvas, gCanvas_nativeInstanceID);
471*d57664e9SAndroid Build Coastguard Worker if (!canvasHandle) {
472*d57664e9SAndroid Build Coastguard Worker return NULL;
473*d57664e9SAndroid Build Coastguard Worker }
474*d57664e9SAndroid Build Coastguard Worker return reinterpret_cast<android::Canvas*>(canvasHandle);
475*d57664e9SAndroid Build Coastguard Worker }
476*d57664e9SAndroid Build Coastguard Worker
getNativeRegion(JNIEnv * env,jobject region)477*d57664e9SAndroid Build Coastguard Worker SkRegion* GraphicsJNI::getNativeRegion(JNIEnv* env, jobject region)
478*d57664e9SAndroid Build Coastguard Worker {
479*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env);
480*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(region);
481*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(env->IsInstanceOf(region, gRegion_class));
482*d57664e9SAndroid Build Coastguard Worker jlong regionHandle = env->GetLongField(region, gRegion_nativeInstanceID);
483*d57664e9SAndroid Build Coastguard Worker SkRegion* r = reinterpret_cast<SkRegion*>(regionHandle);
484*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(r);
485*d57664e9SAndroid Build Coastguard Worker return r;
486*d57664e9SAndroid Build Coastguard Worker }
487*d57664e9SAndroid Build Coastguard Worker
set_metrics(JNIEnv * env,jobject metrics,const SkFontMetrics & skmetrics)488*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::set_metrics(JNIEnv* env, jobject metrics, const SkFontMetrics& skmetrics) {
489*d57664e9SAndroid Build Coastguard Worker if (metrics == nullptr) return;
490*d57664e9SAndroid Build Coastguard Worker LOG_FATAL_IF(!env->IsInstanceOf(metrics, gFontMetrics_class));
491*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(metrics, gFontMetrics_top, SkScalarToFloat(skmetrics.fTop));
492*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(metrics, gFontMetrics_ascent, SkScalarToFloat(skmetrics.fAscent));
493*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(metrics, gFontMetrics_descent, SkScalarToFloat(skmetrics.fDescent));
494*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(metrics, gFontMetrics_bottom, SkScalarToFloat(skmetrics.fBottom));
495*d57664e9SAndroid Build Coastguard Worker env->SetFloatField(metrics, gFontMetrics_leading, SkScalarToFloat(skmetrics.fLeading));
496*d57664e9SAndroid Build Coastguard Worker }
497*d57664e9SAndroid Build Coastguard Worker
set_metrics_int(JNIEnv * env,jobject metrics,const SkFontMetrics & skmetrics)498*d57664e9SAndroid Build Coastguard Worker int GraphicsJNI::set_metrics_int(JNIEnv* env, jobject metrics, const SkFontMetrics& skmetrics) {
499*d57664e9SAndroid Build Coastguard Worker int ascent = SkScalarRoundToInt(skmetrics.fAscent);
500*d57664e9SAndroid Build Coastguard Worker int descent = SkScalarRoundToInt(skmetrics.fDescent);
501*d57664e9SAndroid Build Coastguard Worker int leading = SkScalarRoundToInt(skmetrics.fLeading);
502*d57664e9SAndroid Build Coastguard Worker
503*d57664e9SAndroid Build Coastguard Worker if (metrics) {
504*d57664e9SAndroid Build Coastguard Worker LOG_FATAL_IF(!env->IsInstanceOf(metrics, gFontMetricsInt_class));
505*d57664e9SAndroid Build Coastguard Worker env->SetIntField(metrics, gFontMetricsInt_top, SkScalarFloorToInt(skmetrics.fTop));
506*d57664e9SAndroid Build Coastguard Worker env->SetIntField(metrics, gFontMetricsInt_ascent, ascent);
507*d57664e9SAndroid Build Coastguard Worker env->SetIntField(metrics, gFontMetricsInt_descent, descent);
508*d57664e9SAndroid Build Coastguard Worker env->SetIntField(metrics, gFontMetricsInt_bottom, SkScalarCeilToInt(skmetrics.fBottom));
509*d57664e9SAndroid Build Coastguard Worker env->SetIntField(metrics, gFontMetricsInt_leading, leading);
510*d57664e9SAndroid Build Coastguard Worker }
511*d57664e9SAndroid Build Coastguard Worker return descent - ascent + leading;
512*d57664e9SAndroid Build Coastguard Worker }
513*d57664e9SAndroid Build Coastguard Worker
set_cluster_count_to_run_info(JNIEnv * env,jobject runInfo,jint clusterCount)514*d57664e9SAndroid Build Coastguard Worker void GraphicsJNI::set_cluster_count_to_run_info(JNIEnv* env, jobject runInfo, jint clusterCount) {
515*d57664e9SAndroid Build Coastguard Worker env->SetIntField(runInfo, gRunInfo_clusterCount, clusterCount);
516*d57664e9SAndroid Build Coastguard Worker }
517*d57664e9SAndroid Build Coastguard Worker
518*d57664e9SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////////////
519*d57664e9SAndroid Build Coastguard Worker
createBitmapRegionDecoder(JNIEnv * env,BitmapRegionDecoderWrapper * bitmap)520*d57664e9SAndroid Build Coastguard Worker jobject GraphicsJNI::createBitmapRegionDecoder(JNIEnv* env, BitmapRegionDecoderWrapper* bitmap) {
521*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(bitmap != NULL);
522*d57664e9SAndroid Build Coastguard Worker
523*d57664e9SAndroid Build Coastguard Worker jobject obj = env->NewObject(gBitmapRegionDecoder_class,
524*d57664e9SAndroid Build Coastguard Worker gBitmapRegionDecoder_constructorMethodID,
525*d57664e9SAndroid Build Coastguard Worker reinterpret_cast<jlong>(bitmap));
526*d57664e9SAndroid Build Coastguard Worker hasException(env); // For the side effect of logging.
527*d57664e9SAndroid Build Coastguard Worker return obj;
528*d57664e9SAndroid Build Coastguard Worker }
529*d57664e9SAndroid Build Coastguard Worker
createRegion(JNIEnv * env,SkRegion * region)530*d57664e9SAndroid Build Coastguard Worker jobject GraphicsJNI::createRegion(JNIEnv* env, SkRegion* region)
531*d57664e9SAndroid Build Coastguard Worker {
532*d57664e9SAndroid Build Coastguard Worker ALOG_ASSERT(region != NULL);
533*d57664e9SAndroid Build Coastguard Worker jobject obj = env->NewObject(gRegion_class, gRegion_constructorMethodID,
534*d57664e9SAndroid Build Coastguard Worker reinterpret_cast<jlong>(region), 0);
535*d57664e9SAndroid Build Coastguard Worker hasException(env); // For the side effect of logging.
536*d57664e9SAndroid Build Coastguard Worker return obj;
537*d57664e9SAndroid Build Coastguard Worker }
538*d57664e9SAndroid Build Coastguard Worker
539*d57664e9SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
540*d57664e9SAndroid Build Coastguard Worker
getColorSpace(JNIEnv * env,SkColorSpace * decodeColorSpace,SkColorType decodeColorType)541*d57664e9SAndroid Build Coastguard Worker jobject GraphicsJNI::getColorSpace(JNIEnv* env, SkColorSpace* decodeColorSpace,
542*d57664e9SAndroid Build Coastguard Worker SkColorType decodeColorType) {
543*d57664e9SAndroid Build Coastguard Worker if (!decodeColorSpace || decodeColorType == kAlpha_8_SkColorType) {
544*d57664e9SAndroid Build Coastguard Worker return nullptr;
545*d57664e9SAndroid Build Coastguard Worker }
546*d57664e9SAndroid Build Coastguard Worker
547*d57664e9SAndroid Build Coastguard Worker // Special checks for the common sRGB cases and their extended variants.
548*d57664e9SAndroid Build Coastguard Worker jobject namedCS = nullptr;
549*d57664e9SAndroid Build Coastguard Worker sk_sp<SkColorSpace> srgbLinear = SkColorSpace::MakeSRGBLinear();
550*d57664e9SAndroid Build Coastguard Worker if (decodeColorType == kRGBA_F16_SkColorType) {
551*d57664e9SAndroid Build Coastguard Worker // An F16 Bitmap will always report that it is EXTENDED if
552*d57664e9SAndroid Build Coastguard Worker // it matches a ColorSpace that has an EXTENDED variant.
553*d57664e9SAndroid Build Coastguard Worker if (decodeColorSpace->isSRGB()) {
554*d57664e9SAndroid Build Coastguard Worker namedCS = env->GetStaticObjectField(gColorSpace_Named_class,
555*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_ExtendedSRGBFieldID);
556*d57664e9SAndroid Build Coastguard Worker } else if (decodeColorSpace == srgbLinear.get()) {
557*d57664e9SAndroid Build Coastguard Worker namedCS = env->GetStaticObjectField(gColorSpace_Named_class,
558*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_LinearExtendedSRGBFieldID);
559*d57664e9SAndroid Build Coastguard Worker }
560*d57664e9SAndroid Build Coastguard Worker } else if (decodeColorSpace->isSRGB()) {
561*d57664e9SAndroid Build Coastguard Worker namedCS = env->GetStaticObjectField(gColorSpace_Named_class,
562*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_sRGBFieldID);
563*d57664e9SAndroid Build Coastguard Worker } else if (decodeColorSpace == srgbLinear.get()) {
564*d57664e9SAndroid Build Coastguard Worker namedCS = env->GetStaticObjectField(gColorSpace_Named_class,
565*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_LinearSRGBFieldID);
566*d57664e9SAndroid Build Coastguard Worker }
567*d57664e9SAndroid Build Coastguard Worker
568*d57664e9SAndroid Build Coastguard Worker if (namedCS) {
569*d57664e9SAndroid Build Coastguard Worker return env->CallStaticObjectMethod(gColorSpace_class, gColorSpace_getMethodID, namedCS);
570*d57664e9SAndroid Build Coastguard Worker }
571*d57664e9SAndroid Build Coastguard Worker
572*d57664e9SAndroid Build Coastguard Worker // Try to match against known RGB color spaces using the CIE XYZ D50
573*d57664e9SAndroid Build Coastguard Worker // conversion matrix and numerical transfer function parameters
574*d57664e9SAndroid Build Coastguard Worker skcms_Matrix3x3 xyzMatrix;
575*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!decodeColorSpace->toXYZD50(&xyzMatrix));
576*d57664e9SAndroid Build Coastguard Worker
577*d57664e9SAndroid Build Coastguard Worker skcms_TransferFunction transferParams;
578*d57664e9SAndroid Build Coastguard Worker decodeColorSpace->transferFn(&transferParams);
579*d57664e9SAndroid Build Coastguard Worker auto res = skcms_TransferFunction_getType(&transferParams);
580*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(res == skcms_TFType_HLGinvish || res == skcms_TFType_Invalid);
581*d57664e9SAndroid Build Coastguard Worker
582*d57664e9SAndroid Build Coastguard Worker jobject params;
583*d57664e9SAndroid Build Coastguard Worker params = env->NewObject(gTransferParameters_class, gTransferParameters_constructorMethodID,
584*d57664e9SAndroid Build Coastguard Worker transferParams.a, transferParams.b, transferParams.c, transferParams.d,
585*d57664e9SAndroid Build Coastguard Worker transferParams.e, transferParams.f, transferParams.g);
586*d57664e9SAndroid Build Coastguard Worker
587*d57664e9SAndroid Build Coastguard Worker // Some transfer functions that are considered valid by Skia are not
588*d57664e9SAndroid Build Coastguard Worker // accepted by android.graphics.
589*d57664e9SAndroid Build Coastguard Worker if (hasException(env)) {
590*d57664e9SAndroid Build Coastguard Worker // Callers (e.g. Bitmap#getColorSpace) are not expected to throw an
591*d57664e9SAndroid Build Coastguard Worker // Exception, so clear it and return null, which is a documented
592*d57664e9SAndroid Build Coastguard Worker // possibility.
593*d57664e9SAndroid Build Coastguard Worker env->ExceptionClear();
594*d57664e9SAndroid Build Coastguard Worker return nullptr;
595*d57664e9SAndroid Build Coastguard Worker }
596*d57664e9SAndroid Build Coastguard Worker
597*d57664e9SAndroid Build Coastguard Worker jfloatArray xyzArray = env->NewFloatArray(9);
598*d57664e9SAndroid Build Coastguard Worker jfloat xyz[9] = {
599*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[0][0],
600*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[1][0],
601*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[2][0],
602*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[0][1],
603*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[1][1],
604*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[2][1],
605*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[0][2],
606*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[1][2],
607*d57664e9SAndroid Build Coastguard Worker xyzMatrix.vals[2][2]
608*d57664e9SAndroid Build Coastguard Worker };
609*d57664e9SAndroid Build Coastguard Worker env->SetFloatArrayRegion(xyzArray, 0, 9, xyz);
610*d57664e9SAndroid Build Coastguard Worker
611*d57664e9SAndroid Build Coastguard Worker jobject colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
612*d57664e9SAndroid Build Coastguard Worker gColorSpace_matchMethodID, xyzArray, params);
613*d57664e9SAndroid Build Coastguard Worker
614*d57664e9SAndroid Build Coastguard Worker if (colorSpace == nullptr) {
615*d57664e9SAndroid Build Coastguard Worker // We couldn't find an exact match, let's create a new color space
616*d57664e9SAndroid Build Coastguard Worker // instance with the 3x3 conversion matrix and transfer function
617*d57664e9SAndroid Build Coastguard Worker colorSpace = env->NewObject(gColorSpaceRGB_class,
618*d57664e9SAndroid Build Coastguard Worker gColorSpaceRGB_constructorMethodID,
619*d57664e9SAndroid Build Coastguard Worker env->NewStringUTF("Unknown"), xyzArray, params);
620*d57664e9SAndroid Build Coastguard Worker }
621*d57664e9SAndroid Build Coastguard Worker
622*d57664e9SAndroid Build Coastguard Worker env->DeleteLocalRef(xyzArray);
623*d57664e9SAndroid Build Coastguard Worker return colorSpace;
624*d57664e9SAndroid Build Coastguard Worker }
625*d57664e9SAndroid Build Coastguard Worker
626*d57664e9SAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
allocPixelRef(SkBitmap * bitmap)627*d57664e9SAndroid Build Coastguard Worker bool HeapAllocator::allocPixelRef(SkBitmap* bitmap) {
628*d57664e9SAndroid Build Coastguard Worker mStorage = android::Bitmap::allocateHeapBitmap(bitmap);
629*d57664e9SAndroid Build Coastguard Worker return !!mStorage;
630*d57664e9SAndroid Build Coastguard Worker }
631*d57664e9SAndroid Build Coastguard Worker
632*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
633*d57664e9SAndroid Build Coastguard Worker
RecyclingClippingPixelAllocator(android::Bitmap * recycledBitmap,bool mustMatchColorType,std::optional<SkRect> desiredSubset)634*d57664e9SAndroid Build Coastguard Worker RecyclingClippingPixelAllocator::RecyclingClippingPixelAllocator(
635*d57664e9SAndroid Build Coastguard Worker android::Bitmap* recycledBitmap, bool mustMatchColorType,
636*d57664e9SAndroid Build Coastguard Worker std::optional<SkRect> desiredSubset)
637*d57664e9SAndroid Build Coastguard Worker : mRecycledBitmap(recycledBitmap)
638*d57664e9SAndroid Build Coastguard Worker , mRecycledBytes(recycledBitmap ? recycledBitmap->getAllocationByteCount() : 0)
639*d57664e9SAndroid Build Coastguard Worker , mSkiaBitmap(nullptr)
640*d57664e9SAndroid Build Coastguard Worker , mNeedsCopy(false)
641*d57664e9SAndroid Build Coastguard Worker , mMustMatchColorType(mustMatchColorType)
642*d57664e9SAndroid Build Coastguard Worker , mDesiredSubset(getSourceBoundsForUpsample(desiredSubset)) {}
643*d57664e9SAndroid Build Coastguard Worker
~RecyclingClippingPixelAllocator()644*d57664e9SAndroid Build Coastguard Worker RecyclingClippingPixelAllocator::~RecyclingClippingPixelAllocator() {}
645*d57664e9SAndroid Build Coastguard Worker
allocPixelRef(SkBitmap * bitmap)646*d57664e9SAndroid Build Coastguard Worker bool RecyclingClippingPixelAllocator::allocPixelRef(SkBitmap* bitmap) {
647*d57664e9SAndroid Build Coastguard Worker // Ensure that the caller did not pass in a NULL bitmap to the constructor or this
648*d57664e9SAndroid Build Coastguard Worker // function.
649*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!mRecycledBitmap);
650*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(!bitmap);
651*d57664e9SAndroid Build Coastguard Worker mSkiaBitmap = bitmap;
652*d57664e9SAndroid Build Coastguard Worker
653*d57664e9SAndroid Build Coastguard Worker if (mMustMatchColorType) {
654*d57664e9SAndroid Build Coastguard Worker // This behaves differently than the RecyclingPixelAllocator. For backwards
655*d57664e9SAndroid Build Coastguard Worker // compatibility, the original color type of the recycled bitmap must be maintained.
656*d57664e9SAndroid Build Coastguard Worker if (mRecycledBitmap->info().colorType() != bitmap->colorType()) {
657*d57664e9SAndroid Build Coastguard Worker ALOGW("recycled color type %d != bitmap color type %d",
658*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap->info().colorType(), bitmap->colorType());
659*d57664e9SAndroid Build Coastguard Worker return false;
660*d57664e9SAndroid Build Coastguard Worker }
661*d57664e9SAndroid Build Coastguard Worker } else {
662*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap->reconfigure(mRecycledBitmap->info().makeColorType(bitmap->colorType()));
663*d57664e9SAndroid Build Coastguard Worker }
664*d57664e9SAndroid Build Coastguard Worker
665*d57664e9SAndroid Build Coastguard Worker // The Skia bitmap specifies the width and height needed by the decoder.
666*d57664e9SAndroid Build Coastguard Worker // mRecycledBitmap specifies the width and height of the bitmap that we
667*d57664e9SAndroid Build Coastguard Worker // want to reuse. Neither can be changed. We will try to find a way
668*d57664e9SAndroid Build Coastguard Worker // to reuse the memory.
669*d57664e9SAndroid Build Coastguard Worker const int maxWidth = std::max(bitmap->width(), mRecycledBitmap->info().width());
670*d57664e9SAndroid Build Coastguard Worker const int maxHeight = std::max(bitmap->height(), mRecycledBitmap->info().height());
671*d57664e9SAndroid Build Coastguard Worker const SkImageInfo maxInfo = bitmap->info().makeWH(maxWidth, maxHeight);
672*d57664e9SAndroid Build Coastguard Worker const size_t rowBytes = maxInfo.minRowBytes();
673*d57664e9SAndroid Build Coastguard Worker const size_t bytesNeeded = maxInfo.computeByteSize(rowBytes);
674*d57664e9SAndroid Build Coastguard Worker
675*d57664e9SAndroid Build Coastguard Worker if (!mDesiredSubset && bytesNeeded <= mRecycledBytes) {
676*d57664e9SAndroid Build Coastguard Worker // Here we take advantage of reconfigure() to reset the rowBytes
677*d57664e9SAndroid Build Coastguard Worker // of mRecycledBitmap. It is very important that we pass in
678*d57664e9SAndroid Build Coastguard Worker // mRecycledBitmap->info() for the SkImageInfo. According to the
679*d57664e9SAndroid Build Coastguard Worker // specification for BitmapRegionDecoder, we are not allowed to change
680*d57664e9SAndroid Build Coastguard Worker // the SkImageInfo.
681*d57664e9SAndroid Build Coastguard Worker // We can (must) preserve the color space since it doesn't affect the
682*d57664e9SAndroid Build Coastguard Worker // storage needs
683*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap->reconfigure(
684*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap->info().makeColorSpace(bitmap->refColorSpace()),
685*d57664e9SAndroid Build Coastguard Worker rowBytes);
686*d57664e9SAndroid Build Coastguard Worker
687*d57664e9SAndroid Build Coastguard Worker // Give the bitmap the same pixelRef as mRecycledBitmap.
688*d57664e9SAndroid Build Coastguard Worker // skbug.com/4538: We also need to make sure that the rowBytes on the pixel ref
689*d57664e9SAndroid Build Coastguard Worker // match the rowBytes on the bitmap.
690*d57664e9SAndroid Build Coastguard Worker bitmap->setInfo(bitmap->info(), rowBytes);
691*d57664e9SAndroid Build Coastguard Worker bitmap->setPixelRef(sk_ref_sp(mRecycledBitmap), 0, 0);
692*d57664e9SAndroid Build Coastguard Worker
693*d57664e9SAndroid Build Coastguard Worker // Make sure that the recycled bitmap has the correct alpha type.
694*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap->setAlphaType(bitmap->alphaType());
695*d57664e9SAndroid Build Coastguard Worker
696*d57664e9SAndroid Build Coastguard Worker bitmap->notifyPixelsChanged();
697*d57664e9SAndroid Build Coastguard Worker mNeedsCopy = false;
698*d57664e9SAndroid Build Coastguard Worker
699*d57664e9SAndroid Build Coastguard Worker // TODO: If the dimensions of the SkBitmap are smaller than those of
700*d57664e9SAndroid Build Coastguard Worker // mRecycledBitmap, should we zero the memory in mRecycledBitmap?
701*d57664e9SAndroid Build Coastguard Worker return true;
702*d57664e9SAndroid Build Coastguard Worker }
703*d57664e9SAndroid Build Coastguard Worker
704*d57664e9SAndroid Build Coastguard Worker // In the event that mRecycledBitmap is not large enough, allocate new memory
705*d57664e9SAndroid Build Coastguard Worker // on the heap.
706*d57664e9SAndroid Build Coastguard Worker SkBitmap::HeapAllocator heapAllocator;
707*d57664e9SAndroid Build Coastguard Worker
708*d57664e9SAndroid Build Coastguard Worker // We will need to copy from heap memory to mRecycledBitmap's memory after the
709*d57664e9SAndroid Build Coastguard Worker // decode is complete.
710*d57664e9SAndroid Build Coastguard Worker mNeedsCopy = true;
711*d57664e9SAndroid Build Coastguard Worker
712*d57664e9SAndroid Build Coastguard Worker return heapAllocator.allocPixelRef(bitmap);
713*d57664e9SAndroid Build Coastguard Worker }
714*d57664e9SAndroid Build Coastguard Worker
copyIfNecessary()715*d57664e9SAndroid Build Coastguard Worker void RecyclingClippingPixelAllocator::copyIfNecessary() {
716*d57664e9SAndroid Build Coastguard Worker if (mNeedsCopy) {
717*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap->ref();
718*d57664e9SAndroid Build Coastguard Worker android::Bitmap* recycledPixels = mRecycledBitmap;
719*d57664e9SAndroid Build Coastguard Worker if (mDesiredSubset) {
720*d57664e9SAndroid Build Coastguard Worker recycledPixels->setAlphaType(mSkiaBitmap->alphaType());
721*d57664e9SAndroid Build Coastguard Worker recycledPixels->setColorSpace(mSkiaBitmap->refColorSpace());
722*d57664e9SAndroid Build Coastguard Worker
723*d57664e9SAndroid Build Coastguard Worker auto canvas = SkCanvas(recycledPixels->getSkBitmap());
724*d57664e9SAndroid Build Coastguard Worker SkRect destination = SkRect::Make(recycledPixels->info().bounds());
725*d57664e9SAndroid Build Coastguard Worker destination.intersect(SkRect::Make(mSkiaBitmap->info().bounds()));
726*d57664e9SAndroid Build Coastguard Worker canvas.drawImageRect(mSkiaBitmap->asImage(), *mDesiredSubset, destination,
727*d57664e9SAndroid Build Coastguard Worker SkSamplingOptions(SkFilterMode::kLinear), nullptr,
728*d57664e9SAndroid Build Coastguard Worker SkCanvas::kFast_SrcRectConstraint);
729*d57664e9SAndroid Build Coastguard Worker } else {
730*d57664e9SAndroid Build Coastguard Worker void* dst = recycledPixels->pixels();
731*d57664e9SAndroid Build Coastguard Worker const size_t dstRowBytes = mRecycledBitmap->rowBytes();
732*d57664e9SAndroid Build Coastguard Worker const size_t bytesToCopy = std::min(mRecycledBitmap->info().minRowBytes(),
733*d57664e9SAndroid Build Coastguard Worker mSkiaBitmap->info().minRowBytes());
734*d57664e9SAndroid Build Coastguard Worker const int rowsToCopy =
735*d57664e9SAndroid Build Coastguard Worker std::min(mRecycledBitmap->info().height(), mSkiaBitmap->info().height());
736*d57664e9SAndroid Build Coastguard Worker for (int y = 0; y < rowsToCopy; y++) {
737*d57664e9SAndroid Build Coastguard Worker memcpy(dst, mSkiaBitmap->getAddr(0, y), bytesToCopy);
738*d57664e9SAndroid Build Coastguard Worker // Cast to bytes in order to apply the dstRowBytes offset correctly.
739*d57664e9SAndroid Build Coastguard Worker dst = reinterpret_cast<void*>(reinterpret_cast<uint8_t*>(dst) + dstRowBytes);
740*d57664e9SAndroid Build Coastguard Worker }
741*d57664e9SAndroid Build Coastguard Worker recycledPixels->setAlphaType(mSkiaBitmap->alphaType());
742*d57664e9SAndroid Build Coastguard Worker recycledPixels->setColorSpace(mSkiaBitmap->refColorSpace());
743*d57664e9SAndroid Build Coastguard Worker }
744*d57664e9SAndroid Build Coastguard Worker recycledPixels->notifyPixelsChanged();
745*d57664e9SAndroid Build Coastguard Worker recycledPixels->unref();
746*d57664e9SAndroid Build Coastguard Worker }
747*d57664e9SAndroid Build Coastguard Worker mRecycledBitmap = nullptr;
748*d57664e9SAndroid Build Coastguard Worker mSkiaBitmap = nullptr;
749*d57664e9SAndroid Build Coastguard Worker }
750*d57664e9SAndroid Build Coastguard Worker
getSourceBoundsForUpsample(std::optional<SkRect> subset)751*d57664e9SAndroid Build Coastguard Worker std::optional<SkRect> RecyclingClippingPixelAllocator::getSourceBoundsForUpsample(
752*d57664e9SAndroid Build Coastguard Worker std::optional<SkRect> subset) {
753*d57664e9SAndroid Build Coastguard Worker if (!uirenderer::Properties::resampleGainmapRegions() || !subset || subset->isEmpty()) {
754*d57664e9SAndroid Build Coastguard Worker return std::nullopt;
755*d57664e9SAndroid Build Coastguard Worker }
756*d57664e9SAndroid Build Coastguard Worker
757*d57664e9SAndroid Build Coastguard Worker if (subset->left() == floor(subset->left()) && subset->top() == floor(subset->top()) &&
758*d57664e9SAndroid Build Coastguard Worker subset->right() == floor(subset->right()) && subset->bottom() == floor(subset->bottom())) {
759*d57664e9SAndroid Build Coastguard Worker return std::nullopt;
760*d57664e9SAndroid Build Coastguard Worker }
761*d57664e9SAndroid Build Coastguard Worker
762*d57664e9SAndroid Build Coastguard Worker return subset;
763*d57664e9SAndroid Build Coastguard Worker }
764*d57664e9SAndroid Build Coastguard Worker
765*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
766*d57664e9SAndroid Build Coastguard Worker
AshmemPixelAllocator(JNIEnv * env)767*d57664e9SAndroid Build Coastguard Worker AshmemPixelAllocator::AshmemPixelAllocator(JNIEnv *env) {
768*d57664e9SAndroid Build Coastguard Worker LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&mJavaVM) != JNI_OK,
769*d57664e9SAndroid Build Coastguard Worker "env->GetJavaVM failed");
770*d57664e9SAndroid Build Coastguard Worker }
771*d57664e9SAndroid Build Coastguard Worker
allocPixelRef(SkBitmap * bitmap)772*d57664e9SAndroid Build Coastguard Worker bool AshmemPixelAllocator::allocPixelRef(SkBitmap* bitmap) {
773*d57664e9SAndroid Build Coastguard Worker mStorage = android::Bitmap::allocateAshmemBitmap(bitmap);
774*d57664e9SAndroid Build Coastguard Worker return !!mStorage;
775*d57664e9SAndroid Build Coastguard Worker }
776*d57664e9SAndroid Build Coastguard Worker
777*d57664e9SAndroid Build Coastguard Worker ////////////////////////////////////////////////////////////////////////////////
778*d57664e9SAndroid Build Coastguard Worker
register_android_graphics_Graphics(JNIEnv * env)779*d57664e9SAndroid Build Coastguard Worker int register_android_graphics_Graphics(JNIEnv* env)
780*d57664e9SAndroid Build Coastguard Worker {
781*d57664e9SAndroid Build Coastguard Worker jmethodID m;
782*d57664e9SAndroid Build Coastguard Worker jclass c;
783*d57664e9SAndroid Build Coastguard Worker
784*d57664e9SAndroid Build Coastguard Worker gRect_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Rect"));
785*d57664e9SAndroid Build Coastguard Worker gRect_leftFieldID = GetFieldIDOrDie(env, gRect_class, "left", "I");
786*d57664e9SAndroid Build Coastguard Worker gRect_topFieldID = GetFieldIDOrDie(env, gRect_class, "top", "I");
787*d57664e9SAndroid Build Coastguard Worker gRect_rightFieldID = GetFieldIDOrDie(env, gRect_class, "right", "I");
788*d57664e9SAndroid Build Coastguard Worker gRect_bottomFieldID = GetFieldIDOrDie(env, gRect_class, "bottom", "I");
789*d57664e9SAndroid Build Coastguard Worker
790*d57664e9SAndroid Build Coastguard Worker gRectF_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/RectF"));
791*d57664e9SAndroid Build Coastguard Worker gRectF_leftFieldID = GetFieldIDOrDie(env, gRectF_class, "left", "F");
792*d57664e9SAndroid Build Coastguard Worker gRectF_topFieldID = GetFieldIDOrDie(env, gRectF_class, "top", "F");
793*d57664e9SAndroid Build Coastguard Worker gRectF_rightFieldID = GetFieldIDOrDie(env, gRectF_class, "right", "F");
794*d57664e9SAndroid Build Coastguard Worker gRectF_bottomFieldID = GetFieldIDOrDie(env, gRectF_class, "bottom", "F");
795*d57664e9SAndroid Build Coastguard Worker
796*d57664e9SAndroid Build Coastguard Worker gPoint_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Point"));
797*d57664e9SAndroid Build Coastguard Worker gPoint_xFieldID = GetFieldIDOrDie(env, gPoint_class, "x", "I");
798*d57664e9SAndroid Build Coastguard Worker gPoint_yFieldID = GetFieldIDOrDie(env, gPoint_class, "y", "I");
799*d57664e9SAndroid Build Coastguard Worker
800*d57664e9SAndroid Build Coastguard Worker gPointF_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/PointF"));
801*d57664e9SAndroid Build Coastguard Worker gPointF_xFieldID = GetFieldIDOrDie(env, gPointF_class, "x", "F");
802*d57664e9SAndroid Build Coastguard Worker gPointF_yFieldID = GetFieldIDOrDie(env, gPointF_class, "y", "F");
803*d57664e9SAndroid Build Coastguard Worker
804*d57664e9SAndroid Build Coastguard Worker gBitmapRegionDecoder_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/BitmapRegionDecoder"));
805*d57664e9SAndroid Build Coastguard Worker gBitmapRegionDecoder_constructorMethodID = GetMethodIDOrDie(env, gBitmapRegionDecoder_class, "<init>", "(J)V");
806*d57664e9SAndroid Build Coastguard Worker
807*d57664e9SAndroid Build Coastguard Worker gBitmapConfig_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Bitmap$Config"));
808*d57664e9SAndroid Build Coastguard Worker gBitmapConfig_nativeInstanceID = GetFieldIDOrDie(env, gBitmapConfig_class, "nativeInt", "I");
809*d57664e9SAndroid Build Coastguard Worker gBitmapConfig_nativeToConfigMethodID = GetStaticMethodIDOrDie(env, gBitmapConfig_class,
810*d57664e9SAndroid Build Coastguard Worker "nativeToConfig",
811*d57664e9SAndroid Build Coastguard Worker "(I)Landroid/graphics/Bitmap$Config;");
812*d57664e9SAndroid Build Coastguard Worker
813*d57664e9SAndroid Build Coastguard Worker gCanvas_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Canvas"));
814*d57664e9SAndroid Build Coastguard Worker gCanvas_nativeInstanceID = GetFieldIDOrDie(env, gCanvas_class, "mNativeCanvasWrapper", "J");
815*d57664e9SAndroid Build Coastguard Worker
816*d57664e9SAndroid Build Coastguard Worker gPicture_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Picture"));
817*d57664e9SAndroid Build Coastguard Worker gPicture_nativeInstanceID = GetFieldIDOrDie(env, gPicture_class, "mNativePicture", "J");
818*d57664e9SAndroid Build Coastguard Worker
819*d57664e9SAndroid Build Coastguard Worker gRegion_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/Region"));
820*d57664e9SAndroid Build Coastguard Worker gRegion_nativeInstanceID = GetFieldIDOrDie(env, gRegion_class, "mNativeRegion", "J");
821*d57664e9SAndroid Build Coastguard Worker gRegion_constructorMethodID = GetMethodIDOrDie(env, gRegion_class, "<init>", "(JI)V");
822*d57664e9SAndroid Build Coastguard Worker
823*d57664e9SAndroid Build Coastguard Worker c = env->FindClass("java/lang/Byte");
824*d57664e9SAndroid Build Coastguard Worker gByte_class = (jclass) env->NewGlobalRef(
825*d57664e9SAndroid Build Coastguard Worker env->GetStaticObjectField(c, env->GetStaticFieldID(c, "TYPE", "Ljava/lang/Class;")));
826*d57664e9SAndroid Build Coastguard Worker
827*d57664e9SAndroid Build Coastguard Worker gColorSpace_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/ColorSpace"));
828*d57664e9SAndroid Build Coastguard Worker gColorSpace_getMethodID = GetStaticMethodIDOrDie(env, gColorSpace_class,
829*d57664e9SAndroid Build Coastguard Worker "get", "(Landroid/graphics/ColorSpace$Named;)Landroid/graphics/ColorSpace;");
830*d57664e9SAndroid Build Coastguard Worker gColorSpace_matchMethodID = GetStaticMethodIDOrDie(env, gColorSpace_class, "match",
831*d57664e9SAndroid Build Coastguard Worker "([FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)Landroid/graphics/ColorSpace;");
832*d57664e9SAndroid Build Coastguard Worker
833*d57664e9SAndroid Build Coastguard Worker gColorSpaceRGB_class = MakeGlobalRefOrDie(env,
834*d57664e9SAndroid Build Coastguard Worker FindClassOrDie(env, "android/graphics/ColorSpace$Rgb"));
835*d57664e9SAndroid Build Coastguard Worker gColorSpaceRGB_constructorMethodID = GetMethodIDOrDie(env, gColorSpaceRGB_class,
836*d57664e9SAndroid Build Coastguard Worker "<init>", "(Ljava/lang/String;[FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)V");
837*d57664e9SAndroid Build Coastguard Worker
838*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_class = MakeGlobalRefOrDie(env,
839*d57664e9SAndroid Build Coastguard Worker FindClassOrDie(env, "android/graphics/ColorSpace$Named"));
840*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_sRGBFieldID = GetStaticFieldIDOrDie(env,
841*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_class, "SRGB", "Landroid/graphics/ColorSpace$Named;");
842*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_ExtendedSRGBFieldID = GetStaticFieldIDOrDie(env,
843*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_class, "EXTENDED_SRGB", "Landroid/graphics/ColorSpace$Named;");
844*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_LinearSRGBFieldID = GetStaticFieldIDOrDie(env,
845*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_class, "LINEAR_SRGB", "Landroid/graphics/ColorSpace$Named;");
846*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_LinearExtendedSRGBFieldID = GetStaticFieldIDOrDie(env,
847*d57664e9SAndroid Build Coastguard Worker gColorSpace_Named_class, "LINEAR_EXTENDED_SRGB", "Landroid/graphics/ColorSpace$Named;");
848*d57664e9SAndroid Build Coastguard Worker
849*d57664e9SAndroid Build Coastguard Worker gTransferParameters_class = MakeGlobalRefOrDie(env, FindClassOrDie(env,
850*d57664e9SAndroid Build Coastguard Worker "android/graphics/ColorSpace$Rgb$TransferParameters"));
851*d57664e9SAndroid Build Coastguard Worker gTransferParameters_constructorMethodID =
852*d57664e9SAndroid Build Coastguard Worker GetMethodIDOrDie(env, gTransferParameters_class, "<init>", "(DDDDDDD)V");
853*d57664e9SAndroid Build Coastguard Worker
854*d57664e9SAndroid Build Coastguard Worker gFontMetrics_class = FindClassOrDie(env, "android/graphics/Paint$FontMetrics");
855*d57664e9SAndroid Build Coastguard Worker gFontMetrics_class = MakeGlobalRefOrDie(env, gFontMetrics_class);
856*d57664e9SAndroid Build Coastguard Worker
857*d57664e9SAndroid Build Coastguard Worker gFontMetrics_top = GetFieldIDOrDie(env, gFontMetrics_class, "top", "F");
858*d57664e9SAndroid Build Coastguard Worker gFontMetrics_ascent = GetFieldIDOrDie(env, gFontMetrics_class, "ascent", "F");
859*d57664e9SAndroid Build Coastguard Worker gFontMetrics_descent = GetFieldIDOrDie(env, gFontMetrics_class, "descent", "F");
860*d57664e9SAndroid Build Coastguard Worker gFontMetrics_bottom = GetFieldIDOrDie(env, gFontMetrics_class, "bottom", "F");
861*d57664e9SAndroid Build Coastguard Worker gFontMetrics_leading = GetFieldIDOrDie(env, gFontMetrics_class, "leading", "F");
862*d57664e9SAndroid Build Coastguard Worker
863*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_class = FindClassOrDie(env, "android/graphics/Paint$FontMetricsInt");
864*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_class = MakeGlobalRefOrDie(env, gFontMetricsInt_class);
865*d57664e9SAndroid Build Coastguard Worker
866*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_top = GetFieldIDOrDie(env, gFontMetricsInt_class, "top", "I");
867*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_ascent = GetFieldIDOrDie(env, gFontMetricsInt_class, "ascent", "I");
868*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_descent = GetFieldIDOrDie(env, gFontMetricsInt_class, "descent", "I");
869*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_bottom = GetFieldIDOrDie(env, gFontMetricsInt_class, "bottom", "I");
870*d57664e9SAndroid Build Coastguard Worker gFontMetricsInt_leading = GetFieldIDOrDie(env, gFontMetricsInt_class, "leading", "I");
871*d57664e9SAndroid Build Coastguard Worker
872*d57664e9SAndroid Build Coastguard Worker gRunInfo_class = FindClassOrDie(env, "android/graphics/Paint$RunInfo");
873*d57664e9SAndroid Build Coastguard Worker gRunInfo_class = MakeGlobalRefOrDie(env, gRunInfo_class);
874*d57664e9SAndroid Build Coastguard Worker
875*d57664e9SAndroid Build Coastguard Worker gRunInfo_clusterCount = GetFieldIDOrDie(env, gRunInfo_class, "mClusterCount", "I");
876*d57664e9SAndroid Build Coastguard Worker
877*d57664e9SAndroid Build Coastguard Worker return 0;
878*d57664e9SAndroid Build Coastguard Worker }
879