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 typedef GLWindowContext INHERITED;
38 };
39
GLWindowContext_win(HWND wnd,const DisplayParams & params)40 GLWindowContext_win::GLWindowContext_win(HWND wnd, const DisplayParams& params)
41 : INHERITED(params)
42 , fHWND(wnd)
43 , fHGLRC(NULL) {
44
45 // any config code here (particularly for msaa)?
46
47 this->initializeContext();
48 }
49
~GLWindowContext_win()50 GLWindowContext_win::~GLWindowContext_win() {
51 this->destroyContext();
52 }
53
onInitializeContext()54 void GLWindowContext_win::onInitializeContext() {
55 HDC dc = GetDC(fHWND);
56
57 fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */,
58 kGLPreferCompatibilityProfile_SkWGLContextRequest);
59 if (NULL == fHGLRC) {
60 return;
61 }
62
63 // Look to see if RenderDoc is attached. If so, re-create the context with a core profile
64 if (wglMakeCurrent(dc, fHGLRC)) {
65 const GrGLInterface* glInterface = GrGLCreateNativeInterface();
66 bool renderDocAttached = glInterface->hasExtension("GL_EXT_debug_tool");
67 SkSafeUnref(glInterface);
68 if (renderDocAttached) {
69 wglDeleteContext(fHGLRC);
70 fHGLRC = SkCreateWGLContext(dc, fDisplayParams.fMSAASampleCount, false /* deepColor */,
71 kGLPreferCoreProfile_SkWGLContextRequest);
72 if (NULL == fHGLRC) {
73 return;
74 }
75 }
76 }
77
78 if (wglMakeCurrent(dc, fHGLRC)) {
79 glClearStencil(0);
80 glClearColor(0, 0, 0, 0);
81 glStencilMask(0xffffffff);
82 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
83
84 // use DescribePixelFormat to get the stencil and color bit depth.
85 int pixelFormat = GetPixelFormat(dc);
86 PIXELFORMATDESCRIPTOR pfd;
87 DescribePixelFormat(dc, pixelFormat, sizeof(pfd), &pfd);
88 fStencilBits = pfd.cStencilBits;
89
90 // Get sample count if the MSAA WGL extension is present
91 SkWGLExtensions extensions;
92 if (extensions.hasExtension(dc, "WGL_ARB_multisample")) {
93 static const int kSampleCountAttr = SK_WGL_SAMPLES;
94 extensions.getPixelFormatAttribiv(dc,
95 pixelFormat,
96 0,
97 1,
98 &kSampleCountAttr,
99 &fSampleCount);
100 } else {
101 fSampleCount = 0;
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 }
111
112
onDestroyContext()113 void GLWindowContext_win::onDestroyContext() {
114 wglDeleteContext(fHGLRC);
115 fHGLRC = NULL;
116 }
117
118
onSwapBuffers()119 void GLWindowContext_win::onSwapBuffers() {
120 HDC dc = GetDC((HWND)fHWND);
121 SwapBuffers(dc);
122 ReleaseDC((HWND)fHWND, dc);
123 }
124
125
126 } // anonymous namespace
127
128 namespace sk_app {
129 namespace window_context_factory {
130
NewGLForWin(HWND wnd,const DisplayParams & params)131 WindowContext* NewGLForWin(HWND wnd, const DisplayParams& params) {
132 GLWindowContext_win* ctx = new GLWindowContext_win(wnd, params);
133 if (!ctx->isValid()) {
134 delete ctx;
135 return nullptr;
136 }
137 return ctx;
138 }
139
140 } // namespace window_context_factory
141 } // namespace sk_app
142