diff options
Diffstat (limited to 'src/gpu/gl/win/GrGLMakeNativeInterface_win.cpp')
-rw-r--r-- | src/gpu/gl/win/GrGLMakeNativeInterface_win.cpp | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/src/gpu/gl/win/GrGLMakeNativeInterface_win.cpp b/src/gpu/gl/win/GrGLMakeNativeInterface_win.cpp new file mode 100644 index 0000000000..77db59a754 --- /dev/null +++ b/src/gpu/gl/win/GrGLMakeNativeInterface_win.cpp @@ -0,0 +1,92 @@ +/* + * Copyright 2011 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +#include "SkTypes.h" +#if defined(SK_BUILD_FOR_WIN32) + +#include "SkLeanWindows.h" + +#include "gl/GrGLInterface.h" +#include "gl/GrGLAssembleInterface.h" +#include "gl/GrGLUtil.h" + +class AutoLibraryUnload { +public: + AutoLibraryUnload(const char* moduleName) { + fModule = LoadLibraryA(moduleName); + } + ~AutoLibraryUnload() { + if (fModule) { + FreeLibrary(fModule); + } + } + HMODULE get() const { return fModule; } + +private: + HMODULE fModule; +}; + +class GLProcGetter { +public: + GLProcGetter() : fGLLib("opengl32.dll") {} + + bool isInitialized() const { return SkToBool(fGLLib.get()); } + + GrGLFuncPtr getProc(const char name[]) const { + GrGLFuncPtr proc; + if ((proc = (GrGLFuncPtr) GetProcAddress(fGLLib.get(), name))) { + return proc; + } + if ((proc = (GrGLFuncPtr) wglGetProcAddress(name))) { + return proc; + } + return nullptr; + } + +private: + AutoLibraryUnload fGLLib; +}; + +static GrGLFuncPtr win_get_gl_proc(void* ctx, const char name[]) { + SkASSERT(ctx); + SkASSERT(wglGetCurrentContext()); + const GLProcGetter* getter = (const GLProcGetter*) ctx; + return getter->getProc(name); +} + +/* + * Windows makes the GL funcs all be __stdcall instead of __cdecl :( + * This implementation will only work if GR_GL_FUNCTION_TYPE is __stdcall. + * Otherwise, a springboard would be needed that hides the calling convention. + */ +sk_sp<const GrGLInterface> GrGLMakeNativeInterface() { + if (nullptr == wglGetCurrentContext()) { + return nullptr; + } + + GLProcGetter getter; + if (!getter.isInitialized()) { + return nullptr; + } + + GrGLGetStringProc getString = (GrGLGetStringProc)getter.getProc("glGetString"); + if (nullptr == getString) { + return nullptr; + } + const char* verStr = reinterpret_cast<const char*>(getString(GR_GL_VERSION)); + GrGLStandard standard = GrGLGetStandardInUseFromString(verStr); + + if (kGLES_GrGLStandard == standard) { + return GrGLAssembleGLESInterface(&getter, win_get_gl_proc); + } else if (kGL_GrGLStandard == standard) { + return GrGLAssembleGLInterface(&getter, win_get_gl_proc); + } + return nullptr; +} + +const GrGLInterface* GrGLCreateNativeInterface() { return GrGLMakeNativeInterface().release(); } + +#endif//defined(SK_BUILD_FOR_WIN32) |