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 
     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
     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 
     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