11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2011 Google Inc.
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
94f1dae40e24d57d647db01443b8bf2410514b8b5Derek Sollenberger#include "gl/SkNativeGLContext.h"
101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#define WIN32_LEAN_AND_MEAN
121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger#include <Windows.h>
131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
141cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkNativeGLContext::AutoContextRestore::AutoContextRestore() {
151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fOldHGLRC = wglGetCurrentContext();
161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fOldHDC = wglGetCurrentDC();
171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
191cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    wglMakeCurrent(fOldHDC, fOldHGLRC);
211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
251cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerATOM SkNativeGLContext::gWC = 0;
261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
271cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkNativeGLContext::SkNativeGLContext()
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    : fWindow(NULL)
291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    , fDeviceContext(NULL)
301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    , fGlRenderContext(0) {
311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
331cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkNativeGLContext::~SkNativeGLContext() {
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->destroyGLContext();
351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkNativeGLContext::destroyGLContext() {
381cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fGlRenderContext) {
391cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wglDeleteContext(fGlRenderContext);
401cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
411cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fWindow && fDeviceContext) {
421cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        ReleaseDC(fWindow, fDeviceContext);
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
441cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (fWindow) {
451cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        DestroyWindow(fWindow);
461cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
471cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
481cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerconst GrGLInterface* SkNativeGLContext::createGLContext() {
501cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
511cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
521cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!gWC) {
531cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        WNDCLASS wc;
541cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.cbClsExtra = 0;
551cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.cbWndExtra = 0;
561cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.hbrBackground = NULL;
571cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.hCursor = LoadCursor(NULL, IDC_ARROW);
581cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
591cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.hInstance = hInstance;
601cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.lpfnWndProc = (WNDPROC) DefWindowProc;
611cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.lpszClassName = TEXT("Griffin");
621cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.lpszMenuName = NULL;
631cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
641cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        gWC = RegisterClass(&wc);
661cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        if (!gWC) {
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            SkDebugf("Could not register window class.\n");
681cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger            return NULL;
691cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        }
701cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
711cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
721cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(fWindow = CreateWindow(TEXT("Griffin"),
731cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 TEXT("The Invisible Man"),
741cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 WS_OVERLAPPEDWINDOW,
751cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 0, 0, 1, 1,
761cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 NULL, NULL,
771cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger                                 hInstance, NULL))) {
781cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not create window.\n");
791cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
801cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
811cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
821cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(fDeviceContext = GetDC(fWindow))) {
831cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not get device context.\n");
841cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->destroyGLContext();
851cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
861cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
871cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
881cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    PIXELFORMATDESCRIPTOR pfd;
891cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    ZeroMemory(&pfd, sizeof(pfd));
901cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.nSize = sizeof(pfd);
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.nVersion = 1;
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.dwFlags = PFD_SUPPORT_OPENGL;
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.iPixelType = PFD_TYPE_RGBA;
941cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.cColorBits = 32;
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.cDepthBits = 0;
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.cStencilBits = 0;
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    pfd.iLayerType = PFD_MAIN_PLANE;
981cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    int pixelFormat = 0;
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(pixelFormat = ChoosePixelFormat(fDeviceContext, &pfd))) {
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("No matching pixel format descriptor.\n");
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->destroyGLContext();
1031cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!SetPixelFormat(fDeviceContext, pixelFormat, &pfd)) {
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not set the pixel format %d.\n", pixelFormat);
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->destroyGLContext();
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1121cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(fGlRenderContext = wglCreateContext(fDeviceContext))) {
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not create rendering context.\n");
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->destroyGLContext();
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!(wglMakeCurrent(fDeviceContext, fGlRenderContext))) {
1191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not set the context.\n");
1201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->destroyGLContext();
1211cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
1221cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1231cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    const GrGLInterface* interface = GrGLCreateNativeInterface();
1241cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (NULL == interface) {
1251cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not create GL interface.\n");
1261cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        this->destroyGLContext();
1271cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        return NULL;
1281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1291cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1301cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return interface;
1311cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1321cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1331cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkNativeGLContext::makeCurrent() const {
1341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    if (!wglMakeCurrent(fDeviceContext, fGlRenderContext)) {
1351cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkDebugf("Could not create rendering context.\n");
1361cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    }
1371cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
138