blob: ef07bea61e7bb2b6ac138c641d5d4febcd65799d [file] [log] [blame]
bsalomon@google.combd7c6412011-12-01 16:34:28 +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
9#include "SkWGL.h"
10
bsalomon@google.com8a189b02012-04-17 12:43:00 +000011#include "SkTDArray.h"
12#include "SkTSearch.h"
bsalomon@google.com20f7f172013-05-17 19:05:03 +000013#include "SkTSort.h"
bsalomon@google.com8a189b02012-04-17 12:43:00 +000014
bsalomon@google.combd7c6412011-12-01 16:34:28 +000015bool SkWGLExtensions::hasExtension(HDC dc, const char* ext) const {
halcanary96fcdcc2015-08-27 07:41:13 -070016 if (nullptr == this->fGetExtensionsString) {
bsalomon@google.combd7c6412011-12-01 16:34:28 +000017 return false;
18 }
19 if (!strcmp("WGL_ARB_extensions_string", ext)) {
20 return true;
21 }
22 const char* extensionString = this->getExtensionsString(dc);
robertphillips@google.comadacc702013-10-14 21:53:24 +000023 size_t extLength = strlen(ext);
bsalomon@google.combd7c6412011-12-01 16:34:28 +000024
25 while (true) {
robertphillips@google.comadacc702013-10-14 21:53:24 +000026 size_t n = strcspn(extensionString, " ");
bsalomon@google.combd7c6412011-12-01 16:34:28 +000027 if (n == extLength && 0 == strncmp(ext, extensionString, n)) {
28 return true;
29 }
30 if (0 == extensionString[n]) {
31 return false;
32 }
33 extensionString += n+1;
34 }
35
36 return false;
37}
38
39const char* SkWGLExtensions::getExtensionsString(HDC hdc) const {
40 return fGetExtensionsString(hdc);
41}
42
43BOOL SkWGLExtensions::choosePixelFormat(HDC hdc,
44 const int* piAttribIList,
45 const FLOAT* pfAttribFList,
46 UINT nMaxFormats,
47 int* piFormats,
48 UINT* nNumFormats) const {
49 return fChoosePixelFormat(hdc, piAttribIList, pfAttribFList,
50 nMaxFormats, piFormats, nNumFormats);
51}
52
53BOOL SkWGLExtensions::getPixelFormatAttribiv(HDC hdc,
54 int iPixelFormat,
55 int iLayerPlane,
56 UINT nAttributes,
57 const int *piAttributes,
58 int *piValues) const {
59 return fGetPixelFormatAttribiv(hdc, iPixelFormat, iLayerPlane,
60 nAttributes, piAttributes, piValues);
61}
62
63BOOL SkWGLExtensions::getPixelFormatAttribfv(HDC hdc,
64 int iPixelFormat,
65 int iLayerPlane,
66 UINT nAttributes,
67 const int *piAttributes,
68 float *pfValues) const {
69 return fGetPixelFormatAttribfv(hdc, iPixelFormat, iLayerPlane,
70 nAttributes, piAttributes, pfValues);
71}
72HGLRC SkWGLExtensions::createContextAttribs(HDC hDC,
73 HGLRC hShareContext,
74 const int *attribList) const {
75 return fCreateContextAttribs(hDC, hShareContext, attribList);
76}
77
bsalomon9245b7e2014-07-01 07:20:11 -070078BOOL SkWGLExtensions::swapInterval(int interval) const {
79 return fSwapInterval(interval);
80}
81
82HPBUFFER SkWGLExtensions::createPbuffer(HDC hDC,
83 int iPixelFormat,
84 int iWidth,
85 int iHeight,
86 const int *piAttribList) const {
87 return fCreatePbuffer(hDC, iPixelFormat, iWidth, iHeight, piAttribList);
88}
89
90HDC SkWGLExtensions::getPbufferDC(HPBUFFER hPbuffer) const {
91 return fGetPbufferDC(hPbuffer);
92}
93
94int SkWGLExtensions::releasePbufferDC(HPBUFFER hPbuffer, HDC hDC) const {
95 return fReleasePbufferDC(hPbuffer, hDC);
96}
97
98BOOL SkWGLExtensions::destroyPbuffer(HPBUFFER hPbuffer) const {
99 return fDestroyPbuffer(hPbuffer);
100}
101
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000102namespace {
103
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000104struct PixelFormat {
105 int fFormat;
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000106 int fSampleCnt;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000107 int fChoosePixelFormatRank;
108};
109
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000110bool pf_less(const PixelFormat& a, const PixelFormat& b) {
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000111 if (a.fSampleCnt < b.fSampleCnt) {
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000112 return true;
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000113 } else if (b.fSampleCnt < a.fSampleCnt) {
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000114 return false;
115 } else if (a.fChoosePixelFormatRank < b.fChoosePixelFormatRank) {
116 return true;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000117 }
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000118 return false;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000119}
120}
121
122int SkWGLExtensions::selectFormat(const int formats[],
123 int formatCount,
124 HDC dc,
bsalomon9245b7e2014-07-01 07:20:11 -0700125 int desiredSampleCount) const {
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000126 PixelFormat desiredFormat = {
127 0,
128 desiredSampleCount,
129 0,
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000130 };
131 SkTDArray<PixelFormat> rankedFormats;
132 rankedFormats.setCount(formatCount);
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000133 for (int i = 0; i < formatCount; ++i) {
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000134 static const int kQueryAttr = SK_WGL_SAMPLES;
135 int numSamples;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000136 this->getPixelFormatAttribiv(dc,
137 formats[i],
138 0,
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000139 1,
140 &kQueryAttr,
141 &numSamples);
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000142 rankedFormats[i].fFormat = formats[i];
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000143 rankedFormats[i].fSampleCnt = numSamples;
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000144 rankedFormats[i].fChoosePixelFormatRank = i;
145 }
bsalomon@google.com20f7f172013-05-17 19:05:03 +0000146 SkTQSort(rankedFormats.begin(),
147 rankedFormats.begin() + rankedFormats.count() - 1,
148 SkTLessFunctionToFunctorAdaptor<PixelFormat, pf_less>());
149 int idx = SkTSearch<PixelFormat, pf_less>(rankedFormats.begin(),
150 rankedFormats.count(),
151 desiredFormat,
152 sizeof(PixelFormat));
bsalomon@google.com8a189b02012-04-17 12:43:00 +0000153 if (idx < 0) {
154 idx = ~idx;
155 }
156 return rankedFormats[idx].fFormat;
157}
158
159
160namespace {
161
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000162#if defined(UNICODE)
163 #define STR_LIT(X) L## #X
164#else
165 #define STR_LIT(X) #X
166#endif
167
168#define DUMMY_CLASS STR_LIT("DummyClass")
169
170HWND create_dummy_window() {
halcanary96fcdcc2015-08-27 07:41:13 -0700171 HMODULE module = GetModuleHandle(nullptr);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000172 HWND dummy;
173 RECT windowRect;
174 windowRect.left = 0;
175 windowRect.right = 8;
176 windowRect.top = 0;
177 windowRect.bottom = 8;
178
179 WNDCLASS wc;
180
181 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
182 wc.lpfnWndProc = (WNDPROC) DefWindowProc;
183 wc.cbClsExtra = 0;
184 wc.cbWndExtra = 0;
185 wc.hInstance = module;
halcanary96fcdcc2015-08-27 07:41:13 -0700186 wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO);
187 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
188 wc.hbrBackground = nullptr;
189 wc.lpszMenuName = nullptr;
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000190 wc.lpszClassName = DUMMY_CLASS;
191
192 if(!RegisterClass(&wc)) {
193 return 0;
194 }
195
196 DWORD style, exStyle;
197 exStyle = WS_EX_CLIENTEDGE;
198 style = WS_SYSMENU;
199
200 AdjustWindowRectEx(&windowRect, style, false, exStyle);
201 if(!(dummy = CreateWindowEx(exStyle,
202 DUMMY_CLASS,
203 STR_LIT("DummyWindow"),
204 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
205 0, 0,
206 windowRect.right-windowRect.left,
207 windowRect.bottom-windowRect.top,
halcanary96fcdcc2015-08-27 07:41:13 -0700208 nullptr, nullptr,
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000209 module,
halcanary96fcdcc2015-08-27 07:41:13 -0700210 nullptr))) {
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000211 UnregisterClass(DUMMY_CLASS, module);
halcanary96fcdcc2015-08-27 07:41:13 -0700212 return nullptr;
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000213 }
214 ShowWindow(dummy, SW_HIDE);
215
216 return dummy;
217}
218
219void destroy_dummy_window(HWND dummy) {
220 DestroyWindow(dummy);
halcanary96fcdcc2015-08-27 07:41:13 -0700221 HMODULE module = GetModuleHandle(nullptr);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000222 UnregisterClass(DUMMY_CLASS, module);
223}
224}
225
226#define GET_PROC(NAME, SUFFIX) f##NAME = \
227 (##NAME##Proc) wglGetProcAddress("wgl" #NAME #SUFFIX)
228
229SkWGLExtensions::SkWGLExtensions()
halcanary96fcdcc2015-08-27 07:41:13 -0700230 : fGetExtensionsString(nullptr)
231 , fChoosePixelFormat(nullptr)
232 , fGetPixelFormatAttribfv(nullptr)
233 , fGetPixelFormatAttribiv(nullptr)
234 , fCreateContextAttribs(nullptr)
235 , fSwapInterval(nullptr)
236 , fCreatePbuffer(nullptr)
237 , fGetPbufferDC(nullptr)
238 , fReleasePbufferDC(nullptr)
239 , fDestroyPbuffer(nullptr)
bsalomon9245b7e2014-07-01 07:20:11 -0700240 {
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000241 HDC prevDC = wglGetCurrentDC();
242 HGLRC prevGLRC = wglGetCurrentContext();
243
244 PIXELFORMATDESCRIPTOR dummyPFD;
245
246 ZeroMemory(&dummyPFD, sizeof(dummyPFD));
247 dummyPFD.nSize = sizeof(dummyPFD);
248 dummyPFD.nVersion = 1;
249 dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
250 dummyPFD.iPixelType = PFD_TYPE_RGBA;
251 dummyPFD.cColorBits = 32;
252 dummyPFD.cDepthBits = 0;
253 dummyPFD.cStencilBits = 8;
254 dummyPFD.iLayerType = PFD_MAIN_PLANE;
255 HWND dummyWND = create_dummy_window();
256 if (dummyWND) {
257 HDC dummyDC = GetDC(dummyWND);
258 int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD);
259 SetPixelFormat(dummyDC, dummyFormat, &dummyPFD);
260 HGLRC dummyGLRC = wglCreateContext(dummyDC);
261 SkASSERT(dummyGLRC);
262 wglMakeCurrent(dummyDC, dummyGLRC);
263
264 GET_PROC(GetExtensionsString, ARB);
265 GET_PROC(ChoosePixelFormat, ARB);
266 GET_PROC(GetPixelFormatAttribiv, ARB);
267 GET_PROC(GetPixelFormatAttribfv, ARB);
268 GET_PROC(CreateContextAttribs, ARB);
bsalomon9245b7e2014-07-01 07:20:11 -0700269 GET_PROC(SwapInterval, EXT);
270 GET_PROC(CreatePbuffer, ARB);
271 GET_PROC(GetPbufferDC, ARB);
272 GET_PROC(ReleasePbufferDC, ARB);
273 GET_PROC(DestroyPbuffer, ARB);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000274
halcanary96fcdcc2015-08-27 07:41:13 -0700275 wglMakeCurrent(dummyDC, nullptr);
bsalomon@google.combd7c6412011-12-01 16:34:28 +0000276 wglDeleteContext(dummyGLRC);
277 destroy_dummy_window(dummyWND);
278 }
279
280 wglMakeCurrent(prevDC, prevGLRC);
281}
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000282
bsalomon9245b7e2014-07-01 07:20:11 -0700283///////////////////////////////////////////////////////////////////////////////
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000284
bsalomon9245b7e2014-07-01 07:20:11 -0700285static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions,
286 bool doubleBuffered, int msaaSampleCount,
287 int formatsToTry[2]) {
288 int iAttrs[] = {
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000289 SK_WGL_DRAW_TO_WINDOW, TRUE,
bsalomon9245b7e2014-07-01 07:20:11 -0700290 SK_WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE),
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000291 SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION,
292 SK_WGL_SUPPORT_OPENGL, TRUE,
293 SK_WGL_COLOR_BITS, 24,
294 SK_WGL_ALPHA_BITS, 8,
295 SK_WGL_STENCIL_BITS, 8,
296 0, 0
297 };
298
299 float fAttrs[] = {0, 0};
300
bsalomon9245b7e2014-07-01 07:20:11 -0700301 // Get a MSAA format if requested and possible.
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000302 if (msaaSampleCount > 0 &&
303 extensions.hasExtension(dc, "WGL_ARB_multisample")) {
304 static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs);
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000305 int msaaIAttrs[kIAttrsCount + 4];
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000306 memcpy(msaaIAttrs, iAttrs, sizeof(int) * kIAttrsCount);
307 SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] &&
308 0 == msaaIAttrs[kIAttrsCount - 1]);
309 msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS;
310 msaaIAttrs[kIAttrsCount - 1] = TRUE;
311 msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES;
312 msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount;
commit-bot@chromium.org040fd8f2013-09-06 20:00:41 +0000313 msaaIAttrs[kIAttrsCount + 2] = 0;
314 msaaIAttrs[kIAttrsCount + 3] = 0;
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000315 unsigned int num;
316 int formats[64];
317 extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num);
bsalomon@google.comf3f2d162013-07-31 18:52:31 +0000318 num = SkTMin(num, 64U);
bsalomon9245b7e2014-07-01 07:20:11 -0700319 formatsToTry[0] = extensions.selectFormat(formats, num, dc, msaaSampleCount);
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000320 }
321
bsalomon9245b7e2014-07-01 07:20:11 -0700322 // Get a non-MSAA format
323 int* format = -1 == formatsToTry[0] ? &formatsToTry[0] : &formatsToTry[1];
324 unsigned int num;
325 extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, format, &num);
326}
327
328static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextRequest contextType) {
329 HDC prevDC = wglGetCurrentDC();
330 HGLRC prevGLRC = wglGetCurrentContext();
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000331
halcanary96fcdcc2015-08-27 07:41:13 -0700332 HGLRC glrc = nullptr;
kkinnunen80549fc2014-06-30 06:36:31 -0700333 if (kGLES_SkWGLContextRequest == contextType) {
334 if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) {
bsalomon9245b7e2014-07-01 07:20:11 -0700335 wglMakeCurrent(prevDC, prevGLRC);
halcanary96fcdcc2015-08-27 07:41:13 -0700336 return nullptr;
kkinnunen80549fc2014-06-30 06:36:31 -0700337 }
338 static const int glesAttribs[] = {
339 SK_WGL_CONTEXT_MAJOR_VERSION, 3,
340 SK_WGL_CONTEXT_MINOR_VERSION, 0,
341 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT,
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000342 0,
343 };
halcanary96fcdcc2015-08-27 07:41:13 -0700344 glrc = extensions.createContextAttribs(dc, nullptr, glesAttribs);
345 if (nullptr == glrc) {
bsalomon9245b7e2014-07-01 07:20:11 -0700346 wglMakeCurrent(prevDC, prevGLRC);
halcanary96fcdcc2015-08-27 07:41:13 -0700347 return nullptr;
kkinnunen80549fc2014-06-30 06:36:31 -0700348 }
349 } else {
350 if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
351 extensions.hasExtension(dc, "WGL_ARB_create_context")) {
352 static const int kCoreGLVersions[] = {
353 4, 3,
354 4, 2,
355 4, 1,
356 4, 0,
357 3, 3,
358 3, 2,
359 };
360 int coreProfileAttribs[] = {
361 SK_WGL_CONTEXT_MAJOR_VERSION, -1,
362 SK_WGL_CONTEXT_MINOR_VERSION, -1,
363 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_CORE_PROFILE_BIT,
364 0,
365 };
366 for (int v = 0; v < SK_ARRAY_COUNT(kCoreGLVersions) / 2; ++v) {
367 coreProfileAttribs[1] = kCoreGLVersions[2 * v];
368 coreProfileAttribs[3] = kCoreGLVersions[2 * v + 1];
halcanary96fcdcc2015-08-27 07:41:13 -0700369 glrc = extensions.createContextAttribs(dc, nullptr, coreProfileAttribs);
bsalomon49f085d2014-09-05 13:34:00 -0700370 if (glrc) {
kkinnunen80549fc2014-06-30 06:36:31 -0700371 break;
372 }
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000373 }
374 }
375 }
376
halcanary96fcdcc2015-08-27 07:41:13 -0700377 if (nullptr == glrc) {
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000378 glrc = wglCreateContext(dc);
379 }
380 SkASSERT(glrc);
381
382 wglMakeCurrent(prevDC, prevGLRC);
bsalomon9245b7e2014-07-01 07:20:11 -0700383
384 // This might help make the context non-vsynced.
385 if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
386 extensions.swapInterval(-1);
387 }
bsalomon@google.comb7f20f22013-03-05 19:13:09 +0000388 return glrc;
389}
bsalomon9245b7e2014-07-01 07:20:11 -0700390
391HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest contextType) {
392 SkWGLExtensions extensions;
393 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
halcanary96fcdcc2015-08-27 07:41:13 -0700394 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700395 }
396
397 BOOL set = FALSE;
398
399 int pixelFormatsToTry[] = { -1, -1 };
400 get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, pixelFormatsToTry);
401 for (int f = 0;
402 !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry);
403 ++f) {
404 PIXELFORMATDESCRIPTOR pfd;
405 DescribePixelFormat(dc, pixelFormatsToTry[f], sizeof(pfd), &pfd);
406 set = SetPixelFormat(dc, pixelFormatsToTry[f], &pfd);
407 }
408
409 if (!set) {
halcanary96fcdcc2015-08-27 07:41:13 -0700410 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700411 }
412
413 return create_gl_context(dc, extensions, contextType);}
414
415SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCount,
416 SkWGLContextRequest contextType) {
417 SkWGLExtensions extensions;
418 if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
419 !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) {
halcanary96fcdcc2015-08-27 07:41:13 -0700420 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700421 }
422
423 // try for single buffer first
424 for (int dblBuffer = 0; dblBuffer < 2; ++dblBuffer) {
425 int pixelFormatsToTry[] = { -1, -1 };
426 get_pixel_formats_to_try(parentDC, extensions, (0 != dblBuffer), msaaSampleCount,
427 pixelFormatsToTry);
428 for (int f = 0; -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsToTry); ++f) {
halcanary96fcdcc2015-08-27 07:41:13 -0700429 HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormatsToTry[f], 1, 1, nullptr);
bsalomon9245b7e2014-07-01 07:20:11 -0700430 if (0 != pbuf) {
431 HDC dc = extensions.getPbufferDC(pbuf);
bsalomon49f085d2014-09-05 13:34:00 -0700432 if (dc) {
bsalomon9245b7e2014-07-01 07:20:11 -0700433 HGLRC glrc = create_gl_context(dc, extensions, contextType);
bsalomon49f085d2014-09-05 13:34:00 -0700434 if (glrc) {
halcanary385fe4d2015-08-26 13:07:48 -0700435 return new SkWGLPbufferContext(pbuf, dc, glrc);
bsalomon9245b7e2014-07-01 07:20:11 -0700436 }
437 extensions.releasePbufferDC(pbuf, dc);
438 }
439 extensions.destroyPbuffer(pbuf);
440 }
441 }
442 }
halcanary96fcdcc2015-08-27 07:41:13 -0700443 return nullptr;
bsalomon9245b7e2014-07-01 07:20:11 -0700444}
445
446SkWGLPbufferContext::~SkWGLPbufferContext() {
447 SkASSERT(fExtensions.hasExtension(fDC, "WGL_ARB_pbuffer"));
448 wglDeleteContext(fGLRC);
449 fExtensions.releasePbufferDC(fPbuffer, fDC);
450 fExtensions.destroyPbuffer(fPbuffer);
451}
452
453SkWGLPbufferContext::SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc)
454 : fPbuffer(pbuffer)
455 , fDC(dc)
456 , fGLRC(glrc) {
457}