• 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 onPlatformMakeCurrent() const override;
44     std::function<void()> onPlatformGetAutoContextRestore() const override;
45     void onPlatformSwapBuffers() 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 
55 ATOM WinGLTestContext::gWC = 0;
56 
WinGLTestContext(GrGLStandard forcedGpuAPI,WinGLTestContext * shareContext)57 WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
58     : fWindow(nullptr)
59     , fDeviceContext(nullptr)
60     , fGlRenderContext(0)
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     // Requesting a Core profile would bar us from using NVPR. So we request
100     // compatibility profile or GL ES.
101     SkWGLContextRequest contextType =
102         kGLES_GrGLStandard == forcedGpuAPI ?
103         kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
104 
105     HGLRC winShareContext = nullptr;
106     if (shareContext) {
107         winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
108                                                         : shareContext->fGlRenderContext;
109     }
110     fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, contextType, winShareContext);
111 
112     HDC dc;
113     HGLRC glrc;
114     if (nullptr == fPbufferContext) {
115         if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType,
116                                                     winShareContext))) {
117             SkDebugf("Could not create rendering context.\n");
118             this->destroyGLContext();
119             return;
120         }
121         dc = fDeviceContext;
122         glrc = fGlRenderContext;
123     } else {
124         ReleaseDC(fWindow, fDeviceContext);
125         fDeviceContext = 0;
126         DestroyWindow(fWindow);
127         fWindow = 0;
128 
129         dc = fPbufferContext->getDC();
130         glrc = fPbufferContext->getGLRC();
131     }
132 
133     SkScopeExit restorer(context_restorer());
134     if (!(wglMakeCurrent(dc, glrc))) {
135         SkDebugf("Could not set the context.\n");
136         this->destroyGLContext();
137         return;
138     }
139 
140     auto gl = GrGLMakeNativeInterface();
141     if (!gl) {
142         SkDebugf("Could not create GL interface.\n");
143         this->destroyGLContext();
144         return;
145     }
146     if (!gl->validate()) {
147         SkDebugf("Could not validate GL interface.\n");
148         this->destroyGLContext();
149         return;
150     }
151 
152     this->init(std::move(gl));
153 }
154 
~WinGLTestContext()155 WinGLTestContext::~WinGLTestContext() {
156     this->teardown();
157     this->destroyGLContext();
158 }
159 
destroyGLContext()160 void WinGLTestContext::destroyGLContext() {
161     fPbufferContext = nullptr;
162     if (fGlRenderContext) {
163         // This deletes the context immediately even if it is current.
164         wglDeleteContext(fGlRenderContext);
165         fGlRenderContext = 0;
166     }
167     if (fWindow && fDeviceContext) {
168         ReleaseDC(fWindow, fDeviceContext);
169         fDeviceContext = 0;
170     }
171     if (fWindow) {
172         DestroyWindow(fWindow);
173         fWindow = 0;
174     }
175 }
176 
onPlatformMakeCurrent() const177 void WinGLTestContext::onPlatformMakeCurrent() const {
178     HDC dc;
179     HGLRC glrc;
180 
181     if (nullptr == fPbufferContext) {
182         dc = fDeviceContext;
183         glrc = fGlRenderContext;
184     } else {
185         dc = fPbufferContext->getDC();
186         glrc = fPbufferContext->getGLRC();
187     }
188 
189     if (!wglMakeCurrent(dc, glrc)) {
190         SkDebugf("Could not create rendering context.\n");
191     }
192 }
193 
onPlatformGetAutoContextRestore() const194 std::function<void()> WinGLTestContext::onPlatformGetAutoContextRestore() const {
195     if (wglGetCurrentContext() == fGlRenderContext) {
196         return nullptr;
197     }
198     return context_restorer();
199 }
200 
onPlatformSwapBuffers() const201 void WinGLTestContext::onPlatformSwapBuffers() const {
202     HDC dc;
203 
204     if (nullptr == fPbufferContext) {
205         dc = fDeviceContext;
206     } else {
207         dc = fPbufferContext->getDC();
208     }
209     if (!SwapBuffers(dc)) {
210         SkDebugf("Could not complete SwapBuffers.\n");
211     }
212 }
213 
onPlatformGetProcAddress(const char * name) const214 GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
215     return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
216 }
217 
218 } // anonymous namespace
219 
220 namespace sk_gpu_test {
CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,GLTestContext * shareContext)221 GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
222                                            GLTestContext *shareContext) {
223     WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
224     WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
225     if (!ctx->isValid()) {
226         delete ctx;
227         return nullptr;
228     }
229     return ctx;
230 }
231 }  // namespace sk_gpu_test
232 
233 #endif
234