blob: cce7a56b75a3ad62833fb7be656ca2b604bda742 [file] [log] [blame]
bsalomon@google.combd7c6412011-12-01 16:34:28 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
mtklein1ee76512015-11-02 10:20:27 -08008#include "SkTypes.h"
9#if defined(SK_BUILD_FOR_WIN32)
10
bsalomon@google.combd7c6412011-12-01 16:34:28 +000011#include "SkWGL.h"
12
bsalomon@google.com8a189b02012-04-17 12:43:00 +000013#include "SkTDArray.h"
14#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000015#include "SkTSort.h"
bsalomon@google.com8a189b02012-04-17 12:43:00 +000016
bsalomon@google.combd7c6412011-12-01 16:34:28 +000017bool SkWGLExtensions::hasExtension(HDC dc, const char* ext) const {
halcanary96fcdcc2015-08-27 07:41:13 -070018 if (nullptr == this->fGetExtensionsString) {
bsalomon@google.combd7c6412011-12-01 16:34:28 +000019 return false;
20 }
21 if (!strcmp("WGL_ARB_extensions_string", ext)) {
22 return true;
23 }
24 const char* extensionString = this->getExtensionsString(dc);
robertphillips@google.comadacc702013-10-14 21:53:24 +000025 size_t extLength = strlen(ext);
bsalomon@google.combd7c6412011-12-01 16:34:28 +000026
27 while (true) {
robertphillips@google.comadacc702013-10-14 21:53:24 +000028 size_t n = strcspn(extensionString, " ");
bsalomon@google.combd7c6412011-12-01 16:34:28 +000029 if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
30 return true;
31 }
32 if (0 == extensionString[n]) {
33 return false;
34 }
35 extensionString += n+1;
36 }
37
38 return false;
39}
40
41const char* SkWGLExtensions::getExtensionsString(HDC hdc) const {
42 return fGetExtensionsString(hdc);
43}
44
45BOOL SkWGLExtensions::choosePixelFormat(HDC hdc,
46 const int* piAttribIList,
47 const FLOAT* pfAttribFList,
48 UINT nMaxFormats,
49 int* piFormats,
50 UINT* nNumFormats) const {
51 return fChoosePixelFormat(hdc, piAttribIList, pfAttribFList,
52 nMaxFormats, piFormats, nNumFormats);
53}
54
55BOOL SkWGLExtensions::getPixelFormatAttribiv(HDC hdc,
56 int iPixelFormat,
57 int iLayerPlane,
58 UINT nAttributes,
59 const int *piAttributes,
60 int *piValues) const {
61 return fGetPixelFormatAttribiv(hdc, iPixelFormat, iLayerPlane,
62 nAttributes, piAttributes, piValues);
63}
64
65BOOL SkWGLExtensions::getPixelFormatAttribfv(HDC hdc,
66 int iPixelFormat,
67 int iLayerPlane,
68 UINT nAttributes,
69 const int *piAttributes,
70 float *pfValues) const {
71 return fGetPixelFormatAttribfv(hdc, iPixelFormat, iLayerPlane,
72 nAttributes, piAttributes, pfValues);
73}
74HGLRC SkWGLExtensions::createContextAttribs(HDC hDC,
75 HGLRC hShareContext,
76 const int *attribList) const {
77 return fCreateContextAttribs(hDC, hShareContext, attribList);
78}
79
bsalomon9245b7e2014-07-01 07:20:11 -070080BOOL SkWGLExtensions::swapInterval(int interval) const {
81 return fSwapInterval(interval);
82}
83
84HPBUFFER SkWGLExtensions::createPbuffer(HDC hDC,
85 int iPixelFormat,
86 int iWidth,
87 int iHeight,
88 const int *piAttribList) const {
89 return fCreatePbuffer(hDC, iPixelFormat, iWidth, iHeight, piAttribList);
90}
91
92HDC SkWGLExtensions::getPbufferDC(HPBUFFER hPbuffer) const {
93 return fGetPbufferDC(hPbuffer);
94}
95
96int SkWGLExtensions::releasePbufferDC(HPBUFFER hPbuffer, HDC hDC) const {
97 return fReleasePbufferDC(hPbuffer, hDC);
98}
99
100BOOL SkWGLExtensions::destroyPbuffer(HPBUFFER hPbuffer) const {
101 return fDestroyPbuffer(hPbuffer);
102}
103
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000104namespace {
105
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000106struct PixelFormat {
107 int fFormat;
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000108 int fSampleCnt;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000109 int fChoosePixelFormatRank;
110};
111
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000112bool pf_less(const PixelFormat& a, const PixelFormat& b) {
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000113 if (a.fSampleCnt < b.fSampleCnt) {
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000114 return true;
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000115 } else if (b.fSampleCnt < a.fSampleCnt) {
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000116 return false;
117 } else if (a.fChoosePixelFormatRank < b.fChoosePixelFormatRank) {
118 return true;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000119 }
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000120 return false;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000121}
122}
123
124int SkWGLExtensions::selectFormat(const int formats[],
125 int formatCount,
126 HDC dc,
bsalomon9245b7e2014-07-01 07:20:11 -0700127 int desiredSampleCount) const {
aleksandar.stojiljkovic2944fbb2015-11-05 07:48:12 -0800128 if (formatCount <= 0) {
129 return -1;
130 }
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000131 PixelFormat desiredFormat = {
132 0,
133 desiredSampleCount,
134 0,
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000135 };
136 SkTDArray<PixelFormat> rankedFormats;
137 rankedFormats.setCount(formatCount);
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000138 for (int i = 0; i < formatCount; ++i) {
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000139 static const int kQueryAttr = SK_WGL_SAMPLES;
140 int numSamples;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000141 this->getPixelFormatAttribiv(dc,
142 formats[i],
143 0,
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000144 1,
145 &kQueryAttr,
146 &numSamples);
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000147 rankedFormats[i].fFormat = formats[i];
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000148 rankedFormats[i].fSampleCnt = numSamples;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000149 rankedFormats[i].fChoosePixelFormatRank = i;
150 }
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000151 SkTQSort(rankedFormats.begin(),
152 rankedFormats.begin() + rankedFormats.count() - 1,
153 SkTLessFunctionToFunctorAdaptor<PixelFormat, pf_less>());
154 int idx = SkTSearch<PixelFormat, pf_less>(rankedFormats.begin(),
155 rankedFormats.count(),
156 desiredFormat,
157 sizeof(PixelFormat));
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000158 if (idx < 0) {
159 idx = ~idx;
160 }
161 return rankedFormats[idx].fFormat;
162}
163
164
165namespace {
166
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000167#if defined(UNICODE)
168 #define STR_LIT(X) L## #X
169#else
170 #define STR_LIT(X) #X
171#endif
172
173#define DUMMY_CLASS STR_LIT("DummyClass")
174
175HWND create_dummy_window() {
halcanary96fcdcc2015-08-27 07:41:13 -0700176 HMODULE module = GetModuleHandle(nullptr);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000177 HWND dummy;
178 RECT windowRect;
179 windowRect.left = 0;
180 windowRect.right = 8;
181 windowRect.top = 0;
182 windowRect.bottom = 8;
183
184 WNDCLASS wc;
185
186 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
187 wc.lpfnWndProc = (WNDPROC) DefWindowProc;
188 wc.cbClsExtra = 0;
189 wc.cbWndExtra = 0;
190 wc.hInstance = module;
halcanary96fcdcc2015-08-27 07:41:13 -0700191 wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
192 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
193 wc.hbrBackground = nullptr;
194 wc.lpszMenuName = nullptr;
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000195 wc.lpszClassName = DUMMY_CLASS;
196
197 if(!RegisterClass(&wc)) {
198 return 0;
199 }
200
201 DWORD style, exStyle;
202 exStyle = WS_EX_CLIENTEDGE;
203 style = WS_SYSMENU;
204
205 AdjustWindowRectEx(&windowRect, style, false, exStyle);
206 if(!(dummy = CreateWindowEx(exStyle,
207 DUMMY_CLASS,
208 STR_LIT("DummyWindow"),
209 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
210 0, 0,
211 windowRect.right-windowRect.left,
212 windowRect.bottom-windowRect.top,
halcanary96fcdcc2015-08-27 07:41:13 -0700213 nullptr, nullptr,
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000214 module,
halcanary96fcdcc2015-08-27 07:41:13 -0700215 nullptr))) {
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000216 UnregisterClass(DUMMY_CLASS, module);
halcanary96fcdcc2015-08-27 07:41:13 -0700217 return nullptr;
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000218 }
219 ShowWindow(dummy, SW_HIDE);
220
221 return dummy;
222}
223
224void destroy_dummy_window(HWND dummy) {
225 DestroyWindow(dummy);
halcanary96fcdcc2015-08-27 07:41:13 -0700226 HMODULE module = GetModuleHandle(nullptr);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000227 UnregisterClass(DUMMY_CLASS, module);
228}
229}
230
231#define GET_PROC(NAME, SUFFIX) f##NAME = \
Mike Kleinc722f792017-07-31 11:57:21 -0400232 (NAME##Proc) wglGetProcAddress("wgl" #NAME #SUFFIX)
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000233
234SkWGLExtensions::SkWGLExtensions()
halcanary96fcdcc2015-08-27 07:41:13 -0700235 : fGetExtensionsString(nullptr)
236 , fChoosePixelFormat(nullptr)
237 , fGetPixelFormatAttribfv(nullptr)
238 , fGetPixelFormatAttribiv(nullptr)
239 , fCreateContextAttribs(nullptr)
240 , fSwapInterval(nullptr)
241 , fCreatePbuffer(nullptr)
242 , fGetPbufferDC(nullptr)
243 , fReleasePbufferDC(nullptr)
244 , fDestroyPbuffer(nullptr)
bsalomon9245b7e2014-07-01 07:20:11 -0700245 {
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000246 HDC prevDC = wglGetCurrentDC();
247 HGLRC prevGLRC = wglGetCurrentContext();
248
249 PIXELFORMATDESCRIPTOR dummyPFD;
250
251 ZeroMemory(&dummyPFD, sizeof(dummyPFD));
252 dummyPFD.nSize = sizeof(dummyPFD);
253 dummyPFD.nVersion = 1;
254 dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
255 dummyPFD.iPixelType = PFD_TYPE_RGBA;
256 dummyPFD.cColorBits = 32;
257 dummyPFD.cDepthBits = 0;
258 dummyPFD.cStencilBits = 8;
259 dummyPFD.iLayerType = PFD_MAIN_PLANE;
260 HWND dummyWND = create_dummy_window();
261 if (dummyWND) {
262 HDC dummyDC = GetDC(dummyWND);
263 int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD);
264 SetPixelFormat(dummyDC, dummyFormat, &dummyPFD);
265 HGLRC dummyGLRC = wglCreateContext(dummyDC);
266 SkASSERT(dummyGLRC);
267 wglMakeCurrent(dummyDC, dummyGLRC);
268
269 GET_PROC(GetExtensionsString, ARB);
270 GET_PROC(ChoosePixelFormat, ARB);
271 GET_PROC(GetPixelFormatAttribiv, ARB);
272 GET_PROC(GetPixelFormatAttribfv, ARB);
273 GET_PROC(CreateContextAttribs, ARB);
bsalomon9245b7e2014-07-01 07:20:11 -0700274 GET_PROC(SwapInterval, EXT);
275 GET_PROC(CreatePbuffer, ARB);
276 GET_PROC(GetPbufferDC, ARB);
277 GET_PROC(ReleasePbufferDC, ARB);
278 GET_PROC(DestroyPbuffer, ARB);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000279
halcanary96fcdcc2015-08-27 07:41:13 -0700280 wglMakeCurrent(dummyDC, nullptr);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000281 wglDeleteContext(dummyGLRC);
282 destroy_dummy_window(dummyWND);
283 }
284
285 wglMakeCurrent(prevDC, prevGLRC);
286}
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000287
bsalomon9245b7e2014-07-01 07:20:11 -0700288///////////////////////////////////////////////////////////////////////////////
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000289
bsalomon9245b7e2014-07-01 07:20:11 -0700290static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions,
brianosman2d1ee792016-05-05 12:24:31 -0700291 bool doubleBuffered, int msaaSampleCount, bool deepColor,
bsalomon9245b7e2014-07-01 07:20:11 -0700292 int formatsToTry[2]) {
brianosman2d1ee792016-05-05 12:24:31 -0700293 auto appendAttr = [](SkTDArray<int>& attrs, int attr, int value) {
294 attrs.push(attr);
295 attrs.push(value);
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000296 };
297
brianosman2d1ee792016-05-05 12:24:31 -0700298 SkTDArray<int> iAttrs;
299 appendAttr(iAttrs, SK_WGL_DRAW_TO_WINDOW, TRUE);
300 appendAttr(iAttrs, SK_WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE));
301 appendAttr(iAttrs, SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION);
302 appendAttr(iAttrs, SK_WGL_SUPPORT_OPENGL, TRUE);
303 if (deepColor) {
304 appendAttr(iAttrs, SK_WGL_RED_BITS, 10);
305 appendAttr(iAttrs, SK_WGL_GREEN_BITS, 10);
306 appendAttr(iAttrs, SK_WGL_BLUE_BITS, 10);
307 appendAttr(iAttrs, SK_WGL_ALPHA_BITS, 2);
308 } else {
309 appendAttr(iAttrs, SK_WGL_COLOR_BITS, 24);
310 appendAttr(iAttrs, SK_WGL_ALPHA_BITS, 8);
311 }
312 appendAttr(iAttrs, SK_WGL_STENCIL_BITS, 8);
313
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000314 float fAttrs[] = {0, 0};
315
bsalomon9245b7e2014-07-01 07:20:11 -0700316 // Get a MSAA format if requested and possible.
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000317 if (msaaSampleCount > 0 &&
318 extensions.hasExtension(dc, "WGL_ARB_multisample")) {
brianosman2d1ee792016-05-05 12:24:31 -0700319 SkTDArray<int> msaaIAttrs = iAttrs;
320 appendAttr(msaaIAttrs, SK_WGL_SAMPLE_BUFFERS, TRUE);
321 appendAttr(msaaIAttrs, SK_WGL_SAMPLES, msaaSampleCount);
322 appendAttr(msaaIAttrs, 0, 0);
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000323 unsigned int num;
324 int formats[64];
brianosman2d1ee792016-05-05 12:24:31 -0700325 extensions.choosePixelFormat(dc, msaaIAttrs.begin(), fAttrs, 64, formats, &num);
bsalomon@google.comf3f2d162013-07-31 18:52:31 +0000326 num = SkTMin(num, 64U);
bsalomon9245b7e2014-07-01 07:20:11 -0700327 formatsToTry[0] = extensions.selectFormat(formats, num, dc, msaaSampleCount);
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000328 }
329
bsalomon9245b7e2014-07-01 07:20:11 -0700330 // Get a non-MSAA format
331 int* format = -1 == formatsToTry[0] ? &formatsToTry[0] : &formatsToTry[1];
332 unsigned int num;
brianosman2d1ee792016-05-05 12:24:31 -0700333 appendAttr(iAttrs, 0, 0);
334 extensions.choosePixelFormat(dc, iAttrs.begin(), fAttrs, 1, format, &num);
bsalomon9245b7e2014-07-01 07:20:11 -0700335}
336
Brian Osman60c774d2017-02-21 16:58:08 -0500337static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextRequest contextType,
338 HGLRC shareContext) {
bsalomon9245b7e2014-07-01 07:20:11 -0700339 HDC prevDC = wglGetCurrentDC();
340 HGLRC prevGLRC = wglGetCurrentContext();
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000341
halcanary96fcdcc2015-08-27 07:41:13 -0700342 HGLRC glrc = nullptr;
kkinnunen80549fc2014-06-30 06:36:31 -0700343 if (kGLES_SkWGLContextRequest == contextType) {
344 if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) {
bsalomon9245b7e2014-07-01 07:20:11 -0700345 wglMakeCurrent(prevDC, prevGLRC);
halcanary96fcdcc2015-08-27 07:41:13 -0700346 return nullptr;
kkinnunen80549fc2014-06-30 06:36:31 -0700347 }
348 static const int glesAttribs[] = {
349 SK_WGL_CONTEXT_MAJOR_VERSION, 3,
350 SK_WGL_CONTEXT_MINOR_VERSION, 0,
351 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT,
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000352 0,
353 };
Brian Osman60c774d2017-02-21 16:58:08 -0500354 glrc = extensions.createContextAttribs(dc, shareContext, glesAttribs);
halcanary96fcdcc2015-08-27 07:41:13 -0700355 if (nullptr == glrc) {
bsalomon9245b7e2014-07-01 07:20:11 -0700356 wglMakeCurrent(prevDC, prevGLRC);
halcanary96fcdcc2015-08-27 07:41:13 -0700357 return nullptr;
kkinnunen80549fc2014-06-30 06:36:31 -0700358 }
359 } else {
360 if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
361 extensions.hasExtension(dc, "WGL_ARB_create_context")) {
362 static const int kCoreGLVersions[] = {
363 4, 3,
364 4, 2,
365 4, 1,
366 4, 0,
367 3, 3,
368 3, 2,
369 };
370 int coreProfileAttribs[] = {
371 SK_WGL_CONTEXT_MAJOR_VERSION, -1,
372 SK_WGL_CONTEXT_MINOR_VERSION, -1,
373 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_CORE_PROFILE_BIT,
374 0,
375 };
376 for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) {
377 coreProfileAttribs[1] = kCoreGLVersions[2 * v];
378 coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1];
Brian Osman60c774d2017-02-21 16:58:08 -0500379 glrc = extensions.createContextAttribs(dc, shareContext, coreProfileAttribs);
bsalomon49f085d2014-09-05 13:34:00 -0700380 if (glrc) {
kkinnunen80549fc2014-06-30 06:36:31 -0700381 break;
382 }
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000383 }
384 }
385 }
386
halcanary96fcdcc2015-08-27 07:41:13 -0700387 if (nullptr == glrc) {
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000388 glrc = wglCreateContext(dc);
Brian Osman60c774d2017-02-21 16:58:08 -0500389 if (shareContext) {
390 if (!wglShareLists(shareContext, glrc)) {
391 wglDeleteContext(glrc);
392 return nullptr;
393 }
394 }
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000395 }
396 SkASSERT(glrc);
397
398 wglMakeCurrent(prevDC, prevGLRC);
bsalomon9245b7e2014-07-01 07:20:11 -0700399
400 // This might help make the context non-vsynced.
401 if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
402 extensions.swapInterval(-1);
403 }
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000404 return glrc;
405}
bsalomon9245b7e2014-07-01 07:20:11 -0700406
brianosman2d1ee792016-05-05 12:24:31 -0700407HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, bool deepColor,
Brian Osman60c774d2017-02-21 16:58:08 -0500408 SkWGLContextRequest contextType, HGLRC shareContext) {
bsalomon9245b7e2014-07-01 07:20:11 -0700409 SkWGLExtensions extensions;
410 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
halcanary96fcdcc2015-08-27 07:41:13 -0700411 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700412 }
413
414 BOOL set = FALSE;
415
416 int pixelFormatsToTry[] = { -1, -1 };
brianosman2d1ee792016-05-05 12:24:31 -0700417 get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, deepColor, pixelFormatsToTry);
bsalomon9245b7e2014-07-01 07:20:11 -0700418 for (int f = 0;
419 !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry);
420 ++f) {
421 PIXELFORMATDESCRIPTOR pfd;
422 DescribePixelFormat(dc, pixelFormatsToTry[f], sizeof(pfd), &pfd);
423 set = SetPixelFormat(dc, pixelFormatsToTry[f], &pfd);
424 }
425
426 if (!set) {
halcanary96fcdcc2015-08-27 07:41:13 -0700427 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700428 }
429
Brian Osman60c774d2017-02-21 16:58:08 -0500430 return create_gl_context(dc, extensions, contextType, shareContext);
431}
bsalomon9245b7e2014-07-01 07:20:11 -0700432
433SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCount,
Brian Osman60c774d2017-02-21 16:58:08 -0500434 SkWGLContextRequest contextType,
435 HGLRC shareContext) {
bsalomon9245b7e2014-07-01 07:20:11 -0700436 SkWGLExtensions extensions;
437 if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
438 !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) {
halcanary96fcdcc2015-08-27 07:41:13 -0700439 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700440 }
441
442 // try for single buffer first
443 for (int dblBuffer = 0; dblBuffer < 2; ++dblBuffer) {
444 int pixelFormatsToTry[] = { -1, -1 };
445 get_pixel_formats_to_try(parentDC, extensions, (0 != dblBuffer), msaaSampleCount,
brianosman2d1ee792016-05-05 12:24:31 -0700446 false, pixelFormatsToTry);
bsalomon9245b7e2014-07-01 07:20:11 -0700447 for (int f = 0; -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry); ++f) {
halcanary96fcdcc2015-08-27 07:41:13 -0700448 HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormatsToTry[f], 1, 1, nullptr);
bsalomon9245b7e2014-07-01 07:20:11 -0700449 if (0 != pbuf) {
450 HDC dc = extensions.getPbufferDC(pbuf);
bsalomon49f085d2014-09-05 13:34:00 -0700451 if (dc) {
Brian Osman60c774d2017-02-21 16:58:08 -0500452 HGLRC glrc = create_gl_context(dc, extensions, contextType, shareContext);
bsalomon49f085d2014-09-05 13:34:00 -0700453 if (glrc) {
halcanary385fe4d2015-08-26 13:07:48 -0700454 return new SkWGLPbufferContext(pbuf, dc, glrc);
bsalomon9245b7e2014-07-01 07:20:11 -0700455 }
456 extensions.releasePbufferDC(pbuf, dc);
457 }
458 extensions.destroyPbuffer(pbuf);
459 }
460 }
461 }
halcanary96fcdcc2015-08-27 07:41:13 -0700462 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700463}
464
465SkWGLPbufferContext::~SkWGLPbufferContext() {
466 SkASSERT(fExtensions.hasExtension(fDC, "WGL_ARB_pbuffer"));
467 wglDeleteContext(fGLRC);
468 fExtensions.releasePbufferDC(fPbuffer, fDC);
469 fExtensions.destroyPbuffer(fPbuffer);
470}
471
472SkWGLPbufferContext::SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc)
473 : fPbuffer(pbuffer)
474 , fDC(dc)
475 , fGLRC(glrc) {
476}
mtklein1ee76512015-11-02 10:20:27 -0800477
478#endif//defined(SK_BUILD_FOR_WIN32)