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 15namespace { 16 17static 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 31static void ShaderBuilder_Release(JNIEnv* env, jobject, jlong native_instance) { 32 if (auto* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(native_instance)) { 33 delete builder; 34 } 35} 36 37static 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 43static 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 49static 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 57static 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 68int 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