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(DrawArrays) 101 SET_PROC(DrawElements) 102 SET_PROC(DrawBuffer) 103 SET_PROC(Enable) 104 SET_PROC(FrontFace) 105 SET_PROC(Finish) 106 SET_PROC(Flush) 107 SET_PROC(GenTextures) 108 SET_PROC(GetError) 109 SET_PROC(GetIntegerv) 110 SET_PROC(GetString) 111 SET_PROC(GetTexLevelParameteriv) 112 SET_PROC(LineWidth) 113 SET_PROC(LoadIdentity) 114 SET_PROC(LoadMatrixf) 115 SET_PROC(MatrixMode) 116 SET_PROC(PixelStorei) 117 SET_PROC(ReadBuffer) 118 SET_PROC(ReadPixels) 119 SET_PROC(Scissor) 120 SET_PROC(StencilFunc) 121 SET_PROC(StencilMask) 122 SET_PROC(StencilOp) 123 SET_PROC(TexImage2D) 124 SET_PROC(TexParameteri) 125 SET_PROC(TexParameteriv) 126 if (glVer >= GR_GL_VER(4,2) || extensions.has("GL_ARB_texture_storage")) { 127 WGL_SET_PROC(TexStorage2D); 128 } else if (extensions.has("GL_EXT_texture_storage")) { 129 WGL_SET_PROC_SUFFIX(TexStorage2D, EXT); 130 } 131 SET_PROC(TexSubImage2D) 132 SET_PROC(Viewport) 133 134 WGL_SET_PROC(ActiveTexture); 135 WGL_SET_PROC(AttachShader); 136 WGL_SET_PROC(BeginQuery); 137 WGL_SET_PROC(BindAttribLocation); 138 WGL_SET_PROC(BindBuffer); 139 WGL_SET_PROC(BindFragDataLocation); 140 WGL_SET_PROC(BufferData); 141 WGL_SET_PROC(BufferSubData); 142 WGL_SET_PROC(CompileShader); 143 WGL_SET_PROC(CompressedTexImage2D); 144 WGL_SET_PROC(CreateProgram); 145 WGL_SET_PROC(CreateShader); 146 WGL_SET_PROC(DeleteBuffers); 147 WGL_SET_PROC(DeleteQueries); 148 WGL_SET_PROC(DeleteProgram); 149 WGL_SET_PROC(DeleteShader); 150 WGL_SET_PROC(DisableVertexAttribArray); 151 WGL_SET_PROC(DrawBuffers); 152 WGL_SET_PROC(EnableVertexAttribArray); 153 WGL_SET_PROC(EndQuery); 154 WGL_SET_PROC(GenBuffers); 155 WGL_SET_PROC(GenerateMipmap); 156 WGL_SET_PROC(GenQueries); 157 WGL_SET_PROC(GetBufferParameteriv); 158 WGL_SET_PROC(GetQueryiv); 159 WGL_SET_PROC(GetQueryObjectiv); 160 WGL_SET_PROC(GetQueryObjectuiv); 161 if (glVer > GR_GL_VER(3,3) || extensions.has("GL_ARB_timer_query")) { 162 WGL_SET_PROC(GetQueryObjecti64v); 163 WGL_SET_PROC(GetQueryObjectui64v); 164 WGL_SET_PROC(QueryCounter); 165 } else if (extensions.has("GL_EXT_timer_query")) { 166 WGL_SET_PROC_SUFFIX(GetQueryObjecti64v, EXT); 167 WGL_SET_PROC_SUFFIX(GetQueryObjectui64v, EXT); 168 } 169 WGL_SET_PROC(GetProgramInfoLog); 170 WGL_SET_PROC(GetProgramiv); 171 WGL_SET_PROC(GetShaderInfoLog); 172 WGL_SET_PROC(GetShaderiv); 173 WGL_SET_PROC(GetStringi) 174 WGL_SET_PROC(GetUniformLocation); 175 WGL_SET_PROC(LinkProgram); 176 if (extensions.has("GL_NV_framebuffer_multisample_coverage")) { 177 WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisampleCoverage, NV); 178 } 179 WGL_SET_PROC(ShaderSource); 180 WGL_SET_PROC(StencilFuncSeparate); 181 WGL_SET_PROC(StencilMaskSeparate); 182 WGL_SET_PROC(StencilOpSeparate); 183 WGL_SET_PROC(Uniform1f); 184 WGL_SET_PROC(Uniform1i); 185 WGL_SET_PROC(Uniform1fv); 186 WGL_SET_PROC(Uniform1iv); 187 WGL_SET_PROC(Uniform2f); 188 WGL_SET_PROC(Uniform2i); 189 WGL_SET_PROC(Uniform2fv); 190 WGL_SET_PROC(Uniform2iv); 191 WGL_SET_PROC(Uniform3f); 192 WGL_SET_PROC(Uniform3i); 193 WGL_SET_PROC(Uniform3fv); 194 WGL_SET_PROC(Uniform3iv); 195 WGL_SET_PROC(Uniform4f); 196 WGL_SET_PROC(Uniform4i); 197 WGL_SET_PROC(Uniform4fv); 198 WGL_SET_PROC(Uniform4iv); 199 WGL_SET_PROC(UniformMatrix2fv); 200 WGL_SET_PROC(UniformMatrix3fv); 201 WGL_SET_PROC(UniformMatrix4fv); 202 WGL_SET_PROC(UseProgram); 203 WGL_SET_PROC(VertexAttrib4fv); 204 WGL_SET_PROC(VertexAttribPointer); 205 WGL_SET_PROC(BindFragDataLocationIndexed); 206 207 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_vertex_array_object")) { 208 // no ARB suffix for GL_ARB_vertex_array_object 209 WGL_SET_PROC(BindVertexArray); 210 WGL_SET_PROC(DeleteVertexArrays); 211 WGL_SET_PROC(GenVertexArrays); 212 } 213 214 // First look for GL3.0 FBO or GL_ARB_framebuffer_object (same since 215 // GL_ARB_framebuffer_object doesn't use ARB suffix.) 216 if (glVer >= GR_GL_VER(3,0) || extensions.has("GL_ARB_framebuffer_object")) { 217 WGL_SET_PROC(GenFramebuffers); 218 WGL_SET_PROC(GetFramebufferAttachmentParameteriv); 219 WGL_SET_PROC(GetRenderbufferParameteriv); 220 WGL_SET_PROC(BindFramebuffer); 221 WGL_SET_PROC(FramebufferTexture2D); 222 WGL_SET_PROC(CheckFramebufferStatus); 223 WGL_SET_PROC(DeleteFramebuffers); 224 WGL_SET_PROC(RenderbufferStorage); 225 WGL_SET_PROC(GenRenderbuffers); 226 WGL_SET_PROC(DeleteRenderbuffers); 227 WGL_SET_PROC(FramebufferRenderbuffer); 228 WGL_SET_PROC(BindRenderbuffer); 229 WGL_SET_PROC(RenderbufferStorageMultisample); 230 WGL_SET_PROC(BlitFramebuffer); 231 } else if (extensions.has("GL_EXT_framebuffer_object")) { 232 WGL_SET_PROC_SUFFIX(GenFramebuffers, EXT); 233 WGL_SET_PROC_SUFFIX(GetFramebufferAttachmentParameteriv, EXT); 234 WGL_SET_PROC_SUFFIX(GetRenderbufferParameteriv, EXT); 235 WGL_SET_PROC_SUFFIX(BindFramebuffer, EXT); 236 WGL_SET_PROC_SUFFIX(FramebufferTexture2D, EXT); 237 WGL_SET_PROC_SUFFIX(CheckFramebufferStatus, EXT); 238 WGL_SET_PROC_SUFFIX(DeleteFramebuffers, EXT); 239 WGL_SET_PROC_SUFFIX(RenderbufferStorage, EXT); 240 WGL_SET_PROC_SUFFIX(GenRenderbuffers, EXT); 241 WGL_SET_PROC_SUFFIX(DeleteRenderbuffers, EXT); 242 WGL_SET_PROC_SUFFIX(FramebufferRenderbuffer, EXT); 243 WGL_SET_PROC_SUFFIX(BindRenderbuffer, EXT); 244 if (extensions.has("GL_EXT_framebuffer_multisample")) { 245 WGL_SET_PROC_SUFFIX(RenderbufferStorageMultisample, EXT); 246 } 247 if (extensions.has("GL_EXT_framebuffer_blit")) { 248 WGL_SET_PROC_SUFFIX(BlitFramebuffer, EXT); 249 } 250 } else { 251 // we must have FBOs 252 delete interface; 253 return NULL; 254 } 255 WGL_SET_PROC(MapBuffer); 256 WGL_SET_PROC(UnmapBuffer); 257 258 if (extensions.has("GL_NV_path_rendering")) { 259 WGL_SET_PROC_SUFFIX(PathCommands, NV); 260 WGL_SET_PROC_SUFFIX(PathCoords, NV); 261 WGL_SET_PROC_SUFFIX(PathSubCommands, NV); 262 WGL_SET_PROC_SUFFIX(PathSubCoords, NV); 263 WGL_SET_PROC_SUFFIX(PathString, NV); 264 WGL_SET_PROC_SUFFIX(PathGlyphs, NV); 265 WGL_SET_PROC_SUFFIX(PathGlyphRange, NV); 266 WGL_SET_PROC_SUFFIX(WeightPaths, NV); 267 WGL_SET_PROC_SUFFIX(CopyPath, NV); 268 WGL_SET_PROC_SUFFIX(InterpolatePaths, NV); 269 WGL_SET_PROC_SUFFIX(TransformPath, NV); 270 WGL_SET_PROC_SUFFIX(PathParameteriv, NV); 271 WGL_SET_PROC_SUFFIX(PathParameteri, NV); 272 WGL_SET_PROC_SUFFIX(PathParameterfv, NV); 273 WGL_SET_PROC_SUFFIX(PathParameterf, NV); 274 WGL_SET_PROC_SUFFIX(PathDashArray, NV); 275 WGL_SET_PROC_SUFFIX(GenPaths, NV); 276 WGL_SET_PROC_SUFFIX(DeletePaths, NV); 277 WGL_SET_PROC_SUFFIX(IsPath, NV); 278 WGL_SET_PROC_SUFFIX(PathStencilFunc, NV); 279 WGL_SET_PROC_SUFFIX(PathStencilDepthOffset, NV); 280 WGL_SET_PROC_SUFFIX(StencilFillPath, NV); 281 WGL_SET_PROC_SUFFIX(StencilStrokePath, NV); 282 WGL_SET_PROC_SUFFIX(StencilFillPathInstanced, NV); 283 WGL_SET_PROC_SUFFIX(StencilStrokePathInstanced, NV); 284 WGL_SET_PROC_SUFFIX(PathCoverDepthFunc, NV); 285 WGL_SET_PROC_SUFFIX(PathColorGen, NV); 286 WGL_SET_PROC_SUFFIX(PathTexGen, NV); 287 WGL_SET_PROC_SUFFIX(PathFogGen, NV); 288 WGL_SET_PROC_SUFFIX(CoverFillPath, NV); 289 WGL_SET_PROC_SUFFIX(CoverStrokePath, NV); 290 WGL_SET_PROC_SUFFIX(CoverFillPathInstanced, NV); 291 WGL_SET_PROC_SUFFIX(CoverStrokePathInstanced, NV); 292 WGL_SET_PROC_SUFFIX(GetPathParameteriv, NV); 293 WGL_SET_PROC_SUFFIX(GetPathParameterfv, NV); 294 WGL_SET_PROC_SUFFIX(GetPathCommands, NV); 295 WGL_SET_PROC_SUFFIX(GetPathCoords, NV); 296 WGL_SET_PROC_SUFFIX(GetPathDashArray, NV); 297 WGL_SET_PROC_SUFFIX(GetPathMetrics, NV); 298 WGL_SET_PROC_SUFFIX(GetPathMetricRange, NV); 299 WGL_SET_PROC_SUFFIX(GetPathSpacing, NV); 300 WGL_SET_PROC_SUFFIX(GetPathColorGeniv, NV); 301 WGL_SET_PROC_SUFFIX(GetPathColorGenfv, NV); 302 WGL_SET_PROC_SUFFIX(GetPathTexGeniv, NV); 303 WGL_SET_PROC_SUFFIX(GetPathTexGenfv, NV); 304 WGL_SET_PROC_SUFFIX(IsPointInFillPath, NV); 305 WGL_SET_PROC_SUFFIX(IsPointInStrokePath, NV); 306 WGL_SET_PROC_SUFFIX(GetPathLength, NV); 307 WGL_SET_PROC_SUFFIX(PointAlongPath, NV); 308 } 309 310 interface->fBindingsExported = kDesktop_GrGLBinding; 311 312 return interface; 313 } else { 314 return NULL; 315 } 316} 317