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