blob: 19f43cd8a7e2c8d5563623a1a0e7dcf4285cdece [file] [log] [blame]
/*
* 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;
}