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