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/SkNativeGLContext.h"
     10 
     11 #define WIN32_LEAN_AND_MEAN
     12 #include <windows.h>
     13 
     14 SkNativeGLContext::AutoContextRestore::AutoContextRestore() {
     15     fOldHGLRC = wglGetCurrentContext();
     16     fOldHDC = wglGetCurrentDC();
     17 }
     18 
     19 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
     20     wglMakeCurrent(fOldHDC, fOldHGLRC);
     21 }
     22 
     23 ///////////////////////////////////////////////////////////////////////////////
     24 
     25 ATOM SkNativeGLContext::gWC = 0;
     26 
     27 SkNativeGLContext::SkNativeGLContext()
     28     : fWindow(NULL)
     29     , fDeviceContext(NULL)
     30     , fGlRenderContext(0)
     31     , fPbufferContext(NULL) {
     32 }
     33 
     34 SkNativeGLContext::~SkNativeGLContext() {
     35     this->destroyGLContext();
     36 }
     37 
     38 void SkNativeGLContext::destroyGLContext() {
     39     SkSafeSetNull(fPbufferContext);
     40     if (fGlRenderContext) {
     41         wglDeleteContext(fGlRenderContext);
     42         fGlRenderContext = 0;
     43     }
     44     if (fWindow && fDeviceContext) {
     45         ReleaseDC(fWindow, fDeviceContext);
     46         fDeviceContext = 0;
     47     }
     48     if (fWindow) {
     49         DestroyWindow(fWindow);
     50         fWindow = 0;
     51     }
     52 }
     53 
     54 const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     55     HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
     56 
     57     if (!gWC) {
     58         WNDCLASS wc;
     59         wc.cbClsExtra = 0;
     60         wc.cbWndExtra = 0;
     61         wc.hbrBackground = NULL;
     62         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
     63         wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
     64         wc.hInstance = hInstance;
     65         wc.lpfnWndProc = (WNDPROC) DefWindowProc;
     66         wc.lpszClassName = TEXT("Griffin");
     67         wc.lpszMenuName = NULL;
     68         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
     69 
     70         gWC = RegisterClass(&wc);
     71         if (!gWC) {
     72             SkDebugf("Could not register window class.\n");
     73             return NULL;
     74         }
     75     }
     76 
     77     if (!(fWindow = CreateWindow(TEXT("Griffin"),
     78                                  TEXT("The Invisible Man"),
     79                                  WS_OVERLAPPEDWINDOW,
     80                                  0, 0, 1, 1,
     81                                  NULL, NULL,
     82                                  hInstance, NULL))) {
     83         SkDebugf("Could not create window.\n");
     84         return NULL;
     85     }
     86 
     87     if (!(fDeviceContext = GetDC(fWindow))) {
     88         SkDebugf("Could not get device context.\n");
     89         this->destroyGLContext();
     90         return NULL;
     91     }
     92     // Requesting a Core profile would bar us from using NVPR. So we request
     93     // compatibility profile or GL ES.
     94     SkWGLContextRequest contextType =
     95         kGLES_GrGLStandard == forcedGpuAPI ?
     96         kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
     97 
     98     fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType);
     99 
    100     HDC dc;
    101     HGLRC glrc;
    102 
    103     if (NULL == fPbufferContext) {
    104         if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
    105             SkDebugf("Could not create rendering context.\n");
    106             this->destroyGLContext();
    107             return NULL;
    108         }
    109         dc = fDeviceContext;
    110         glrc = fGlRenderContext;
    111     } else {
    112         ReleaseDC(fWindow, fDeviceContext);
    113         fDeviceContext = 0;
    114         DestroyWindow(fWindow);
    115         fWindow = 0;
    116 
    117         dc = fPbufferContext->getDC();
    118         glrc = fPbufferContext->getGLRC();
    119     }
    120 
    121     if (!(wglMakeCurrent(dc, glrc))) {
    122         SkDebugf("Could not set the context.\n");
    123         this->destroyGLContext();
    124         return NULL;
    125     }
    126 
    127     const GrGLInterface* interface = GrGLCreateNativeInterface();
    128     if (NULL == interface) {
    129         SkDebugf("Could not create GL interface.\n");
    130         this->destroyGLContext();
    131         return NULL;
    132     }
    133 
    134     return interface;
    135 }
    136 
    137 void SkNativeGLContext::makeCurrent() const {
    138     HDC dc;
    139     HGLRC glrc;
    140 
    141     if (NULL == fPbufferContext) {
    142         dc = fDeviceContext;
    143         glrc = fGlRenderContext;
    144     } else {
    145         dc = fPbufferContext->getDC();
    146         glrc = fPbufferContext->getGLRC();
    147     }
    148 
    149     if (!wglMakeCurrent(dc, glrc)) {
    150         SkDebugf("Could not create rendering context.\n");
    151     }
    152 }
    153 
    154 void SkNativeGLContext::swapBuffers() const {
    155     HDC dc;
    156 
    157     if (NULL == fPbufferContext) {
    158         dc = fDeviceContext;
    159     } else {
    160         dc = fPbufferContext->getDC();
    161     }
    162     if (!SwapBuffers(dc)) {
    163         SkDebugf("Could not complete SwapBuffers.\n");
    164     }
    165 }
    166