1cb93a386Sopenharmony_ci 2cb93a386Sopenharmony_ci/* 3cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 4cb93a386Sopenharmony_ci * 5cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 6cb93a386Sopenharmony_ci * found in the LICENSE file. 7cb93a386Sopenharmony_ci */ 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#include "tools/gpu/gl/GLTestContext.h" 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#if defined(_M_ARM64) 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_cinamespace sk_gpu_test { 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ciGLTestContext* CreatePlatformGLTestContext(GrGLStandard, GLTestContext*) { return nullptr; } 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_ci} // namespace sk_gpu_test 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci#else 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci#include <windows.h> 22cb93a386Sopenharmony_ci// #include <GL/GL.h> 23cb93a386Sopenharmony_ci#include <GL/gl.h> 24cb93a386Sopenharmony_ci#include "src/utils/win/SkWGL.h" 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci#include <windows.h> 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_cinamespace { 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_cistd::function<void()> context_restorer() { 31cb93a386Sopenharmony_ci auto glrc = wglGetCurrentContext(); 32cb93a386Sopenharmony_ci auto dc = wglGetCurrentDC(); 33cb93a386Sopenharmony_ci return [glrc, dc] { wglMakeCurrent(dc, glrc); }; 34cb93a386Sopenharmony_ci} 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ciclass WinGLTestContext : public sk_gpu_test::GLTestContext { 37cb93a386Sopenharmony_cipublic: 38cb93a386Sopenharmony_ci WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext); 39cb93a386Sopenharmony_ci ~WinGLTestContext() override; 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ciprivate: 42cb93a386Sopenharmony_ci void destroyGLContext(); 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ci void onPlatformMakeNotCurrent() const override; 45cb93a386Sopenharmony_ci void onPlatformMakeCurrent() const override; 46cb93a386Sopenharmony_ci std::function<void()> onPlatformGetAutoContextRestore() const override; 47cb93a386Sopenharmony_ci GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override; 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci HWND fWindow; 50cb93a386Sopenharmony_ci HDC fDeviceContext; 51cb93a386Sopenharmony_ci HGLRC fGlRenderContext; 52cb93a386Sopenharmony_ci static ATOM gWC; 53cb93a386Sopenharmony_ci sk_sp<SkWGLPbufferContext> fPbufferContext; 54cb93a386Sopenharmony_ci}; 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ciATOM WinGLTestContext::gWC = 0; 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ciWinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext) 59cb93a386Sopenharmony_ci : fWindow(nullptr) 60cb93a386Sopenharmony_ci , fDeviceContext(nullptr) 61cb93a386Sopenharmony_ci , fGlRenderContext(0) 62cb93a386Sopenharmony_ci , fPbufferContext(nullptr) { 63cb93a386Sopenharmony_ci HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci if (!gWC) { 66cb93a386Sopenharmony_ci WNDCLASS wc; 67cb93a386Sopenharmony_ci wc.cbClsExtra = 0; 68cb93a386Sopenharmony_ci wc.cbWndExtra = 0; 69cb93a386Sopenharmony_ci wc.hbrBackground = nullptr; 70cb93a386Sopenharmony_ci wc.hCursor = LoadCursor(nullptr, IDC_ARROW); 71cb93a386Sopenharmony_ci wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION); 72cb93a386Sopenharmony_ci wc.hInstance = hInstance; 73cb93a386Sopenharmony_ci wc.lpfnWndProc = (WNDPROC) DefWindowProc; 74cb93a386Sopenharmony_ci wc.lpszClassName = TEXT("Griffin"); 75cb93a386Sopenharmony_ci wc.lpszMenuName = nullptr; 76cb93a386Sopenharmony_ci wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci gWC = RegisterClass(&wc); 79cb93a386Sopenharmony_ci if (!gWC) { 80cb93a386Sopenharmony_ci SkDebugf("Could not register window class.\n"); 81cb93a386Sopenharmony_ci return; 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci } 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci if (!(fWindow = CreateWindow(TEXT("Griffin"), 86cb93a386Sopenharmony_ci TEXT("The Invisible Man"), 87cb93a386Sopenharmony_ci WS_OVERLAPPEDWINDOW, 88cb93a386Sopenharmony_ci 0, 0, 1, 1, 89cb93a386Sopenharmony_ci nullptr, nullptr, 90cb93a386Sopenharmony_ci hInstance, nullptr))) { 91cb93a386Sopenharmony_ci SkDebugf("Could not create window.\n"); 92cb93a386Sopenharmony_ci return; 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci 95cb93a386Sopenharmony_ci if (!(fDeviceContext = GetDC(fWindow))) { 96cb93a386Sopenharmony_ci SkDebugf("Could not get device context.\n"); 97cb93a386Sopenharmony_ci this->destroyGLContext(); 98cb93a386Sopenharmony_ci return; 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci // We request a compatibility context since glMultiDrawArraysIndirect, apparently, doesn't 102cb93a386Sopenharmony_ci // work correctly on Intel Iris GPUs with the core profile (skbug.com/11787). 103cb93a386Sopenharmony_ci SkWGLContextRequest contextType = 104cb93a386Sopenharmony_ci kGLES_GrGLStandard == forcedGpuAPI ? kGLES_SkWGLContextRequest 105cb93a386Sopenharmony_ci : kGLPreferCompatibilityProfile_SkWGLContextRequest; 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci HGLRC winShareContext = nullptr; 108cb93a386Sopenharmony_ci if (shareContext) { 109cb93a386Sopenharmony_ci winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC() 110cb93a386Sopenharmony_ci : shareContext->fGlRenderContext; 111cb93a386Sopenharmony_ci } 112cb93a386Sopenharmony_ci fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, contextType, winShareContext); 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci HDC dc; 115cb93a386Sopenharmony_ci HGLRC glrc; 116cb93a386Sopenharmony_ci if (nullptr == fPbufferContext) { 117cb93a386Sopenharmony_ci if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType, 118cb93a386Sopenharmony_ci winShareContext))) { 119cb93a386Sopenharmony_ci SkDebugf("Could not create rendering context.\n"); 120cb93a386Sopenharmony_ci this->destroyGLContext(); 121cb93a386Sopenharmony_ci return; 122cb93a386Sopenharmony_ci } 123cb93a386Sopenharmony_ci dc = fDeviceContext; 124cb93a386Sopenharmony_ci glrc = fGlRenderContext; 125cb93a386Sopenharmony_ci } else { 126cb93a386Sopenharmony_ci ReleaseDC(fWindow, fDeviceContext); 127cb93a386Sopenharmony_ci fDeviceContext = 0; 128cb93a386Sopenharmony_ci DestroyWindow(fWindow); 129cb93a386Sopenharmony_ci fWindow = 0; 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_ci dc = fPbufferContext->getDC(); 132cb93a386Sopenharmony_ci glrc = fPbufferContext->getGLRC(); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci SkScopeExit restorer(context_restorer()); 136cb93a386Sopenharmony_ci if (!(wglMakeCurrent(dc, glrc))) { 137cb93a386Sopenharmony_ci SkDebugf("Could not set the context.\n"); 138cb93a386Sopenharmony_ci this->destroyGLContext(); 139cb93a386Sopenharmony_ci return; 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci#ifdef SK_GL 143cb93a386Sopenharmony_ci auto gl = GrGLMakeNativeInterface(); 144cb93a386Sopenharmony_ci if (!gl) { 145cb93a386Sopenharmony_ci SkDebugf("Could not create GL interface.\n"); 146cb93a386Sopenharmony_ci this->destroyGLContext(); 147cb93a386Sopenharmony_ci return; 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci if (!gl->validate()) { 150cb93a386Sopenharmony_ci SkDebugf("Could not validate GL interface.\n"); 151cb93a386Sopenharmony_ci this->destroyGLContext(); 152cb93a386Sopenharmony_ci return; 153cb93a386Sopenharmony_ci } 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci this->init(std::move(gl)); 156cb93a386Sopenharmony_ci#else 157cb93a386Sopenharmony_ci // Allow the GLTestContext creation to succeed without a GrGLInterface to support 158cb93a386Sopenharmony_ci // GrContextFactory's persistent GL context workaround for Vulkan. We won't need the 159cb93a386Sopenharmony_ci // GrGLInterface since we're not running the GL backend. 160cb93a386Sopenharmony_ci this->init(nullptr); 161cb93a386Sopenharmony_ci#endif 162cb93a386Sopenharmony_ci} 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ciWinGLTestContext::~WinGLTestContext() { 165cb93a386Sopenharmony_ci this->teardown(); 166cb93a386Sopenharmony_ci this->destroyGLContext(); 167cb93a386Sopenharmony_ci} 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_civoid WinGLTestContext::destroyGLContext() { 170cb93a386Sopenharmony_ci fPbufferContext = nullptr; 171cb93a386Sopenharmony_ci if (fGlRenderContext) { 172cb93a386Sopenharmony_ci // This deletes the context immediately even if it is current. 173cb93a386Sopenharmony_ci wglDeleteContext(fGlRenderContext); 174cb93a386Sopenharmony_ci fGlRenderContext = 0; 175cb93a386Sopenharmony_ci } 176cb93a386Sopenharmony_ci if (fWindow && fDeviceContext) { 177cb93a386Sopenharmony_ci ReleaseDC(fWindow, fDeviceContext); 178cb93a386Sopenharmony_ci fDeviceContext = 0; 179cb93a386Sopenharmony_ci } 180cb93a386Sopenharmony_ci if (fWindow) { 181cb93a386Sopenharmony_ci DestroyWindow(fWindow); 182cb93a386Sopenharmony_ci fWindow = 0; 183cb93a386Sopenharmony_ci } 184cb93a386Sopenharmony_ci} 185cb93a386Sopenharmony_ci 186cb93a386Sopenharmony_civoid WinGLTestContext::onPlatformMakeNotCurrent() const { 187cb93a386Sopenharmony_ci if (!wglMakeCurrent(NULL, NULL)) { 188cb93a386Sopenharmony_ci SkDebugf("Could not null out the rendering context.\n"); 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci} 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_civoid WinGLTestContext::onPlatformMakeCurrent() const { 193cb93a386Sopenharmony_ci HDC dc; 194cb93a386Sopenharmony_ci HGLRC glrc; 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci if (nullptr == fPbufferContext) { 197cb93a386Sopenharmony_ci dc = fDeviceContext; 198cb93a386Sopenharmony_ci glrc = fGlRenderContext; 199cb93a386Sopenharmony_ci } else { 200cb93a386Sopenharmony_ci dc = fPbufferContext->getDC(); 201cb93a386Sopenharmony_ci glrc = fPbufferContext->getGLRC(); 202cb93a386Sopenharmony_ci } 203cb93a386Sopenharmony_ci 204cb93a386Sopenharmony_ci if (!wglMakeCurrent(dc, glrc)) { 205cb93a386Sopenharmony_ci SkDebugf("Could not make current.\n"); 206cb93a386Sopenharmony_ci } 207cb93a386Sopenharmony_ci} 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_cistd::function<void()> WinGLTestContext::onPlatformGetAutoContextRestore() const { 210cb93a386Sopenharmony_ci if (wglGetCurrentContext() == fGlRenderContext) { 211cb93a386Sopenharmony_ci return nullptr; 212cb93a386Sopenharmony_ci } 213cb93a386Sopenharmony_ci return context_restorer(); 214cb93a386Sopenharmony_ci} 215cb93a386Sopenharmony_ci 216cb93a386Sopenharmony_ciGrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const { 217cb93a386Sopenharmony_ci return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name)); 218cb93a386Sopenharmony_ci} 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci} // anonymous namespace 221cb93a386Sopenharmony_ci 222cb93a386Sopenharmony_cinamespace sk_gpu_test { 223cb93a386Sopenharmony_ciGLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI, 224cb93a386Sopenharmony_ci GLTestContext *shareContext) { 225cb93a386Sopenharmony_ci WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext); 226cb93a386Sopenharmony_ci WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext); 227cb93a386Sopenharmony_ci if (!ctx->isValid()) { 228cb93a386Sopenharmony_ci delete ctx; 229cb93a386Sopenharmony_ci return nullptr; 230cb93a386Sopenharmony_ci } 231cb93a386Sopenharmony_ci return ctx; 232cb93a386Sopenharmony_ci} 233cb93a386Sopenharmony_ci} // namespace sk_gpu_test 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci#endif 236