Home | History | Annotate | Download | only in win
      1 
      2 /*
      3  * Copyright 2011 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 "gl/GLTestContext.h"
     10 
     11 #include <windows.h>
     12 #include <GL/GL.h>
     13 #include "win/SkWGL.h"
     14 
     15 #include <windows.h>
     16 
     17 namespace {
     18 
     19 class WinGLTestContext : public sk_gpu_test::GLTestContext {
     20 public:
     21     WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext);
     22     ~WinGLTestContext() override;
     23 
     24 private:
     25     void destroyGLContext();
     26 
     27     void onPlatformMakeCurrent() const override;
     28     void onPlatformSwapBuffers() const override;
     29     GrGLFuncPtr onPlatformGetProcAddress(const char* name) const override;
     30 
     31     HWND fWindow;
     32     HDC fDeviceContext;
     33     HGLRC fGlRenderContext;
     34     static ATOM gWC;
     35     SkWGLPbufferContext* fPbufferContext;
     36 };
     37 
     38 ATOM WinGLTestContext::gWC = 0;
     39 
     40 WinGLTestContext::WinGLTestContext(GrGLStandard forcedGpuAPI, WinGLTestContext* shareContext)
     41     : fWindow(nullptr)
     42     , fDeviceContext(nullptr)
     43     , fGlRenderContext(0)
     44     , fPbufferContext(nullptr) {
     45     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(nullptr);
     46 
     47     if (!gWC) {
     48         WNDCLASS wc;
     49         wc.cbClsExtra = 0;
     50         wc.cbWndExtra = 0;
     51         wc.hbrBackground = nullptr;
     52         wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
     53         wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
     54         wc.hInstance = hInstance;
     55         wc.lpfnWndProc = (WNDPROC) DefWindowProc;
     56         wc.lpszClassName = TEXT("Griffin");
     57         wc.lpszMenuName = nullptr;
     58         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
     59 
     60         gWC = RegisterClass(&wc);
     61         if (!gWC) {
     62             SkDebugf("Could not register window class.\n");
     63             return;
     64         }
     65     }
     66 
     67     if (!(fWindow = CreateWindow(TEXT("Griffin"),
     68                                  TEXT("The Invisible Man"),
     69                                  WS_OVERLAPPEDWINDOW,
     70                                  0, 0, 1, 1,
     71                                  nullptr, nullptr,
     72                                  hInstance, nullptr))) {
     73         SkDebugf("Could not create window.\n");
     74         return;
     75     }
     76 
     77     if (!(fDeviceContext = GetDC(fWindow))) {
     78         SkDebugf("Could not get device context.\n");
     79         this->destroyGLContext();
     80         return;
     81     }
     82     // Requesting a Core profile would bar us from using NVPR. So we request
     83     // compatibility profile or GL ES.
     84     SkWGLContextRequest contextType =
     85         kGLES_GrGLStandard == forcedGpuAPI ?
     86         kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
     87 
     88     HGLRC winShareContext = nullptr;
     89     if (shareContext) {
     90         winShareContext = shareContext->fPbufferContext ? shareContext->fPbufferContext->getGLRC()
     91                                                         : shareContext->fGlRenderContext;
     92     }
     93     fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType, winShareContext);
     94 
     95     HDC dc;
     96     HGLRC glrc;
     97     if (nullptr == fPbufferContext) {
     98         if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false, contextType,
     99                                                     winShareContext))) {
    100             SkDebugf("Could not create rendering context.\n");
    101             this->destroyGLContext();
    102             return;
    103         }
    104         dc = fDeviceContext;
    105         glrc = fGlRenderContext;
    106     } else {
    107         ReleaseDC(fWindow, fDeviceContext);
    108         fDeviceContext = 0;
    109         DestroyWindow(fWindow);
    110         fWindow = 0;
    111 
    112         dc = fPbufferContext->getDC();
    113         glrc = fPbufferContext->getGLRC();
    114     }
    115 
    116     if (!(wglMakeCurrent(dc, glrc))) {
    117         SkDebugf("Could not set the context.\n");
    118         this->destroyGLContext();
    119         return;
    120     }
    121 
    122     sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
    123     if (nullptr == gl.get()) {
    124         SkDebugf("Could not create GL interface.\n");
    125         this->destroyGLContext();
    126         return;
    127     }
    128     if (!gl->validate()) {
    129         SkDebugf("Could not validate GL interface.\n");
    130         this->destroyGLContext();
    131         return;
    132     }
    133 
    134     this->init(gl.release());
    135 }
    136 
    137 WinGLTestContext::~WinGLTestContext() {
    138     this->teardown();
    139     this->destroyGLContext();
    140 }
    141 
    142 void WinGLTestContext::destroyGLContext() {
    143     SkSafeSetNull(fPbufferContext);
    144     if (fGlRenderContext) {
    145         wglDeleteContext(fGlRenderContext);
    146         fGlRenderContext = 0;
    147     }
    148     if (fWindow && fDeviceContext) {
    149         ReleaseDC(fWindow, fDeviceContext);
    150         fDeviceContext = 0;
    151     }
    152     if (fWindow) {
    153         DestroyWindow(fWindow);
    154         fWindow = 0;
    155     }
    156 }
    157 
    158 void WinGLTestContext::onPlatformMakeCurrent() const {
    159     HDC dc;
    160     HGLRC glrc;
    161 
    162     if (nullptr == fPbufferContext) {
    163         dc = fDeviceContext;
    164         glrc = fGlRenderContext;
    165     } else {
    166         dc = fPbufferContext->getDC();
    167         glrc = fPbufferContext->getGLRC();
    168     }
    169 
    170     if (!wglMakeCurrent(dc, glrc)) {
    171         SkDebugf("Could not create rendering context.\n");
    172     }
    173 }
    174 
    175 void WinGLTestContext::onPlatformSwapBuffers() const {
    176     HDC dc;
    177 
    178     if (nullptr == fPbufferContext) {
    179         dc = fDeviceContext;
    180     } else {
    181         dc = fPbufferContext->getDC();
    182     }
    183     if (!SwapBuffers(dc)) {
    184         SkDebugf("Could not complete SwapBuffers.\n");
    185     }
    186 }
    187 
    188 GrGLFuncPtr WinGLTestContext::onPlatformGetProcAddress(const char* name) const {
    189     return reinterpret_cast<GrGLFuncPtr>(wglGetProcAddress(name));
    190 }
    191 
    192 } // anonymous namespace
    193 
    194 namespace sk_gpu_test {
    195 GLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
    196                                            GLTestContext *shareContext) {
    197     WinGLTestContext* winShareContext = reinterpret_cast<WinGLTestContext*>(shareContext);
    198     WinGLTestContext *ctx = new WinGLTestContext(forcedGpuAPI, winShareContext);
    199     if (!ctx->isValid()) {
    200         delete ctx;
    201         return nullptr;
    202     }
    203     return ctx;
    204 }
    205 }  // namespace sk_gpu_test
    206 
    207