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
17using sk_app::GLWindowContext;
18using sk_app::DisplayParams;
19
20namespace {
21
22class GLWindowContext_win : public GLWindowContext {
23public:
24    GLWindowContext_win(HWND, const DisplayParams&);
25    ~GLWindowContext_win() override;
26
27protected:
28    void onSwapBuffers() override;
29
30    void onInitializeContext() override;
31    void onDestroyContext() override;
32
33private:
34    HWND              fHWND;
35    HGLRC             fHGLRC;
36};
37
38GLWindowContext_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
48GLWindowContext_win::~GLWindowContext_win() {
49    this->destroyContext();
50}
51
52void 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
111void GLWindowContext_win::onDestroyContext() {
112    wglDeleteContext(fHGLRC);
113    fHGLRC = NULL;
114}
115
116
117void GLWindowContext_win::onSwapBuffers() {
118    HDC dc = GetDC((HWND)fHWND);
119    SwapBuffers(dc);
120    ReleaseDC((HWND)fHWND, dc);
121}
122
123
124}  // anonymous namespace
125
126namespace sk_app {
127namespace window_context_factory {
128
129WindowContext* 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