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