Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
getglprocaddress.cc
Go to the documentation of this file.
1 
18 #if defined(ION_PLATFORM_ANDROID) || defined(ION_PLATFORM_IOS) || \
19  defined(ION_PLATFORM_MAC) || defined(ION_PLATFORM_QNX) || \
20  defined(ION_PLATFORM_GENERIC_ARM) || \
21  (defined(ION_PLATFORM_LINUX) && defined(ION_GFX_OGLES20))
22 # include <dlfcn.h> // For dlsym().
23 #elif defined(ION_PLATFORM_LINUX) && !defined(ION_GFX_OGLES20)
24 # define GLCOREARB_PROTOTYPES
25 #elif defined(ION_PLATFORM_WINDOWS)
26 # undef NOGDI // Need to get wglGetProcAddress() from windows.h.
27 # include <windows.h>
28 # define GLCOREARB_PROTOTYPES
29 #endif
30 
31 #include <cstring>
32 #include <sstream>
33 #include <string>
34 
35 #include "base/macros.h"
36 #include "ion/base/logging.h"
38 #include "ion/portgfx/glheaders.h"
39 
40 #if defined(ION_PLATFORM_LINUX) && !defined(ION_GFX_OGLES20)
41 # include <GL/glx.h> // NOLINT
42 #endif
43 
44 namespace ion {
45 namespace portgfx {
46 
47 #if ((defined(ION_PLATFORM_LINUX) || defined(ION_PLATFORM_MAC) || \
48  defined(ION_PLATFORM_WINDOWS)) && \
49  !(defined(ION_ANGLE) || defined(ION_GOOGLE_INTERNAL)))
50 # define ION_USES_DOUBLE_DEPTH 1
51 #else
52 # define ION_USES_DOUBLE_DEPTH 0
53 #endif
54 
55 #if ION_USES_DOUBLE_DEPTH
56 namespace {
57 struct GlToEsFunctionMapping {
58  const char* name;
59  void* func;
60 };
61 
63 static GLvoid ION_APIENTRY ClearDepthf(GLfloat f) {
64  ::glClearDepth(static_cast<double>(f));
65 }
66 
67 static GLvoid ION_APIENTRY DepthRangef(GLfloat nearVal, GLfloat farVal) {
68  ::glDepthRange(static_cast<double>(nearVal), static_cast<double>(farVal));
69 }
70 
71 #define MAP_GL_TO_ES_FUNCTION(name, func) { #name, func }
72 
74 static const GlToEsFunctionMapping kGlToEsFunctionMap[] = {
75  MAP_GL_TO_ES_FUNCTION(glClearDepthf, reinterpret_cast<void*>(ClearDepthf)),
76  MAP_GL_TO_ES_FUNCTION(glDepthRangef, reinterpret_cast<void*>(DepthRangef))
77 };
78 
79 #undef MAP_GL_TO_ES_FUNCTION
80 
81 const int kNumGlToEsMappings = arraysize(kGlToEsFunctionMap);
82 
83 static void* MappedFunction(const char* name) {
84  void* func = NULL;
85  for (int i = 0; i < kNumGlToEsMappings; ++i) {
86  if (strcmp(kGlToEsFunctionMap[i].name, name) == 0)
87  func = kGlToEsFunctionMap[i].func;
88  }
89  return func;
90 }
91 
92 }; // namespace
93 #endif
94 
95 #if defined(ION_PLATFORM_ASMJS) || defined(ION_PLATFORM_NACL)
96 namespace {
97 struct GlFunctionInfo {
98  const char* name;
99  void* function;
100 };
101 
102 #define BIND_GLES_FUNCTION(name) { #name, reinterpret_cast<void*>(&name) }
103 static const GlFunctionInfo kEs2FunctionMap[] = {
106  BIND_GLES_FUNCTION(glActiveTexture),
107  BIND_GLES_FUNCTION(glAttachShader),
108  BIND_GLES_FUNCTION(glBindAttribLocation),
109  BIND_GLES_FUNCTION(glBindBuffer),
110  BIND_GLES_FUNCTION(glBindFramebuffer),
111  BIND_GLES_FUNCTION(glBindRenderbuffer),
112  BIND_GLES_FUNCTION(glBindTexture),
113  BIND_GLES_FUNCTION(glBlendColor),
114  BIND_GLES_FUNCTION(glBlendEquation),
115  BIND_GLES_FUNCTION(glBlendEquationSeparate),
116  BIND_GLES_FUNCTION(glBlendFunc),
117  BIND_GLES_FUNCTION(glBlendFuncSeparate),
118  BIND_GLES_FUNCTION(glBufferData),
119  BIND_GLES_FUNCTION(glBufferSubData),
120  BIND_GLES_FUNCTION(glCheckFramebufferStatus),
121  BIND_GLES_FUNCTION(glClear),
122  BIND_GLES_FUNCTION(glClearColor),
123  BIND_GLES_FUNCTION(glClearDepthf),
124  BIND_GLES_FUNCTION(glClearStencil),
125  BIND_GLES_FUNCTION(glColorMask),
126  BIND_GLES_FUNCTION(glCompileShader),
127  BIND_GLES_FUNCTION(glCompressedTexImage2D),
128  BIND_GLES_FUNCTION(glCompressedTexSubImage2D),
129  BIND_GLES_FUNCTION(glCopyTexImage2D),
130  BIND_GLES_FUNCTION(glCopyTexSubImage2D),
131  BIND_GLES_FUNCTION(glCreateProgram),
132  BIND_GLES_FUNCTION(glCreateShader),
133  BIND_GLES_FUNCTION(glCullFace),
134  BIND_GLES_FUNCTION(glDeleteBuffers),
135  BIND_GLES_FUNCTION(glDeleteFramebuffers),
136  BIND_GLES_FUNCTION(glDeleteProgram),
137  BIND_GLES_FUNCTION(glDeleteRenderbuffers),
138  BIND_GLES_FUNCTION(glDeleteShader),
139  BIND_GLES_FUNCTION(glDeleteTextures),
140  BIND_GLES_FUNCTION(glDepthFunc),
141  BIND_GLES_FUNCTION(glDepthMask),
142  BIND_GLES_FUNCTION(glDepthRangef),
143  BIND_GLES_FUNCTION(glDetachShader),
144  BIND_GLES_FUNCTION(glDisable),
145  BIND_GLES_FUNCTION(glDisableVertexAttribArray),
146  BIND_GLES_FUNCTION(glDrawArrays),
147  BIND_GLES_FUNCTION(glDrawElements),
148  BIND_GLES_FUNCTION(glEnable),
149  BIND_GLES_FUNCTION(glEnableVertexAttribArray),
150  BIND_GLES_FUNCTION(glFinish),
151  BIND_GLES_FUNCTION(glFlush),
152  BIND_GLES_FUNCTION(glFramebufferRenderbuffer),
153  BIND_GLES_FUNCTION(glFramebufferTexture2D),
154  BIND_GLES_FUNCTION(glFrontFace),
155  BIND_GLES_FUNCTION(glGenBuffers),
156  BIND_GLES_FUNCTION(glGenerateMipmap),
157  BIND_GLES_FUNCTION(glGenFramebuffers),
158  BIND_GLES_FUNCTION(glGenRenderbuffers),
159  BIND_GLES_FUNCTION(glGenTextures),
160  BIND_GLES_FUNCTION(glGetActiveAttrib),
161  BIND_GLES_FUNCTION(glGetActiveUniform),
162  BIND_GLES_FUNCTION(glGetAttachedShaders),
163  BIND_GLES_FUNCTION(glGetAttribLocation),
164  BIND_GLES_FUNCTION(glGetBooleanv),
165  BIND_GLES_FUNCTION(glGetBufferParameteriv),
166  BIND_GLES_FUNCTION(glGetError),
167  BIND_GLES_FUNCTION(glGetFloatv),
168  BIND_GLES_FUNCTION(glGetFramebufferAttachmentParameteriv),
169  BIND_GLES_FUNCTION(glGetIntegerv),
170  BIND_GLES_FUNCTION(glGetProgramInfoLog),
171  BIND_GLES_FUNCTION(glGetProgramiv),
172  BIND_GLES_FUNCTION(glGetRenderbufferParameteriv),
173  BIND_GLES_FUNCTION(glGetShaderInfoLog),
174  BIND_GLES_FUNCTION(glGetShaderiv),
175  BIND_GLES_FUNCTION(glGetShaderPrecisionFormat),
176  BIND_GLES_FUNCTION(glGetShaderSource),
177  BIND_GLES_FUNCTION(glGetString),
178  BIND_GLES_FUNCTION(glGetTexParameterfv),
179  BIND_GLES_FUNCTION(glGetTexParameteriv),
180  BIND_GLES_FUNCTION(glGetUniformfv),
181  BIND_GLES_FUNCTION(glGetUniformiv),
182  BIND_GLES_FUNCTION(glGetVertexAttribfv),
183  BIND_GLES_FUNCTION(glGetVertexAttribiv),
184  BIND_GLES_FUNCTION(glGetVertexAttribPointerv),
185  BIND_GLES_FUNCTION(glGetUniformLocation),
186  BIND_GLES_FUNCTION(glHint),
187  BIND_GLES_FUNCTION(glIsBuffer),
188  BIND_GLES_FUNCTION(glIsEnabled),
189  BIND_GLES_FUNCTION(glIsFramebuffer),
190  BIND_GLES_FUNCTION(glIsProgram),
191  BIND_GLES_FUNCTION(glIsRenderbuffer),
192  BIND_GLES_FUNCTION(glIsShader),
193  BIND_GLES_FUNCTION(glIsTexture),
194  BIND_GLES_FUNCTION(glLineWidth),
195  BIND_GLES_FUNCTION(glLinkProgram),
196  BIND_GLES_FUNCTION(glPixelStorei),
197  BIND_GLES_FUNCTION(glPolygonOffset),
198  BIND_GLES_FUNCTION(glReadPixels),
199  BIND_GLES_FUNCTION(glReleaseShaderCompiler),
200  BIND_GLES_FUNCTION(glRenderbufferStorage),
201  BIND_GLES_FUNCTION(glSampleCoverage),
202  BIND_GLES_FUNCTION(glScissor),
203  BIND_GLES_FUNCTION(glShaderBinary),
204  BIND_GLES_FUNCTION(glShaderSource),
205  BIND_GLES_FUNCTION(glStencilFunc),
206  BIND_GLES_FUNCTION(glStencilFuncSeparate),
207  BIND_GLES_FUNCTION(glStencilMask),
208  BIND_GLES_FUNCTION(glStencilMaskSeparate),
209  BIND_GLES_FUNCTION(glStencilOp),
210  BIND_GLES_FUNCTION(glStencilOpSeparate),
211  BIND_GLES_FUNCTION(glTexImage2D),
212  BIND_GLES_FUNCTION(glTexParameterf),
213  BIND_GLES_FUNCTION(glTexParameterfv),
214  BIND_GLES_FUNCTION(glTexParameteri),
215  BIND_GLES_FUNCTION(glTexParameteriv),
216  BIND_GLES_FUNCTION(glTexSubImage2D),
217  BIND_GLES_FUNCTION(glUniform1f),
218  BIND_GLES_FUNCTION(glUniform1fv),
219  BIND_GLES_FUNCTION(glUniform1i),
220  BIND_GLES_FUNCTION(glUniform1iv),
221  BIND_GLES_FUNCTION(glUniform2f),
222  BIND_GLES_FUNCTION(glUniform2fv),
223  BIND_GLES_FUNCTION(glUniform2i),
224  BIND_GLES_FUNCTION(glUniform2iv),
225  BIND_GLES_FUNCTION(glUniform3f),
226  BIND_GLES_FUNCTION(glUniform3fv),
227  BIND_GLES_FUNCTION(glUniform3i),
228  BIND_GLES_FUNCTION(glUniform3iv),
229  BIND_GLES_FUNCTION(glUniform4f),
230  BIND_GLES_FUNCTION(glUniform4fv),
231  BIND_GLES_FUNCTION(glUniform4i),
232  BIND_GLES_FUNCTION(glUniform4iv),
233  BIND_GLES_FUNCTION(glUniformMatrix2fv),
234  BIND_GLES_FUNCTION(glUniformMatrix3fv),
235  BIND_GLES_FUNCTION(glUniformMatrix4fv),
236  BIND_GLES_FUNCTION(glUseProgram),
237  BIND_GLES_FUNCTION(glValidateProgram),
238  BIND_GLES_FUNCTION(glVertexAttrib1f),
239  BIND_GLES_FUNCTION(glVertexAttrib1fv),
240  BIND_GLES_FUNCTION(glVertexAttrib2f),
241  BIND_GLES_FUNCTION(glVertexAttrib2fv),
242  BIND_GLES_FUNCTION(glVertexAttrib3f),
243  BIND_GLES_FUNCTION(glVertexAttrib3fv),
244  BIND_GLES_FUNCTION(glVertexAttrib4f),
245  BIND_GLES_FUNCTION(glVertexAttrib4fv),
246  BIND_GLES_FUNCTION(glVertexAttribPointer),
247  BIND_GLES_FUNCTION(glViewport),
248 };
249 
250 #undef BIND_GLES_FUNCTION
251 
252 const int kNumGlFunctions = arraysize(kEs2FunctionMap);
253 
254 } // namespace
255 #endif
256 
257 namespace {
258 
259 #if defined(ION_PLATFORM_ANDROID) || defined(ION_PLATFORM_GENERIC_ARM)
260 static void* GetAndroidGlLibrary() {
265  void* libGLESv2 = NULL;
266  if (!libGLESv2) {
267  if (FILE* egl_config = fopen("/system/lib/egl/egl.cfg", "r")) {
268  char line[256];
269  while (fgets(line, 256, egl_config)) {
270  int display;
271  int implementation;
272  char tag[256];
273  std::istringstream s(line);
274  s >> display >> implementation >> tag;
275  if (!s.fail() && tag[0] != '\0') {
278  if (strcmp(tag, "android")) {
279  std::string library("libGLESv2_");
280  library += tag;
281  library += ".so";
282  libGLESv2 = dlopen(library.c_str(), RTLD_NOW);
283  break;
284  }
285  }
286  }
287  fclose(egl_config);
288  }
290  if (!libGLESv2)
291  libGLESv2 = dlopen("libGLESv2_android.so", RTLD_NOW);
293  if (!libGLESv2)
294  libGLESv2 = dlopen("libGLESv2.so", RTLD_NOW);
295  }
296  return libGLESv2;
297 }
298 #endif
299 
300 static void* LookupSymbol(const char* name, bool is_core) {
301  void* func = NULL;
302 #if defined(ION_PLATFORM_ASMJS)
303  func = reinterpret_cast<void*>(eglGetProcAddress(name));
304 
305 #elif defined(ION_PLATFORM_NACL)
306  for (int i = 0; i < kNumGlFunctions; ++i)
307  if (strcmp(kEs2FunctionMap[i].name, name) == 0)
308  return kEs2FunctionMap[i].function;
309 
310 #elif defined(ION_PLATFORM_ANDROID) || defined(ION_PLATFORM_GENERIC_ARM) || \
311  (defined(ION_PLATFORM_LINUX) && defined(ION_GFX_OGLES20))
312  static void* libGLESv2 = NULL;
313  if (!libGLESv2) {
314 # if defined(ION_PLATFORM_ANDROID) || defined(ION_PLATFORM_GENERIC_ARM)
315  libGLESv2 = GetAndroidGlLibrary();
316 # else
317  libGLESv2 = dlopen("libGLESv2.so.2", RTLD_NOW);
320  if (!libGLESv2)
321  libGLESv2 = dlopen("libGLESv2.so", RTLD_NOW);
322 # endif
323  DCHECK(libGLESv2);
324  }
331  func = reinterpret_cast<void*>(dlsym(libGLESv2, name));
332  if (func || strstr(name, "EGL")) {
335  if (!is_core)
336  func = reinterpret_cast<void*>(eglGetProcAddress(name));
337  }
338 
339 #elif defined(ION_PLATFORM_IOS) || defined(ION_PLATFORM_MAC) || \
340  defined(ION_PLATFORM_QNX)
341  func = reinterpret_cast<void*>(dlsym(RTLD_DEFAULT, name));
342 
343 #elif defined(ION_PLATFORM_LINUX) && !defined(ION_GFX_OGLES20)
344  func = reinterpret_cast<void*>(glXGetProcAddressARB(
345  reinterpret_cast<const GLubyte*>(name)));
346 
347 #elif defined(ION_PLATFORM_WINDOWS)
348 # if defined(ION_ANGLE)
349 # define winGlGetProcAddress eglGetProcAddress
350 # define winGlDll "libGLESv2.dll"
351 # else
352 # define winGlGetProcAddress wglGetProcAddress
353 # define winGlDll "opengl32.dll"
354 # endif
355  func = reinterpret_cast<void*>(winGlGetProcAddress(name));
356  if (!func) {
358  static HMODULE opengl_module = LoadLibrary(winGlDll);
359  func = opengl_module ? GetProcAddress(opengl_module, name) : NULL;
360  }
361 # undef winGlGetProcAddress
362 # undef winGlDll
363 
364 #else
365 # error No valid platform defined
366 #endif
367  return func;
368 }
369 
372 static void* LookupSymbolWithSuffix(const std::string& name,
373  const char** suffixes, bool is_core) {
374  for (const char** suffix = suffixes; *suffix; ++suffix) {
375  const std::string function_name = name + *suffix;
376  if (void* func = LookupSymbol(function_name.c_str(), is_core))
377  return func;
378  }
379  return NULL;
380 }
381 
382 } // namespace
383 
384 void* GetGlProcAddress(const char* name, bool is_core) {
386 #if defined(ION_PLATFORM_ASMJS) || defined(ION_PLATFORM_NACL)
387  const char* suffixes[] = { "", NULL };
388 #elif defined(ION_PLATFORM_ANDROID) || defined(ION_PLATFORM_IOS) || \
389  defined(ION_PLATFORM_QNX) || defined(ION_PLATFORM_GENERIC_ARM) || \
390  (defined(ION_PLATFORM_LINUX) && defined(ION_GFX_OGLES20)) || \
391  (defined(ION_PLATFORM_WINDOWS) && defined(ION_ANGLE))
392  const char* suffixes[] =
393  { "", "OES", "APPLE", "ARB", "EXT", "KHR", "NV", NULL };
394 #elif defined(ION_PLATFORM_LINUX) || defined(ION_PLATFORM_WINDOWS)
395  const char* suffixes[] = { "", "ARB", "EXT", "KHR", "NV", NULL };
396 #elif defined(ION_PLATFORM_MAC)
397  const char* compat_suffixes[] = {"APPLE", "", "ARB", "EXT", "KHR", "NV",
400  NULL};
401  const char* core_suffixes[] = {"", "APPLE", "ARB", "EXT", "KHR", "NV", NULL};
402 
403  GLint mask = 0;
404  glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
407  glGetError();
408 
409  const bool is_core_profile = mask & GL_CONTEXT_CORE_PROFILE_BIT;
410  const char** suffixes = is_core_profile ? core_suffixes : compat_suffixes;
411 #endif
412  if (void* func = LookupSymbolWithSuffix(name, suffixes, is_core))
413  return func;
414 
415 #if ION_USES_DOUBLE_DEPTH
416  return MappedFunction(name);
418 #else
419  return NULL;
420 #endif
421 }
422 
423 #undef ION_USES_DOUBLE_DEPTH
424 
425 } // namespace portgfx
426 } // namespace ion
#define DCHECK(expr)
Definition: logging.h:331
void * GetGlProcAddress(const char *name, bool is_core)
Returns a generic pointer to an OpenGL function or OpenGL extension function with the given name...
std::string name
Definition: printer.cc:324
Copyright 2016 Google Inc.