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