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
12 #include <OpenGL/gl.h>
13 #include <OpenGL/glext.h>
14
15 #include <mach-o/dyld.h>
16
17
18 // This uses deprecated functions, should rewrite using dlopen, dlsym, dlclose
GetProcAddress(const char * name)19 void* GetProcAddress(const char* name) {
20 NSSymbol symbol = NULL;
21 if (NSIsSymbolNameDefined(name)) {
22 symbol = NSLookupAndBindSymbol(name);
23 }
24 return NULL == symbol ? NULL : NSAddressOfSymbol(symbol);
25 }
26
27 #define GET_PROC(name) ((GrGL ## name ## Proc) GetProcAddress("_gl" #name))
28 #define GET_PROC_SUFFIX(name, suffix) ((GrGL ## name ## Proc) GetProcAddress("_gl" #name #suffix))
29
GrGLCreateNativeInterface()30 const GrGLInterface* GrGLCreateNativeInterface() {
31 // The gl functions are not context-specific so we create one global
32 // interface
33 static SkAutoTUnref<GrGLInterface> glInterface;
34 if (!glInterface.get()) {
35 GrGLInterface* interface = new GrGLInterface;
36 glInterface.reset(interface);
37 const char* verStr = (const char*) glGetString(GL_VERSION);
38 GrGLVersion ver = GrGLGetVersionFromString(verStr);
39 const char* extStr = (const char*) glGetString(GL_EXTENSIONS);
40
41 interface->fBindingsExported = kDesktop_GrGLBinding;
42 interface->fActiveTexture = glActiveTexture;
43 interface->fAttachShader = glAttachShader;
44 interface->fBeginQuery = glBeginQuery;
45 interface->fBindAttribLocation = glBindAttribLocation;
46 interface->fBindBuffer = glBindBuffer;
47 if (ver >= GR_GL_VER(3,0)) {
48 #if GL_VERSION_3_0
49 interface->fBindFragDataLocation = glBindFragDataLocation;
50 #else
51 interface->fBindFragDataLocation = GET_PROC(BindFragDataLocation);
52 #endif
53 }
54 interface->fBindTexture = glBindTexture;
55 interface->fBlendColor = glBlendColor;
56 interface->fBlendFunc = glBlendFunc;
57 interface->fBufferData = glBufferData;
58 interface->fBufferSubData = glBufferSubData;
59 interface->fClear = glClear;
60 interface->fClearColor = glClearColor;
61 interface->fClearStencil = glClearStencil;
62 interface->fColorMask = glColorMask;
63 interface->fColorPointer = glColorPointer;
64 interface->fCompileShader = glCompileShader;
65 interface->fCompressedTexImage2D = glCompressedTexImage2D;
66 interface->fCreateProgram = glCreateProgram;
67 interface->fCreateShader = glCreateShader;
68 interface->fCullFace = glCullFace;
69 interface->fDeleteBuffers = glDeleteBuffers;
70 interface->fDeleteProgram = glDeleteProgram;
71 interface->fDeleteQueries = glDeleteQueries;
72 interface->fDeleteShader = glDeleteShader;
73 interface->fDeleteTextures = glDeleteTextures;
74 interface->fDepthMask = glDepthMask;
75 interface->fDisable = glDisable;
76 interface->fDisableVertexAttribArray =
77 glDisableVertexAttribArray;
78 interface->fDrawArrays = glDrawArrays;
79 interface->fDrawBuffer = glDrawBuffer;
80 interface->fDrawBuffers = glDrawBuffers;
81 interface->fDrawElements = glDrawElements;
82 interface->fEnable = glEnable;
83 interface->fEnableVertexAttribArray = glEnableVertexAttribArray;
84 interface->fEndQuery = glEndQuery;
85 interface->fFinish = glFinish;
86 interface->fFlush = glFlush;
87 interface->fFrontFace = glFrontFace;
88 interface->fGenBuffers = glGenBuffers;
89 interface->fGenQueries = glGenQueries;
90 interface->fGetBufferParameteriv = glGetBufferParameteriv;
91 interface->fGetError = glGetError;
92 interface->fGetIntegerv = glGetIntegerv;
93 interface->fGetProgramInfoLog = glGetProgramInfoLog;
94 interface->fGetProgramiv = glGetProgramiv;
95 interface->fGetQueryiv = glGetQueryiv;
96 interface->fGetQueryObjectiv = glGetQueryObjectiv;
97 interface->fGetQueryObjectuiv = glGetQueryObjectuiv;
98 interface->fGetShaderInfoLog = glGetShaderInfoLog;
99 interface->fGetShaderiv = glGetShaderiv;
100 interface->fGetString = glGetString;
101 interface->fGetTexLevelParameteriv = glGetTexLevelParameteriv;
102 interface->fGenTextures = glGenTextures;
103 interface->fGetUniformLocation = glGetUniformLocation;
104 interface->fLineWidth = glLineWidth;
105 interface->fLinkProgram = glLinkProgram;
106 interface->fMapBuffer = glMapBuffer;
107 interface->fPixelStorei = glPixelStorei;
108 interface->fReadBuffer = glReadBuffer;
109 interface->fReadPixels = glReadPixels;
110 interface->fScissor = glScissor;
111 interface->fShaderSource = glShaderSource;
112 interface->fStencilFunc = glStencilFunc;
113 interface->fStencilFuncSeparate = glStencilFuncSeparate;
114 interface->fStencilMask = glStencilMask;
115 interface->fStencilMaskSeparate = glStencilMaskSeparate;
116 interface->fStencilOp = glStencilOp;
117 interface->fStencilOpSeparate = glStencilOpSeparate;
118 // mac uses GLenum for internalFormat param (non-standard)
119 // amounts to int vs. uint.
120 interface->fTexImage2D = (GrGLTexImage2DProc)glTexImage2D;
121 interface->fTexParameteri = glTexParameteri;
122 #if GL_ARB_texture_storage || GL_VERSION_4_2
123 interface->fTexStorage2D = glTexStorage2D
124 #elif GL_EXT_texture_storage
125 interface->fTexStorage2D = glTexStorage2DEXT;
126 #else
127 if (ver >= GR_GL_VER(4,2) ||
128 GrGLHasExtensionFromString("GL_ARB_texture_storage", extStr)) {
129 GET_PROC(TexStorage2D);
130 } else if (GrGLHasExtensionFromString("GL_EXT_texture_storage", extStr)) {
131 GET_PROC_SUFFIX(TexStorage2D, EXT);
132 }
133 #endif
134 interface->fTexSubImage2D = glTexSubImage2D;
135 interface->fUniform1f = glUniform1f;
136 interface->fUniform1i = glUniform1i;
137 interface->fUniform1fv = glUniform1fv;
138 interface->fUniform1iv = glUniform1iv;
139 interface->fUniform2f = glUniform2f;
140 interface->fUniform2i = glUniform2i;
141 interface->fUniform2fv = glUniform2fv;
142 interface->fUniform2iv = glUniform2iv;
143 interface->fUniform3f = glUniform3f;
144 interface->fUniform3i = glUniform3i;
145 interface->fUniform3fv = glUniform3fv;
146 interface->fUniform3iv = glUniform3iv;
147 interface->fUniform4f = glUniform4f;
148 interface->fUniform4i = glUniform4i;
149 interface->fUniform4fv = glUniform4fv;
150 interface->fUniform4iv = glUniform4iv;
151 interface->fUniform4fv = glUniform4fv;
152 interface->fUniformMatrix2fv = glUniformMatrix2fv;
153 interface->fUniformMatrix3fv = glUniformMatrix3fv;
154 interface->fUniformMatrix4fv = glUniformMatrix4fv;
155 interface->fUnmapBuffer = glUnmapBuffer;
156 interface->fUseProgram = glUseProgram;
157 interface->fVertexAttrib4fv = glVertexAttrib4fv;
158 interface->fVertexAttribPointer = glVertexAttribPointer;
159 interface->fViewport = glViewport;
160
161 if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_timer_query", extStr)) {
162 // ARB extension doesn't use the ARB suffix on the function name
163 #if GL_ARB_timer_query || GL_VERSION_3_3
164 interface->fQueryCounter = glQueryCounter;
165 interface->fGetQueryObjecti64v = glGetQueryObjecti64v;
166 interface->fGetQueryObjectui64v = glGetQueryObjectui64v;
167 #else
168 interface->fQueryCounter = GET_PROC(QueryCounter);
169 interface->fGetQueryObjecti64v = GET_PROC(GetQueryObjecti64v);
170 interface->fGetQueryObjectui64v = GET_PROC(GetQueryObjectui64v);
171 #endif
172 } else if (GrGLHasExtensionFromString("GL_EXT_timer_query", extStr)) {
173 #if GL_EXT_timer_query
174 interface->fGetQueryObjecti64v = glGetQueryObjecti64vEXT;
175 interface->fGetQueryObjectui64v = glGetQueryObjectui64vEXT;
176 #else
177 interface->fGetQueryObjecti64v = GET_PROC_SUFFIX(GetQueryObjecti64v, EXT);
178 interface->fGetQueryObjectui64v = GET_PROC_SUFFIX(GetQueryObjectui64v, EXT);
179 #endif
180 }
181
182 if (ver >= GR_GL_VER(3,0) || GrGLHasExtensionFromString("GL_ARB_framebuffer_object", extStr)) {
183 // ARB extension doesn't use the ARB suffix on the function names
184 #if GL_VERSION_3_0 || GL_ARB_framebuffer_object
185 interface->fGenFramebuffers = glGenFramebuffers;
186 interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
187 interface->fGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
188 interface->fBindFramebuffer = glBindFramebuffer;
189 interface->fFramebufferTexture2D = glFramebufferTexture2D;
190 interface->fCheckFramebufferStatus = glCheckFramebufferStatus;
191 interface->fDeleteFramebuffers = glDeleteFramebuffers;
192 interface->fRenderbufferStorage = glRenderbufferStorage;
193 interface->fGenRenderbuffers = glGenRenderbuffers;
194 interface->fDeleteRenderbuffers = glDeleteRenderbuffers;
195 interface->fFramebufferRenderbuffer = glFramebufferRenderbuffer;
196 interface->fBindRenderbuffer = glBindRenderbuffer;
197 interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisample;
198 interface->fBlitFramebuffer = glBlitFramebuffer;
199 #else
200 interface->fGenFramebuffers = GET_PROC(GenFramebuffers);
201 interface->fGetFramebufferAttachmentParameteriv = GET_PROC(GetFramebufferAttachmentParameteriv);
202 interface->fGetRenderbufferParameteriv = GET_PROC(GetRenderbufferParameteriv);
203 interface->fBindFramebuffer = GET_PROC(BindFramebuffer);
204 interface->fFramebufferTexture2D = GET_PROC(FramebufferTexture2D);
205 interface->fCheckFramebufferStatus = GET_PROC(CheckFramebufferStatus);
206 interface->fDeleteFramebuffers = GET_PROC(DeleteFramebuffers);
207 interface->fRenderbufferStorage = GET_PROC(RenderbufferStorage);
208 interface->fGenRenderbuffers = GET_PROC(GenRenderbuffers);
209 interface->fDeleteRenderbuffers = GET_PROC(DeleteRenderbuffers);
210 interface->fFramebufferRenderbuffer = GET_PROC(FramebufferRenderbuffer);
211 interface->fBindRenderbuffer = GET_PROC(BindRenderbuffer);
212 interface->fRenderbufferStorageMultisample = GET_PROC(RenderbufferStorageMultisample);
213 interface->fBlitFramebuffer = GET_PROC(BlitFramebuffer);
214 #endif
215 } else {
216 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_object", extStr)) {
217 #if GL_EXT_framebuffer_object
218 interface->fGenFramebuffers = glGenFramebuffersEXT;
219 interface->fGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameterivEXT;
220 interface->fGetRenderbufferParameteriv = glGetRenderbufferParameterivEXT;
221 interface->fBindFramebuffer = glBindFramebufferEXT;
222 interface->fFramebufferTexture2D = glFramebufferTexture2DEXT;
223 interface->fCheckFramebufferStatus = glCheckFramebufferStatusEXT;
224 interface->fDeleteFramebuffers = glDeleteFramebuffersEXT;
225 interface->fRenderbufferStorage = glRenderbufferStorageEXT;
226 interface->fGenRenderbuffers = glGenRenderbuffersEXT;
227 interface->fDeleteRenderbuffers = glDeleteRenderbuffersEXT;
228 interface->fFramebufferRenderbuffer = glFramebufferRenderbufferEXT;
229 interface->fBindRenderbuffer = glBindRenderbufferEXT;
230 #else
231 interface->fGenFramebuffers = GET_PROC_SUFFIX(GenFramebuffers, EXT);
232 interface->fGetFramebufferAttachmentParameteriv = GET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT);
233 interface->fGetRenderbufferParameteriv = GET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT);
234 interface->fBindFramebuffer = GET_PROC_SUFFIX(BindFramebuffer, EXT);
235 interface->fFramebufferTexture2D = GET_PROC_SUFFIX(FramebufferTexture2D, EXT);
236 interface->fCheckFramebufferStatus = GET_PROC_SUFFIX(CheckFramebufferStatus, EXT);
237 interface->fDeleteFramebuffers = GET_PROC_SUFFIX(DeleteFramebuffers, EXT);
238 interface->fRenderbufferStorage = GET_PROC_SUFFIX(RenderbufferStorage, EXT);
239 interface->fGenRenderbuffers = GET_PROC_SUFFIX(GenRenderbuffers, EXT);
240 interface->fDeleteRenderbuffers = GET_PROC_SUFFIX(DeleteRenderbuffers, EXT);
241 interface->fFramebufferRenderbuffer = GET_PROC_SUFFIX(FramebufferRenderbuffer, EXT);
242 interface->fBindRenderbuffer = GET_PROC_SUFFIX(BindRenderbuffer, EXT);
243 #endif
244 }
245 if (GrGLHasExtensionFromString("GL_EXT_framebuffer_multisample", extStr)) {
246 #if GL_EXT_framebuffer_multisample
247 interface->fRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
248 #else
249 interface->fRenderbufferStorageMultisample = GET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT);
250 #endif
251 }
252 if (GrGLHasExtensionFromString("", extStr)) {
253 #if GL_EXT_framebuffer_blit
254 interface->fBlitFramebuffer = glBlitFramebufferEXT;
255 #else
256 interface->fBlitFramebuffer = GET_PROC_SUFFIX(BlitFramebuffer, EXT);
257 #endif
258 }
259 }
260 if (ver >= GR_GL_VER(3,3) || GrGLHasExtensionFromString("GL_ARB_blend_func_extended", extStr)) {
261 // ARB extension doesn't use the ARB suffix on the function name
262 #if GL_VERSION_3_3 || GL_ARB_blend_func_extended
263 interface->fBindFragDataLocationIndexed = glBindFragDataLocationIndexed;
264 #else
265 interface->fBindFragDataLocationIndexed = GET_PROC(BindFragDataLocationIndexed);
266 #endif
267 }
268
269 interface->fBindingsExported = kDesktop_GrGLBinding;
270 }
271 glInterface.get()->ref();
272 return glInterface.get();
273 }
274