1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2024 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker *
4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker *
8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker *
10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker */
16*d57664e9SAndroid Build Coastguard Worker
17*d57664e9SAndroid Build Coastguard Worker #include "ColorFilter.h"
18*d57664e9SAndroid Build Coastguard Worker #include "GraphicsJNI.h"
19*d57664e9SAndroid Build Coastguard Worker #include "RuntimeEffectUtils.h"
20*d57664e9SAndroid Build Coastguard Worker #include "SkBlender.h"
21*d57664e9SAndroid Build Coastguard Worker
22*d57664e9SAndroid Build Coastguard Worker using namespace android::uirenderer;
23*d57664e9SAndroid Build Coastguard Worker
SkRuntimeEffectBuilder_delete(SkRuntimeEffectBuilder * builder)24*d57664e9SAndroid Build Coastguard Worker static void SkRuntimeEffectBuilder_delete(SkRuntimeEffectBuilder* builder) {
25*d57664e9SAndroid Build Coastguard Worker delete builder;
26*d57664e9SAndroid Build Coastguard Worker }
27*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_getNativeFinalizer(JNIEnv *,jobject)28*d57664e9SAndroid Build Coastguard Worker static jlong RuntimeXfermode_getNativeFinalizer(JNIEnv*, jobject) {
29*d57664e9SAndroid Build Coastguard Worker return static_cast<jlong>(reinterpret_cast<uintptr_t>(&SkRuntimeEffectBuilder_delete));
30*d57664e9SAndroid Build Coastguard Worker }
31*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_createBuilder(JNIEnv * env,jobject,jstring sksl)32*d57664e9SAndroid Build Coastguard Worker static jlong RuntimeXfermode_createBuilder(JNIEnv* env, jobject, jstring sksl) {
33*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars strSksl(env, sksl);
34*d57664e9SAndroid Build Coastguard Worker auto result =
35*d57664e9SAndroid Build Coastguard Worker SkRuntimeEffect::MakeForBlender(SkString(strSksl.c_str()), SkRuntimeEffect::Options{});
36*d57664e9SAndroid Build Coastguard Worker if (result.effect.get() == nullptr) {
37*d57664e9SAndroid Build Coastguard Worker doThrowIAE(env, result.errorText.c_str());
38*d57664e9SAndroid Build Coastguard Worker return 0;
39*d57664e9SAndroid Build Coastguard Worker }
40*d57664e9SAndroid Build Coastguard Worker return reinterpret_cast<jlong>(new SkRuntimeEffectBuilder(std::move(result.effect)));
41*d57664e9SAndroid Build Coastguard Worker }
42*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_create(JNIEnv * env,jobject,jlong builderPtr)43*d57664e9SAndroid Build Coastguard Worker static jlong RuntimeXfermode_create(JNIEnv* env, jobject, jlong builderPtr) {
44*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
45*d57664e9SAndroid Build Coastguard Worker sk_sp<SkBlender> blender = builder->makeBlender();
46*d57664e9SAndroid Build Coastguard Worker if (!blender) {
47*d57664e9SAndroid Build Coastguard Worker doThrowIAE(env);
48*d57664e9SAndroid Build Coastguard Worker }
49*d57664e9SAndroid Build Coastguard Worker return reinterpret_cast<jlong>(blender.release());
50*d57664e9SAndroid Build Coastguard Worker }
51*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_updateFloatArrayUniforms(JNIEnv * env,jobject,jlong builderPtr,jstring uniformName,jfloatArray uniforms,jboolean isColor)52*d57664e9SAndroid Build Coastguard Worker static void RuntimeXfermode_updateFloatArrayUniforms(JNIEnv* env, jobject, jlong builderPtr,
53*d57664e9SAndroid Build Coastguard Worker jstring uniformName, jfloatArray uniforms,
54*d57664e9SAndroid Build Coastguard Worker jboolean isColor) {
55*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
56*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars name(env, uniformName);
57*d57664e9SAndroid Build Coastguard Worker AutoJavaFloatArray autoValues(env, uniforms, 0, kRO_JNIAccess);
58*d57664e9SAndroid Build Coastguard Worker UpdateFloatUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length(), isColor);
59*d57664e9SAndroid Build Coastguard Worker }
60*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_updateFloatUniforms(JNIEnv * env,jobject,jlong builderPtr,jstring uniformName,jfloat value1,jfloat value2,jfloat value3,jfloat value4,jint count)61*d57664e9SAndroid Build Coastguard Worker static void RuntimeXfermode_updateFloatUniforms(JNIEnv* env, jobject, jlong builderPtr,
62*d57664e9SAndroid Build Coastguard Worker jstring uniformName, jfloat value1, jfloat value2,
63*d57664e9SAndroid Build Coastguard Worker jfloat value3, jfloat value4, jint count) {
64*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
65*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars name(env, uniformName);
66*d57664e9SAndroid Build Coastguard Worker const float values[4] = {value1, value2, value3, value4};
67*d57664e9SAndroid Build Coastguard Worker UpdateFloatUniforms(env, builder, name.c_str(), values, count, false);
68*d57664e9SAndroid Build Coastguard Worker }
69*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_updateIntArrayUniforms(JNIEnv * env,jobject,jlong builderPtr,jstring uniformName,jintArray uniforms)70*d57664e9SAndroid Build Coastguard Worker static void RuntimeXfermode_updateIntArrayUniforms(JNIEnv* env, jobject, jlong builderPtr,
71*d57664e9SAndroid Build Coastguard Worker jstring uniformName, jintArray uniforms) {
72*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
73*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars name(env, uniformName);
74*d57664e9SAndroid Build Coastguard Worker AutoJavaIntArray autoValues(env, uniforms, 0);
75*d57664e9SAndroid Build Coastguard Worker UpdateIntUniforms(env, builder, name.c_str(), autoValues.ptr(), autoValues.length());
76*d57664e9SAndroid Build Coastguard Worker }
77*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_updateIntUniforms(JNIEnv * env,jobject,jlong builderPtr,jstring uniformName,jint value1,jint value2,jint value3,jint value4,jint count)78*d57664e9SAndroid Build Coastguard Worker static void RuntimeXfermode_updateIntUniforms(JNIEnv* env, jobject, jlong builderPtr,
79*d57664e9SAndroid Build Coastguard Worker jstring uniformName, jint value1, jint value2,
80*d57664e9SAndroid Build Coastguard Worker jint value3, jint value4, jint count) {
81*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
82*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars name(env, uniformName);
83*d57664e9SAndroid Build Coastguard Worker const int values[4] = {value1, value2, value3, value4};
84*d57664e9SAndroid Build Coastguard Worker UpdateIntUniforms(env, builder, name.c_str(), values, count);
85*d57664e9SAndroid Build Coastguard Worker }
86*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_updateChild(JNIEnv * env,jobject,jlong builderPtr,jstring childName,jlong childPtr)87*d57664e9SAndroid Build Coastguard Worker static void RuntimeXfermode_updateChild(JNIEnv* env, jobject, jlong builderPtr, jstring childName,
88*d57664e9SAndroid Build Coastguard Worker jlong childPtr) {
89*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
90*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars name(env, childName);
91*d57664e9SAndroid Build Coastguard Worker auto* child = reinterpret_cast<SkFlattenable*>(childPtr);
92*d57664e9SAndroid Build Coastguard Worker if (child) {
93*d57664e9SAndroid Build Coastguard Worker UpdateChild(env, builder, name.c_str(), child);
94*d57664e9SAndroid Build Coastguard Worker }
95*d57664e9SAndroid Build Coastguard Worker }
96*d57664e9SAndroid Build Coastguard Worker
RuntimeXfermode_updateColorFilter(JNIEnv * env,jobject,jlong builderPtr,jstring childName,jlong colorFilterPtr)97*d57664e9SAndroid Build Coastguard Worker static void RuntimeXfermode_updateColorFilter(JNIEnv* env, jobject, jlong builderPtr,
98*d57664e9SAndroid Build Coastguard Worker jstring childName, jlong colorFilterPtr) {
99*d57664e9SAndroid Build Coastguard Worker auto* builder = reinterpret_cast<SkRuntimeEffectBuilder*>(builderPtr);
100*d57664e9SAndroid Build Coastguard Worker ScopedUtfChars name(env, childName);
101*d57664e9SAndroid Build Coastguard Worker auto* child = reinterpret_cast<ColorFilter*>(colorFilterPtr);
102*d57664e9SAndroid Build Coastguard Worker if (child) {
103*d57664e9SAndroid Build Coastguard Worker auto childInput = child->getInstance();
104*d57664e9SAndroid Build Coastguard Worker if (childInput) {
105*d57664e9SAndroid Build Coastguard Worker UpdateChild(env, builder, name.c_str(), childInput.release());
106*d57664e9SAndroid Build Coastguard Worker }
107*d57664e9SAndroid Build Coastguard Worker }
108*d57664e9SAndroid Build Coastguard Worker }
109*d57664e9SAndroid Build Coastguard Worker
110*d57664e9SAndroid Build Coastguard Worker static const JNINativeMethod gRuntimeXfermodeMethods[] = {
111*d57664e9SAndroid Build Coastguard Worker {"nativeGetFinalizer", "()J", (void*)RuntimeXfermode_getNativeFinalizer},
112*d57664e9SAndroid Build Coastguard Worker {"nativeCreateBlenderBuilder", "(Ljava/lang/String;)J",
113*d57664e9SAndroid Build Coastguard Worker (void*)RuntimeXfermode_createBuilder},
114*d57664e9SAndroid Build Coastguard Worker {"nativeCreateNativeInstance", "(J)J", (void*)RuntimeXfermode_create},
115*d57664e9SAndroid Build Coastguard Worker {"nativeUpdateUniforms", "(JLjava/lang/String;[FZ)V",
116*d57664e9SAndroid Build Coastguard Worker (void*)RuntimeXfermode_updateFloatArrayUniforms},
117*d57664e9SAndroid Build Coastguard Worker {"nativeUpdateUniforms", "(JLjava/lang/String;FFFFI)V",
118*d57664e9SAndroid Build Coastguard Worker (void*)RuntimeXfermode_updateFloatUniforms},
119*d57664e9SAndroid Build Coastguard Worker {"nativeUpdateUniforms", "(JLjava/lang/String;[I)V",
120*d57664e9SAndroid Build Coastguard Worker (void*)RuntimeXfermode_updateIntArrayUniforms},
121*d57664e9SAndroid Build Coastguard Worker {"nativeUpdateUniforms", "(JLjava/lang/String;IIIII)V",
122*d57664e9SAndroid Build Coastguard Worker (void*)RuntimeXfermode_updateIntUniforms},
123*d57664e9SAndroid Build Coastguard Worker {"nativeUpdateChild", "(JLjava/lang/String;J)V", (void*)RuntimeXfermode_updateChild},
124*d57664e9SAndroid Build Coastguard Worker {"nativeUpdateColorFilter", "(JLjava/lang/String;J)V",
125*d57664e9SAndroid Build Coastguard Worker (void*)RuntimeXfermode_updateColorFilter},
126*d57664e9SAndroid Build Coastguard Worker };
127*d57664e9SAndroid Build Coastguard Worker
register_android_graphics_RuntimeXfermode(JNIEnv * env)128*d57664e9SAndroid Build Coastguard Worker int register_android_graphics_RuntimeXfermode(JNIEnv* env) {
129*d57664e9SAndroid Build Coastguard Worker android::RegisterMethodsOrDie(env, "android/graphics/RuntimeXfermode", gRuntimeXfermodeMethods,
130*d57664e9SAndroid Build Coastguard Worker NELEM(gRuntimeXfermodeMethods));
131*d57664e9SAndroid Build Coastguard Worker
132*d57664e9SAndroid Build Coastguard Worker return 0;
133*d57664e9SAndroid Build Coastguard Worker }
134