Index: src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp |
diff --git a/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp b/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..e99aa15eb7963dfc29f80d1b3f1fedcab6c85f1a |
--- /dev/null |
+++ b/src/gpu/gl/win/SkCreatePlatformGLContext_win.cpp |
@@ -0,0 +1,200 @@ |
+/* |
+ * 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 "gl/SkGLContext.h" |
+ |
+#include <windows.h> |
+#include <GL/GL.h> |
+#include "win/SkWGL.h" |
+ |
+#define WIN32_LEAN_AND_MEAN |
+#include <windows.h> |
+ |
+namespace { |
+ |
+class WinGLContext : public SkGLContext { |
+public: |
+ WinGLContext(GrGLStandard forcedGpuAPI); |
+ ~WinGLContext() override; |
+ |
+private: |
+ void destroyGLContext(); |
+ |
+ void onPlatformMakeCurrent() const override; |
+ void onPlatformSwapBuffers() const override; |
+ GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override; |
+ |
+ HWND fWindow; |
+ HDC fDeviceContext; |
+ HGLRC fGlRenderContext; |
+ static ATOM gWC; |
+ SkWGLPbufferContext* fPbufferContext; |
+}; |
+ |
+ATOM WinGLContext::gWC = 0; |
+ |
+WinGLContext::WinGLContext(GrGLStandard forcedGpuAPI) |
+ : fWindow(nullptr) |
+ , fDeviceContext(nullptr) |
+ , fGlRenderContext(0) |
+ , fPbufferContext(nullptr) { |
+ HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr); |
+ |
+ if (!gWC) { |
+ WNDCLASS wc; |
+ wc.cbClsExtra = 0; |
+ wc.cbWndExtra = 0; |
+ wc.hbrBackground = nullptr; |
+ wc.hCursor = LoadCursor(nullptr, IDC_ARROW); |
+ wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION); |
+ wc.hInstance = hInstance; |
+ wc.lpfnWndProc = (WNDPROC) DefWindowProc; |
+ wc.lpszClassName = TEXT("Griffin"); |
+ wc.lpszMenuName = nullptr; |
+ wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; |
+ |
+ gWC = RegisterClass(&wc); |
+ if (!gWC) { |
+ SkDebugf("Could not register window class.\n"); |
+ return; |
+ } |
+ } |
+ |
+ if (!(fWindow = CreateWindow(TEXT("Griffin"), |
+ TEXT("The Invisible Man"), |
+ WS_OVERLAPPEDWINDOW, |
+ 0, 0, 1, 1, |
+ nullptr, nullptr, |
+ hInstance, nullptr))) { |
+ SkDebugf("Could not create window.\n"); |
+ return; |
+ } |
+ |
+ if (!(fDeviceContext = GetDC(fWindow))) { |
+ SkDebugf("Could not get device context.\n"); |
+ this->destroyGLContext(); |
+ return; |
+ } |
+ // Requesting a Core profile would bar us from using NVPR. So we request |
+ // compatibility profile or GL ES. |
+ SkWGLContextRequest contextType = |
+ kGLES_GrGLStandard == forcedGpuAPI ? |
+ kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest; |
+ |
+ fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType); |
+ |
+ HDC dc; |
+ HGLRC glrc; |
+ |
+ if (nullptr == fPbufferContext) { |
+ if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) { |
+ SkDebugf("Could not create rendering context.\n"); |
+ this->destroyGLContext(); |
+ return; |
+ } |
+ dc = fDeviceContext; |
+ glrc = fGlRenderContext; |
+ } else { |
+ ReleaseDC(fWindow, fDeviceContext); |
+ fDeviceContext = 0; |
+ DestroyWindow(fWindow); |
+ fWindow = 0; |
+ |
+ dc = fPbufferContext->getDC(); |
+ glrc = fPbufferContext->getGLRC(); |
+ } |
+ |
+ if (!(wglMakeCurrent(dc, glrc))) { |
+ SkDebugf("Could not set the context.\n"); |
+ this->destroyGLContext(); |
+ return; |
+ } |
+ |
+ SkAutoTUnref<const GrGLInterface> gl(GrGLCreateNativeInterface()); |
+ if (nullptr == gl.get()) { |
+ SkDebugf("Could not create GL interface.\n"); |
+ this->destroyGLContext(); |
+ return; |
+ } |
+ if (!gl->validate()) { |
+ SkDebugf("Could not validate GL interface.\n"); |
+ this->destroyGLContext(); |
+ return; |
+ } |
+ |
+ this->init(gl.release()); |
+} |
+ |
+WinGLContext::~WinGLContext() { |
+ this->teardown(); |
+ this->destroyGLContext(); |
+} |
+ |
+void WinGLContext::destroyGLContext() { |
+ SkSafeSetNull(fPbufferContext); |
+ if (fGlRenderContext) { |
+ wglDeleteContext(fGlRenderContext); |
+ fGlRenderContext = 0; |
+ } |
+ if (fWindow && fDeviceContext) { |
+ ReleaseDC(fWindow, fDeviceContext); |
+ fDeviceContext = 0; |
+ } |
+ if (fWindow) { |
+ DestroyWindow(fWindow); |
+ fWindow = 0; |
+ } |
+} |
+ |
+void WinGLContext::onPlatformMakeCurrent() const { |
+ HDC dc; |
+ HGLRC glrc; |
+ |
+ if (nullptr == fPbufferContext) { |
+ dc = fDeviceContext; |
+ glrc = fGlRenderContext; |
+ } else { |
+ dc = fPbufferContext->getDC(); |
+ glrc = fPbufferContext->getGLRC(); |
+ } |
+ |
+ if (!wglMakeCurrent(dc, glrc)) { |
+ SkDebugf("Could not create rendering context.\n"); |
+ } |
+} |
+ |
+void WinGLContext::onPlatformSwapBuffers() const { |
+ HDC dc; |
+ |
+ if (nullptr == fPbufferContext) { |
+ dc = fDeviceContext; |
+ } else { |
+ dc = fPbufferContext->getDC(); |
+ } |
+ if (!SwapBuffers(dc)) { |
+ SkDebugf("Could not complete SwapBuffers.\n"); |
+ } |
+} |
+ |
+GrGLFuncPtr WinGLContext::onPlatformGetProcAddress(const char* name) const { |
+ return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name)); |
+} |
+ |
+} // anonymous namespace |
+ |
+SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI, SkGLContext* shareContext) { |
+ SkASSERT(!shareContext); |
+ if (shareContext) { |
+ return nullptr; |
+ } |
+ WinGLContext* ctx = new WinGLContext(forcedGpuAPI); |
+ if (!ctx->isValid()) { |
+ delete ctx; |
+ return nullptr; |
+ } |
+ return ctx; |
+} |