Home | History | Annotate | Download | only in mac
      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 "gl/GrGLExtensions.h"
     12 #include "../GrGLUtil.h"
     13 
     14 #include <dlfcn.h>
     15 
     16 // We get the proc addresss of all GL functions dynamically because we sometimes link against
     17 // alternative GL implementations (e.g. MESA) in addition to the native GL implementation.
     18 class GLLoader {
     19 public:
     20     GLLoader() {
     21         fLibrary = dlopen(
     22                     "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
     23                     RTLD_LAZY);
     24     }
     25     ~GLLoader() {
     26         if (NULL != fLibrary) {
     27             dlclose(fLibrary);
     28         }
     29     }
     30     void* handle() {
     31         return NULL == fLibrary ? RTLD_DEFAULT : fLibrary;
     32     }
     33 private:
     34     void* fLibrary;
     35 };
     36 
     37 static void* GetProcAddress(const char* name) {
     38     static GLLoader gLoader;
     39     return dlsym(gLoader.handle(), name);
     40 }
     41 
     42 #define GET_PROC(name) (interface->f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name)))
     43 #define GET_PROC_SUFFIX(name, suffix) (interface->f ## name = ((GrGL ## name ## Proc) GetProcAddress("gl" #name #suffix)))
     44 
     45 const GrGLInterface* GrGLCreateNativeInterface() {
     46     // The gl functions are not context-specific so we create one global interface
     47     static SkAutoTUnref<GrGLInterface> glInterface;
     48     if (!glInterface.get()) {
     49         GrGLInterface* interface = new GrGLInterface;
     50 
     51         GrGLGetStringProc glGetString = (GrGLGetStringProc) GetProcAddress("glGetString");
     52         GrGLGetStringiProc glGetStringi = (GrGLGetStringiProc) GetProcAddress("glGetStringi");
     53         GrGLGetIntegervProc glGetIntegerv = (GrGLGetIntegervProc) GetProcAddress("glGetIntegerv");
     54 
     55         glInterface.reset(interface);
     56         const char* verStr = (const char*) glGetString(GR_GL_VERSION);
     57         GrGLVersion ver = GrGLGetVersionFromString(verStr);
     58         GrGLExtensions extensions;
     59         if (!extensions.init(kDesktop_GrGLBinding, glGetString, glGetStringi, glGetIntegerv)) {
     60             glInterface.reset(NULL);
     61             return NULL;
     62         }
     63         interface->fBindingsExported = kDesktop_GrGLBinding;
     64 
     65         GET_PROC(ActiveTexture);
     66         GET_PROC(AttachShader);
     67         GET_PROC(BeginQuery);
     68         GET_PROC(BindAttribLocation);
     69         GET_PROC(BindBuffer);
     70         if (ver >= GR_GL_VER(3,0)) {
     71             GET_PROC(BindFragDataLocation);
     72         }
     73         GET_PROC(BindTexture);
     74         GET_PROC(BlendFunc);
     75 
     76         if (ver >= GR_GL_VER(1,4) ||
     77             extensions.has("GL_ARB_imaging") ||
     78             extensions.has("GL_EXT_blend_color")) {
     79             GET_PROC(BlendColor);
     80         }
     81 
     82         GET_PROC(BufferData);
     83         GET_PROC(BufferSubData);
     84         GET_PROC(Clear);
     85         GET_PROC(ClearColor);
     86         GET_PROC(ClearStencil);
     87         GET_PROC(ColorMask);
     88         GET_PROC(CompileShader);
     89         GET_PROC(CompressedTexImage2D);
     90         GET_PROC(CopyTexSubImage2D);
     91         GET_PROC(CreateProgram);
     92         GET_PROC(CreateShader);
     93         GET_PROC(CullFace);
     94         GET_PROC(DeleteBuffers);
     95         GET_PROC(DeleteProgram);
     96         GET_PROC(DeleteQueries);
     97         GET_PROC(DeleteShader);
     98         GET_PROC(DeleteTextures);
     99         GET_PROC(DepthMask);
    100         GET_PROC(Disable);
    101         GET_PROC(DisableVertexAttribArray);
    102         GET_PROC(DrawArrays);
    103         GET_PROC(DrawBuffer);
    104         GET_PROC(DrawBuffers);
    105         GET_PROC(DrawElements);
    106         GET_PROC(Enable);
    107         GET_PROC(EnableVertexAttribArray);
    108         GET_PROC(EndQuery);
    109         GET_PROC(Finish);
    110         GET_PROC(Flush);
    111         GET_PROC(FrontFace);
    112         GET_PROC(GenBuffers);
    113         GET_PROC(GenerateMipmap);
    114         GET_PROC(GenQueries);
    115         GET_PROC(GetBufferParameteriv);
    116         GET_PROC(GetError);
    117         GET_PROC(GetIntegerv);
    118         GET_PROC(GetProgramInfoLog);
    119         GET_PROC(GetProgramiv);
    120         GET_PROC(GetQueryiv);
    121         GET_PROC(GetQueryObjectiv);
    122         GET_PROC(GetQueryObjectuiv);
    123         GET_PROC(GetShaderInfoLog);
    124         GET_PROC(GetShaderiv);
    125         GET_PROC(GetString);
    126         GET_PROC(GetStringi);
    127         GET_PROC(GetTexLevelParameteriv);
    128         GET_PROC(GenTextures);
    129         GET_PROC(GetUniformLocation);
    130         GET_PROC(LineWidth);
    131         GET_PROC(LinkProgram);
    132         GET_PROC(MapBuffer);
    133         GET_PROC(PixelStorei);
    134         GET_PROC(ReadBuffer);
    135         GET_PROC(ReadPixels);
    136         GET_PROC(Scissor);
    137         GET_PROC(ShaderSource);
    138         GET_PROC(StencilFunc);
    139         GET_PROC(StencilFuncSeparate);
    140         GET_PROC(StencilMask);
    141         GET_PROC(StencilMaskSeparate);
    142         GET_PROC(StencilOp);
    143         GET_PROC(StencilOpSeparate);
    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     glInterface.get()->ref();
    240     return glInterface.get();
    241 }
    242