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 #include "gl/GrGLInterface.h"
     10 #include "gl/GrGLAssembleInterface.h"
     11 #include "gl/GrGLUtil.h"
     12 #define WIN32_LEAN_AND_MEAN
     13 #include <windows.h>
     14 
     15 class AutoLibraryUnload {
     16 public:
     17     AutoLibraryUnload(const char* moduleName) {
     18         fModule = LoadLibrary(moduleName);
     19     }
     20     ~AutoLibraryUnload() {
     21         if (fModule) {
     22             FreeLibrary(fModule);
     23         }
     24     }
     25     HMODULE get() const { return fModule; }
     26 
     27 private:
     28     HMODULE fModule;
     29 };
     30 
     31 class GLProcGetter {
     32 public:
     33     GLProcGetter() : fGLLib("opengl32.dll") {}
     34 
     35     bool isInitialized() const { return SkToBool(fGLLib.get()); }
     36 
     37     GrGLFuncPtr getProc(const char name[]) const {
     38         GrGLFuncPtr proc;
     39         if ((proc = (GrGLFuncPtr) GetProcAddress(fGLLib.get(), name))) {
     40             return proc;
     41         }
     42         if ((proc = (GrGLFuncPtr) wglGetProcAddress(name))) {
     43             return proc;
     44         }
     45         return NULL;
     46     }
     47 
     48 private:
     49     AutoLibraryUnload fGLLib;
     50 };
     51 
     52 static GrGLFuncPtr win_get_gl_proc(void* ctx, const char name[]) {
     53     SkASSERT(ctx);
     54     SkASSERT(wglGetCurrentContext());
     55     const GLProcGetter* getter = (const GLProcGetter*) ctx;
     56     return getter->getProc(name);
     57 }
     58 
     59 /*
     60  * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
     61  * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
     62  * Otherwise, a springboard would be needed that hides the calling convention.
     63  */
     64 const GrGLInterface* GrGLCreateNativeInterface() {
     65     if (NULL == wglGetCurrentContext()) {
     66         return NULL;
     67     }
     68 
     69     GLProcGetter getter;
     70     if (!getter.isInitialized()) {
     71         return NULL;
     72     }
     73 
     74     GrGLGetStringProc getString = (GrGLGetStringProc)getter.getProc("glGetString");
     75     if (NULL == getString) {
     76         return NULL;
     77     }
     78     const char* verStr = reinterpret_cast<const char*>(getString(GR_GL_VERSION));
     79     GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
     80 
     81     if (kGLES_GrGLStandard == standard) {
     82         return GrGLAssembleGLESInterface(&getter, win_get_gl_proc);
     83     } else if (kGL_GrGLStandard == standard) {
     84         return GrGLAssembleGLInterface(&getter, win_get_gl_proc);
     85     }
     86     return NULL;
     87 }
     88