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