blob: d362556a4e96271e4846f560785bd0acc4173c5c [file] [log] [blame]
bsalomon@google.com373a6632011-10-19 20:43:20 +00001
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
kkinnunen9e61bb72014-10-09 05:24:15 -07009#include "gl/SkGLContext.h"
10
11#include <windows.h>
12#include <GL/GL.h>
13#include "SkWGL.h"
bsalomon@google.com373a6632011-10-19 20:43:20 +000014
15#define WIN32_LEAN_AND_MEAN
bungeman@google.com0d9e3da2013-12-03 15:23:37 +000016#include <windows.h>
bsalomon@google.com373a6632011-10-19 20:43:20 +000017
kkinnunen9e61bb72014-10-09 05:24:15 -070018namespace {
bsalomon@google.com57f5d982011-10-24 21:17:53 +000019
kkinnunen9e61bb72014-10-09 05:24:15 -070020class WinGLContext : public SkGLContext {
21public:
22 WinGLContext();
bsalomon@google.com57f5d982011-10-24 21:17:53 +000023
kkinnunen9e61bb72014-10-09 05:24:15 -070024 virtual ~WinGLContext();
bsalomon@google.com57f5d982011-10-24 21:17:53 +000025
kkinnunen9e61bb72014-10-09 05:24:15 -070026 virtual void makeCurrent() const SK_OVERRIDE;
27 virtual void swapBuffers() const SK_OVERRIDE;
28protected:
29 virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_OVERRIDE;
30 virtual void destroyGLContext() SK_OVERRIDE;
bsalomon@google.com373a6632011-10-19 20:43:20 +000031
kkinnunen9e61bb72014-10-09 05:24:15 -070032private:
33 HWND fWindow;
34 HDC fDeviceContext;
35 HGLRC fGlRenderContext;
36 static ATOM gWC;
37 SkWGLPbufferContext* fPbufferContext;
38};
39
40ATOM WinGLContext::gWC = 0;
41
42WinGLContext::WinGLContext()
bsalomon@google.com57f5d982011-10-24 21:17:53 +000043 : fWindow(NULL)
44 , fDeviceContext(NULL)
bsalomon9245b7e2014-07-01 07:20:11 -070045 , fGlRenderContext(0)
46 , fPbufferContext(NULL) {
bsalomon@google.com373a6632011-10-19 20:43:20 +000047}
48
kkinnunen9e61bb72014-10-09 05:24:15 -070049WinGLContext::~WinGLContext() {
bsalomon@google.com373a6632011-10-19 20:43:20 +000050 this->destroyGLContext();
51}
52
kkinnunen9e61bb72014-10-09 05:24:15 -070053void WinGLContext::destroyGLContext() {
bsalomon9245b7e2014-07-01 07:20:11 -070054 SkSafeSetNull(fPbufferContext);
bsalomon@google.com373a6632011-10-19 20:43:20 +000055 if (fGlRenderContext) {
56 wglDeleteContext(fGlRenderContext);
bsalomon9245b7e2014-07-01 07:20:11 -070057 fGlRenderContext = 0;
bsalomon@google.com373a6632011-10-19 20:43:20 +000058 }
59 if (fWindow && fDeviceContext) {
60 ReleaseDC(fWindow, fDeviceContext);
bsalomon9245b7e2014-07-01 07:20:11 -070061 fDeviceContext = 0;
bsalomon@google.com373a6632011-10-19 20:43:20 +000062 }
63 if (fWindow) {
64 DestroyWindow(fWindow);
bsalomon9245b7e2014-07-01 07:20:11 -070065 fWindow = 0;
bsalomon@google.com373a6632011-10-19 20:43:20 +000066 }
67}
68
kkinnunen9e61bb72014-10-09 05:24:15 -070069const GrGLInterface* WinGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
bsalomon@google.com373a6632011-10-19 20:43:20 +000070 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
71
bsalomon@google.comacf3ecc2013-03-05 19:30:54 +000072 if (!gWC) {
73 WNDCLASS wc;
74 wc.cbClsExtra = 0;
75 wc.cbWndExtra = 0;
76 wc.hbrBackground = NULL;
77 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
78 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
79 wc.hInstance = hInstance;
80 wc.lpfnWndProc = (WNDPROC) DefWindowProc;
81 wc.lpszClassName = TEXT("Griffin");
82 wc.lpszMenuName = NULL;
83 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
84
85 gWC = RegisterClass(&wc);
86 if (!gWC) {
87 SkDebugf("Could not register window class.\n");
88 return NULL;
89 }
90 }
91
92 if (!(fWindow = CreateWindow(TEXT("Griffin"),
93 TEXT("The Invisible Man"),
94 WS_OVERLAPPEDWINDOW,
95 0, 0, 1, 1,
96 NULL, NULL,
97 hInstance, NULL))) {
98 SkDebugf("Could not create window.\n");
99 return NULL;
100 }
bsalomon@google.com373a6632011-10-19 20:43:20 +0000101
102 if (!(fDeviceContext = GetDC(fWindow))) {
103 SkDebugf("Could not get device context.\n");
104 this->destroyGLContext();
105 return NULL;
106 }
kkinnunen80549fc2014-06-30 06:36:31 -0700107 // Requesting a Core profile would bar us from using NVPR. So we request
108 // compatibility profile or GL ES.
109 SkWGLContextRequest contextType =
110 kGLES_GrGLStandard == forcedGpuAPI ?
111 kGLES_SkWGLContextRequest : kGLPreferCompatibilityProfile_SkWGLContextRequest;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000112
bsalomon9245b7e2014-07-01 07:20:11 -0700113 fPbufferContext = SkWGLPbufferContext::Create(fDeviceContext, 0, contextType);
114
115 HDC dc;
116 HGLRC glrc;
117
118 if (NULL == fPbufferContext) {
119 if (!(fGlRenderContext = SkCreateWGLContext(fDeviceContext, 0, contextType))) {
120 SkDebugf("Could not create rendering context.\n");
121 this->destroyGLContext();
122 return NULL;
123 }
124 dc = fDeviceContext;
125 glrc = fGlRenderContext;
126 } else {
127 ReleaseDC(fWindow, fDeviceContext);
128 fDeviceContext = 0;
129 DestroyWindow(fWindow);
130 fWindow = 0;
131
132 dc = fPbufferContext->getDC();
133 glrc = fPbufferContext->getGLRC();
bsalomon@google.com373a6632011-10-19 20:43:20 +0000134 }
135
bsalomon9245b7e2014-07-01 07:20:11 -0700136 if (!(wglMakeCurrent(dc, glrc))) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000137 SkDebugf("Could not set the context.\n");
138 this->destroyGLContext();
139 return NULL;
140 }
bsalomon9245b7e2014-07-01 07:20:11 -0700141
bsalomon@google.com373a6632011-10-19 20:43:20 +0000142 const GrGLInterface* interface = GrGLCreateNativeInterface();
143 if (NULL == interface) {
144 SkDebugf("Could not create GL interface.\n");
145 this->destroyGLContext();
146 return NULL;
147 }
148
149 return interface;
150}
151
kkinnunen9e61bb72014-10-09 05:24:15 -0700152void WinGLContext::makeCurrent() const {
bsalomon9245b7e2014-07-01 07:20:11 -0700153 HDC dc;
154 HGLRC glrc;
155
156 if (NULL == fPbufferContext) {
157 dc = fDeviceContext;
158 glrc = fGlRenderContext;
159 } else {
160 dc = fPbufferContext->getDC();
161 glrc = fPbufferContext->getGLRC();
162 }
163
164 if (!wglMakeCurrent(dc, glrc)) {
bsalomon@google.com373a6632011-10-19 20:43:20 +0000165 SkDebugf("Could not create rendering context.\n");
166 }
167}
djsollen@google.comc9542ca2013-10-09 18:25:38 +0000168
kkinnunen9e61bb72014-10-09 05:24:15 -0700169void WinGLContext::swapBuffers() const {
bsalomon9245b7e2014-07-01 07:20:11 -0700170 HDC dc;
171
172 if (NULL == fPbufferContext) {
173 dc = fDeviceContext;
174 } else {
175 dc = fPbufferContext->getDC();
176 }
177 if (!SwapBuffers(dc)) {
djsollen@google.comc9542ca2013-10-09 18:25:38 +0000178 SkDebugf("Could not complete SwapBuffers.\n");
179 }
180}
kkinnunen9e61bb72014-10-09 05:24:15 -0700181
182} // anonymous namespace
183
184SkGLContext* SkCreatePlatformGLContext() {
185 return SkNEW(WinGLContext);
186}
187