Home | History | Annotate | Download | only in ndk_helper
      1 /*
      2  * Copyright 2013 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 <EGL/egl.h>
     18 #include <GLES2/gl2.h>
     19 
     20 #include "shader.h"
     21 #include "JNIHelper.h"
     22 
     23 namespace ndk_helper
     24 {
     25 
     26 #define DEBUG (1)
     27 
     28 bool shader::CompileShader( GLuint *shader,
     29         const GLenum type,
     30         const char *str_file_name,
     31         const std::map<std::string, std::string>& map_parameters )
     32 {
     33     std::vector<uint8_t> data;
     34     if( !JNIHelper::GetInstance()->ReadFile( str_file_name, &data ) )
     35     {
     36         LOGI( "Can not open a file:%s", str_file_name );
     37         return false;
     38     }
     39 
     40     const char REPLACEMENT_TAG = '*';
     41     //Fill-in parameters
     42     std::string str( data.begin(), data.end() );
     43     std::string str_replacement_map( data.size(), ' ' );
     44 
     45     std::map<std::string, std::string>::const_iterator it = map_parameters.begin();
     46     std::map<std::string, std::string>::const_iterator itEnd = map_parameters.end();
     47     while( it != itEnd )
     48     {
     49         size_t pos = 0;
     50         while( (pos = str.find( it->first, pos )) != std::string::npos )
     51         {
     52             //Check if the sub string is already touched
     53 
     54             size_t replaced_pos = str_replacement_map.find( REPLACEMENT_TAG, pos );
     55             if( replaced_pos == std::string::npos || replaced_pos > pos )
     56             {
     57 
     58                 str.replace( pos, it->first.length(), it->second );
     59                 str_replacement_map.replace( pos, it->first.length(), it->first.length(),
     60                         REPLACEMENT_TAG );
     61                 pos += it->second.length();
     62             }
     63             else
     64             {
     65                 //The replacement target has been touched by other tag, skipping them
     66                 pos += it->second.length();
     67             }
     68         }
     69         it++;
     70     }
     71 
     72     LOGI( "Patched Shdader:\n%s", str.c_str() );
     73 
     74     std::vector<uint8_t> v( str.begin(), str.end() );
     75     str.clear();
     76     return shader::CompileShader( shader, type, v );
     77 }
     78 
     79 bool shader::CompileShader( GLuint *shader,
     80         const GLenum type,
     81         const GLchar *source,
     82         const int32_t iSize )
     83 {
     84     if( source == NULL || iSize <= 0 )
     85         return false;
     86 
     87     *shader = glCreateShader( type );
     88     glShaderSource( *shader, 1, &source, &iSize ); //Not specifying 3rd parameter (size) could be troublesome..
     89 
     90     glCompileShader( *shader );
     91 
     92 #if defined(DEBUG)
     93     GLint logLength;
     94     glGetShaderiv( *shader, GL_INFO_LOG_LENGTH, &logLength );
     95     if( logLength > 0 )
     96     {
     97         GLchar *log = (GLchar *) malloc( logLength );
     98         glGetShaderInfoLog( *shader, logLength, &logLength, log );
     99         LOGI( "Shader compile log:\n%s", log );
    100         free( log );
    101     }
    102 #endif
    103 
    104     GLint status;
    105     glGetShaderiv( *shader, GL_COMPILE_STATUS, &status );
    106     if( status == 0 )
    107     {
    108         glDeleteShader( *shader );
    109         return false;
    110     }
    111 
    112     return true;
    113 }
    114 
    115 bool shader::CompileShader( GLuint *shader,
    116         const GLenum type,
    117         std::vector<uint8_t>& data )
    118 {
    119     if( !data.size() )
    120         return false;
    121 
    122     const GLchar *source = (GLchar *) &data[0];
    123     int32_t iSize = data.size();
    124     return shader::CompileShader( shader, type, source, iSize );
    125 }
    126 
    127 bool shader::CompileShader( GLuint *shader,
    128         const GLenum type,
    129         const char *strFileName )
    130 {
    131     std::vector<uint8_t> data;
    132     bool b = JNIHelper::GetInstance()->ReadFile( strFileName, &data );
    133     if( !b )
    134     {
    135         LOGI( "Can not open a file:%s", strFileName );
    136         return false;
    137     }
    138 
    139     return shader::CompileShader( shader, type, data );
    140 }
    141 
    142 bool shader::LinkProgram( const GLuint prog )
    143 {
    144     GLint status;
    145 
    146     glLinkProgram( prog );
    147 
    148 #if defined(DEBUG)
    149     GLint logLength;
    150     glGetProgramiv( prog, GL_INFO_LOG_LENGTH, &logLength );
    151     if( logLength > 0 )
    152     {
    153         GLchar *log = (GLchar *) malloc( logLength );
    154         glGetProgramInfoLog( prog, logLength, &logLength, log );
    155         LOGI( "Program link log:\n%s", log );
    156         free( log );
    157     }
    158 #endif
    159 
    160     glGetProgramiv( prog, GL_LINK_STATUS, &status );
    161     if( status == 0 )
    162     {
    163         LOGI( "Program link failed\n" );
    164         return false;
    165     }
    166 
    167     return true;
    168 }
    169 
    170 bool shader::ValidateProgram( const GLuint prog )
    171 {
    172     GLint logLength, status;
    173 
    174     glValidateProgram( prog );
    175     glGetProgramiv( prog, GL_INFO_LOG_LENGTH, &logLength );
    176     if( logLength > 0 )
    177     {
    178         GLchar *log = (GLchar *) malloc( logLength );
    179         glGetProgramInfoLog( prog, logLength, &logLength, log );
    180         LOGI( "Program validate log:\n%s", log );
    181         free( log );
    182     }
    183 
    184     glGetProgramiv( prog, GL_VALIDATE_STATUS, &status );
    185     if( status == 0 )
    186         return false;
    187 
    188     return true;
    189 }
    190 
    191 } //namespace ndkHelper
    192 
    193