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