1 2/* 3 * Copyright 2015 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 <Windows.h> 10#include <GL/gl.h> 11#include "../GLWindowContext.h" 12#include "GrGLInterface.h" 13#include "WindowContextFactory_win.h" 14#include "win/SkWGL.h" 15 16using sk_app::GLWindowContext; 17using sk_app::DisplayParams; 18 19namespace { 20 21class GLWindowContext_win : public GLWindowContext { 22public: 23 GLWindowContext_win(HWND, const DisplayParams&); 24 ~GLWindowContext_win() override; 25 26protected: 27 void onSwapBuffers() override; 28 29 sk_sp<const GrGLInterface> onInitializeContext() override; 30 void onDestroyContext() override; 31 32private: 33 HWND fHWND; 34 HGLRC fHGLRC; 35 36 typedef GLWindowContext INHERITED; 37}; 38 39GLWindowContext_win::GLWindowContext_win(HWND wnd, const DisplayParams& params) 40 : INHERITED(params) 41 , fHWND(wnd) 42 , fHGLRC(NULL) { 43 44 // any config code here (particularly for msaa)? 45 46 this->initializeContext(); 47} 48 49GLWindowContext_win::~GLWindowContext_win() { 50 this->destroyContext(); 51} 52 53sk_sp<const GrGLInterface> GLWindowContext_win::onInitializeContext() { 54 HDC dc = GetDC(fHWND); 55 56 fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */, 57 kGLPreferCompatibilityProfile_SkWGLContextRequest); 58 if (NULL == fHGLRC) { 59 return nullptr; 60 } 61 62 // Look to see if RenderDoc is attached. If so, re-create the context with a core profile 63 if (wglMakeCurrent(dc, fHGLRC)) { 64 auto interface = GrGLMakeNativeInterface(); 65 bool renderDocAttached = interface->hasExtension("GL_EXT_debug_tool"); 66 interface.reset(nullptr); 67 if (renderDocAttached) { 68 wglDeleteContext(fHGLRC); 69 fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */, 70 kGLPreferCoreProfile_SkWGLContextRequest); 71 if (NULL == fHGLRC) { 72 return nullptr; 73 } 74 } 75 } 76 77 if (wglMakeCurrent(dc, fHGLRC)) { 78 glClearStencil(0); 79 glClearColor(0, 0, 0, 0); 80 glStencilMask(0xffffffff); 81 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 82 83 // use DescribePixelFormat to get the stencil and color bit depth. 84 int pixelFormat = GetPixelFormat(dc); 85 PIXELFORMATDESCRIPTOR pfd; 86 DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd); 87 fStencilBits = pfd.cStencilBits; 88 89 // Get sample count if the MSAA WGL extension is present 90 SkWGLExtensions extensions; 91 if (extensions.hasExtension(dc, "WGL_ARB_multisample")) { 92 static const int kSampleCountAttr = SK_WGL_SAMPLES; 93 extensions.getPixelFormatAttribiv(dc, 94 pixelFormat, 95 0, 96 1, 97 &kSampleCountAttr, 98 &fSampleCount); 99 fSampleCount = SkTMax(fSampleCount, 1); 100 } else { 101 fSampleCount = 1; 102 } 103 104 RECT rect; 105 GetClientRect(fHWND, &rect); 106 fWidth = rect.right - rect.left; 107 fHeight = rect.bottom - rect.top; 108 glViewport(0, 0, fWidth, fHeight); 109 } 110 return GrGLMakeNativeInterface(); 111} 112 113 114void GLWindowContext_win::onDestroyContext() { 115 wglDeleteContext(fHGLRC); 116 fHGLRC = NULL; 117} 118 119 120void GLWindowContext_win::onSwapBuffers() { 121 HDC dc = GetDC((HWND)fHWND); 122 SwapBuffers(dc); 123 ReleaseDC((HWND)fHWND, dc); 124} 125 126 127} // anonymous namespace 128 129namespace sk_app { 130namespace window_context_factory { 131 132WindowContext* NewGLForWin(HWND wnd, const DisplayParams& params) { 133 GLWindowContext_win* ctx = new GLWindowContext_win(wnd, params); 134 if (!ctx->isValid()) { 135 delete ctx; 136 return nullptr; 137 } 138 return ctx; 139} 140 141} // namespace window_context_factory 142} // namespace sk_app 143