SkNativeGLContext_win.cpp revision 68c74884d0da1aa794bb660a37f31f2f9108bc36
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#include "SkWGL.h"
11
12#define WIN32_LEAN_AND_MEAN
13#include <windows.h>
14
15SkNativeGLContext::AutoContextRestore::AutoContextRestore() {
16    fOldHGLRC = wglGetCurrentContext();
17    fOldHDC = wglGetCurrentDC();
18}
19
20SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
21    wglMakeCurrent(fOldHDC, fOldHGLRC);
22}
23
24///////////////////////////////////////////////////////////////////////////////
25
26ATOM SkNativeGLContext::gWC = 0;
27
28SkNativeGLContext::SkNativeGLContext()
29    : fWindow(NULL)
30    , fDeviceContext(NULL)
31    , fGlRenderContext(0) {
32}
33
34SkNativeGLContext::~SkNativeGLContext() {
35    this->destroyGLContext();
36}
37
38void SkNativeGLContext::destroyGLContext() {
39    if (fGlRenderContext) {
40        wglDeleteContext(fGlRenderContext);
41    }
42    if (fWindow && fDeviceContext) {
43        ReleaseDC(fWindow, fDeviceContext);
44    }
45    if (fWindow) {
46        DestroyWindow(fWindow);
47    }
48}
49
50const GrGLInterface* SkNativeGLContext::createGLContext() {
51    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
52
53    if (!gWC) {
54        WNDCLASS wc;
55        wc.cbClsExtra = 0;
56        wc.cbWndExtra = 0;
57        wc.hbrBackground = NULL;
58        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
59        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
60        wc.hInstance = hInstance;
61        wc.lpfnWndProc = (WNDPROC) DefWindowProc;
62        wc.lpszClassName = TEXT("Griffin");
63        wc.lpszMenuName = NULL;
64        wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
65
66        gWC = RegisterClass(&wc);
67        if (!gWC) {
68            SkDebugf("Could not register window class.\n");
69            return NULL;
70        }
71    }
72
73    if (!(fWindow = CreateWindow(TEXT("Griffin"),
74                                 TEXT("The Invisible Man"),
75                                 WS_OVERLAPPEDWINDOW,
76                                 0, 0, 1, 1,
77                                 NULL, NULL,
78                                 hInstance, NULL))) {
79        SkDebugf("Could not create window.\n");
80        return NULL;
81    }
82
83    if (!(fDeviceContext = GetDC(fWindow))) {
84        SkDebugf("Could not get device context.\n");
85        this->destroyGLContext();
86        return NULL;
87    }
88
89    // We don't want the core profile when using NV path rendering (since
90    // NV path rendering relies on fixed function calls)
91    if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0,
92                                                !GR_GL_USE_NV_PATH_RENDERING))) {
93        SkDebugf("Could not create rendering context.\n");
94        this->destroyGLContext();
95        return NULL;
96    }
97
98    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
99        SkDebugf("Could not set the context.\n");
100        this->destroyGLContext();
101        return NULL;
102    }
103    const GrGLInterface* interface = GrGLCreateNativeInterface();
104    if (NULL == interface) {
105        SkDebugf("Could not create GL interface.\n");
106        this->destroyGLContext();
107        return NULL;
108    }
109
110    return interface;
111}
112
113void SkNativeGLContext::makeCurrent() const {
114    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
115        SkDebugf("Could not create rendering context.\n");
116    }
117}
118
119void SkNativeGLContext::swapBuffers() const {
120    if (!SwapBuffers(fDeviceContext)) {
121        SkDebugf("Could not complete SwapBuffers.\n");
122    }
123}
124