• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #include "tools/gpu/gl/GLTestContext.h"
10 
11 #if defined(_M_ARM64)
12 
13 namespace sk_gpu_test {
14 
CreatePlatformGLTestContext(GrGLStandard,GLTestContext *)15 GLTestContext* CreatePlatformGLTestContext(GrGLStandard, GLTestContext*) { return nullptr; }
16 
17 }  // namespace sk_gpu_test
18 
19 #else
20 
21 #include <windows.h>
22 #include <GL/GL.h>
23 #include "src/utils/win/SkWGL.h"
24 
25 #include <windows.h>
26 
27 namespace {
28 
context_restorer()29 std::function<void()> context_restorer() {
30     auto glrc = wglGetCurrentContext();
31     auto dc = wglGetCurrentDC();
32     return [glrc, dc] { wglMakeCurrent(dc, glrc); };
33 }
34 
35 class WinGLTestContext : public sk_gpu_test::GLTestContext {
36 public:
37     WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext);
38     ~WinGLTestContext() override;
39 
40 private:
41     void destroyGLContext();
42 
43     void onPlatformMakeNotCurrent() const override;
44     void onPlatformMakeCurrent() const override;
45     std::function<void()> onPlatformGetAutoContextRestore() const override;
46     void onPlatformSwapBuffers() const override;
47     GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
48 
49     HWND fWindow;
50     HDC fDeviceContext;
51     HGLRC fGlRenderContext;
52     static ATOM gWC;
53     sk_sp<SkWGLPbufferContext> fPbufferContext;
54 };
55 
56 ATOM WinGLTestContext::gWC = 0;
57 
WinGLTestContext(GrGLStandard forcedGpuAPI,WinGLTestContext * shareContext)58 WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
59     : fWindow(nullptr)
60     , fDeviceContext(nullptr)
61     , fGlRenderContext(0)
62     , fPbufferContext(nullptr) {
63     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
64 
65     if (!gWC) {
66         WNDCLASS wc;
67         wc.cbClsExtra = 0;
68         wc.cbWndExtra = 0;
69         wc.hbrBackground = nullptr;
70         wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
71         wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
72         wc.hInstance = hInstance;
73         wc.lpfnWndProc = (WNDPROC) DefWindowProc;
74         wc.lpszClassName = TEXT("Griffin");
75         wc.lpszMenuName = nullptr;
76         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
77 
78         gWC = RegisterClass(&wc);
79         if (!gWC) {
80             SkDebugf("Could not register window class.\n");
81             return;
82         }
83     }
84 
85     if (!(fWindow = CreateWindow(TEXT("Griffin"),
86                                  TEXT("The Invisible Man"),
87                                  WS_OVERLAPPEDWINDOW,
88                                  0, 0, 1, 1,
89                                  nullptr, nullptr,
90                                  hInstance, nullptr))) {
91         SkDebugf("Could not create window.\n");
92         return;
93     }
94 
95     if (!(fDeviceContext = GetDC(fWindow))) {
96         SkDebugf("Could not get device context.\n");
97         this->destroyGLContext();
98         return;
99     }
100     // Requesting a Core profile would bar us from using NVPR. So we request
101     // compatibility profile or GL ES.
102     SkWGLContextRequest contextType =
103         kGLES_GrGLStandard == forcedGpuAPI ?
104         kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
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 = 0;
127         DestroyWindow(fWindow);
128         fWindow = 0;
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     auto gl = GrGLMakeNativeInterface();
142     if (!gl) {
143         SkDebugf("Could not create GL interface.\n");
144         this->destroyGLContext();
145         return;
146     }
147     if (!gl->validate()) {
148         SkDebugf("Could not validate GL interface.\n");
149         this->destroyGLContext();
150         return;
151     }
152 
153     this->init(std::move(gl));
154 }
155 
~WinGLTestContext()156 WinGLTestContext::~WinGLTestContext() {
157     this->teardown();
158     this->destroyGLContext();
159 }
160 
destroyGLContext()161 void WinGLTestContext::destroyGLContext() {
162     fPbufferContext = nullptr;
163     if (fGlRenderContext) {
164         // This deletes the context immediately even if it is current.
165         wglDeleteContext(fGlRenderContext);
166         fGlRenderContext = 0;
167     }
168     if (fWindow && fDeviceContext) {
169         ReleaseDC(fWindow, fDeviceContext);
170         fDeviceContext = 0;
171     }
172     if (fWindow) {
173         DestroyWindow(fWindow);
174         fWindow = 0;
175     }
176 }
177 
onPlatformMakeNotCurrent() const178 void WinGLTestContext::onPlatformMakeNotCurrent() const {
179     if (!wglMakeCurrent(NULL, NULL)) {
180         SkDebugf("Could not null out the rendering context.\n");
181     }
182 }
183 
onPlatformMakeCurrent() const184 void WinGLTestContext::onPlatformMakeCurrent() const {
185     HDC dc;
186     HGLRC glrc;
187 
188     if (nullptr == fPbufferContext) {
189         dc = fDeviceContext;
190         glrc = fGlRenderContext;
191     } else {
192         dc = fPbufferContext->getDC();
193         glrc = fPbufferContext->getGLRC();
194     }
195 
196     if (!wglMakeCurrent(dc, glrc)) {
197         SkDebugf("Could not create rendering context.\n");
198     }
199 }
200 
onPlatformGetAutoContextRestore() const201 std::function<void()> WinGLTestContext::onPlatformGetAutoContextRestore() const {
202     if (wglGetCurrentContext() == fGlRenderContext) {
203         return nullptr;
204     }
205     return context_restorer();
206 }
207 
onPlatformSwapBuffers() const208 void WinGLTestContext::onPlatformSwapBuffers() const {
209     HDC dc;
210 
211     if (nullptr == fPbufferContext) {
212         dc = fDeviceContext;
213     } else {
214         dc = fPbufferContext->getDC();
215     }
216     if (!SwapBuffers(dc)) {
217         SkDebugf("Could not complete SwapBuffers.\n");
218     }
219 }
220 
onPlatformGetProcAddress(const char * name) const221 GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
222     return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
223 }
224 
225 } // anonymous namespace
226 
227 namespace sk_gpu_test {
CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,GLTestContext * shareContext)228 GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
229                                            GLTestContext *shareContext) {
230     WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
231     WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
232     if (!ctx->isValid()) {
233         delete ctx;
234         return nullptr;
235     }
236     return ctx;
237 }
238 }  // namespace sk_gpu_test
239 
240 #endif
241