Home | History | Annotate | Download | only in win
      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 
     27 class AutoLibraryUnload {
     28 public:
     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 
     39 private:
     40     HMODULE fModule;
     41 };
     42 
     43 const 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