/* * 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 #include #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(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(env, thiz)); } jboolean Java_android_filterfw_core_ShaderProgram_compileAndLink(JNIEnv* env, jobject thiz) { ShaderProgram* program = ConvertFromJava(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(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(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(env, thiz); std::vector 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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_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(env, thiz); if (program) { // Get the vertex frame VertexFrame* v_frame = ConvertFromJava(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; }