blob: 2e4d7f62f671a3fcc835acf5312ed26f2d12cd0e [file] [log] [blame]
Derek Sollenberger783e5ae2021-01-11 15:44:46 -05001#undef LOG_TAG
2#define LOG_TAG "ShaderJNI"
3
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004#include "GraphicsJNI.h"
Derek Sollenbergerfb0c8fc2017-07-26 13:53:27 -04005#include "SkColorFilter.h"
Ben Wagner60126ef2015-08-07 12:13:48 -04006#include "SkGradientShader.h"
Matt Sarett62feb3a2016-09-20 10:34:11 -04007#include "SkImagePriv.h"
Ben Wagner60126ef2015-08-07 12:13:48 -04008#include "SkShader.h"
Mike Reedc2f31df2016-10-28 17:21:45 -04009#include "SkBlendMode.h"
Brian Osmanbc44fa02020-01-03 15:28:06 -050010#include "include/effects/SkRuntimeEffect.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -050012#include <vector>
13
Romain Guy06f96e22010-07-30 19:18:16 -070014using namespace android::uirenderer;
15
Derek Sollenberger669b15a2017-03-31 12:09:24 -040016/**
17 * By default Skia gradients will interpolate their colors in unpremul space
18 * and then premultiply each of the results. We must set this flag to preserve
19 * backwards compatiblity by premultiplying the colors of the gradient first,
20 * and then interpolating between them.
21 */
22static const uint32_t sGradientShaderFlags = SkGradientShader::kInterpolateColorsInPremul_Flag;
23
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -050024#define ThrowIAE_IfNull(env, ptr) \
25 if (nullptr == ptr) { \
26 doThrowIAE(env); \
27 return 0; \
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Ashok Bhat36bef0b2014-01-20 20:08:01 +000030static void Color_RGBToHSV(JNIEnv* env, jobject, jint red, jint green, jint blue, jfloatArray hsvArray)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031{
32 SkScalar hsv[3];
33 SkRGBToHSV(red, green, blue, hsv);
34
35 AutoJavaFloatArray autoHSV(env, hsvArray, 3);
36 float* values = autoHSV.ptr();
37 for (int i = 0; i < 3; i++) {
38 values[i] = SkScalarToFloat(hsv[i]);
39 }
40}
Elliott Hughes4cb17532011-04-12 16:10:26 -070041
Ashok Bhat36bef0b2014-01-20 20:08:01 +000042static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvArray)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043{
44 AutoJavaFloatArray autoHSV(env, hsvArray, 3);
Leon Scroggins III2e0103e2014-04-04 17:05:24 -040045#ifdef SK_SCALAR_IS_FLOAT
46 SkScalar* hsv = autoHSV.ptr();
47#else
48 #error Need to convert float array to SkScalar array before calling the following function.
49#endif
Elliott Hughes4cb17532011-04-12 16:10:26 -070050
Ashok Bhat36bef0b2014-01-20 20:08:01 +000051 return static_cast<jint>(SkHSVToColor(alpha, hsv));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052}
53
54///////////////////////////////////////////////////////////////////////////////////////////////
55
Nader Jawad5bed1f52020-09-25 00:27:29 -070056static void Shader_safeUnref(SkShader* shader) {
Derek Sollenberger6062c592011-02-22 13:55:04 -050057 SkSafeUnref(shader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058}
59
John Reck8bde0be2017-05-19 10:55:20 -070060static jlong Shader_getNativeFinalizer(JNIEnv*, jobject) {
61 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
62}
63
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064///////////////////////////////////////////////////////////////////////////////////////////////
65
Leon Scroggins III71fae622019-03-26 16:28:41 -040066static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, jlong bitmapHandle,
Mike Reed3ed30892020-12-11 12:25:30 -050067 jint tileModeX, jint tileModeY, bool filter) {
Chris Craikb581e672017-03-07 15:27:36 -080068 const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
Stan Iliev7bc3bc62017-05-24 13:28:36 -040069 sk_sp<SkImage> image;
Leon Scroggins III71fae622019-03-26 16:28:41 -040070 if (bitmapHandle) {
Chris Craikb786bbd2015-06-10 16:58:42 -070071 // Only pass a valid SkBitmap object to the constructor if the Bitmap exists. Otherwise,
72 // we'll pass an empty SkBitmap to avoid crashing/excepting for compatibility.
Leon Scroggins III71fae622019-03-26 16:28:41 -040073 image = android::bitmap::toBitmap(bitmapHandle).makeImage();
Chris Craikb786bbd2015-06-10 16:58:42 -070074 }
Romain Guy06f96e22010-07-30 19:18:16 -070075
Stan Iliev7bc3bc62017-05-24 13:28:36 -040076 if (!image.get()) {
77 SkBitmap bitmap;
78 image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
79 }
Mike Reed3ed30892020-12-11 12:25:30 -050080 SkSamplingOptions sampling(filter ? SkFilterMode::kLinear : SkFilterMode::kNearest,
81 SkMipmapMode::kNone);
Nader Jawad5bed1f52020-09-25 00:27:29 -070082 sk_sp<SkShader> shader = image->makeShader(
Mike Reed3ed30892020-12-11 12:25:30 -050083 (SkTileMode)tileModeX, (SkTileMode)tileModeY, sampling);
Nader Jawad5bed1f52020-09-25 00:27:29 -070084 ThrowIAE_IfNull(env, shader.get());
Derek Sollenberger450756a2016-11-07 15:55:47 -050085
Nader Jawad5bed1f52020-09-25 00:27:29 -070086 if (matrix) {
87 shader = shader->makeWithLocalMatrix(*matrix);
88 }
ztenghuib244fb52017-04-04 17:33:40 -070089
Nader Jawad5bed1f52020-09-25 00:27:29 -070090 return reinterpret_cast<jlong>(shader.release());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091}
Romain Guy06f96e22010-07-30 19:18:16 -070092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093///////////////////////////////////////////////////////////////////////////////////////////////
94
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -050095static std::vector<SkColor4f> convertColorLongs(JNIEnv* env, jlongArray colorArray) {
96 const size_t count = env->GetArrayLength(colorArray);
97 const jlong* colorValues = env->GetLongArrayElements(colorArray, nullptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -050099 std::vector<SkColor4f> colors(count);
100 for (size_t i = 0; i < count; ++i) {
101 colors[i] = GraphicsJNI::convertColorLong(colorValues[i]);
ztenghuib244fb52017-04-04 17:33:40 -0700102 }
Romain Guy06f96e22010-07-30 19:18:16 -0700103
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500104 env->ReleaseLongArrayElements(colorArray, const_cast<jlong*>(colorValues), JNI_ABORT);
105 return colors;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106}
107
108///////////////////////////////////////////////////////////////////////////////////////////////
109
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500110static jlong LinearGradient_create(JNIEnv* env, jobject, jlong matrixPtr,
111 jfloat x0, jfloat y0, jfloat x1, jfloat y1, jlongArray colorArray,
Leon Scroggins III2befe1d2019-01-31 13:19:26 -0500112 jfloatArray posArray, jint tileMode, jlong colorSpaceHandle) {
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500113 SkPoint pts[2];
114 pts[0].set(x0, y0);
115 pts[1].set(x1, y1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500117 std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500119 AutoJavaFloatArray autoPos(env, posArray, colors.size());
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400120#ifdef SK_SCALAR_IS_FLOAT
121 SkScalar* pos = autoPos.ptr();
122#else
123 #error Need to convert float array to SkScalar array before calling the following function.
124#endif
Elliott Hughes4cb17532011-04-12 16:10:26 -0700125
Nader Jawad5bed1f52020-09-25 00:27:29 -0700126 sk_sp<SkShader> shader(SkGradientShader::MakeLinear(pts, &colors[0],
127 GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
128 static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr));
129 ThrowIAE_IfNull(env, shader);
ztenghuib244fb52017-04-04 17:33:40 -0700130
Nader Jawad5bed1f52020-09-25 00:27:29 -0700131 const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
132 if (matrix) {
133 shader = shader->makeWithLocalMatrix(*matrix);
134 }
135
136 return reinterpret_cast<jlong>(shader.release());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137}
138
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500139///////////////////////////////////////////////////////////////////////////////////////////////
140
Nader Jawade7ab8412020-10-16 18:00:04 -0700141static jlong RadialGradient_create(JNIEnv* env,
142 jobject,
143 jlong matrixPtr,
144 jfloat startX,
145 jfloat startY,
146 jfloat startRadius,
147 jfloat endX,
148 jfloat endY,
149 jfloat endRadius,
150 jlongArray colorArray,
151 jfloatArray posArray,
152 jint tileMode,
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500153 jlong colorSpaceHandle) {
Nader Jawade7ab8412020-10-16 18:00:04 -0700154
155 SkPoint start;
156 start.set(startX, startY);
157
158 SkPoint end;
159 end.set(endX, endY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500161 std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500163 AutoJavaFloatArray autoPos(env, posArray, colors.size());
164#ifdef SK_SCALAR_IS_FLOAT
165 SkScalar* pos = autoPos.ptr();
166#else
167 #error Need to convert float array to SkScalar array before calling the following function.
168#endif
ztenghuib244fb52017-04-04 17:33:40 -0700169
Nader Jawade7ab8412020-10-16 18:00:04 -0700170 auto colorSpace = GraphicsJNI::getNativeColorSpace(colorSpaceHandle);
171 auto skTileMode = static_cast<SkTileMode>(tileMode);
172 sk_sp<SkShader> shader = SkGradientShader::MakeTwoPointConical(start, startRadius, end,
173 endRadius, &colors[0], std::move(colorSpace), pos, colors.size(), skTileMode,
174 sGradientShaderFlags, nullptr);
Nader Jawad5bed1f52020-09-25 00:27:29 -0700175 ThrowIAE_IfNull(env, shader);
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500176
Nader Jawade7ab8412020-10-16 18:00:04 -0700177 // Explicitly create a new shader with the specified matrix to match existing behavior.
178 // Passing in the matrix in the instantiation above can throw exceptions for non-invertible
179 // matrices. However, makeWithLocalMatrix will still allow for the shader to be created
180 // and skia handles null-shaders internally (i.e. is ignored)
Nader Jawad5bed1f52020-09-25 00:27:29 -0700181 const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
182 if (matrix) {
183 shader = shader->makeWithLocalMatrix(*matrix);
184 }
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500185
Nader Jawad5bed1f52020-09-25 00:27:29 -0700186 return reinterpret_cast<jlong>(shader.release());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187}
188
189///////////////////////////////////////////////////////////////////////////////
190
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500191static jlong SweepGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat x, jfloat y,
192 jlongArray colorArray, jfloatArray jpositions, jlong colorSpaceHandle) {
193 std::vector<SkColor4f> colors = convertColorLongs(env, colorArray);
Elliott Hughes4cb17532011-04-12 16:10:26 -0700194
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500195 AutoJavaFloatArray autoPos(env, jpositions, colors.size());
Leon Scroggins III2e0103e2014-04-04 17:05:24 -0400196#ifdef SK_SCALAR_IS_FLOAT
197 SkScalar* pos = autoPos.ptr();
198#else
199 #error Need to convert float array to SkScalar array before calling the following function.
200#endif
Elliott Hughes4cb17532011-04-12 16:10:26 -0700201
Nader Jawad5bed1f52020-09-25 00:27:29 -0700202 sk_sp<SkShader> shader = SkGradientShader::MakeSweep(x, y, &colors[0],
203 GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
204 sGradientShaderFlags, nullptr);
205 ThrowIAE_IfNull(env, shader);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
Nader Jawad5bed1f52020-09-25 00:27:29 -0700207 const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
208 if (matrix) {
209 shader = shader->makeWithLocalMatrix(*matrix);
210 }
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500211
Nader Jawad5bed1f52020-09-25 00:27:29 -0700212 return reinterpret_cast<jlong>(shader.release());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213}
214
215///////////////////////////////////////////////////////////////////////////////////////////////
216
Chris Craikb581e672017-03-07 15:27:36 -0800217static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
218 jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle) {
Nader Jawad5bed1f52020-09-25 00:27:29 -0700219 const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
220 SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
221 SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
222 SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
223 sk_sp<SkShader> baseShader(SkShaders::Blend(mode,
224 sk_ref_sp(shaderA), sk_ref_sp(shaderB)));
Chris Craikb581e672017-03-07 15:27:36 -0800225
Nader Jawad5bed1f52020-09-25 00:27:29 -0700226 SkShader* shader;
Chris Craikb581e672017-03-07 15:27:36 -0800227
Nader Jawad5bed1f52020-09-25 00:27:29 -0700228 if (matrix) {
229 shader = baseShader->makeWithLocalMatrix(*matrix).release();
230 } else {
231 shader = baseShader.release();
232 }
233 return reinterpret_cast<jlong>(shader);
Nader Jawad322cb9c2020-08-17 17:15:54 -0700234}
235
236///////////////////////////////////////////////////////////////////////////////////////////////
237
Stan Iliev6867fc82019-11-22 18:00:01 -0500238///////////////////////////////////////////////////////////////////////////////////////////////
239
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500240static jlong RuntimeShader_createShaderBuilder(JNIEnv* env, jobject, jstring sksl) {
Stan Iliev6867fc82019-11-22 18:00:01 -0500241 ScopedUtfChars strSksl(env, sksl);
John Stiles5f2f3e42021-02-10 16:58:04 +0000242 auto result = SkRuntimeEffect::Make(SkString(strSksl.c_str()), SkRuntimeEffect::Options{});
243 if (result.effect.get() == nullptr) {
244 doThrowIAE(env, result.errorText.c_str());
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500245 return 0;
John Reckc784d9a2020-08-03 10:45:39 -0700246 }
John Stiles5f2f3e42021-02-10 16:58:04 +0000247 return reinterpret_cast<jlong>(new SkRuntimeShaderBuilder(std::move(result.effect)));
Stan Iliev6867fc82019-11-22 18:00:01 -0500248}
249
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500250static void SkRuntimeShaderBuilder_delete(SkRuntimeShaderBuilder* builder) {
251 delete builder;
Nader Jawad5bed1f52020-09-25 00:27:29 -0700252}
253
Stan Iliev6867fc82019-11-22 18:00:01 -0500254static jlong RuntimeShader_getNativeFinalizer(JNIEnv*, jobject) {
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500255 return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SkRuntimeShaderBuilder_delete));
256}
257
258static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderBuilder, jlong matrixPtr,
259 jboolean isOpaque) {
260 SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
261 const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
262 sk_sp<SkShader> shader = builder->makeShader(matrix, isOpaque == JNI_TRUE);
263 ThrowIAE_IfNull(env, shader);
264 return reinterpret_cast<jlong>(shader.release());
265}
266
267static inline int ThrowIAEFmt(JNIEnv* env, const char* fmt, ...) {
268 va_list args;
269 va_start(args, fmt);
Greg Kaiser9c1f79f2021-01-19 07:35:49 -0800270 int ret = jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException", fmt, args);
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500271 va_end(args);
Greg Kaiser9c1f79f2021-01-19 07:35:49 -0800272 return ret;
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500273}
274
275static void RuntimeShader_updateUniforms(JNIEnv* env, jobject, jlong shaderBuilder,
276 jstring jUniformName, jfloatArray jvalues) {
277 SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
278 ScopedUtfChars name(env, jUniformName);
279 AutoJavaFloatArray autoValues(env, jvalues, 0, kRO_JNIAccess);
280
281 SkRuntimeShaderBuilder::BuilderUniform uniform = builder->uniform(name.c_str());
282 if (uniform.fVar == nullptr) {
283 ThrowIAEFmt(env, "unable to find uniform named %s", name.c_str());
284 } else if (!uniform.set<float>(autoValues.ptr(), autoValues.length())) {
285 ThrowIAEFmt(env, "mismatch in byte size for uniform [expected: %zu actual: %zu]",
286 uniform.fVar->sizeInBytes(), sizeof(float) * autoValues.length());
287 }
288}
289
290static void RuntimeShader_updateShader(JNIEnv* env, jobject, jlong shaderBuilder,
291 jstring jUniformName, jlong shaderHandle) {
292 SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(shaderBuilder);
293 ScopedUtfChars name(env, jUniformName);
294 SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
295
296 SkRuntimeShaderBuilder::BuilderChild child = builder->child(name.c_str());
297 if (child.fIndex == -1) {
298 ThrowIAEFmt(env, "unable to find shader named %s", name.c_str());
299 return;
300 }
301
302 builder->child(name.c_str()) = sk_ref_sp(shader);
Stan Iliev6867fc82019-11-22 18:00:01 -0500303}
304
305///////////////////////////////////////////////////////////////////////////////////////////////
306
Daniel Micay76f6a862015-09-19 17:31:01 -0400307static const JNINativeMethod gColorMethods[] = {
Chris Craikb581e672017-03-07 15:27:36 -0800308 { "nativeRGBToHSV", "(III[F)V", (void*)Color_RGBToHSV },
309 { "nativeHSVToColor", "(I[F)I", (void*)Color_HSVToColor }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310};
311
Daniel Micay76f6a862015-09-19 17:31:01 -0400312static const JNINativeMethod gShaderMethods[] = {
John Reck8bde0be2017-05-19 10:55:20 -0700313 { "nativeGetFinalizer", "()J", (void*)Shader_getNativeFinalizer },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314};
315
Daniel Micay76f6a862015-09-19 17:31:01 -0400316static const JNINativeMethod gBitmapShaderMethods[] = {
Mike Reed3ed30892020-12-11 12:25:30 -0500317 { "nativeCreate", "(JJIIZ)J", (void*)BitmapShader_constructor },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318};
319
Daniel Micay76f6a862015-09-19 17:31:01 -0400320static const JNINativeMethod gLinearGradientMethods[] = {
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500321 { "nativeCreate", "(JFFFF[J[FIJ)J", (void*)LinearGradient_create },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322};
323
Daniel Micay76f6a862015-09-19 17:31:01 -0400324static const JNINativeMethod gRadialGradientMethods[] = {
Nader Jawade7ab8412020-10-16 18:00:04 -0700325 { "nativeCreate", "(JFFFFFF[J[FIJ)J", (void*)RadialGradient_create },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326};
327
Daniel Micay76f6a862015-09-19 17:31:01 -0400328static const JNINativeMethod gSweepGradientMethods[] = {
Leon Scroggins IIIb0aecc22019-01-18 11:09:59 -0500329 { "nativeCreate", "(JFF[J[FJ)J", (void*)SweepGradient_create },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330};
331
Daniel Micay76f6a862015-09-19 17:31:01 -0400332static const JNINativeMethod gComposeShaderMethods[] = {
Chris Craikb581e672017-03-07 15:27:36 -0800333 { "nativeCreate", "(JJJI)J", (void*)ComposeShader_create },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334};
335
Stan Iliev6867fc82019-11-22 18:00:01 -0500336static const JNINativeMethod gRuntimeShaderMethods[] = {
Derek Sollenberger783e5ae2021-01-11 15:44:46 -0500337 {"nativeGetFinalizer", "()J", (void*)RuntimeShader_getNativeFinalizer},
338 {"nativeCreateShader", "(JJZ)J", (void*)RuntimeShader_create},
339 {"nativeCreateBuilder", "(Ljava/lang/String;)J", (void*)RuntimeShader_createShaderBuilder},
340 {"nativeUpdateUniforms", "(JLjava/lang/String;[F)V", (void*)RuntimeShader_updateUniforms},
341 {"nativeUpdateShader", "(JLjava/lang/String;J)V", (void*)RuntimeShader_updateShader},
Stan Iliev6867fc82019-11-22 18:00:01 -0500342};
343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344int register_android_graphics_Shader(JNIEnv* env)
345{
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800346 android::RegisterMethodsOrDie(env, "android/graphics/Color", gColorMethods,
347 NELEM(gColorMethods));
348 android::RegisterMethodsOrDie(env, "android/graphics/Shader", gShaderMethods,
349 NELEM(gShaderMethods));
350 android::RegisterMethodsOrDie(env, "android/graphics/BitmapShader", gBitmapShaderMethods,
351 NELEM(gBitmapShaderMethods));
352 android::RegisterMethodsOrDie(env, "android/graphics/LinearGradient", gLinearGradientMethods,
353 NELEM(gLinearGradientMethods));
354 android::RegisterMethodsOrDie(env, "android/graphics/RadialGradient", gRadialGradientMethods,
355 NELEM(gRadialGradientMethods));
356 android::RegisterMethodsOrDie(env, "android/graphics/SweepGradient", gSweepGradientMethods,
357 NELEM(gSweepGradientMethods));
358 android::RegisterMethodsOrDie(env, "android/graphics/ComposeShader", gComposeShaderMethods,
359 NELEM(gComposeShaderMethods));
Stan Iliev6867fc82019-11-22 18:00:01 -0500360 android::RegisterMethodsOrDie(env, "android/graphics/RuntimeShader", gRuntimeShaderMethods,
361 NELEM(gRuntimeShaderMethods));
Elliott Hughes4cb17532011-04-12 16:10:26 -0700362
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800363 return 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800364}