1373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
2373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com/*
3373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com * Copyright 2011 Google Inc.
4373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com *
5373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
6373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com * found in the LICENSE file.
7373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com */
8373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
96c8c34e65ff8248ec7374e0d662d7f5684d800fatomhudson@google.com#include "gl/SkNativeGLContext.h"
10b7f20f20ac4d87819789211aec5935ec1b83ffcdbsalomon@google.com#include "SkWGL.h"
11373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
12373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com#define WIN32_LEAN_AND_MEAN
130d9e3da8bb853c5ed96d13646a4264eb57b13a2abungeman@google.com#include <windows.h>
14373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
1557f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.comSkNativeGLContext::AutoContextRestore::AutoContextRestore() {
1657f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com    fOldHGLRC = wglGetCurrentContext();
1757f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com    fOldHDC = wglGetCurrentDC();
1857f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com}
1957f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com
2057f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.comSkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
2157f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com    wglMakeCurrent(fOldHDC, fOldHGLRC);
2257f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com}
2357f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com
2457f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
2557f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com
26373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comATOM SkNativeGLContext::gWC = 0;
27373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
28373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comSkNativeGLContext::SkNativeGLContext()
2957f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com    : fWindow(NULL)
3057f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com    , fDeviceContext(NULL)
3157f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com    , fGlRenderContext(0) {
32373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
33373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
34373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comSkNativeGLContext::~SkNativeGLContext() {
35373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    this->destroyGLContext();
36373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
37373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
38373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comvoid SkNativeGLContext::destroyGLContext() {
39373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (fGlRenderContext) {
40373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        wglDeleteContext(fGlRenderContext);
41373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
42373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (fWindow && fDeviceContext) {
43373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        ReleaseDC(fWindow, fDeviceContext);
44373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
45373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (fWindow) {
46373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        DestroyWindow(fWindow);
47373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
48373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
49373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
50373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comconst GrGLInterface* SkNativeGLContext::createGLContext() {
51373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
52373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
53acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com    if (!gWC) {
54acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        WNDCLASS wc;
55acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.cbClsExtra = 0;
56acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.cbWndExtra = 0;
57acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.hbrBackground = NULL;
58acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
59acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
60acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.hInstance = hInstance;
61acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.lpfnWndProc = (WNDPROC) DefWindowProc;
62acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.lpszClassName = TEXT("Griffin");
63acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.lpszMenuName = NULL;
64acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
65acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com
66acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        gWC = RegisterClass(&wc);
67acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        if (!gWC) {
68acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com            SkDebugf("Could not register window class.\n");
69acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com            return NULL;
70acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        }
71acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com    }
72acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com
73acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com    if (!(fWindow = CreateWindow(TEXT("Griffin"),
74acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com                                 TEXT("The Invisible Man"),
75acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com                                 WS_OVERLAPPEDWINDOW,
76acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com                                 0, 0, 1, 1,
77acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com                                 NULL, NULL,
78acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com                                 hInstance, NULL))) {
79acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        SkDebugf("Could not create window.\n");
80acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com        return NULL;
81acf3ecc7f70567a26f1435b5d3de45b316338b3ebsalomon@google.com    }
82373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
83373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (!(fDeviceContext = GetDC(fWindow))) {
84373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        SkDebugf("Could not get device context.\n");
85373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        this->destroyGLContext();
86373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        return NULL;
87373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
88d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
89d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org    // Requesting a Core profile would bar us from using NVPR. So we pass false.
90d8ed85101ee77ad2cb0c186a79d197698a75d246commit-bot@chromium.org    if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, false))) {
91373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        SkDebugf("Could not create rendering context.\n");
92373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        this->destroyGLContext();
93373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        return NULL;
94373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
95373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
96373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
97373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        SkDebugf("Could not set the context.\n");
98373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        this->destroyGLContext();
99373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        return NULL;
100373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
101373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    const GrGLInterface* interface = GrGLCreateNativeInterface();
102373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (NULL == interface) {
103373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        SkDebugf("Could not create GL interface.\n");
104373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        this->destroyGLContext();
105373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        return NULL;
106373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
107373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
108373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    return interface;
109373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
110373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
111373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.comvoid SkNativeGLContext::makeCurrent() const {
112373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
113373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        SkDebugf("Could not create rendering context.\n");
114373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
115373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
116c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com
117c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.comvoid SkNativeGLContext::swapBuffers() const {
118c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com    if (!SwapBuffers(fDeviceContext)) {
119c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com        SkDebugf("Could not complete SwapBuffers.\n");
120c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com    }
121c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com}
122