Home | History | Annotate | Download | only in win
      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 
     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 
     50 GLWindowContext_win::~GLWindowContext_win() {
     51     this->destroyContext();
     52 }
     53 
     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 
    113 void GLWindowContext_win::onDestroyContext() {
    114     wglDeleteContext(fHGLRC);
    115     fHGLRC = NULL;
    116 }
    117 
    118 
    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 
    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