OpenGL ES SDK for Android ARM Developer Center
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
common.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2015-2017, ARM Limited and Contributors
2  *
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge,
6  * to any person obtaining a copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
14  * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19  */
20 
21 #include "common.hpp"
22 #include <stdlib.h>
23 #include <string>
24 #include <vector>
25 
26 using namespace std;
27 
28 static GLuint common_compile(GLenum type, const char *source)
29 {
30  GL_CHECK(GLuint shader = glCreateShader(type));
31  GL_CHECK(glShaderSource(shader, 1, &source, NULL));
32  GL_CHECK(glCompileShader(shader));
33 
34  GLint status;
35  GL_CHECK(glGetShaderiv(shader, GL_COMPILE_STATUS, &status));
36  if (status == GL_FALSE)
37  {
38  GLint len;
39  GLsizei out_len;
40 
41  GL_CHECK(glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len));
42  vector<char> buf(len);
43  GL_CHECK(glGetShaderInfoLog(shader, len, &out_len, &buf[0]));
44  LOGI("Shader log:\n%s", &buf[0]);
45 
46  GL_CHECK(glDeleteShader(shader));
47  return 0;
48  }
49 
50  return shader;
51 }
52 
53 static bool check_program(GLuint prog)
54 {
55  GLint status;
56  GL_CHECK(glGetProgramiv(prog, GL_LINK_STATUS, &status));
57  if (status == GL_FALSE)
58  {
59  GLint len;
60  GLsizei out_len;
61 
62  GL_CHECK(glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len));
63  vector<char> buf(len);
64  GL_CHECK(glGetProgramInfoLog(prog, len, &out_len, &buf[0]));
65  LOGI("Program log:\n%s", &buf[0]);
66 
67  GL_CHECK(glDeleteProgram(prog));
68  return false;
69  }
70 
71  return true;
72 }
73 
74 GLuint common_compile_shader(const char *vs_source, const char *fs_source)
75 {
76  GL_CHECK(GLuint prog = glCreateProgram());
77  GLuint vs = common_compile(GL_VERTEX_SHADER, vs_source);
78  if (!vs)
79  {
80  glDeleteProgram(prog);
81  return 0;
82  }
83 
84  GLuint fs = common_compile(GL_FRAGMENT_SHADER, fs_source);
85  if (!fs)
86  {
87  GL_CHECK(glDeleteShader(vs));
88  GL_CHECK(glDeleteProgram(prog));
89  return 0;
90  }
91 
92  GL_CHECK(glAttachShader(prog, vs));
93  GL_CHECK(glAttachShader(prog, fs));
94  GL_CHECK(glLinkProgram(prog));
95 
96  GL_CHECK(glDeleteShader(vs));
97  GL_CHECK(glDeleteShader(fs));
98 
99  if (!check_program(prog))
100  {
101  LOGE("Failed to link program.");
102  return 0;
103  }
104 
105  return prog;
106 }
107 
108 GLuint common_compile_shader(const char *vs_source,
109  const char *tc_source, const char *te_source, const char *geom_source,
110  const char *fs_source)
111 {
112  GLuint prog = glCreateProgram();
113  GLuint shaders[5] = {0};
114 
115  const char *sources[] = {
116  vs_source,
117  tc_source,
118  te_source,
119  geom_source,
120  fs_source,
121  };
122 
123  const GLenum stages[] = {
124  GL_VERTEX_SHADER,
128  GL_FRAGMENT_SHADER,
129  };
130 
131  for (unsigned i = 0; i < 5; i++)
132  {
133  if (sources[i])
134  {
135  shaders[i] = common_compile(stages[i], sources[i]);
136  if (shaders[i] == 0)
137  {
138  goto error;
139  }
140  }
141  }
142 
143  for (auto shader : shaders)
144  {
145  if (shader != 0)
146  {
147  GL_CHECK(glAttachShader(prog, shader));
148  }
149  }
150  GL_CHECK(glLinkProgram(prog));
151 
152  for (auto shader : shaders)
153  {
154  if (shader != 0)
155  {
156  GL_CHECK(glDeleteShader(shader));
157  }
158  }
159 
160  if (!check_program(prog))
161  {
162  LOGE("Failed to link program.");
163  return 0;
164  }
165 
166  return prog;
167 
168 error:
169  for (auto shader : shaders)
170  {
171  if (shader != 0)
172  {
173  GL_CHECK(glDeleteShader(shader));
174  }
175  }
176  GL_CHECK(glDeleteProgram(prog));
177  return 0;
178 }
179 
180 GLuint common_compile_compute_shader(const char *cs_source)
181 {
182  GL_CHECK(GLuint prog = glCreateProgram());
183  GLuint cs = common_compile(GL_COMPUTE_SHADER, cs_source);
184  if (!cs)
185  {
186  GL_CHECK(glDeleteProgram(prog));
187  return 0;
188  }
189 
190  GL_CHECK(glAttachShader(prog, cs));
191  GL_CHECK(glLinkProgram(prog));
192 
193  GL_CHECK(glDeleteShader(cs));
194 
195  if (!check_program(prog))
196  {
197  LOGE("Failed to link program.");
198  return 0;
199  }
200 
201  return prog;
202 }
203 
204 bool common_read_file_string(const char *path, char **out_buf)
205 {
206  FILE *file = common_fopen(path, "rb");
207  if (!file)
208  {
209  LOGE("Failed to open file: %s.", path);
210  return false;
211  }
212 
213  fseek(file, 0, SEEK_END);
214  long len = ftell(file);
215  rewind(file);
216 
217  char *buf = (char*)malloc(len + 1);
218  if (!buf)
219  {
220  fclose(file);
221  return false;
222  }
223 
224  long ret = fread(buf, 1, len, file);
225  fclose(file);
226 
227  if (ret == len)
228  {
229  buf[len] = '\0';
230  *out_buf = buf;
231  return true;
232  }
233  else
234  {
235  free(buf);
236  *out_buf = NULL;
237  return false;
238  }
239 }
240 
241 GLuint common_compile_shader_from_file(const char *vs_source, const char *fs_source)
242 {
243  LOGI("Compiling vertex/fragment shader: %s, %s.", vs_source, fs_source);
244  char *vs_buf = NULL;
245  char *fs_buf = NULL;
246  if (!common_read_file_string(vs_source, &vs_buf))
247  {
248  return 0;
249  }
250 
251  if (!common_read_file_string(fs_source, &fs_buf))
252  {
253  free(vs_buf);
254  return 0;
255  }
256 
257  GLuint prog = common_compile_shader(vs_buf, fs_buf);
258  free(vs_buf);
259  free(fs_buf);
260  return prog;
261 }
262 
264  const char *tc_source, const char *te_source, const char *geom_source,
265  const char *fs_source)
266 {
267  LOGI("Compiling shader: %s, %s, %s, %s, %s.",
268  vs_source,
269  tc_source ? tc_source : "none",
270  te_source ? te_source : "none",
271  geom_source ? geom_source : "none",
272  fs_source);
273 
274  GLuint prog = 0;
275  char *vs_buf = NULL;
276  char *tc_buf = NULL;
277  char *te_buf = NULL;
278  char *geom_buf = NULL;
279  char *fs_buf = NULL;
280 
281  if (vs_source && !common_read_file_string(vs_source, &vs_buf))
282  {
283  goto end;
284  }
285 
286  if (tc_source && !common_read_file_string(tc_source, &tc_buf))
287  {
288  goto end;
289  }
290 
291  if (te_source && !common_read_file_string(te_source, &te_buf))
292  {
293  goto end;
294  }
295 
296  if (geom_source && !common_read_file_string(geom_source, &geom_buf))
297  {
298  goto end;
299  }
300 
301  if (fs_source && !common_read_file_string(fs_source, &fs_buf))
302  {
303  goto end;
304  }
305 
306  prog = common_compile_shader(vs_buf, tc_buf, te_buf, geom_buf, fs_buf);
307 
308 end:
309  free(vs_buf);
310  free(tc_buf);
311  free(te_buf);
312  free(geom_buf);
313  free(fs_buf);
314  return prog;
315 }
316 
318 {
319  LOGI("Compiling compute shader from %s.", cs_source);
320  char *cs_buf = NULL;
321  if (!common_read_file_string(cs_source, &cs_buf))
322  {
323  return 0;
324  }
325 
326  GLuint prog = common_compile_compute_shader(cs_buf);
327  free(cs_buf);
328  return prog;
329 }
330 
331 static string common_basedir;
332 void common_set_basedir(const char *basedir)
333 {
334  common_basedir = basedir;
335 }
336 
337 string common_get_path(const char *basepath)
338 {
339  if (!common_basedir.empty())
340  {
341  return common_basedir + "/" + basepath;
342  }
343  else
344  {
345  return basepath;
346  }
347 }
348 
349 FILE *common_fopen(const char *path, const char *mode)
350 {
351  string join_path = common_get_path(path);
352  FILE *ret = fopen(join_path.c_str(), mode);
353  LOGI("Opening: %s (%s).", join_path.c_str(), ret ? "success" : "failure");
354  return ret;
355 }
356 
GLuint GLuint end
Definition: gl2ext.h:323
static GLuint common_compile(GLenum type, const char *source)
Definition: common.cpp:28
#define LOGI(...)
Definition: AstcTextures.h:29
#define GL_TESS_CONTROL_SHADER_EXT
Definition: gl2ext.h:1669
GLbitfield stages
Definition: gl2ext.h:1503
static bool check_program(GLuint prog)
Definition: common.cpp:53
GLuint common_compile_compute_shader_from_file(const char *cs_source)
Definition: common.cpp:317
GLsizei GLenum * sources
Definition: gl2ext.h:136
GLuint common_compile_shader_from_file(const char *vs_source, const char *fs_source)
Definition: common.cpp:241
bool common_read_file_string(const char *path, char **out_buf)
Definition: common.cpp:204
static string common_basedir
Definition: common.cpp:331
GLuint common_compile_shader(const char *vs_source, const char *fs_source)
Definition: common.cpp:74
GLenum mode
Definition: gl2ext.h:302
void common_set_basedir(const char *basedir)
Definition: common.cpp:332
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:877
#define GL_TESS_EVALUATION_SHADER_EXT
Definition: gl2ext.h:1670
#define GL_CHECK(x)
Definition: AstcTextures.h:59
GLenum type
Definition: gl2ext.h:133
string common_get_path(const char *basepath)
Definition: common.cpp:337
FILE * common_fopen(const char *path, const char *mode)
Definition: common.cpp:349
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: gl2ext.h:134
#define LOGE(...)
Definition: AstcTextures.h:30
GLuint common_compile_compute_shader(const char *cs_source)
Definition: common.cpp:180
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count
#define GL_GEOMETRY_SHADER_EXT
Definition: gl2ext.h:1255