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
CompileShader(GLuint * shader,const GLenum type,const char * str_file_name,const std::map<std::string,std::string> & map_parameters)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
CompileShader(GLuint * shader,const GLenum type,const GLchar * source,const int32_t iSize)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
CompileShader(GLuint * shader,const GLenum type,std::vector<uint8_t> & data)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
CompileShader(GLuint * shader,const GLenum type,const char * strFileName)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
LinkProgram(const GLuint prog)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
ValidateProgram(const GLuint prog)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