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