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