• 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 "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