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 "gl/GLTestContext.h"
10
11 #include <windows.h>
12 #include <GL/GL.h>
13 #include "win/SkWGL.h"
14
15 #include <windows.h>
16
17 namespace {
18
19 class WinGLTestContext : public sk_gpu_test::GLTestContext {
20 public:
21 WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext);
22 ~WinGLTestContext() override;
23
24 private:
25 void destroyGLContext();
26
27 void onPlatformMakeCurrent() const override;
28 void onPlatformSwapBuffers() const override;
29 GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
30
31 HWND fWindow;
32 HDC fDeviceContext;
33 HGLRC fGlRenderContext;
34 static ATOM gWC;
35 SkWGLPbufferContext* fPbufferContext;
36 };
37
38 ATOM WinGLTestContext::gWC = 0;
39
WinGLTestContext(GrGLStandard forcedGpuAPI,WinGLTestContext * shareContext)40 WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
41 : fWindow(nullptr)
42 , fDeviceContext(nullptr)
43 , fGlRenderContext(0)
44 , fPbufferContext(nullptr) {
45 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
46
47 if (!gWC) {
48 WNDCLASS wc;
49 wc.cbClsExtra = 0;
50 wc.cbWndExtra = 0;
51 wc.hbrBackground = nullptr;
52 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
53 wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
54 wc.hInstance = hInstance;
55 wc.lpfnWndProc = (WNDPROC) DefWindowProc;
56 wc.lpszClassName = TEXT("Griffin");
57 wc.lpszMenuName = nullptr;
58 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
59
60 gWC = RegisterClass(&wc);
61 if (!gWC) {
62 SkDebugf("Could not register window class.\n");
63 return;
64 }
65 }
66
67 if (!(fWindow = CreateWindow(TEXT("Griffin"),
68 TEXT("The Invisible Man"),
69 WS_OVERLAPPEDWINDOW,
70 0, 0, 1, 1,
71 nullptr, nullptr,
72 hInstance, nullptr))) {
73 SkDebugf("Could not create window.\n");
74 return;
75 }
76
77 if (!(fDeviceContext = GetDC(fWindow))) {
78 SkDebugf("Could not get device context.\n");
79 this->destroyGLContext();
80 return;
81 }
82 // Requesting a Core profile would bar us from using NVPR. So we request
83 // compatibility profile or GL ES.
84 SkWGLContextRequest contextType =
85 kGLES_GrGLStandard == forcedGpuAPI ?
86 kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
87
88 HGLRC winShareContext = nullptr;
89 if (shareContext) {
90 winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
91 : shareContext->fGlRenderContext;
92 }
93 fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType, winShareContext);
94
95 HDC dc;
96 HGLRC glrc;
97 if (nullptr == fPbufferContext) {
98 if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType,
99 winShareContext))) {
100 SkDebugf("Could not create rendering context.\n");
101 this->destroyGLContext();
102 return;
103 }
104 dc = fDeviceContext;
105 glrc = fGlRenderContext;
106 } else {
107 ReleaseDC(fWindow, fDeviceContext);
108 fDeviceContext = 0;
109 DestroyWindow(fWindow);
110 fWindow = 0;
111
112 dc = fPbufferContext->getDC();
113 glrc = fPbufferContext->getGLRC();
114 }
115
116 if (!(wglMakeCurrent(dc, glrc))) {
117 SkDebugf("Could not set the context.\n");
118 this->destroyGLContext();
119 return;
120 }
121
122 sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
123 if (nullptr == gl.get()) {
124 SkDebugf("Could not create GL interface.\n");
125 this->destroyGLContext();
126 return;
127 }
128 if (!gl->validate()) {
129 SkDebugf("Could not validate GL interface.\n");
130 this->destroyGLContext();
131 return;
132 }
133
134 this->init(gl.release());
135 }
136
~WinGLTestContext()137 WinGLTestContext::~WinGLTestContext() {
138 this->teardown();
139 this->destroyGLContext();
140 }
141
destroyGLContext()142 void WinGLTestContext::destroyGLContext() {
143 SkSafeSetNull(fPbufferContext);
144 if (fGlRenderContext) {
145 wglDeleteContext(fGlRenderContext);
146 fGlRenderContext = 0;
147 }
148 if (fWindow && fDeviceContext) {
149 ReleaseDC(fWindow, fDeviceContext);
150 fDeviceContext = 0;
151 }
152 if (fWindow) {
153 DestroyWindow(fWindow);
154 fWindow = 0;
155 }
156 }
157
onPlatformMakeCurrent() const158 void WinGLTestContext::onPlatformMakeCurrent() const {
159 HDC dc;
160 HGLRC glrc;
161
162 if (nullptr == fPbufferContext) {
163 dc = fDeviceContext;
164 glrc = fGlRenderContext;
165 } else {
166 dc = fPbufferContext->getDC();
167 glrc = fPbufferContext->getGLRC();
168 }
169
170 if (!wglMakeCurrent(dc, glrc)) {
171 SkDebugf("Could not create rendering context.\n");
172 }
173 }
174
onPlatformSwapBuffers() const175 void WinGLTestContext::onPlatformSwapBuffers() const {
176 HDC dc;
177
178 if (nullptr == fPbufferContext) {
179 dc = fDeviceContext;
180 } else {
181 dc = fPbufferContext->getDC();
182 }
183 if (!SwapBuffers(dc)) {
184 SkDebugf("Could not complete SwapBuffers.\n");
185 }
186 }
187
onPlatformGetProcAddress(const char * name) const188 GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
189 return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
190 }
191
192 } // anonymous namespace
193
194 namespace sk_gpu_test {
CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,GLTestContext * shareContext)195 GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
196 GLTestContext *shareContext) {
197 WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
198 WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
199 if (!ctx->isValid()) {
200 delete ctx;
201 return nullptr;
202 }
203 return ctx;
204 }
205 } // namespace sk_gpu_test
206
207