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