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 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 137 WinGLTestContext::~WinGLTestContext() { 138 this->teardown(); 139 this->destroyGLContext(); 140 } 141 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 158 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 175 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 188 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 { 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