blob: f4cc9e44d7dfd01cbf90e11a0974b622b1d5d099 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001#include <jni.h>
2#include "GraphicsJNI.h"
3
4#include "SkShader.h"
5#include "SkGradientShader.h"
6#include "SkPorterDuff.h"
7#include "SkComposeShader.h"
8#include "SkTemplates.h"
9#include "SkXfermode.h"
10
Romain Guy06f96e22010-07-30 19:18:16 -070011#include <SkiaShader.h>
Romain Guya2341a92010-09-08 18:04:33 -070012#include <Caches.h>
Romain Guy06f96e22010-07-30 19:18:16 -070013
14using namespace android::uirenderer;
15
Romain Guy7fac2e12010-07-16 17:10:13 -070016static struct {
17 jclass clazz;
Romain Guy06f96e22010-07-30 19:18:16 -070018 jfieldID shader;
19} gShaderClassInfo;
Romain Guy7fac2e12010-07-16 17:10:13 -070020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021static void ThrowIAE_IfNull(JNIEnv* env, void* ptr) {
22 if (NULL == ptr) {
23 doThrowIAE(env);
24 }
25}
26
27static void Color_RGBToHSV(JNIEnv* env, jobject, int red, int green, int blue, jfloatArray hsvArray)
28{
29 SkScalar hsv[3];
30 SkRGBToHSV(red, green, blue, hsv);
31
32 AutoJavaFloatArray autoHSV(env, hsvArray, 3);
33 float* values = autoHSV.ptr();
34 for (int i = 0; i < 3; i++) {
35 values[i] = SkScalarToFloat(hsv[i]);
36 }
37}
Elliott Hughes4cb17532011-04-12 16:10:26 -070038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039static int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArray)
40{
41 AutoJavaFloatArray autoHSV(env, hsvArray, 3);
42 float* values = autoHSV.ptr();;
43 SkScalar hsv[3];
44
45 for (int i = 0; i < 3; i++) {
46 hsv[i] = SkFloatToScalar(values[i]);
47 }
Elliott Hughes4cb17532011-04-12 16:10:26 -070048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049 return SkHSVToColor(alpha, hsv);
50}
51
52///////////////////////////////////////////////////////////////////////////////////////////////
53
Romain Guy06f96e22010-07-30 19:18:16 -070054static void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055{
Derek Sollenberger6062c592011-02-22 13:55:04 -050056 SkSafeUnref(shader);
Chet Haase5c13d892010-10-08 08:37:55 -070057 // skiaShader == NULL when not !USE_OPENGL_RENDERER, so no need to delete it outside the ifdef
Romain Guya2341a92010-09-08 18:04:33 -070058#ifdef USE_OPENGL_RENDERER
59 if (android::uirenderer::Caches::hasInstance()) {
Chet Haase5c13d892010-10-08 08:37:55 -070060 android::uirenderer::Caches::getInstance().resourceCache.destructor(skiaShader);
Chet Haasead93c2b2010-10-22 16:17:12 -070061 } else {
62 delete skiaShader;
Romain Guya2341a92010-09-08 18:04:33 -070063 }
64#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065}
66
Romain Guy06f96e22010-07-30 19:18:16 -070067static void Shader_setLocalMatrix(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader,
68 const SkMatrix* matrix)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069{
Mike Reeda04e5552009-07-30 11:05:57 -040070 if (shader) {
71 if (NULL == matrix) {
72 shader->resetLocalMatrix();
73 }
74 else {
75 shader->setLocalMatrix(*matrix);
76 }
Romain Guy16393512010-08-08 00:14:31 -070077#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -070078 skiaShader->setMatrix(const_cast<SkMatrix*>(matrix));
Romain Guy16393512010-08-08 00:14:31 -070079#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080 }
81}
82
83///////////////////////////////////////////////////////////////////////////////////////////////
84
Romain Guy06f96e22010-07-30 19:18:16 -070085static SkShader* BitmapShader_constructor(JNIEnv* env, jobject o, const SkBitmap* bitmap,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 int tileModeX, int tileModeY)
87{
88 SkShader* s = SkShader::CreateBitmapShader(*bitmap,
89 (SkShader::TileMode)tileModeX,
90 (SkShader::TileMode)tileModeY);
Romain Guy06f96e22010-07-30 19:18:16 -070091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092 ThrowIAE_IfNull(env, s);
93 return s;
94}
Romain Guy06f96e22010-07-30 19:18:16 -070095
96static SkiaShader* BitmapShader_postConstructor(JNIEnv* env, jobject o, SkShader* shader,
97 SkBitmap* bitmap, int tileModeX, int tileModeY) {
Romain Guy16393512010-08-08 00:14:31 -070098#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -070099 SkiaShader* skiaShader = new SkiaBitmapShader(bitmap, shader,
100 static_cast<SkShader::TileMode>(tileModeX), static_cast<SkShader::TileMode>(tileModeY),
101 NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
102 return skiaShader;
Romain Guy16393512010-08-08 00:14:31 -0700103#else
104 return NULL;
105#endif
Romain Guy06f96e22010-07-30 19:18:16 -0700106}
Elliott Hughes4cb17532011-04-12 16:10:26 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108///////////////////////////////////////////////////////////////////////////////////////////////
109
Romain Guy7fac2e12010-07-16 17:10:13 -0700110static SkShader* LinearGradient_create1(JNIEnv* env, jobject o,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111 float x0, float y0, float x1, float y1,
112 jintArray colorArray, jfloatArray posArray, int tileMode)
113{
114 SkPoint pts[2];
115 pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0));
116 pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1));
117
Romain Guy06f96e22010-07-30 19:18:16 -0700118 size_t count = env->GetArrayLength(colorArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
120
121 SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700122 SkScalar* pos = NULL;
Romain Guy7fac2e12010-07-16 17:10:13 -0700123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 if (posArray) {
125 AutoJavaFloatArray autoPos(env, posArray, count);
126 const float* posValues = autoPos.ptr();
127 pos = (SkScalar*)storage.get();
Romain Guy7fac2e12010-07-16 17:10:13 -0700128 for (size_t i = 0; i < count; i++) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 pos[i] = SkFloatToScalar(posValues[i]);
Romain Guy06f96e22010-07-30 19:18:16 -0700130 }
131 }
Elliott Hughes4cb17532011-04-12 16:10:26 -0700132
Romain Guy06f96e22010-07-30 19:18:16 -0700133 SkShader* shader = SkGradientShader::CreateLinear(pts,
134 reinterpret_cast<const SkColor*>(colorValues),
135 pos, count,
136 static_cast<SkShader::TileMode>(tileMode));
137
138 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
139 ThrowIAE_IfNull(env, shader);
140 return shader;
141}
142
143static SkiaShader* LinearGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
144 float x0, float y0, float x1, float y1, jintArray colorArray,
145 jfloatArray posArray, int tileMode) {
Romain Guy16393512010-08-08 00:14:31 -0700146#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700147 size_t count = env->GetArrayLength(colorArray);
148 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
149
150 jfloat* storedBounds = new jfloat[4];
151 storedBounds[0] = x0; storedBounds[1] = y0;
152 storedBounds[2] = x1; storedBounds[3] = y1;
153 jfloat* storedPositions = new jfloat[count];
154 uint32_t* storedColors = new uint32_t[count];
Romain Guy61c8c9c2010-08-09 20:48:09 -0700155 for (size_t i = 0; i < count; i++) {
156 storedColors[i] = static_cast<uint32_t>(colorValues[i]);
157 }
Romain Guy06f96e22010-07-30 19:18:16 -0700158
159 if (posArray) {
160 AutoJavaFloatArray autoPos(env, posArray, count);
161 const float* posValues = autoPos.ptr();
162 for (size_t i = 0; i < count; i++) {
Romain Guy7fac2e12010-07-16 17:10:13 -0700163 storedPositions[i] = posValues[i];
164 }
165 } else {
166 storedPositions[0] = 0.0f;
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700167 const jfloat step = 1.0f / (count - 1);
168 for (size_t i = 1; i < count - 1; i++) {
169 storedPositions[i] = step * i;
170 }
171 storedPositions[count - 1] = 1.0f;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 }
Romain Guy06f96e22010-07-30 19:18:16 -0700173
174 SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
175 storedPositions, count, shader, static_cast<SkShader::TileMode>(tileMode), NULL,
176 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
177
178 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
179 return skiaShader;
Romain Guy16393512010-08-08 00:14:31 -0700180#else
181 return NULL;
182#endif
Romain Guy06f96e22010-07-30 19:18:16 -0700183}
184
185static SkiaShader* LinearGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
186 float x0, float y0, float x1, float y1, int color0, int color1, int tileMode) {
Romain Guy16393512010-08-08 00:14:31 -0700187#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700188 float* storedBounds = new float[4];
189 storedBounds[0] = x0; storedBounds[1] = y0;
190 storedBounds[2] = x1; storedBounds[3] = y1;
191
192 float* storedPositions = new float[2];
193 storedPositions[0] = 0.0f;
194 storedPositions[1] = 1.0f;
195
196 uint32_t* storedColors = new uint32_t[2];
Romain Guy61c8c9c2010-08-09 20:48:09 -0700197 storedColors[0] = static_cast<uint32_t>(color0);
198 storedColors[1] = static_cast<uint32_t>(color1);
Romain Guy06f96e22010-07-30 19:18:16 -0700199
200 SkiaShader* skiaShader = new SkiaLinearGradientShader(storedBounds, storedColors,
201 storedPositions, 2, shader, static_cast<SkShader::TileMode>(tileMode), NULL,
202 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
203
204 return skiaShader;
Romain Guy16393512010-08-08 00:14:31 -0700205#else
206 return NULL;
207#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208}
209
Romain Guy7fac2e12010-07-16 17:10:13 -0700210static SkShader* LinearGradient_create2(JNIEnv* env, jobject o,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211 float x0, float y0, float x1, float y1,
212 int color0, int color1, int tileMode)
213{
214 SkPoint pts[2];
215 pts[0].set(SkFloatToScalar(x0), SkFloatToScalar(y0));
216 pts[1].set(SkFloatToScalar(x1), SkFloatToScalar(y1));
217
218 SkColor colors[2];
219 colors[0] = color0;
220 colors[1] = color1;
Elliott Hughes4cb17532011-04-12 16:10:26 -0700221
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2, (SkShader::TileMode)tileMode);
Romain Guy06f96e22010-07-30 19:18:16 -0700223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 ThrowIAE_IfNull(env, s);
225 return s;
226}
227
228///////////////////////////////////////////////////////////////////////////////////////////////
229
Romain Guyddb80be2010-09-20 19:04:33 -0700230static SkShader* RadialGradient_create1(JNIEnv* env, jobject, float x, float y, float radius,
231 jintArray colorArray, jfloatArray posArray, int tileMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800232 SkPoint center;
233 center.set(SkFloatToScalar(x), SkFloatToScalar(y));
234
235 size_t count = env->GetArrayLength(colorArray);
236 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
237
238 SkAutoSTMalloc<8, SkScalar> storage(posArray ? count : 0);
239 SkScalar* pos = NULL;
Elliott Hughes4cb17532011-04-12 16:10:26 -0700240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 if (posArray) {
242 AutoJavaFloatArray autoPos(env, posArray, count);
243 const float* posValues = autoPos.ptr();
244 pos = (SkScalar*)storage.get();
245 for (size_t i = 0; i < count; i++)
246 pos[i] = SkFloatToScalar(posValues[i]);
247 }
248
249 SkShader* shader = SkGradientShader::CreateRadial(center,
250 SkFloatToScalar(radius),
251 reinterpret_cast<const SkColor*>(colorValues),
252 pos, count,
253 static_cast<SkShader::TileMode>(tileMode));
254 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues),
255 JNI_ABORT);
256
257 ThrowIAE_IfNull(env, shader);
258 return shader;
259}
260
Romain Guyddb80be2010-09-20 19:04:33 -0700261static SkShader* RadialGradient_create2(JNIEnv* env, jobject, float x, float y, float radius,
262 int color0, int color1, int tileMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 SkPoint center;
264 center.set(SkFloatToScalar(x), SkFloatToScalar(y));
265
266 SkColor colors[2];
267 colors[0] = color0;
268 colors[1] = color1;
269
270 SkShader* s = SkGradientShader::CreateRadial(center, SkFloatToScalar(radius), colors, NULL,
271 2, (SkShader::TileMode)tileMode);
272 ThrowIAE_IfNull(env, s);
273 return s;
274}
275
Romain Guyddb80be2010-09-20 19:04:33 -0700276static SkiaShader* RadialGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
277 float x, float y, float radius, jintArray colorArray, jfloatArray posArray, int tileMode) {
278#ifdef USE_OPENGL_RENDERER
279 size_t count = env->GetArrayLength(colorArray);
280 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
281
282 jfloat* storedPositions = new jfloat[count];
283 uint32_t* storedColors = new uint32_t[count];
284 for (size_t i = 0; i < count; i++) {
285 storedColors[i] = static_cast<uint32_t>(colorValues[i]);
286 }
287
288 if (posArray) {
289 AutoJavaFloatArray autoPos(env, posArray, count);
290 const float* posValues = autoPos.ptr();
291 for (size_t i = 0; i < count; i++) {
292 storedPositions[i] = posValues[i];
293 }
294 } else {
295 storedPositions[0] = 0.0f;
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700296 const jfloat step = 1.0f / (count - 1);
297 for (size_t i = 1; i < count - 1; i++) {
298 storedPositions[i] = step * i;
299 }
300 storedPositions[count - 1] = 1.0f;
Romain Guyddb80be2010-09-20 19:04:33 -0700301 }
302
303 SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors,
304 storedPositions, count, shader, (SkShader::TileMode) tileMode, NULL,
305 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
306
307 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
308 return skiaShader;
309#else
310 return NULL;
311#endif
312}
313
314static SkiaShader* RadialGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
315 float x, float y, float radius, int color0, int color1, int tileMode) {
316#ifdef USE_OPENGL_RENDERER
317 float* storedPositions = new float[2];
318 storedPositions[0] = 0.0f;
319 storedPositions[1] = 1.0f;
320
321 uint32_t* storedColors = new uint32_t[2];
322 storedColors[0] = static_cast<uint32_t>(color0);
323 storedColors[1] = static_cast<uint32_t>(color1);
324
325 SkiaShader* skiaShader = new SkiaCircularGradientShader(x, y, radius, storedColors,
326 storedPositions, 2, shader, (SkShader::TileMode) tileMode, NULL,
327 (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
328
329 return skiaShader;
330#else
331 return NULL;
332#endif
333}
334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335///////////////////////////////////////////////////////////////////////////////
336
337static SkShader* SweepGradient_create1(JNIEnv* env, jobject, float x, float y,
Romain Guyddb80be2010-09-20 19:04:33 -0700338 jintArray jcolors, jfloatArray jpositions) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 size_t count = env->GetArrayLength(jcolors);
340 const jint* colors = env->GetIntArrayElements(jcolors, NULL);
Elliott Hughes4cb17532011-04-12 16:10:26 -0700341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 SkAutoSTMalloc<8, SkScalar> storage(jpositions ? count : 0);
343 SkScalar* pos = NULL;
Elliott Hughes4cb17532011-04-12 16:10:26 -0700344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 if (NULL != jpositions) {
346 AutoJavaFloatArray autoPos(env, jpositions, count);
347 const float* posValues = autoPos.ptr();
348 pos = (SkScalar*)storage.get();
349 for (size_t i = 0; i < count; i++) {
350 pos[i] = SkFloatToScalar(posValues[i]);
351 }
352 }
353
354 SkShader* shader = SkGradientShader::CreateSweep(SkFloatToScalar(x),
355 SkFloatToScalar(y),
356 reinterpret_cast<const SkColor*>(colors),
357 pos, count);
358 env->ReleaseIntArrayElements(jcolors, const_cast<jint*>(colors),
359 JNI_ABORT);
360 ThrowIAE_IfNull(env, shader);
361 return shader;
362}
363
364static SkShader* SweepGradient_create2(JNIEnv* env, jobject, float x, float y,
Romain Guyddb80be2010-09-20 19:04:33 -0700365 int color0, int color1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 SkColor colors[2];
367 colors[0] = color0;
368 colors[1] = color1;
369 SkShader* s = SkGradientShader::CreateSweep(SkFloatToScalar(x), SkFloatToScalar(y),
370 colors, NULL, 2);
371 ThrowIAE_IfNull(env, s);
372 return s;
373}
374
Romain Guyee916f12010-09-20 17:53:08 -0700375static SkiaShader* SweepGradient_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
376 float x, float y, jintArray colorArray, jfloatArray posArray) {
377#ifdef USE_OPENGL_RENDERER
378 size_t count = env->GetArrayLength(colorArray);
379 const jint* colorValues = env->GetIntArrayElements(colorArray, NULL);
380
381 jfloat* storedPositions = new jfloat[count];
382 uint32_t* storedColors = new uint32_t[count];
383 for (size_t i = 0; i < count; i++) {
384 storedColors[i] = static_cast<uint32_t>(colorValues[i]);
385 }
386
387 if (posArray) {
388 AutoJavaFloatArray autoPos(env, posArray, count);
389 const float* posValues = autoPos.ptr();
390 for (size_t i = 0; i < count; i++) {
391 storedPositions[i] = posValues[i];
392 }
393 } else {
394 storedPositions[0] = 0.0f;
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700395 const jfloat step = 1.0f / (count - 1);
396 for (size_t i = 1; i < count - 1; i++) {
397 storedPositions[i] = step * i;
398 }
399 storedPositions[count - 1] = 1.0f;
Romain Guyee916f12010-09-20 17:53:08 -0700400 }
401
402 SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, count,
403 shader, NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
404
405 env->ReleaseIntArrayElements(colorArray, const_cast<jint*>(colorValues), JNI_ABORT);
406 return skiaShader;
407#else
408 return NULL;
409#endif
410}
411
412static SkiaShader* SweepGradient_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
413 float x, float y, int color0, int color1) {
414#ifdef USE_OPENGL_RENDERER
415 float* storedPositions = new float[2];
416 storedPositions[0] = 0.0f;
417 storedPositions[1] = 1.0f;
418
419 uint32_t* storedColors = new uint32_t[2];
420 storedColors[0] = static_cast<uint32_t>(color0);
421 storedColors[1] = static_cast<uint32_t>(color1);
422
423 SkiaShader* skiaShader = new SkiaSweepGradientShader(x, y, storedColors, storedPositions, 2,
424 shader, NULL, (shader->getFlags() & SkShader::kOpaqueAlpha_Flag) == 0);
425
426 return skiaShader;
427#else
428 return NULL;
429#endif
430}
431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432///////////////////////////////////////////////////////////////////////////////////////////////
433
Romain Guy06f96e22010-07-30 19:18:16 -0700434static SkShader* ComposeShader_create1(JNIEnv* env, jobject o,
435 SkShader* shaderA, SkShader* shaderB, SkXfermode* mode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800436{
437 return new SkComposeShader(shaderA, shaderB, mode);
438}
439
Romain Guy06f96e22010-07-30 19:18:16 -0700440static SkShader* ComposeShader_create2(JNIEnv* env, jobject o,
441 SkShader* shaderA, SkShader* shaderB, SkPorterDuff::Mode porterDuffMode)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800442{
Romain Guy06f96e22010-07-30 19:18:16 -0700443 SkAutoUnref au(SkPorterDuff::CreateXfermode(porterDuffMode));
444 SkXfermode* mode = (SkXfermode*) au.get();
445 return new SkComposeShader(shaderA, shaderB, mode);
446}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800447
Romain Guy06f96e22010-07-30 19:18:16 -0700448static SkiaShader* ComposeShader_postCreate2(JNIEnv* env, jobject o, SkShader* shader,
449 SkiaShader* shaderA, SkiaShader* shaderB, SkPorterDuff::Mode porterDuffMode) {
Romain Guy16393512010-08-08 00:14:31 -0700450#ifdef USE_OPENGL_RENDERER
Romain Guy48daa542010-08-10 19:21:34 -0700451 SkXfermode::Mode mode = SkPorterDuff::ToXfermodeMode(porterDuffMode);
452 return new SkiaComposeShader(shaderA, shaderB, mode, shader);
Romain Guy16393512010-08-08 00:14:31 -0700453#else
454 return NULL;
455#endif
Romain Guy06f96e22010-07-30 19:18:16 -0700456}
457
458static SkiaShader* ComposeShader_postCreate1(JNIEnv* env, jobject o, SkShader* shader,
459 SkiaShader* shaderA, SkiaShader* shaderB, SkXfermode* mode) {
Romain Guy16393512010-08-08 00:14:31 -0700460#ifdef USE_OPENGL_RENDERER
Romain Guy06f96e22010-07-30 19:18:16 -0700461 SkXfermode::Mode skiaMode;
462 if (!SkXfermode::IsMode(mode, &skiaMode)) {
Romain Guy48daa542010-08-10 19:21:34 -0700463 // TODO: Support other modes
Romain Guy06f96e22010-07-30 19:18:16 -0700464 skiaMode = SkXfermode::kSrcOver_Mode;
465 }
466 return new SkiaComposeShader(shaderA, shaderB, skiaMode, shader);
Romain Guy16393512010-08-08 00:14:31 -0700467#else
468 return NULL;
469#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470}
471
472///////////////////////////////////////////////////////////////////////////////////////////////
473
474static JNINativeMethod gColorMethods[] = {
475 { "nativeRGBToHSV", "(III[F)V", (void*)Color_RGBToHSV },
476 { "nativeHSVToColor", "(I[F)I", (void*)Color_HSVToColor }
477};
478
479static JNINativeMethod gShaderMethods[] = {
Romain Guy06f96e22010-07-30 19:18:16 -0700480 { "nativeDestructor", "(II)V", (void*)Shader_destructor },
Romain Guy06f96e22010-07-30 19:18:16 -0700481 { "nativeSetLocalMatrix", "(III)V", (void*)Shader_setLocalMatrix }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482};
483
484static JNINativeMethod gBitmapShaderMethods[] = {
Romain Guy06f96e22010-07-30 19:18:16 -0700485 { "nativeCreate", "(III)I", (void*)BitmapShader_constructor },
486 { "nativePostCreate", "(IIII)I", (void*)BitmapShader_postConstructor }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487};
488
489static JNINativeMethod gLinearGradientMethods[] = {
Romain Guy06f96e22010-07-30 19:18:16 -0700490 { "nativeCreate1", "(FFFF[I[FI)I", (void*)LinearGradient_create1 },
491 { "nativeCreate2", "(FFFFIII)I", (void*)LinearGradient_create2 },
492 { "nativePostCreate1", "(IFFFF[I[FI)I", (void*)LinearGradient_postCreate1 },
493 { "nativePostCreate2", "(IFFFFIII)I", (void*)LinearGradient_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494};
495
496static JNINativeMethod gRadialGradientMethods[] = {
Romain Guyddb80be2010-09-20 19:04:33 -0700497 { "nativeCreate1", "(FFF[I[FI)I", (void*)RadialGradient_create1 },
498 { "nativeCreate2", "(FFFIII)I", (void*)RadialGradient_create2 },
499 { "nativePostCreate1", "(IFFF[I[FI)I", (void*)RadialGradient_postCreate1 },
500 { "nativePostCreate2", "(IFFFIII)I", (void*)RadialGradient_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501};
502
503static JNINativeMethod gSweepGradientMethods[] = {
Romain Guyddb80be2010-09-20 19:04:33 -0700504 { "nativeCreate1", "(FF[I[F)I", (void*)SweepGradient_create1 },
505 { "nativeCreate2", "(FFII)I", (void*)SweepGradient_create2 },
Romain Guyee916f12010-09-20 17:53:08 -0700506 { "nativePostCreate1", "(IFF[I[F)I", (void*)SweepGradient_postCreate1 },
507 { "nativePostCreate2", "(IFFII)I", (void*)SweepGradient_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508};
509
510static JNINativeMethod gComposeShaderMethods[] = {
Romain Guyddb80be2010-09-20 19:04:33 -0700511 { "nativeCreate1", "(III)I", (void*)ComposeShader_create1 },
512 { "nativeCreate2", "(III)I", (void*)ComposeShader_create2 },
513 { "nativePostCreate1", "(IIII)I", (void*)ComposeShader_postCreate1 },
514 { "nativePostCreate2", "(IIII)I", (void*)ComposeShader_postCreate2 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515};
516
517#include <android_runtime/AndroidRuntime.h>
518
519#define REG(env, name, array) \
520 result = android::AndroidRuntime::registerNativeMethods(env, name, array, SK_ARRAY_COUNT(array)); \
521 if (result < 0) return result
522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523int register_android_graphics_Shader(JNIEnv* env)
524{
525 int result;
Elliott Hughes4cb17532011-04-12 16:10:26 -0700526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 REG(env, "android/graphics/Color", gColorMethods);
528 REG(env, "android/graphics/Shader", gShaderMethods);
529 REG(env, "android/graphics/BitmapShader", gBitmapShaderMethods);
530 REG(env, "android/graphics/LinearGradient", gLinearGradientMethods);
531 REG(env, "android/graphics/RadialGradient", gRadialGradientMethods);
532 REG(env, "android/graphics/SweepGradient", gSweepGradientMethods);
533 REG(env, "android/graphics/ComposeShader", gComposeShaderMethods);
Elliott Hughes4cb17532011-04-12 16:10:26 -0700534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 return result;
536}