1 /*
2 * Copyright 2021 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include <android/log.h>
9 #include <jni.h>
10
11 #include "include/core/SkM44.h"
12 #include "include/effects/SkRuntimeEffect.h"
13 #include "modules/androidkit/src/Utils.h"
14
15 namespace {
16
ShaderBuilder_Create(JNIEnv * env,jobject,jstring jsksl)17 static jlong ShaderBuilder_Create(JNIEnv* env, jobject, jstring jsksl) {
18 auto [eff,err] = SkRuntimeEffect::MakeForShader(
19 SkString(androidkit::utils::CString(env, jsksl)));
20
21 if (!eff) {
22 // TODO: throw exception?
23 __android_log_print(ANDROID_LOG_ERROR, "AndroidKit", "Failed to compile shader: %s\n",
24 err.c_str());
25 return 0;
26 }
27
28 return reinterpret_cast<jlong>(new SkRuntimeShaderBuilder(std::move(eff)));
29 }
30
ShaderBuilder_Release(JNIEnv * env,jobject,jlong native_instance)31 static void ShaderBuilder_Release(JNIEnv* env, jobject, jlong native_instance) {
32 if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
33 delete builder;
34 }
35 }
36
ShaderBuilder_SetUniformFloat(JNIEnv * env,jobject,jlong native_instance,jstring jname,float val)37 static void ShaderBuilder_SetUniformFloat(JNIEnv* env, jobject, jlong native_instance, jstring jname, float val) {
38 if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
39 builder->uniform(androidkit::utils::CString(env, jname)) = val;
40 }
41 }
42
ShaderBuilder_SetUniformFloat3(JNIEnv * env,jobject,jlong native_instance,jstring jname,float valX,float valY,float valZ)43 static void ShaderBuilder_SetUniformFloat3(JNIEnv* env, jobject, jlong native_instance, jstring jname, float valX, float valY, float valZ) {
44 if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
45 builder->uniform(androidkit::utils::CString(env, jname)) = SkV3{valX, valY, valZ};
46 }
47 }
48
ShaderBuilder_SetUniformMatrix(JNIEnv * env,jobject,jlong native_instance,jstring jname,jlong native_matrix)49 static void ShaderBuilder_SetUniformMatrix(JNIEnv* env, jobject, jlong native_instance, jstring jname, jlong native_matrix) {
50 if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
51 if (auto* matrix = reinterpret_cast<SkM44*>(native_matrix)) {
52 builder->uniform(androidkit::utils::CString(env, jname)) = *matrix;
53 }
54 }
55 }
56
ShaderBuilder_MakeShader(JNIEnv * env,jobject,jlong native_instance)57 static jlong ShaderBuilder_MakeShader(JNIEnv* env, jobject, jlong native_instance) {
58 if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) {
59 auto shader = builder->makeShader(nullptr, false);
60 return reinterpret_cast<jlong>(shader.release());
61 }
62
63 return 0;
64 }
65
66 } // namespace
67
register_androidkit_RuntimeShaderBuilder(JNIEnv * env)68 int register_androidkit_RuntimeShaderBuilder(JNIEnv* env) {
69 static const JNINativeMethod methods[] = {
70 {"nCreate" , "(Ljava/lang/String;)J" , reinterpret_cast<void*>(ShaderBuilder_Create)},
71 {"nRelease" , "(J)V" , reinterpret_cast<void*>(ShaderBuilder_Release)},
72
73 {"nSetUniformFloat" , "(JLjava/lang/String;F)V" , reinterpret_cast<void*>(ShaderBuilder_SetUniformFloat)},
74 {"nSetUniformFloat3", "(JLjava/lang/String;FFF)V" , reinterpret_cast<void*>(ShaderBuilder_SetUniformFloat3)},
75 {"nSetUniformMatrix", "(JLjava/lang/String;J)V" , reinterpret_cast<void*>(ShaderBuilder_SetUniformMatrix)},
76 {"nMakeShader" , "(J)J" , reinterpret_cast<void*>(ShaderBuilder_MakeShader)},
77 };
78
79 const auto clazz = env->FindClass("org/skia/androidkit/RuntimeShaderBuilder");
80 return clazz
81 ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
82 : JNI_ERR;
83 }
84