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