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