Home | History | Annotate | Download | only in jni
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <string>
     18 #include <vector>
     19 
     20 #include "jni/jni_shader_program.h"
     21 #include "jni/jni_util.h"
     22 
     23 #include "native/base/logging.h"
     24 #include "native/core/geometry.h"
     25 #include "native/core/gl_env.h"
     26 #include "native/core/gl_frame.h"
     27 #include "native/core/shader_program.h"
     28 #include "native/core/vertex_frame.h"
     29 
     30 using android::filterfw::GLEnv;
     31 using android::filterfw::GLFrame;
     32 using android::filterfw::Point;
     33 using android::filterfw::ProgramVar;
     34 using android::filterfw::Quad;
     35 using android::filterfw::ShaderProgram;
     36 using android::filterfw::VertexFrame;
     37 
     38 jboolean Java_android_filterfw_core_ShaderProgram_allocate(JNIEnv* env,
     39                                                            jobject thiz,
     40                                                            jobject gl_env,
     41                                                            jstring vertex_shader,
     42                                                            jstring fragment_shader) {
     43   // Get the GLEnv pointer
     44   GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
     45 
     46   // Create the shader
     47   if (!fragment_shader || !gl_env_ptr)
     48     return false;
     49   else if (!vertex_shader)
     50     return ToJBool(WrapObjectInJava(new ShaderProgram(
     51       gl_env_ptr,
     52       ToCppString(env, fragment_shader)),
     53       env,
     54       thiz,
     55       true));
     56   else
     57     return ToJBool(WrapObjectInJava(new ShaderProgram(
     58       gl_env_ptr,
     59       ToCppString(env, vertex_shader),
     60       ToCppString(env, fragment_shader)),
     61       env,
     62       thiz,
     63       true));
     64 }
     65 
     66 jboolean Java_android_filterfw_core_ShaderProgram_deallocate(JNIEnv* env, jobject thiz) {
     67   return ToJBool(DeleteNativeObject<ShaderProgram>(env, thiz));
     68 }
     69 
     70 jboolean Java_android_filterfw_core_ShaderProgram_compileAndLink(JNIEnv* env, jobject thiz) {
     71   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
     72   return program ? ToJBool(program->CompileAndLink()) : JNI_FALSE;
     73 }
     74 
     75 jboolean Java_android_filterfw_core_ShaderProgram_setUniformValue(JNIEnv* env,
     76                                                                   jobject thiz,
     77                                                                   jstring key,
     78                                                                   jobject value) {
     79   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
     80   const Value c_value = ToCValue(env, value);
     81   const std::string c_key = ToCppString(env, key);
     82   if (c_value.value) {
     83     return ToJBool(program && program->SetUniformValue(c_key, c_value));
     84   } else {
     85     LOGE("ShaderProgram: Could not convert java object value passed for key '%s'!", c_key.c_str());
     86     return JNI_FALSE;
     87   }
     88 }
     89 
     90 jobject Java_android_filterfw_core_ShaderProgram_getUniformValue(JNIEnv* env,
     91                                                                  jobject thiz,
     92                                                                  jstring key) {
     93   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
     94   const std::string c_key = ToCppString(env, key);
     95   return program ? ToJObject(env, program->GetUniformValue(c_key)) : JNI_NULL;
     96 }
     97 
     98 jboolean Java_android_filterfw_core_ShaderProgram_shaderProcess(JNIEnv* env,
     99                                                                 jobject thiz,
    100                                                                 jobjectArray inputs,
    101                                                                 jobject output) {
    102   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    103   std::vector<const GLFrame*> input_frames;
    104   if (program && inputs && output) {
    105     // Get the input frames
    106     const int input_count = env->GetArrayLength(inputs);
    107     for (int i = 0; i < input_count; ++i) {
    108       jobject input = env->GetObjectArrayElement(inputs, i);
    109       const GLFrame* input_frame = ConvertFromJava<GLFrame>(env, input);
    110       if (!input || !input_frame) {
    111         LOGE("ShaderProgram: invalid input frame %d!", i);
    112         return JNI_FALSE;
    113       }
    114       input_frames.push_back(input_frame);
    115     }
    116 
    117     // Get the output frame
    118     GLFrame* output_frame = ConvertFromJava<GLFrame>(env, output);
    119     if (!output_frame) {
    120       LOGE("ShaderProgram: no output frame found!");
    121       return JNI_FALSE;
    122     }
    123 
    124     // Process the frames!
    125     if (!program->Process(input_frames, output_frame)) {
    126       LOGE("ShaderProgram: error processing shader!");
    127       return JNI_FALSE;
    128     }
    129 
    130     return JNI_TRUE;
    131   }
    132   return JNI_FALSE;
    133 }
    134 
    135 jobject Java_android_filterfw_core_ShaderProgram_nativeCreateIdentity(JNIEnv* env,
    136                                                                       jclass,
    137                                                                       jobject gl_env) {
    138   GLEnv* gl_env_ptr = ConvertFromJava<GLEnv>(env, gl_env);
    139   ShaderProgram* program = gl_env_ptr ? ShaderProgram::CreateIdentity(gl_env_ptr) : NULL;
    140   return program ? WrapNewObjectInJava(program, env, false) : NULL;
    141 }
    142 
    143 jboolean Java_android_filterfw_core_ShaderProgram_setSourceRegion(JNIEnv* env,
    144                                                                   jobject thiz,
    145                                                                   jfloat x0,
    146                                                                   jfloat y0,
    147                                                                   jfloat x1,
    148                                                                   jfloat y1,
    149                                                                   jfloat x2,
    150                                                                   jfloat y2,
    151                                                                   jfloat x3,
    152                                                                   jfloat y3) {
    153   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    154   if (program) {
    155     program->SetSourceRegion(Quad(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3)));
    156     return JNI_TRUE;
    157   }
    158   return JNI_FALSE;
    159 }
    160 
    161 jboolean Java_android_filterfw_core_ShaderProgram_setTargetRegion(JNIEnv* env,
    162                                                                   jobject thiz,
    163                                                                   jfloat x0,
    164                                                                   jfloat y0,
    165                                                                   jfloat x1,
    166                                                                   jfloat y1,
    167                                                                   jfloat x2,
    168                                                                   jfloat y2,
    169                                                                   jfloat x3,
    170                                                                   jfloat y3) {
    171   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    172   if (program) {
    173     program->SetTargetRegion(Quad(Point(x0, y0), Point(x1, y1), Point(x2, y2), Point(x3, y3)));
    174     return JNI_TRUE;
    175   }
    176   return JNI_FALSE;
    177 }
    178 
    179 jboolean Java_android_filterfw_core_ShaderProgram_setShaderClearsOutput(JNIEnv* env,
    180                                                                         jobject thiz,
    181                                                                         jboolean clears) {
    182   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    183   if (program) {
    184     program->SetClearsOutput(ToCppBool(clears));
    185     return JNI_TRUE;
    186   }
    187   return JNI_FALSE;
    188 }
    189 
    190 jboolean Java_android_filterfw_core_ShaderProgram_setShaderBlendEnabled(JNIEnv* env,
    191                                                                         jobject thiz,
    192                                                                         jboolean enable) {
    193   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    194   if (program) {
    195     program->SetBlendEnabled(ToCppBool(enable));
    196     return JNI_TRUE;
    197   }
    198   return JNI_FALSE;
    199 }
    200 
    201 jboolean Java_android_filterfw_core_ShaderProgram_setShaderBlendFunc(JNIEnv* env,
    202                                                                      jobject thiz,
    203                                                                      jint sfactor,
    204                                                                      jint dfactor) {
    205   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    206   if (program) {
    207     program->SetBlendFunc(sfactor, dfactor);
    208     return JNI_TRUE;
    209   }
    210   return JNI_FALSE;
    211 }
    212 
    213 jboolean Java_android_filterfw_core_ShaderProgram_setShaderClearColor(JNIEnv* env,
    214                                                                       jobject thiz,
    215                                                                       jfloat r,
    216                                                                       jfloat g,
    217                                                                       jfloat b) {
    218   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    219   if (program) {
    220     program->SetClearColor(r, g, b, 1.0f);
    221     return JNI_TRUE;
    222   }
    223   return JNI_FALSE;
    224 }
    225 
    226 jboolean Java_android_filterfw_core_ShaderProgram_setShaderDrawMode(JNIEnv* env,
    227                                                                     jobject thiz,
    228                                                                     jint draw_mode) {
    229   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    230   if (program) {
    231     program->SetDrawMode(draw_mode);
    232     return JNI_TRUE;
    233   }
    234   return JNI_FALSE;
    235 }
    236 
    237 jboolean Java_android_filterfw_core_ShaderProgram_setShaderTileCounts(JNIEnv* env,
    238                                                                       jobject thiz,
    239                                                                       jint x_count,
    240                                                                       jint y_count) {
    241   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    242   if (program) {
    243     program->SetTileCounts(x_count, y_count);
    244     return JNI_TRUE;
    245   }
    246   return JNI_FALSE;
    247 }
    248 
    249 jboolean Java_android_filterfw_core_ShaderProgram_setShaderVertexCount(JNIEnv* env,
    250                                                                        jobject thiz,
    251                                                                        jint vertex_count) {
    252   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    253   if (program) {
    254     program->SetVertexCount(vertex_count);
    255     return JNI_TRUE;
    256   }
    257   return JNI_FALSE;
    258 }
    259 
    260 jboolean Java_android_filterfw_core_ShaderProgram_beginShaderDrawing(JNIEnv* env, jobject thiz) {
    261     ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    262     return ToJBool(program && program->BeginDraw());
    263 }
    264 
    265 jboolean Java_android_filterfw_core_ShaderProgram_setShaderAttributeValues(
    266     JNIEnv* env,
    267     jobject thiz,
    268     jstring attr_name,
    269     jfloatArray values,
    270     jint component_count) {
    271   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    272   if (program) {
    273     // Get the floats to set
    274     jfloat* float_ptr = env->GetFloatArrayElements(values, NULL);
    275     const int length = env->GetArrayLength(values);
    276 
    277     // Get the program variable to set
    278     const std::string attr_string = ToCppString(env, attr_name);
    279     ProgramVar program_var = program->GetAttribute(attr_string);
    280 
    281     // Set the variable
    282     if (float_ptr && ShaderProgram::IsVarValid(program_var)) {
    283       const bool success = program->SetAttributeValues(program_var,
    284                                                        reinterpret_cast<float*>(float_ptr),
    285                                                        length,
    286                                                        component_count);
    287       env->ReleaseFloatArrayElements(values, float_ptr, JNI_ABORT);
    288       return ToJBool(success);
    289     }
    290   }
    291   return JNI_FALSE;
    292 }
    293 
    294 jboolean Java_android_filterfw_core_ShaderProgram_setShaderAttributeVertexFrame(
    295     JNIEnv* env,
    296     jobject thiz,
    297     jstring attr_name,
    298     jobject vertex_frame,
    299     jint type,
    300     jint component_count,
    301     jint stride,
    302     jint offset,
    303     jboolean normalize) {
    304   ShaderProgram* program = ConvertFromJava<ShaderProgram>(env, thiz);
    305   if (program) {
    306     // Get the vertex frame
    307     VertexFrame* v_frame = ConvertFromJava<VertexFrame>(env, vertex_frame);
    308 
    309     // Get the program variable to set
    310     const std::string attr_string = ToCppString(env, attr_name);
    311     ProgramVar program_var = program->GetAttribute(attr_string);
    312 
    313     // Set the variable
    314     if (v_frame && ShaderProgram::IsVarValid(program_var)) {
    315       const bool success = program->SetAttributeValues(program_var,
    316                                                        v_frame,
    317                                                        type,
    318                                                        component_count,
    319                                                        stride,
    320                                                        offset,
    321                                                        ToCppBool(normalize));
    322       return ToJBool(success);
    323     }
    324   }
    325   return JNI_FALSE;
    326 }
    327