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    if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, true))) {
90        SkDebugf("Could not create rendering context.\n");
91        this->destroyGLContext();
92        return NULL;
93    }
94
95    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
96        SkDebugf("Could not set the context.\n");
97        this->destroyGLContext();
98        return NULL;
99    }
100    const GrGLInterface* interface = GrGLCreateNativeInterface();
101    if (NULL == interface) {
102        SkDebugf("Could not create GL interface.\n");
103        this->destroyGLContext();
104        return NULL;
105    }
106
107    return interface;
108}
109
110void SkNativeGLContext::makeCurrent() const {
111    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
112        SkDebugf("Could not create rendering context.\n");
113    }
114}
115