Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 #include "SkTypes.h"
      8 #if defined(SK_BUILD_FOR_WIN32)
      9 
     10 #include "SkLeanWindows.h"
     11 
     12 #include "gl/GrGLInterface.h"
     13 #include "gl/GrGLAssembleInterface.h"
     14 #include "gl/GrGLUtil.h"
     15 
     16 class AutoLibraryUnload {
     17 public:
     18     AutoLibraryUnload(const char* moduleName) {
     19         fModule = LoadLibraryA(moduleName);
     20     }
     21     ~AutoLibraryUnload() {
     22         if (fModule) {
     23             FreeLibrary(fModule);
     24         }
     25     }
     26     HMODULE get() const { return fModule; }
     27 
     28 private:
     29     HMODULE fModule;
     30 };
     31 
     32 class GLProcGetter {
     33 public:
     34     GLProcGetter() : fGLLib("opengl32.dll") {}
     35 
     36     bool isInitialized() const { return SkToBool(fGLLib.get()); }
     37 
     38     GrGLFuncPtr getProc(const char name[]) const {
     39         GrGLFuncPtr proc;
     40         if ((proc = (GrGLFuncPtr) GetProcAddress(fGLLib.get(), name))) {
     41             return proc;
     42         }
     43         if ((proc = (GrGLFuncPtr) wglGetProcAddress(name))) {
     44             return proc;
     45         }
     46         return nullptr;
     47     }
     48 
     49 private:
     50     AutoLibraryUnload fGLLib;
     51 };
     52 
     53 static GrGLFuncPtr win_get_gl_proc(void* ctx, const char name[]) {
     54     SkASSERT(ctx);
     55     SkASSERT(wglGetCurrentContext());
     56     const GLProcGetter* getter = (const GLProcGetter*) ctx;
     57     return getter->getProc(name);
     58 }
     59 
     60 /*
     61  * Windows makes the GL funcs all be __stdcall instead of __cdecl :(
     62  * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall.
     63  * Otherwise, a springboard would be needed that hides the calling convention.
     64  */
     65 const GrGLInterface* GrGLCreateNativeInterface() {
     66     if (nullptr == wglGetCurrentContext()) {
     67         return nullptr;
     68     }
     69 
     70     GLProcGetter getter;
     71     if (!getter.isInitialized()) {
     72         return nullptr;
     73     }
     74 
     75     GrGLGetStringProc getString = (GrGLGetStringProc)getter.getProc("glGetString");
     76     if (nullptr == getString) {
     77         return nullptr;
     78     }
     79     const char* verStr = reinterpret_cast<const char*>(getString(GR_GL_VERSION));
     80     GrGLStandard standard = GrGLGetStandardInUseFromString(verStr);
     81 
     82     if (kGLES_GrGLStandard == standard) {
     83         return GrGLAssembleGLESInterface(&getter, win_get_gl_proc);
     84     } else if (kGL_GrGLStandard == standard) {
     85         return GrGLAssembleGLInterface(&getter, win_get_gl_proc);
     86     }
     87     return nullptr;
     88 }
     89 
     90 #endif//defined(SK_BUILD_FOR_WIN32)
     91