Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
CreatePlatformGLTestContext_win.cpp
Go to the documentation of this file.
1
2/*
3 * Copyright 2011 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
10
11#if defined(_M_ARM64)
12
13namespace sk_gpu_test {
14
15GLTestContext* CreatePlatformGLTestContext(GrGLStandard, GLTestContext*) { return nullptr; }
16
17} // namespace sk_gpu_test
18
19#else
20
21#include <windows.h>
22#include <GL/GL.h>
24
25#include <windows.h>
26
27namespace {
28
29std::function<void()> context_restorer() {
30 auto glrc = wglGetCurrentContext();
31 auto dc = wglGetCurrentDC();
32 return [glrc, dc] { wglMakeCurrent(dc, glrc); };
33}
34
35class WinGLTestContext : public sk_gpu_test::GLTestContext {
36public:
37 WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext);
38 ~WinGLTestContext() override;
39
40private:
41 void destroyGLContext();
42
43 void onPlatformMakeNotCurrent() const override;
44 void onPlatformMakeCurrent() const override;
45 std::function<void()> onPlatformGetAutoContextRestore() const override;
46 GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
47
48 HWND fWindow;
49 HDC fDeviceContext;
50 HGLRC fGlRenderContext;
51 static ATOM gWC;
52 sk_sp<SkWGLPbufferContext> fPbufferContext;
53};
54
55ATOM WinGLTestContext::gWC = 0;
56
57WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
58 : fWindow(nullptr)
59 , fDeviceContext(nullptr)
60 , fGlRenderContext(nullptr)
61 , fPbufferContext(nullptr) {
62 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
63
64 if (!gWC) {
65 WNDCLASS wc;
66 wc.cbClsExtra = 0;
67 wc.cbWndExtra = 0;
68 wc.hbrBackground = nullptr;
69 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
70 wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
71 wc.hInstance = hInstance;
72 wc.lpfnWndProc = (WNDPROC) DefWindowProc;
73 wc.lpszClassName = TEXT("Griffin");
74 wc.lpszMenuName = nullptr;
75 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
76
77 gWC = RegisterClass(&wc);
78 if (!gWC) {
79 SkDebugf("Could not register window class.\n");
80 return;
81 }
82 }
83
84 if (!(fWindow = CreateWindow(TEXT("Griffin"),
85 TEXT("The Invisible Man"),
86 WS_OVERLAPPEDWINDOW,
87 0, 0, 1, 1,
88 nullptr, nullptr,
89 hInstance, nullptr))) {
90 SkDebugf("Could not create window.\n");
91 return;
92 }
93
94 if (!(fDeviceContext = GetDC(fWindow))) {
95 SkDebugf("Could not get device context.\n");
96 this->destroyGLContext();
97 return;
98 }
99
100 // We request a compatibility context since glMultiDrawArraysIndirect, apparently, doesn't
101 // work correctly on Intel Iris GPUs with the core profile (skbug.com/11787).
102 SkWGLContextRequest contextType =
105
106 HGLRC winShareContext = nullptr;
107 if (shareContext) {
108 winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
109 : shareContext->fGlRenderContext;
110 }
111 fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, contextType, winShareContext);
112
113 HDC dc;
114 HGLRC glrc;
115 if (nullptr == fPbufferContext) {
116 if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType,
117 winShareContext))) {
118 SkDebugf("Could not create rendering context.\n");
119 this->destroyGLContext();
120 return;
121 }
122 dc = fDeviceContext;
123 glrc = fGlRenderContext;
124 } else {
125 ReleaseDC(fWindow, fDeviceContext);
126 fDeviceContext = nullptr;
127 DestroyWindow(fWindow);
128 fWindow = nullptr;
129
130 dc = fPbufferContext->getDC();
131 glrc = fPbufferContext->getGLRC();
132 }
133
134 SkScopeExit restorer(context_restorer());
135 if (!(wglMakeCurrent(dc, glrc))) {
136 SkDebugf("Could not set the context.\n");
137 this->destroyGLContext();
138 return;
139 }
140
141#ifdef SK_GL
143 if (!gl) {
144 SkDebugf("Could not create GL interface.\n");
145 this->destroyGLContext();
146 return;
147 }
148 if (!gl->validate()) {
149 SkDebugf("Could not validate GL interface.\n");
150 this->destroyGLContext();
151 return;
152 }
153
154 this->init(std::move(gl));
155#else
156 // Allow the GLTestContext creation to succeed without a GrGLInterface to support
157 // GrContextFactory's persistent GL context workaround for Vulkan. We won't need the
158 // GrGLInterface since we're not running the GL backend.
159 this->init(nullptr);
160#endif
161}
162
163WinGLTestContext::~WinGLTestContext() {
164 this->teardown();
165 this->destroyGLContext();
166}
167
168void WinGLTestContext::destroyGLContext() {
169 fPbufferContext = nullptr;
170 if (fGlRenderContext) {
171 // This deletes the context immediately even if it is current.
172 wglDeleteContext(fGlRenderContext);
173 fGlRenderContext = nullptr;
174 }
175 if (fWindow && fDeviceContext) {
176 ReleaseDC(fWindow, fDeviceContext);
177 fDeviceContext = nullptr;
178 }
179 if (fWindow) {
180 DestroyWindow(fWindow);
181 fWindow = nullptr;
182 }
183}
184
185void WinGLTestContext::onPlatformMakeNotCurrent() const {
186 if (!wglMakeCurrent(nullptr, nullptr)) {
187 SkDebugf("Could not null out the rendering context.\n");
188 }
189}
190
191void WinGLTestContext::onPlatformMakeCurrent() const {
192 HDC dc;
193 HGLRC glrc;
194
195 if (nullptr == fPbufferContext) {
196 dc = fDeviceContext;
197 glrc = fGlRenderContext;
198 } else {
199 dc = fPbufferContext->getDC();
200 glrc = fPbufferContext->getGLRC();
201 }
202
203 if (!wglMakeCurrent(dc, glrc)) {
204 SkDebugf("Could not make current.\n");
205 }
206}
207
208std::function<void()> WinGLTestContext::onPlatformGetAutoContextRestore() const {
209 if (wglGetCurrentContext() == fGlRenderContext) {
210 return nullptr;
211 }
212 return context_restorer();
213}
214
215GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
216 return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
217}
218
219} // anonymous namespace
220
221namespace sk_gpu_test {
222GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
223 GLTestContext *shareContext) {
224 WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
225 WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
226 if (!ctx->isValid()) {
227 delete ctx;
228 return nullptr;
229 }
230 return ctx;
231}
232} // namespace sk_gpu_test
233
234#endif
SK_API sk_sp< const GrGLInterface > GrGLMakeNativeInterface()
void(* GrGLFuncPtr)()
GrGLStandard
Definition GrGLTypes.h:19
@ kGLES_GrGLStandard
Definition GrGLTypes.h:22
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor, SkWGLContextRequest context, HGLRC shareContext=nullptr)
SkWGLContextRequest
Definition SkWGL.h:119
@ kGLES_SkWGLContextRequest
Definition SkWGL.h:127
@ kGLPreferCompatibilityProfile_SkWGLContextRequest
Definition SkWGL.h:125
static sk_sp< SkWGLPbufferContext > Create(HDC parentDC, SkWGLContextRequest contextType, HGLRC shareContext)
const char * name
Definition fuchsia.cc:50
GLTestContext * CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, GLTestContext *shareContext)
init(device_serial, adb_binary)
Definition _adb_path.py:12
WORD ATOM
#define LoadIcon