xref: /aosp_15_r20/frameworks/base/libs/hwui/jni/RuntimeXfermode.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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