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/GrGLExtensions.h" 11#include "gl/GrGLInterface.h" 12#include "gl/GrGLUtil.h" 13#define WIN32_LEAN_AND_MEAN 14#include <windows.h> 15 16/* 17 * Windows makes the GL funcs all be __stdcall instead of __cdecl :( 18 * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall. 19 * Otherwise, a springboard would be needed that hides the calling convention. 20 */ 21 22#define SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) GetProcAddress(alu.get(), "gl" #F); 23#define WGL_SET_PROC(F) interface->f ## F = (GrGL ## F ## Proc) wglGetProcAddress("gl" #F); 24#define WGL_SET_PROC_SUFFIX(F, S) interface->f ## F = \ 25 (GrGL ## F ## Proc) wglGetProcAddress("gl" #F #S); 26 27class AutoLibraryUnload { 28public: 29 AutoLibraryUnload(const char* moduleName) { 30 fModule = LoadLibrary(moduleName); 31 } 32 ~AutoLibraryUnload() { 33 if (NULL != fModule) { 34 FreeLibrary(fModule); 35 } 36 } 37 HMODULE get() const { return fModule; } 38 39private: 40 HMODULE fModule; 41}; 42 43const GrGLInterface* GrGLCreateNativeInterface() { 44 // wglGetProcAddress requires a context. 45 // GL Function pointers retrieved in one context may not be valid in another 46 // context. For that reason we create a new GrGLInterface each time we're 47 // called. 48 AutoLibraryUnload alu("opengl32.dll"); 49 if (NULL == alu.get()) { 50 return NULL; 51 } 52 53 if (NULL != wglGetCurrentContext()) { 54 55 // These should always be present and don't require wglGetProcAddress 56 GrGLGetStringProc glGetString = 57 (GrGLGetStringProc) GetProcAddress(alu.get(), "glGetString"); 58 GrGLGetIntegervProc glGetIntegerv = 59 (GrGLGetIntegervProc) GetProcAddress(alu.get(), "glGetIntegerv"); 60 if (NULL == glGetString || NULL == glGetIntegerv) { 61 return NULL; 62 } 63 64 // This may or may not succeed depending on the gl version. 65 GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) wglGetProcAddress("glGetStringi"); 66 67 GrGLExtensions extensions; 68 if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) { 69 return NULL; 70 } 71 const char* versionString = (const char*) glGetString(GR_GL_VERSION); 72 GrGLVersion glVer = GrGLGetVersionFromString(versionString); 73 74 if (glVer < GR_GL_VER(1,5)) { 75 // We must have array and element_array buffer objects. 76 return NULL; 77 } 78 GrGLInterface* interface = new GrGLInterface(); 79 80 // Functions that are part of GL 1.1 will return NULL in 81 // wglGetProcAddress 82 SET_PROC(BindTexture) 83 SET_PROC(BlendFunc) 84 85 if (glVer >= GR_GL_VER(1,4) || 86 extensions.has("GL_ARB_imaging") || 87 extensions.has("GL_EXT_blend_color")) { 88 WGL_SET_PROC(BlendColor); 89 } 90 91 SET_PROC(Clear) 92 SET_PROC(ClearColor) 93 SET_PROC(ClearStencil) 94 SET_PROC(ColorMask) 95 SET_PROC(CopyTexSubImage2D) 96 SET_PROC(CullFace) 97 SET_PROC(DeleteTextures) 98 SET_PROC(DepthMask) 99 SET_PROC(Disable) 100 SET_PROC(DisableClientState) 101 SET_PROC(DrawArrays) 102 SET_PROC(DrawElements) 103 SET_PROC(DrawBuffer) 104 SET_PROC(Enable) 105 SET_PROC(EnableClientState) 106 SET_PROC(FrontFace) 107 SET_PROC(Finish) 108 SET_PROC(Flush) 109 SET_PROC(GenTextures) 110 SET_PROC(GetError) 111 SET_PROC(GetIntegerv) 112 SET_PROC(GetString) 113 SET_PROC(GetTexLevelParameteriv) 114 SET_PROC(LineWidth) 115 SET_PROC(LoadIdentity) 116 SET_PROC(LoadMatrixf) 117 SET_PROC(MatrixMode) 118 SET_PROC(PixelStorei) 119 SET_PROC(ReadBuffer) 120 SET_PROC(ReadPixels) 121 SET_PROC(Scissor) 122 SET_PROC(StencilFunc) 123 SET_PROC(StencilMask) 124 SET_PROC(StencilOp) 125 SET_PROC(TexGenf) 126 SET_PROC(TexGenfv) 127 SET_PROC(TexGeni) 128 SET_PROC(TexImage2D) 129 SET_PROC(TexParameteri) 130 SET_PROC(TexParameteriv) 131 if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) { 132 WGL_SET_PROC(TexStorage2D); 133 } else if (extensions.has("GL_EXT_texture_storage")) { 134 WGL_SET_PROC_SUFFIX(TexStorage2D, EXT); 135 } 136 SET_PROC(TexSubImage2D) 137 SET_PROC(Viewport) 138 SET_PROC(VertexPointer) 139 140 WGL_SET_PROC(ActiveTexture); 141 WGL_SET_PROC(AttachShader); 142 WGL_SET_PROC(BeginQuery); 143 WGL_SET_PROC(BindAttribLocation); 144 WGL_SET_PROC(BindBuffer); 145 WGL_SET_PROC(BindFragDataLocation); 146 WGL_SET_PROC(BufferData); 147 WGL_SET_PROC(BufferSubData); 148 WGL_SET_PROC(ClientActiveTexture); 149 WGL_SET_PROC(CompileShader); 150 WGL_SET_PROC(CompressedTexImage2D); 151 WGL_SET_PROC(CreateProgram); 152 WGL_SET_PROC(CreateShader); 153 WGL_SET_PROC(DeleteBuffers); 154 WGL_SET_PROC(DeleteQueries); 155 WGL_SET_PROC(DeleteProgram); 156 WGL_SET_PROC(DeleteShader); 157 WGL_SET_PROC(DisableVertexAttribArray); 158 WGL_SET_PROC(DrawBuffers); 159 WGL_SET_PROC(EnableVertexAttribArray); 160 WGL_SET_PROC(EndQuery); 161 WGL_SET_PROC(GenBuffers); 162 WGL_SET_PROC(GenerateMipmap); 163 WGL_SET_PROC(GenQueries); 164 WGL_SET_PROC(GetBufferParameteriv); 165 WGL_SET_PROC(GetQueryiv); 166 WGL_SET_PROC(GetQueryObjectiv); 167 WGL_SET_PROC(GetQueryObjectuiv); 168 if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { 169 WGL_SET_PROC(GetQueryObjecti64v); 170 WGL_SET_PROC(GetQueryObjectui64v); 171 WGL_SET_PROC(QueryCounter); 172 } else if (extensions.has("GL_EXT_timer_query")) { 173 WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT); 174 WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT); 175 } 176 WGL_SET_PROC(GetProgramInfoLog); 177 WGL_SET_PROC(GetProgramiv); 178 WGL_SET_PROC(GetShaderInfoLog); 179 WGL_SET_PROC(GetShaderiv); 180 WGL_SET_PROC(GetStringi) 181 WGL_SET_PROC(GetUniformLocation); 182 WGL_SET_PROC(LinkProgram); 183 WGL_SET_PROC(ShaderSource); 184 WGL_SET_PROC(StencilFuncSeparate); 185 WGL_SET_PROC(StencilMaskSeparate); 186 WGL_SET_PROC(StencilOpSeparate); 187 WGL_SET_PROC(Uniform1f); 188 WGL_SET_PROC(Uniform1i); 189 WGL_SET_PROC(Uniform1fv); 190 WGL_SET_PROC(Uniform1iv); 191 WGL_SET_PROC(Uniform2f); 192 WGL_SET_PROC(Uniform2i); 193 WGL_SET_PROC(Uniform2fv); 194 WGL_SET_PROC(Uniform2iv); 195 WGL_SET_PROC(Uniform3f); 196 WGL_SET_PROC(Uniform3i); 197 WGL_SET_PROC(Uniform3fv); 198 WGL_SET_PROC(Uniform3iv); 199 WGL_SET_PROC(Uniform4f); 200 WGL_SET_PROC(Uniform4i); 201 WGL_SET_PROC(Uniform4fv); 202 WGL_SET_PROC(Uniform4iv); 203 WGL_SET_PROC(UniformMatrix2fv); 204 WGL_SET_PROC(UniformMatrix3fv); 205 WGL_SET_PROC(UniformMatrix4fv); 206 WGL_SET_PROC(UseProgram); 207 WGL_SET_PROC(VertexAttrib4fv); 208 WGL_SET_PROC(VertexAttribPointer); 209 WGL_SET_PROC(BindFragDataLocationIndexed); 210 211 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { 212 // no ARB suffix for GL_ARB_vertex_array_object 213 WGL_SET_PROC(BindVertexArray); 214 WGL_SET_PROC(DeleteVertexArrays); 215 WGL_SET_PROC(GenVertexArrays); 216 } 217 218 // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since 219 // GL_ARB_framebuffer_object doesn't use ARB suffix.) 220 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { 221 WGL_SET_PROC(GenFramebuffers); 222 WGL_SET_PROC(GetFramebufferAttachmentParameteriv); 223 WGL_SET_PROC(GetRenderbufferParameteriv); 224 WGL_SET_PROC(BindFramebuffer); 225 WGL_SET_PROC(FramebufferTexture2D); 226 WGL_SET_PROC(CheckFramebufferStatus); 227 WGL_SET_PROC(DeleteFramebuffers); 228 WGL_SET_PROC(RenderbufferStorage); 229 WGL_SET_PROC(GenRenderbuffers); 230 WGL_SET_PROC(DeleteRenderbuffers); 231 WGL_SET_PROC(FramebufferRenderbuffer); 232 WGL_SET_PROC(BindRenderbuffer); 233 WGL_SET_PROC(RenderbufferStorageMultisample); 234 WGL_SET_PROC(BlitFramebuffer); 235 } else if (extensions.has("GL_EXT_framebuffer_object")) { 236 WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT); 237 WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); 238 WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); 239 WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT); 240 WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT); 241 WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT); 242 WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT); 243 WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT); 244 WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT); 245 WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT); 246 WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); 247 WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT); 248 if (extensions.has("GL_EXT_framebuffer_multisample")) { 249 WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); 250 } 251 if (extensions.has("GL_EXT_framebuffer_blit")) { 252 WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT); 253 } 254 } else { 255 // we must have FBOs 256 delete interface; 257 return NULL; 258 } 259 WGL_SET_PROC(MapBuffer); 260 WGL_SET_PROC(UnmapBuffer); 261 262 if (extensions.has("GL_NV_path_rendering")) { 263 WGL_SET_PROC_SUFFIX(PathCommands, NV); 264 WGL_SET_PROC_SUFFIX(PathCoords, NV); 265 WGL_SET_PROC_SUFFIX(PathSubCommands, NV); 266 WGL_SET_PROC_SUFFIX(PathSubCoords, NV); 267 WGL_SET_PROC_SUFFIX(PathString, NV); 268 WGL_SET_PROC_SUFFIX(PathGlyphs, NV); 269 WGL_SET_PROC_SUFFIX(PathGlyphRange, NV); 270 WGL_SET_PROC_SUFFIX(WeightPaths, NV); 271 WGL_SET_PROC_SUFFIX(CopyPath, NV); 272 WGL_SET_PROC_SUFFIX(InterpolatePaths, NV); 273 WGL_SET_PROC_SUFFIX(TransformPath, NV); 274 WGL_SET_PROC_SUFFIX(PathParameteriv, NV); 275 WGL_SET_PROC_SUFFIX(PathParameteri, NV); 276 WGL_SET_PROC_SUFFIX(PathParameterfv, NV); 277 WGL_SET_PROC_SUFFIX(PathParameterf, NV); 278 WGL_SET_PROC_SUFFIX(PathDashArray, NV); 279 WGL_SET_PROC_SUFFIX(GenPaths, NV); 280 WGL_SET_PROC_SUFFIX(DeletePaths, NV); 281 WGL_SET_PROC_SUFFIX(IsPath, NV); 282 WGL_SET_PROC_SUFFIX(PathStencilFunc, NV); 283 WGL_SET_PROC_SUFFIX(PathStencilDepthOffset, NV); 284 WGL_SET_PROC_SUFFIX(StencilFillPath, NV); 285 WGL_SET_PROC_SUFFIX(StencilStrokePath, NV); 286 WGL_SET_PROC_SUFFIX(StencilFillPathInstanced, NV); 287 WGL_SET_PROC_SUFFIX(StencilStrokePathInstanced, NV); 288 WGL_SET_PROC_SUFFIX(PathCoverDepthFunc, NV); 289 WGL_SET_PROC_SUFFIX(PathColorGen, NV); 290 WGL_SET_PROC_SUFFIX(PathTexGen, NV); 291 WGL_SET_PROC_SUFFIX(PathFogGen, NV); 292 WGL_SET_PROC_SUFFIX(CoverFillPath, NV); 293 WGL_SET_PROC_SUFFIX(CoverStrokePath, NV); 294 WGL_SET_PROC_SUFFIX(CoverFillPathInstanced, NV); 295 WGL_SET_PROC_SUFFIX(CoverStrokePathInstanced, NV); 296 WGL_SET_PROC_SUFFIX(GetPathParameteriv, NV); 297 WGL_SET_PROC_SUFFIX(GetPathParameterfv, NV); 298 WGL_SET_PROC_SUFFIX(GetPathCommands, NV); 299 WGL_SET_PROC_SUFFIX(GetPathCoords, NV); 300 WGL_SET_PROC_SUFFIX(GetPathDashArray, NV); 301 WGL_SET_PROC_SUFFIX(GetPathMetrics, NV); 302 WGL_SET_PROC_SUFFIX(GetPathMetricRange, NV); 303 WGL_SET_PROC_SUFFIX(GetPathSpacing, NV); 304 WGL_SET_PROC_SUFFIX(GetPathColorGeniv, NV); 305 WGL_SET_PROC_SUFFIX(GetPathColorGenfv, NV); 306 WGL_SET_PROC_SUFFIX(GetPathTexGeniv, NV); 307 WGL_SET_PROC_SUFFIX(GetPathTexGenfv, NV); 308 WGL_SET_PROC_SUFFIX(IsPointInFillPath, NV); 309 WGL_SET_PROC_SUFFIX(IsPointInStrokePath, NV); 310 WGL_SET_PROC_SUFFIX(GetPathLength, NV); 311 WGL_SET_PROC_SUFFIX(PointAlongPath, NV); 312 } 313 314 interface->fBindingsExported = kDesktop_GrGLBinding; 315 316 return interface; 317 } else { 318 return NULL; 319 } 320} 321