Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/utils/win/SkWGL_win.cpp

Issue 336863009: When performing offscreen rendering on windows, attempt to use a pbuffer context. (Closed) Base URL: https://skia.googlesource.com/skia.git@klein
Patch Set: Address initial comments Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/gl/win/SkNativeGLContext_win.cpp ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkWGL.h" 9 #include "SkWGL.h"
10 10
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 float *pfValues) const { 68 float *pfValues) const {
69 return fGetPixelFormatAttribfv(hdc, iPixelFormat, iLayerPlane, 69 return fGetPixelFormatAttribfv(hdc, iPixelFormat, iLayerPlane,
70 nAttributes, piAttributes, pfValues); 70 nAttributes, piAttributes, pfValues);
71 } 71 }
72 HGLRC SkWGLExtensions::createContextAttribs(HDC hDC, 72 HGLRC SkWGLExtensions::createContextAttribs(HDC hDC,
73 HGLRC hShareContext, 73 HGLRC hShareContext,
74 const int *attribList) const { 74 const int *attribList) const {
75 return fCreateContextAttribs(hDC, hShareContext, attribList); 75 return fCreateContextAttribs(hDC, hShareContext, attribList);
76 } 76 }
77 77
78 BOOL SkWGLExtensions::swapInterval(int interval) const {
79 return fSwapInterval(interval);
80 }
81
82 HPBUFFER 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
90 HDC SkWGLExtensions::getPbufferDC(HPBUFFER hPbuffer) const {
91 return fGetPbufferDC(hPbuffer);
92 }
93
94 int SkWGLExtensions::releasePbufferDC(HPBUFFER hPbuffer, HDC hDC) const {
95 return fReleasePbufferDC(hPbuffer, hDC);
96 }
97
98 BOOL SkWGLExtensions::destroyPbuffer(HPBUFFER hPbuffer) const {
99 return fDestroyPbuffer(hPbuffer);
100 }
101
78 namespace { 102 namespace {
79 103
80 struct PixelFormat { 104 struct PixelFormat {
81 int fFormat; 105 int fFormat;
82 int fSampleCnt; 106 int fSampleCnt;
83 int fChoosePixelFormatRank; 107 int fChoosePixelFormatRank;
84 }; 108 };
85 109
86 bool pf_less(const PixelFormat& a, const PixelFormat& b) { 110 bool pf_less(const PixelFormat& a, const PixelFormat& b) {
87 if (a.fSampleCnt < b.fSampleCnt) { 111 if (a.fSampleCnt < b.fSampleCnt) {
88 return true; 112 return true;
89 } else if (b.fSampleCnt < a.fSampleCnt) { 113 } else if (b.fSampleCnt < a.fSampleCnt) {
90 return false; 114 return false;
91 } else if (a.fChoosePixelFormatRank < b.fChoosePixelFormatRank) { 115 } else if (a.fChoosePixelFormatRank < b.fChoosePixelFormatRank) {
92 return true; 116 return true;
93 } 117 }
94 return false; 118 return false;
95 } 119 }
96 } 120 }
97 121
98 int SkWGLExtensions::selectFormat(const int formats[], 122 int SkWGLExtensions::selectFormat(const int formats[],
99 int formatCount, 123 int formatCount,
100 HDC dc, 124 HDC dc,
101 int desiredSampleCount) { 125 int desiredSampleCount) const {
102 PixelFormat desiredFormat = { 126 PixelFormat desiredFormat = {
103 0, 127 0,
104 desiredSampleCount, 128 desiredSampleCount,
105 0, 129 0,
106 }; 130 };
107 SkTDArray<PixelFormat> rankedFormats; 131 SkTDArray<PixelFormat> rankedFormats;
108 rankedFormats.setCount(formatCount); 132 rankedFormats.setCount(formatCount);
109 for (int i = 0; i < formatCount; ++i) { 133 for (int i = 0; i < formatCount; ++i) {
110 static const int kQueryAttr = SK_WGL_SAMPLES; 134 static const int kQueryAttr = SK_WGL_SAMPLES;
111 int numSamples; 135 int numSamples;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 } 224 }
201 225
202 #define GET_PROC(NAME, SUFFIX) f##NAME = \ 226 #define GET_PROC(NAME, SUFFIX) f##NAME = \
203 (##NAME##Proc) wglGetProcAddress("wgl" #NAME #SUFFIX) 227 (##NAME##Proc) wglGetProcAddress("wgl" #NAME #SUFFIX)
204 228
205 SkWGLExtensions::SkWGLExtensions() 229 SkWGLExtensions::SkWGLExtensions()
206 : fGetExtensionsString(NULL) 230 : fGetExtensionsString(NULL)
207 , fChoosePixelFormat(NULL) 231 , fChoosePixelFormat(NULL)
208 , fGetPixelFormatAttribfv(NULL) 232 , fGetPixelFormatAttribfv(NULL)
209 , fGetPixelFormatAttribiv(NULL) 233 , fGetPixelFormatAttribiv(NULL)
210 , fCreateContextAttribs(NULL) { 234 , fCreateContextAttribs(NULL)
235 , fSwapInterval(NULL)
236 , fCreatePbuffer(NULL)
237 , fGetPbufferDC(NULL)
238 , fReleasePbufferDC(NULL)
239 , fDestroyPbuffer(NULL)
240 {
211 HDC prevDC = wglGetCurrentDC(); 241 HDC prevDC = wglGetCurrentDC();
212 HGLRC prevGLRC = wglGetCurrentContext(); 242 HGLRC prevGLRC = wglGetCurrentContext();
213 243
214 PIXELFORMATDESCRIPTOR dummyPFD; 244 PIXELFORMATDESCRIPTOR dummyPFD;
215 245
216 ZeroMemory(&dummyPFD, sizeof(dummyPFD)); 246 ZeroMemory(&dummyPFD, sizeof(dummyPFD));
217 dummyPFD.nSize = sizeof(dummyPFD); 247 dummyPFD.nSize = sizeof(dummyPFD);
218 dummyPFD.nVersion = 1; 248 dummyPFD.nVersion = 1;
219 dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 249 dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
220 dummyPFD.iPixelType = PFD_TYPE_RGBA; 250 dummyPFD.iPixelType = PFD_TYPE_RGBA;
221 dummyPFD.cColorBits = 32; 251 dummyPFD.cColorBits = 32;
222 dummyPFD.cDepthBits = 0; 252 dummyPFD.cDepthBits = 0;
223 dummyPFD.cStencilBits = 8; 253 dummyPFD.cStencilBits = 8;
224 dummyPFD.iLayerType = PFD_MAIN_PLANE; 254 dummyPFD.iLayerType = PFD_MAIN_PLANE;
225 HWND dummyWND = create_dummy_window(); 255 HWND dummyWND = create_dummy_window();
226 if (dummyWND) { 256 if (dummyWND) {
227 HDC dummyDC = GetDC(dummyWND); 257 HDC dummyDC = GetDC(dummyWND);
228 int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD); 258 int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD);
229 SetPixelFormat(dummyDC, dummyFormat, &dummyPFD); 259 SetPixelFormat(dummyDC, dummyFormat, &dummyPFD);
230 HGLRC dummyGLRC = wglCreateContext(dummyDC); 260 HGLRC dummyGLRC = wglCreateContext(dummyDC);
231 SkASSERT(dummyGLRC); 261 SkASSERT(dummyGLRC);
232 wglMakeCurrent(dummyDC, dummyGLRC); 262 wglMakeCurrent(dummyDC, dummyGLRC);
233 263
234 GET_PROC(GetExtensionsString, ARB); 264 GET_PROC(GetExtensionsString, ARB);
235 GET_PROC(ChoosePixelFormat, ARB); 265 GET_PROC(ChoosePixelFormat, ARB);
236 GET_PROC(GetPixelFormatAttribiv, ARB); 266 GET_PROC(GetPixelFormatAttribiv, ARB);
237 GET_PROC(GetPixelFormatAttribfv, ARB); 267 GET_PROC(GetPixelFormatAttribfv, ARB);
238 GET_PROC(CreateContextAttribs, ARB); 268 GET_PROC(CreateContextAttribs, ARB);
269 GET_PROC(SwapInterval, EXT);
270 GET_PROC(CreatePbuffer, ARB);
271 GET_PROC(GetPbufferDC, ARB);
272 GET_PROC(ReleasePbufferDC, ARB);
273 GET_PROC(DestroyPbuffer, ARB);
239 274
240 wglMakeCurrent(dummyDC, NULL); 275 wglMakeCurrent(dummyDC, NULL);
241 wglDeleteContext(dummyGLRC); 276 wglDeleteContext(dummyGLRC);
242 destroy_dummy_window(dummyWND); 277 destroy_dummy_window(dummyWND);
243 } 278 }
244 279
245 wglMakeCurrent(prevDC, prevGLRC); 280 wglMakeCurrent(prevDC, prevGLRC);
246 } 281 }
247 282
248 HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest contex tType) { 283 ///////////////////////////////////////////////////////////////////////////////
249 SkWGLExtensions extensions;
250 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
251 return NULL;
252 }
253 284
254 HDC prevDC = wglGetCurrentDC(); 285 static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions,
255 HGLRC prevGLRC = wglGetCurrentContext(); 286 bool doubleBuffered, int msaaSampleCount,
256 PIXELFORMATDESCRIPTOR pfd; 287 int formatsToTry[2]) {
257 288 int iAttrs[] = {
258 int format = 0;
259
260 static const int iAttrs[] = {
261 SK_WGL_DRAW_TO_WINDOW, TRUE, 289 SK_WGL_DRAW_TO_WINDOW, TRUE,
262 SK_WGL_DOUBLE_BUFFER, TRUE, 290 SK_WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE),
263 SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION, 291 SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION,
264 SK_WGL_SUPPORT_OPENGL, TRUE, 292 SK_WGL_SUPPORT_OPENGL, TRUE,
265 SK_WGL_COLOR_BITS, 24, 293 SK_WGL_COLOR_BITS, 24,
266 SK_WGL_ALPHA_BITS, 8, 294 SK_WGL_ALPHA_BITS, 8,
267 SK_WGL_STENCIL_BITS, 8, 295 SK_WGL_STENCIL_BITS, 8,
268 0, 0 296 0, 0
269 }; 297 };
270 298
271 float fAttrs[] = {0, 0}; 299 float fAttrs[] = {0, 0};
272 300
301 // Get a MSAA format if requested and possible.
273 if (msaaSampleCount > 0 && 302 if (msaaSampleCount > 0 &&
274 extensions.hasExtension(dc, "WGL_ARB_multisample")) { 303 extensions.hasExtension(dc, "WGL_ARB_multisample")) {
275 static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs); 304 static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs);
276 int msaaIAttrs[kIAttrsCount + 4]; 305 int msaaIAttrs[kIAttrsCount + 4];
277 memcpy(msaaIAttrs, iAttrs, sizeof(int) * kIAttrsCount); 306 memcpy(msaaIAttrs, iAttrs, sizeof(int) * kIAttrsCount);
278 SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] && 307 SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] &&
279 0 == msaaIAttrs[kIAttrsCount - 1]); 308 0 == msaaIAttrs[kIAttrsCount - 1]);
280 msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS; 309 msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS;
281 msaaIAttrs[kIAttrsCount - 1] = TRUE; 310 msaaIAttrs[kIAttrsCount - 1] = TRUE;
282 msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES; 311 msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES;
283 msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount; 312 msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount;
284 msaaIAttrs[kIAttrsCount + 2] = 0; 313 msaaIAttrs[kIAttrsCount + 2] = 0;
285 msaaIAttrs[kIAttrsCount + 3] = 0; 314 msaaIAttrs[kIAttrsCount + 3] = 0;
286 unsigned int num; 315 unsigned int num;
287 int formats[64]; 316 int formats[64];
288 extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num); 317 extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num);
289 num = SkTMin(num, 64U); 318 num = SkTMin(num, 64U);
290 int formatToTry = extensions.selectFormat(formats, 319 formatsToTry[0] = extensions.selectFormat(formats, num, dc, msaaSampleCo unt);
291 num,
292 dc,
293 msaaSampleCount);
294 DescribePixelFormat(dc, formatToTry, sizeof(pfd), &pfd);
295 if (SetPixelFormat(dc, formatToTry, &pfd)) {
296 format = formatToTry;
297 }
298 } 320 }
299 321
300 if (0 == format) { 322 // Get a non-MSAA format
301 // Either MSAA wasn't requested or creation failed 323 int* format = -1 == formatsToTry[0] ? &formatsToTry[0] : &formatsToTry[1];
302 unsigned int num; 324 unsigned int num;
303 extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, &format, &num); 325 extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, format, &num);
304 DescribePixelFormat(dc, format, sizeof(pfd), &pfd); 326 }
305 SkDEBUGCODE(BOOL set =) SetPixelFormat(dc, format, &pfd); 327
306 SkASSERT(TRUE == set); 328 static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextR equest contextType) {
307 } 329 HDC prevDC = wglGetCurrentDC();
330 HGLRC prevGLRC = wglGetCurrentContext();
308 331
309 HGLRC glrc = NULL; 332 HGLRC glrc = NULL;
310 if (kGLES_SkWGLContextRequest == contextType) { 333 if (kGLES_SkWGLContextRequest == contextType) {
311 if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) { 334 if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) {
335 wglMakeCurrent(prevDC, prevGLRC);
312 return NULL; 336 return NULL;
313 } 337 }
314 static const int glesAttribs[] = { 338 static const int glesAttribs[] = {
315 SK_WGL_CONTEXT_MAJOR_VERSION, 3, 339 SK_WGL_CONTEXT_MAJOR_VERSION, 3,
316 SK_WGL_CONTEXT_MINOR_VERSION, 0, 340 SK_WGL_CONTEXT_MINOR_VERSION, 0,
317 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT, 341 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT,
318 0, 342 0,
319 }; 343 };
320 glrc = extensions.createContextAttribs(dc, NULL, glesAttribs); 344 glrc = extensions.createContextAttribs(dc, NULL, glesAttribs);
321 if (NULL == glrc) { 345 if (NULL == glrc) {
346 wglMakeCurrent(prevDC, prevGLRC);
322 return NULL; 347 return NULL;
323 } 348 }
324 } else { 349 } else {
325 if (kGLPreferCoreProfile_SkWGLContextRequest == contextType && 350 if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
326 extensions.hasExtension(dc, "WGL_ARB_create_context")) { 351 extensions.hasExtension(dc, "WGL_ARB_create_context")) {
327 static const int kCoreGLVersions[] = { 352 static const int kCoreGLVersions[] = {
328 4, 3, 353 4, 3,
329 4, 2, 354 4, 2,
330 4, 1, 355 4, 1,
331 4, 0, 356 4, 0,
(...skipping 16 matching lines...) Expand all
348 } 373 }
349 } 374 }
350 } 375 }
351 376
352 if (NULL == glrc) { 377 if (NULL == glrc) {
353 glrc = wglCreateContext(dc); 378 glrc = wglCreateContext(dc);
354 } 379 }
355 SkASSERT(glrc); 380 SkASSERT(glrc);
356 381
357 wglMakeCurrent(prevDC, prevGLRC); 382 wglMakeCurrent(prevDC, prevGLRC);
383
384 // This might help make the context non-vsynced.
385 if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
386 extensions.swapInterval(-1);
387 }
358 return glrc; 388 return glrc;
359 } 389 }
390
391 HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest contex tType) {
392 SkWGLExtensions extensions;
393 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
394 return NULL;
395 }
396
397 BOOL set = FALSE;
398
399 int pixelFormatsToTry[] = { -1, -1 };
400 get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, pixelFormats ToTry);
robertphillips 2014/06/30 20:33:21 one line ?
bsalomon 2014/07/01 13:56:24 It overflows 100 chars
401 for (int f = 0;
402 !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsTo Try);
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) {
410 return NULL;
411 }
412
413 return create_gl_context(dc, extensions, contextType);}
414
415 SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCou nt,
416 SkWGLContextRequest contextType ) {
417 SkWGLExtensions extensions;
418 if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
419 !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) {
420 return NULL;
421 }
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), msaaSam pleCount,
427 pixelFormatsToTry);
428 for (int f = 0; -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFo rmatsToTry); ++f) {
429 HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormatsToTry [f], 1, 1, NULL);
430 if (0 != pbuf) {
431 HDC dc = extensions.getPbufferDC(pbuf);
432 if (NULL != dc) {
433 HGLRC glrc = create_gl_context(dc, extensions, contextType);
434 if (NULL != glrc) {
435 return SkNEW_ARGS(SkWGLPbufferContext, (pbuf, dc, glrc)) ;
436 }
437 extensions.releasePbufferDC(pbuf, dc);
438 }
439 extensions.destroyPbuffer(pbuf);
440 }
441 }
442 }
443 return NULL;
444 }
445
446 SkWGLPbufferContext::~SkWGLPbufferContext() {
447 SkASSERT(fExtensions.hasExtension(fDC, "WGL_ARB_pbuffer"));
448 wglDeleteContext(fGLRC);
449 fExtensions.releasePbufferDC(fPbuffer, fDC);
450 fExtensions.destroyPbuffer(fPbuffer);
451 }
452
453 SkWGLPbufferContext::SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc)
454 : fPbuffer(pbuffer)
455 , fDC(dc)
456 , fGLRC(glrc) {
457 }
OLDNEW
« no previous file with comments | « src/gpu/gl/win/SkNativeGLContext_win.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698