|
1 |
|
2 /* |
|
3 * Copyright 2011 Google Inc. |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 |
|
9 |
|
10 #include "gl/GrGLInterface.h" |
|
11 #include "../GrGLUtil.h" |
|
12 |
|
13 #include <dlfcn.h> |
|
14 |
|
15 // We get the proc addresss of all GL functions dynamically because we sometimes link against |
|
16 // alternative GL implementations (e.g. MESA) in addition to the native GL implementation. |
|
17 class GLLoader { |
|
18 public: |
|
19 GLLoader() { |
|
20 fLibrary = dlopen( |
|
21 "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib", |
|
22 RTLD_LAZY); |
|
23 } |
|
24 ~GLLoader() { |
|
25 if (NULL != fLibrary) { |
|
26 dlclose(fLibrary); |
|
27 } |
|
28 } |
|
29 void* handle() { |
|
30 return NULL == fLibrary ? RTLD_DEFAULT : fLibrary; |
|
31 } |
|
32 private: |
|
33 void* fLibrary; |
|
34 }; |
|
35 |
|
36 static void* GetProcAddress(const char* name) { |
|
37 static GLLoader gLoader; |
|
38 return dlsym(gLoader.handle(), name); |
|
39 } |
|
40 |
|
41 #define GET_PROC(name) (interface->fFunctions.f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name))) |
|
42 #define GET_PROC_SUFFIX(name, suffix) (interface->fFunctions.f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name #suffix))) |
|
43 |
|
44 const GrGLInterface* GrGLCreateNativeInterface() { |
|
45 |
|
46 GrGLGetStringProc glGetString = (GrGLGetStringProc) GetProcAddress("glGetString"); |
|
47 GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) GetProcAddress("glGetStringi"); |
|
48 GrGLGetIntegervProc glGetIntegerv = (GrGLGetIntegervProc) GetProcAddress("glGetIntegerv"); |
|
49 |
|
50 const char* verStr = (const char*) glGetString(GR_GL_VERSION); |
|
51 GrGLVersion ver = GrGLGetVersionFromString(verStr); |
|
52 GrGLExtensions extensions; |
|
53 if (!extensions.init(kGL_GrGLStandard, glGetString, glGetStringi, glGetIntegerv)) { |
|
54 return NULL; |
|
55 } |
|
56 |
|
57 GrGLInterface* interface = SkNEW(GrGLInterface); |
|
58 interface->fStandard = kGL_GrGLStandard; |
|
59 |
|
60 GET_PROC(ActiveTexture); |
|
61 GET_PROC(AttachShader); |
|
62 GET_PROC(BeginQuery); |
|
63 GET_PROC(BindAttribLocation); |
|
64 GET_PROC(BindBuffer); |
|
65 if (ver >= GR_GL_VER(3,0)) { |
|
66 GET_PROC(BindFragDataLocation); |
|
67 } |
|
68 GET_PROC(BindTexture); |
|
69 GET_PROC(BlendFunc); |
|
70 |
|
71 if (ver >= GR_GL_VER(1,4) || |
|
72 extensions.has("GL_ARB_imaging") || |
|
73 extensions.has("GL_EXT_blend_color")) { |
|
74 GET_PROC(BlendColor); |
|
75 } |
|
76 |
|
77 GET_PROC(BufferData); |
|
78 GET_PROC(BufferSubData); |
|
79 GET_PROC(Clear); |
|
80 GET_PROC(ClearColor); |
|
81 GET_PROC(ClearStencil); |
|
82 GET_PROC(ColorMask); |
|
83 GET_PROC(CompileShader); |
|
84 GET_PROC(CompressedTexImage2D); |
|
85 GET_PROC(CopyTexSubImage2D); |
|
86 GET_PROC(CreateProgram); |
|
87 GET_PROC(CreateShader); |
|
88 GET_PROC(CullFace); |
|
89 GET_PROC(DeleteBuffers); |
|
90 GET_PROC(DeleteProgram); |
|
91 GET_PROC(DeleteQueries); |
|
92 GET_PROC(DeleteShader); |
|
93 GET_PROC(DeleteTextures); |
|
94 GET_PROC(DepthMask); |
|
95 GET_PROC(Disable); |
|
96 GET_PROC(DisableVertexAttribArray); |
|
97 GET_PROC(DrawArrays); |
|
98 GET_PROC(DrawBuffer); |
|
99 GET_PROC(DrawBuffers); |
|
100 GET_PROC(DrawElements); |
|
101 GET_PROC(Enable); |
|
102 GET_PROC(EnableVertexAttribArray); |
|
103 GET_PROC(EndQuery); |
|
104 GET_PROC(Finish); |
|
105 GET_PROC(Flush); |
|
106 GET_PROC(FrontFace); |
|
107 GET_PROC(GenBuffers); |
|
108 GET_PROC(GenerateMipmap); |
|
109 GET_PROC(GenQueries); |
|
110 GET_PROC(GetBufferParameteriv); |
|
111 GET_PROC(GetError); |
|
112 GET_PROC(GetIntegerv); |
|
113 GET_PROC(GetProgramInfoLog); |
|
114 GET_PROC(GetProgramiv); |
|
115 GET_PROC(GetQueryiv); |
|
116 GET_PROC(GetQueryObjectiv); |
|
117 GET_PROC(GetQueryObjectuiv); |
|
118 GET_PROC(GetShaderInfoLog); |
|
119 GET_PROC(GetShaderiv); |
|
120 GET_PROC(GetString); |
|
121 GET_PROC(GetStringi); |
|
122 GET_PROC(GetTexLevelParameteriv); |
|
123 GET_PROC(GenTextures); |
|
124 GET_PROC(GetUniformLocation); |
|
125 GET_PROC(LineWidth); |
|
126 GET_PROC(LinkProgram); |
|
127 GET_PROC(LoadIdentity); |
|
128 GET_PROC(LoadMatrixf); |
|
129 GET_PROC(MapBuffer); |
|
130 GET_PROC(MatrixMode); |
|
131 GET_PROC(PixelStorei); |
|
132 GET_PROC(ReadBuffer); |
|
133 GET_PROC(ReadPixels); |
|
134 GET_PROC(Scissor); |
|
135 GET_PROC(ShaderSource); |
|
136 GET_PROC(StencilFunc); |
|
137 GET_PROC(StencilFuncSeparate); |
|
138 GET_PROC(StencilMask); |
|
139 GET_PROC(StencilMaskSeparate); |
|
140 GET_PROC(StencilOp); |
|
141 GET_PROC(StencilOpSeparate); |
|
142 GET_PROC(TexGenfv); |
|
143 GET_PROC(TexGeni); |
|
144 GET_PROC(TexImage2D); |
|
145 GET_PROC(TexParameteri); |
|
146 GET_PROC(TexParameteriv); |
|
147 if (ver >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) { |
|
148 GET_PROC(TexStorage2D); |
|
149 } else if (extensions.has("GL_EXT_texture_storage")) { |
|
150 GET_PROC_SUFFIX(TexStorage2D, EXT); |
|
151 } |
|
152 GET_PROC(TexSubImage2D); |
|
153 GET_PROC(Uniform1f); |
|
154 GET_PROC(Uniform1i); |
|
155 GET_PROC(Uniform1fv); |
|
156 GET_PROC(Uniform1iv); |
|
157 GET_PROC(Uniform2f); |
|
158 GET_PROC(Uniform2i); |
|
159 GET_PROC(Uniform2fv); |
|
160 GET_PROC(Uniform2iv); |
|
161 GET_PROC(Uniform3f); |
|
162 GET_PROC(Uniform3i); |
|
163 GET_PROC(Uniform3fv); |
|
164 GET_PROC(Uniform3iv); |
|
165 GET_PROC(Uniform4f); |
|
166 GET_PROC(Uniform4i); |
|
167 GET_PROC(Uniform4fv); |
|
168 GET_PROC(Uniform4iv); |
|
169 GET_PROC(Uniform4fv); |
|
170 GET_PROC(UniformMatrix2fv); |
|
171 GET_PROC(UniformMatrix3fv); |
|
172 GET_PROC(UniformMatrix4fv); |
|
173 GET_PROC(UnmapBuffer); |
|
174 GET_PROC(UseProgram); |
|
175 GET_PROC(VertexAttrib4fv); |
|
176 GET_PROC(VertexAttribPointer); |
|
177 GET_PROC(Viewport); |
|
178 |
|
179 if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { |
|
180 // no ARB suffix for GL_ARB_vertex_array_object |
|
181 GET_PROC(BindVertexArray); |
|
182 GET_PROC(DeleteVertexArrays); |
|
183 GET_PROC(GenVertexArrays); |
|
184 } |
|
185 |
|
186 if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { |
|
187 // ARB extension doesn't use the ARB suffix on the function name |
|
188 GET_PROC(QueryCounter); |
|
189 GET_PROC(GetQueryObjecti64v); |
|
190 GET_PROC(GetQueryObjectui64v); |
|
191 } else if (extensions.has("GL_EXT_timer_query")) { |
|
192 GET_PROC_SUFFIX(GetQueryObjecti64v, EXT); |
|
193 GET_PROC_SUFFIX(GetQueryObjectui64v, EXT); |
|
194 } |
|
195 |
|
196 if (ver >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { |
|
197 // ARB extension doesn't use the ARB suffix on the function names |
|
198 GET_PROC(GenFramebuffers); |
|
199 GET_PROC(GetFramebufferAttachmentParameteriv); |
|
200 GET_PROC(GetRenderbufferParameteriv); |
|
201 GET_PROC(BindFramebuffer); |
|
202 GET_PROC(FramebufferTexture2D); |
|
203 GET_PROC(CheckFramebufferStatus); |
|
204 GET_PROC(DeleteFramebuffers); |
|
205 GET_PROC(RenderbufferStorage); |
|
206 GET_PROC(GenRenderbuffers); |
|
207 GET_PROC(DeleteRenderbuffers); |
|
208 GET_PROC(FramebufferRenderbuffer); |
|
209 GET_PROC(BindRenderbuffer); |
|
210 GET_PROC(RenderbufferStorageMultisample); |
|
211 GET_PROC(BlitFramebuffer); |
|
212 } else { |
|
213 if (extensions.has("GL_EXT_framebuffer_object")) { |
|
214 GET_PROC_SUFFIX(GenFramebuffers, EXT); |
|
215 GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); |
|
216 GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); |
|
217 GET_PROC_SUFFIX(BindFramebuffer, EXT); |
|
218 GET_PROC_SUFFIX(FramebufferTexture2D, EXT); |
|
219 GET_PROC_SUFFIX(CheckFramebufferStatus, EXT); |
|
220 GET_PROC_SUFFIX(DeleteFramebuffers, EXT); |
|
221 GET_PROC_SUFFIX(RenderbufferStorage, EXT); |
|
222 GET_PROC_SUFFIX(GenRenderbuffers, EXT); |
|
223 GET_PROC_SUFFIX(DeleteRenderbuffers, EXT); |
|
224 GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); |
|
225 GET_PROC_SUFFIX(BindRenderbuffer, EXT); |
|
226 } |
|
227 if (extensions.has("GL_EXT_framebuffer_multisample")) { |
|
228 GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); |
|
229 } |
|
230 if (extensions.has("GL_EXT_framebuffer_blit")) { |
|
231 GET_PROC_SUFFIX(BlitFramebuffer, EXT); |
|
232 } |
|
233 } |
|
234 if (ver >= GR_GL_VER(3,3) || extensions.has("GL_ARB_blend_func_extended")) { |
|
235 // ARB extension doesn't use the ARB suffix on the function name |
|
236 GET_PROC(BindFragDataLocationIndexed); |
|
237 } |
|
238 |
|
239 if (extensions.has("GL_EXT_debug_marker")) { |
|
240 GET_PROC_SUFFIX(InsertEventMarker, EXT); |
|
241 GET_PROC_SUFFIX(PushGroupMarker, EXT); |
|
242 GET_PROC_SUFFIX(PopGroupMarker, EXT); |
|
243 } |
|
244 |
|
245 interface->fExtensions.swap(&extensions); |
|
246 return interface; |
|
247 } |