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    // Requesting a Core profile would bar us from using NVPR. So we pass false.
90    if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false))) {
91        SkDebugf("Could not create rendering context.\n");
92        this->destroyGLContext();
93        return NULL;
94    }
95
96    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
97        SkDebugf("Could not set the context.\n");
98        this->destroyGLContext();
99        return NULL;
100    }
101    const GrGLInterface* interface = GrGLCreateNativeInterface();
102    if (NULL == interface) {
103        SkDebugf("Could not create GL interface.\n");
104        this->destroyGLContext();
105        return NULL;
106    }
107
108    return interface;
109}
110
111void SkNativeGLContext::makeCurrent() const {
112    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
113        SkDebugf("Could not create rendering context.\n");
114    }
115}
116
117void SkNativeGLContext::swapBuffers() const {
118    if (!SwapBuffers(fDeviceContext)) {
119        SkDebugf("Could not complete SwapBuffers.\n");
120    }
121}
122