diff options
Diffstat (limited to 'media/mca/filterfw/jni/jni_shader_program.cpp')
-rw-r--r-- | media/mca/filterfw/jni/jni_shader_program.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/media/mca/filterfw/jni/jni_shader_program.cpp b/media/mca/filterfw/jni/jni_shader_program.cpp new file mode 100644 index 0000000..19f43cd --- /dev/null +++ b/media/mca/filterfw/jni/jni_shader_program.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string> +#include <vector> + +#include "jni/jni_shader_program.h" +#include "jni/jni_util.h" + +#include "native/base/logging.h" +#include "native/core/geometry.h" +#include "native/core/gl_env.h" +#include "native/core/gl_frame.h" +#include "native/core/shader_program.h" +#include "native/core/vertex_frame.h" + +using android::filterfw::GLEnv; +using android::filterfw::GLFrame; +using android::filterfw::Point; +using android::filterfw::ProgramVar; +using android::filterfw::Quad; +using android::filterfw::ShaderProgram; +using android::filterfw::VertexFrame; + +jboolean Java_android_filterfw_core_ShaderProgram_allocate(JNIEnv* env, + jobject thiz, + jobject gl_env, + jstring vertex_shader, + jstring fragment_shader) { + // Get the GLEnv pointer + GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env); + + // Create the shader + if (!fragment_shader || !gl_env_ptr) + return false; + else if (!vertex_shader) + return ToJBool(WrapObjectInJava(new ShaderProgram( + gl_env_ptr, + ToCppString(env, fragment_shader)), + env, + thiz, + true)); + else + return ToJBool(WrapObjectInJava(new ShaderProgram( + gl_env_ptr, + ToCppString(env, vertex_shader), + ToCppString(env, fragment_shader)), + env, + thiz, + true)); +} + +jboolean Java_android_filterfw_core_ShaderProgram_deallocate(JNIEnv* env, jobject thiz) { + return ToJBool(DeleteNativeObject<ShaderProgram>(env, thiz)); +} + +jboolean Java_android_filterfw_core_ShaderProgram_compileAndLink(JNIEnv* env, jobject thiz) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + return program ? ToJBool(program->CompileAndLink()) : JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setUniformValue(JNIEnv* env, + jobject thiz, + jstring key, + jobject value) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + const Value c_value = ToCValue(env, value); + const std::string c_key = ToCppString(env, key); + if (c_value.value) { + return ToJBool(program && program->SetUniformValue(c_key, c_value)); + } else { + ALOGE("ShaderProgram: Could not convert java object value passed for key '%s'!", c_key.c_str()); + return JNI_FALSE; + } +} + +jobject Java_android_filterfw_core_ShaderProgram_getUniformValue(JNIEnv* env, + jobject thiz, + jstring key) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + const std::string c_key = ToCppString(env, key); + return program ? ToJObject(env, program->GetUniformValue(c_key)) : JNI_NULL; +} + +jboolean Java_android_filterfw_core_ShaderProgram_shaderProcess(JNIEnv* env, + jobject thiz, + jobjectArray inputs, + jobject output) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + std::vector<const GLFrame*> input_frames; + if (program && inputs && output) { + // Get the input frames + const int input_count = env->GetArrayLength(inputs); + for (int i = 0; i < input_count; ++i) { + jobject input = env->GetObjectArrayElement(inputs, i); + const GLFrame* input_frame = ConvertFromJava<GLFrame>(env, input); + if (!input || !input_frame) { + ALOGE("ShaderProgram: invalid input frame %d!", i); + return JNI_FALSE; + } + input_frames.push_back(input_frame); + } + + // Get the output frame + GLFrame* output_frame = ConvertFromJava<GLFrame>(env, output); + if (!output_frame) { + ALOGE("ShaderProgram: no output frame found!"); + return JNI_FALSE; + } + + // Process the frames! + if (!program->Process(input_frames, output_frame)) { + ALOGE("ShaderProgram: error processing shader!"); + return JNI_FALSE; + } + + return JNI_TRUE; + } + return JNI_FALSE; +} + +jobject Java_android_filterfw_core_ShaderProgram_nativeCreateIdentity(JNIEnv* env, + jclass, + jobject gl_env) { + GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env); + ShaderProgram* program = gl_env_ptr ? ShaderProgram::CreateIdentity(gl_env_ptr) : NULL; + return program ? WrapNewObjectInJava(program, env, false) : NULL; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setSourceRegion(JNIEnv* env, + jobject thiz, + jfloat x0, + jfloat y0, + jfloat x1, + jfloat y1, + jfloat x2, + jfloat y2, + jfloat x3, + jfloat y3) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetSourceRegion(Quad(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3))); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setTargetRegion(JNIEnv* env, + jobject thiz, + jfloat x0, + jfloat y0, + jfloat x1, + jfloat y1, + jfloat x2, + jfloat y2, + jfloat x3, + jfloat y3) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetTargetRegion(Quad(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3))); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderClearsOutput(JNIEnv* env, + jobject thiz, + jboolean clears) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetClearsOutput(ToCppBool(clears)); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderBlendEnabled(JNIEnv* env, + jobject thiz, + jboolean enable) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetBlendEnabled(ToCppBool(enable)); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderBlendFunc(JNIEnv* env, + jobject thiz, + jint sfactor, + jint dfactor) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetBlendFunc(sfactor, dfactor); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderClearColor(JNIEnv* env, + jobject thiz, + jfloat r, + jfloat g, + jfloat b) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetClearColor(r, g, b, 1.0f); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderDrawMode(JNIEnv* env, + jobject thiz, + jint draw_mode) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetDrawMode(draw_mode); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderTileCounts(JNIEnv* env, + jobject thiz, + jint x_count, + jint y_count) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetTileCounts(x_count, y_count); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderVertexCount(JNIEnv* env, + jobject thiz, + jint vertex_count) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + program->SetVertexCount(vertex_count); + return JNI_TRUE; + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_beginShaderDrawing(JNIEnv* env, jobject thiz) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + return ToJBool(program && program->BeginDraw()); +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderAttributeValues( + JNIEnv* env, + jobject thiz, + jstring attr_name, + jfloatArray values, + jint component_count) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + // Get the floats to set + jfloat* float_ptr = env->GetFloatArrayElements(values, NULL); + const int length = env->GetArrayLength(values); + + // Get the program variable to set + const std::string attr_string = ToCppString(env, attr_name); + ProgramVar program_var = program->GetAttribute(attr_string); + + // Set the variable + if (float_ptr && ShaderProgram::IsVarValid(program_var)) { + const bool success = program->SetAttributeValues(program_var, + reinterpret_cast<float*>(float_ptr), + length, + component_count); + env->ReleaseFloatArrayElements(values, float_ptr, JNI_ABORT); + return ToJBool(success); + } + } + return JNI_FALSE; +} + +jboolean Java_android_filterfw_core_ShaderProgram_setShaderAttributeVertexFrame( + JNIEnv* env, + jobject thiz, + jstring attr_name, + jobject vertex_frame, + jint type, + jint component_count, + jint stride, + jint offset, + jboolean normalize) { + ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz); + if (program) { + // Get the vertex frame + VertexFrame* v_frame = ConvertFromJava<VertexFrame>(env, vertex_frame); + + // Get the program variable to set + const std::string attr_string = ToCppString(env, attr_name); + ProgramVar program_var = program->GetAttribute(attr_string); + + // Set the variable + if (v_frame && ShaderProgram::IsVarValid(program_var)) { + const bool success = program->SetAttributeValues(program_var, + v_frame, + type, + component_count, + stride, + offset, + ToCppBool(normalize)); + return ToJBool(success); + } + } + return JNI_FALSE; +} |