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 "../GLWindowContext.h"
10 #include "gl/GrGLInterface.h"
11 #include "WindowContextFactory_win.h"
12 #include "win/SkWGL.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
NewGLForWin(HWND,const DisplayParams &)25 WindowContext* NewGLForWin(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 typedef GLWindowContext INHERITED;
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 // Look to see if RenderDoc is attached. If so, re-create the context with a core profile
76 if (wglMakeCurrent(dc, fHGLRC)) {
77 auto interface = GrGLMakeNativeInterface();
78 bool renderDocAttached = interface->hasExtension("GL_EXT_debug_tool");
79 interface.reset(nullptr);
80 if (renderDocAttached) {
81 wglDeleteContext(fHGLRC);
82 fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */,
83 kGLPreferCoreProfile_SkWGLContextRequest);
84 if (NULL == fHGLRC) {
85 return nullptr;
86 }
87 }
88 }
89
90 if (wglMakeCurrent(dc, fHGLRC)) {
91 glClearStencil(0);
92 glClearColor(0, 0, 0, 0);
93 glStencilMask(0xffffffff);
94 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
95
96 // use DescribePixelFormat to get the stencil and color bit depth.
97 int pixelFormat = GetPixelFormat(dc);
98 PIXELFORMATDESCRIPTOR pfd;
99 DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
100 fStencilBits = pfd.cStencilBits;
101
102 // Get sample count if the MSAA WGL extension is present
103 SkWGLExtensions extensions;
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 = SkTMax(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 sk_app {
143 namespace window_context_factory {
144
NewGLForWin(HWND wnd,const DisplayParams & params)145 WindowContext* NewGLForWin(HWND wnd, const DisplayParams& params) {
146 GLWindowContext_win* ctx = new GLWindowContext_win(wnd, params);
147 if (!ctx->isValid()) {
148 delete ctx;
149 return nullptr;
150 }
151 return ctx;
152 }
153
154 } // namespace window_context_factory
155 } // namespace sk_app
156
157 #endif
158