xref: /aosp_15_r20/external/skia/tools/window/win/GLWindowContext_win.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 
2 /*
3  * Copyright 2015 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 "include/gpu/ganesh/gl/GrGLInterface.h"
10 #include "tools/gpu/gl/win/SkWGL.h"
11 #include "tools/window/GLWindowContext.h"
12 #include "tools/window/win/WindowContextFactory_win.h"
13 
14 #include <Windows.h>
15 #include <GL/gl.h>
16 
17 using skwindow::DisplayParams;
18 using skwindow::internal::GLWindowContext;
19 
20 #if defined(_M_ARM64)
21 
22 namespace skwindow {
23 
MakeGLForWin(HWND,std::unique_ptr<const DisplayParams>)24 std::unique_ptr<WindowContext> MakeGLForWin(HWND, std::unique_ptr<const DisplayParams>) {
25     return nullptr;
26 }
27 
28 }  // namespace skwindow
29 
30 #else
31 
32 namespace {
33 
34 class GLWindowContext_win : public GLWindowContext {
35 public:
36     GLWindowContext_win(HWND, std::unique_ptr<const DisplayParams>);
37     ~GLWindowContext_win() override;
38 
39 protected:
40     void onSwapBuffers() override;
41 
42     sk_sp<const GrGLInterface> onInitializeContext() override;
43     void onDestroyContext() override;
44 
45 private:
46     HWND              fHWND;
47     HGLRC             fHGLRC;
48 };
49 
GLWindowContext_win(HWND wnd,std::unique_ptr<const DisplayParams> params)50 GLWindowContext_win::GLWindowContext_win(HWND wnd, std::unique_ptr<const DisplayParams> params)
51         : GLWindowContext(std::move(params)), fHWND(wnd), fHGLRC(nullptr) {
52     // any config code here (particularly for msaa)?
53 
54     this->initializeContext();
55 }
56 
~GLWindowContext_win()57 GLWindowContext_win::~GLWindowContext_win() {
58     this->destroyContext();
59 }
60 
onInitializeContext()61 sk_sp<const GrGLInterface> GLWindowContext_win::onInitializeContext() {
62     HDC dc = GetDC(fHWND);
63 
64     fHGLRC = SkCreateWGLContext(dc,
65                                 fDisplayParams->msaaSampleCount(),
66                                 false /* deepColor */,
67                                 kGLPreferCompatibilityProfile_SkWGLContextRequest);
68     if (nullptr == fHGLRC) {
69         return nullptr;
70     }
71 
72     SkWGLExtensions extensions;
73     if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
74         extensions.swapInterval(fDisplayParams->disableVsync() ? 0 : 1);
75     }
76 
77     // Look to see if RenderDoc is attached. If so, re-create the context with a core profile
78     if (wglMakeCurrent(dc, fHGLRC)) {
79         auto interface = GrGLMakeNativeInterface();
80         bool renderDocAttached = interface->hasExtension("GL_EXT_debug_tool");
81         interface.reset(nullptr);
82         if (renderDocAttached) {
83             wglDeleteContext(fHGLRC);
84             fHGLRC = SkCreateWGLContext(dc,
85                                         fDisplayParams->msaaSampleCount(),
86                                         false /* deepColor */,
87                                         kGLPreferCoreProfile_SkWGLContextRequest);
88             if (nullptr == fHGLRC) {
89                 return nullptr;
90             }
91         }
92     }
93 
94     if (wglMakeCurrent(dc, fHGLRC)) {
95         glClearStencil(0);
96         glClearColor(0, 0, 0, 0);
97         glStencilMask(0xffffffff);
98         glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
99 
100         // use DescribePixelFormat to get the stencil and color bit depth.
101         int pixelFormat = GetPixelFormat(dc);
102         PIXELFORMATDESCRIPTOR pfd;
103         DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
104         fStencilBits = pfd.cStencilBits;
105 
106         // Get sample count if the MSAA WGL extension is present
107         if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
108             static const int kSampleCountAttr = SK_WGL_SAMPLES;
109             extensions.getPixelFormatAttribiv(dc,
110                                               pixelFormat,
111                                               0,
112                                               1,
113                                               &kSampleCountAttr,
114                                               &fSampleCount);
115             fSampleCount = std::max(fSampleCount, 1);
116         } else {
117             fSampleCount = 1;
118         }
119 
120         RECT rect;
121         GetClientRect(fHWND, &rect);
122         fWidth = rect.right - rect.left;
123         fHeight = rect.bottom - rect.top;
124         glViewport(0, 0, fWidth, fHeight);
125     }
126     return GrGLMakeNativeInterface();
127 }
128 
129 
onDestroyContext()130 void GLWindowContext_win::onDestroyContext() {
131     wglDeleteContext(fHGLRC);
132     fHGLRC = NULL;
133 }
134 
135 
onSwapBuffers()136 void GLWindowContext_win::onSwapBuffers() {
137     HDC dc = GetDC((HWND)fHWND);
138     SwapBuffers(dc);
139     ReleaseDC((HWND)fHWND, dc);
140 }
141 
142 
143 }  // anonymous namespace
144 
145 namespace skwindow {
146 
MakeGLForWin(HWND wnd,std::unique_ptr<const DisplayParams> params)147 std::unique_ptr<WindowContext> MakeGLForWin(HWND wnd, std::unique_ptr<const DisplayParams> params) {
148     std::unique_ptr<WindowContext> ctx(new GLWindowContext_win(wnd, std::move(params)));
149     if (!ctx->isValid()) {
150         return nullptr;
151     }
152     return ctx;
153 }
154 
155 }  // namespace skwindow
156 
157 #endif
158