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

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: fix sampleapp 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){
robertphillips 2014/06/30 20:03:33 NULL out other guys here too?
bsalomon 2014/06/30 20:09:12 Done.
211 HDC prevDC = wglGetCurrentDC(); 236 HDC prevDC = wglGetCurrentDC();
212 HGLRC prevGLRC = wglGetCurrentContext(); 237 HGLRC prevGLRC = wglGetCurrentContext();
213 238
214 PIXELFORMATDESCRIPTOR dummyPFD; 239 PIXELFORMATDESCRIPTOR dummyPFD;
215 240
216 ZeroMemory(&dummyPFD, sizeof(dummyPFD)); 241 ZeroMemory(&dummyPFD, sizeof(dummyPFD));
217 dummyPFD.nSize = sizeof(dummyPFD); 242 dummyPFD.nSize = sizeof(dummyPFD);
218 dummyPFD.nVersion = 1; 243 dummyPFD.nVersion = 1;
219 dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; 244 dummyPFD.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
220 dummyPFD.iPixelType = PFD_TYPE_RGBA; 245 dummyPFD.iPixelType = PFD_TYPE_RGBA;
221 dummyPFD.cColorBits = 32; 246 dummyPFD.cColorBits = 32;
222 dummyPFD.cDepthBits = 0; 247 dummyPFD.cDepthBits = 0;
223 dummyPFD.cStencilBits = 8; 248 dummyPFD.cStencilBits = 8;
224 dummyPFD.iLayerType = PFD_MAIN_PLANE; 249 dummyPFD.iLayerType = PFD_MAIN_PLANE;
225 HWND dummyWND = create_dummy_window(); 250 HWND dummyWND = create_dummy_window();
226 if (dummyWND) { 251 if (dummyWND) {
227 HDC dummyDC = GetDC(dummyWND); 252 HDC dummyDC = GetDC(dummyWND);
228 int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD); 253 int dummyFormat = ChoosePixelFormat(dummyDC, &dummyPFD);
229 SetPixelFormat(dummyDC, dummyFormat, &dummyPFD); 254 SetPixelFormat(dummyDC, dummyFormat, &dummyPFD);
230 HGLRC dummyGLRC = wglCreateContext(dummyDC); 255 HGLRC dummyGLRC = wglCreateContext(dummyDC);
231 SkASSERT(dummyGLRC); 256 SkASSERT(dummyGLRC);
232 wglMakeCurrent(dummyDC, dummyGLRC); 257 wglMakeCurrent(dummyDC, dummyGLRC);
233 258
234 GET_PROC(GetExtensionsString, ARB); 259 GET_PROC(GetExtensionsString, ARB);
235 GET_PROC(ChoosePixelFormat, ARB); 260 GET_PROC(ChoosePixelFormat, ARB);
236 GET_PROC(GetPixelFormatAttribiv, ARB); 261 GET_PROC(GetPixelFormatAttribiv, ARB);
237 GET_PROC(GetPixelFormatAttribfv, ARB); 262 GET_PROC(GetPixelFormatAttribfv, ARB);
238 GET_PROC(CreateContextAttribs, ARB); 263 GET_PROC(CreateContextAttribs, ARB);
264 GET_PROC(SwapInterval, EXT);
265 GET_PROC(CreatePbuffer, ARB);
266 GET_PROC(GetPbufferDC, ARB);
267 GET_PROC(ReleasePbufferDC, ARB);
268 GET_PROC(DestroyPbuffer, ARB);
239 269
240 wglMakeCurrent(dummyDC, NULL); 270 wglMakeCurrent(dummyDC, NULL);
241 wglDeleteContext(dummyGLRC); 271 wglDeleteContext(dummyGLRC);
242 destroy_dummy_window(dummyWND); 272 destroy_dummy_window(dummyWND);
243 } 273 }
244 274
245 wglMakeCurrent(prevDC, prevGLRC); 275 wglMakeCurrent(prevDC, prevGLRC);
246 } 276 }
247 277
248 HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest contex tType) { 278 ///////////////////////////////////////////////////////////////////////////////
249 SkWGLExtensions extensions;
250 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
251 return NULL;
252 }
253 279
254 HDC prevDC = wglGetCurrentDC(); 280 static void get_pixel_formats_to_try(HDC dc, const SkWGLExtensions& extensions,
255 HGLRC prevGLRC = wglGetCurrentContext(); 281 bool doubleBuffered, int msaaSampleCount,
256 PIXELFORMATDESCRIPTOR pfd; 282 int formatsToTry[2]) {
257 283 int iAttrs[] = {
258 int format = 0;
259
260 static const int iAttrs[] = {
261 SK_WGL_DRAW_TO_WINDOW, TRUE, 284 SK_WGL_DRAW_TO_WINDOW, TRUE,
262 SK_WGL_DOUBLE_BUFFER, TRUE, 285 SK_WGL_DOUBLE_BUFFER, (doubleBuffered ? TRUE : FALSE),
263 SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION, 286 SK_WGL_ACCELERATION, SK_WGL_FULL_ACCELERATION,
264 SK_WGL_SUPPORT_OPENGL, TRUE, 287 SK_WGL_SUPPORT_OPENGL, TRUE,
265 SK_WGL_COLOR_BITS, 24, 288 SK_WGL_COLOR_BITS, 24,
266 SK_WGL_ALPHA_BITS, 8, 289 SK_WGL_ALPHA_BITS, 8,
267 SK_WGL_STENCIL_BITS, 8, 290 SK_WGL_STENCIL_BITS, 8,
268 0, 0 291 0, 0
269 }; 292 };
270 293
271 float fAttrs[] = {0, 0}; 294 float fAttrs[] = {0, 0};
272 295
296 // Get a MSAA format if requested and possible.
273 if (msaaSampleCount > 0 && 297 if (msaaSampleCount > 0 &&
274 extensions.hasExtension(dc, "WGL_ARB_multisample")) { 298 extensions.hasExtension(dc, "WGL_ARB_multisample")) {
275 static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs); 299 static const int kIAttrsCount = SK_ARRAY_COUNT(iAttrs);
276 int msaaIAttrs[kIAttrsCount + 4]; 300 int msaaIAttrs[kIAttrsCount + 4];
277 memcpy(msaaIAttrs, iAttrs, sizeof(int) * kIAttrsCount); 301 memcpy(msaaIAttrs, iAttrs, sizeof(int) * kIAttrsCount);
278 SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] && 302 SkASSERT(0 == msaaIAttrs[kIAttrsCount - 2] &&
279 0 == msaaIAttrs[kIAttrsCount - 1]); 303 0 == msaaIAttrs[kIAttrsCount - 1]);
280 msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS; 304 msaaIAttrs[kIAttrsCount - 2] = SK_WGL_SAMPLE_BUFFERS;
281 msaaIAttrs[kIAttrsCount - 1] = TRUE; 305 msaaIAttrs[kIAttrsCount - 1] = TRUE;
282 msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES; 306 msaaIAttrs[kIAttrsCount + 0] = SK_WGL_SAMPLES;
283 msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount; 307 msaaIAttrs[kIAttrsCount + 1] = msaaSampleCount;
284 msaaIAttrs[kIAttrsCount + 2] = 0; 308 msaaIAttrs[kIAttrsCount + 2] = 0;
285 msaaIAttrs[kIAttrsCount + 3] = 0; 309 msaaIAttrs[kIAttrsCount + 3] = 0;
286 unsigned int num; 310 unsigned int num;
287 int formats[64]; 311 int formats[64];
288 extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num); 312 extensions.choosePixelFormat(dc, msaaIAttrs, fAttrs, 64, formats, &num);
289 num = SkTMin(num, 64U); 313 num = SkTMin(num, 64U);
290 int formatToTry = extensions.selectFormat(formats, 314 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 } 315 }
299 316
300 if (0 == format) { 317 // Get a non-MSAA format
301 // Either MSAA wasn't requested or creation failed 318 int* format = -1 == formatsToTry[0] ? &formatsToTry[0] : &formatsToTry[1];
302 unsigned int num; 319 unsigned int num;
303 extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, &format, &num); 320 extensions.choosePixelFormat(dc, iAttrs, fAttrs, 1, format, &num);
304 DescribePixelFormat(dc, format, sizeof(pfd), &pfd); 321 }
305 SkDEBUGCODE(BOOL set =) SetPixelFormat(dc, format, &pfd); 322
306 SkASSERT(TRUE == set); 323 static HGLRC create_gl_context(HDC dc, SkWGLExtensions extensions, SkWGLContextR equest contextType) {
307 } 324 HDC prevDC = wglGetCurrentDC();
325 HGLRC prevGLRC = wglGetCurrentContext();
308 326
309 HGLRC glrc = NULL; 327 HGLRC glrc = NULL;
310 if (kGLES_SkWGLContextRequest == contextType) { 328 if (kGLES_SkWGLContextRequest == contextType) {
311 if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) { 329 if (!extensions.hasExtension(dc, "WGL_EXT_create_context_es2_profile")) {
330 wglMakeCurrent(prevDC, prevGLRC);
312 return NULL; 331 return NULL;
313 } 332 }
314 static const int glesAttribs[] = { 333 static const int glesAttribs[] = {
315 SK_WGL_CONTEXT_MAJOR_VERSION, 3, 334 SK_WGL_CONTEXT_MAJOR_VERSION, 3,
316 SK_WGL_CONTEXT_MINOR_VERSION, 0, 335 SK_WGL_CONTEXT_MINOR_VERSION, 0,
317 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT, 336 SK_WGL_CONTEXT_PROFILE_MASK, SK_WGL_CONTEXT_ES2_PROFILE_BIT,
318 0, 337 0,
319 }; 338 };
320 glrc = extensions.createContextAttribs(dc, NULL, glesAttribs); 339 glrc = extensions.createContextAttribs(dc, NULL, glesAttribs);
321 if (NULL == glrc) { 340 if (NULL == glrc) {
341 wglMakeCurrent(prevDC, prevGLRC);
322 return NULL; 342 return NULL;
323 } 343 }
324 } else { 344 } else {
325 if (kGLPreferCoreProfile_SkWGLContextRequest == contextType && 345 if (kGLPreferCoreProfile_SkWGLContextRequest == contextType &&
326 extensions.hasExtension(dc, "WGL_ARB_create_context")) { 346 extensions.hasExtension(dc, "WGL_ARB_create_context")) {
327 static const int kCoreGLVersions[] = { 347 static const int kCoreGLVersions[] = {
328 4, 3, 348 4, 3,
329 4, 2, 349 4, 2,
330 4, 1, 350 4, 1,
331 4, 0, 351 4, 0,
(...skipping 16 matching lines...) Expand all
348 } 368 }
349 } 369 }
350 } 370 }
351 371
352 if (NULL == glrc) { 372 if (NULL == glrc) {
353 glrc = wglCreateContext(dc); 373 glrc = wglCreateContext(dc);
354 } 374 }
355 SkASSERT(glrc); 375 SkASSERT(glrc);
356 376
357 wglMakeCurrent(prevDC, prevGLRC); 377 wglMakeCurrent(prevDC, prevGLRC);
378
379 // This might help make the context non-vsynced.
380 if (extensions.hasExtension(dc, "WGL_EXT_swap_control")) {
381 extensions.swapInterval(-1);
382 }
358 return glrc; 383 return glrc;
359 } 384 }
385
386 HGLRC SkCreateWGLContext(HDC dc, int msaaSampleCount, SkWGLContextRequest contex tType) {
387 SkWGLExtensions extensions;
388 if (!extensions.hasExtension(dc, "WGL_ARB_pixel_format")) {
389 return NULL;
390 }
391
392 BOOL set = FALSE;
393
394 int pixelFormatsToTry[] = { -1, -1 };
395 get_pixel_formats_to_try(dc, extensions, true, msaaSampleCount, pixelFormats ToTry);
396 for (int f = 0;
397 !set && -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFormatsTo Try);
398 ++f) {
399 PIXELFORMATDESCRIPTOR pfd;
400 DescribePixelFormat(dc, pixelFormatsToTry[f], sizeof(pfd), &pfd);
401 set = SetPixelFormat(dc, pixelFormatsToTry[f], &pfd);
402 }
403
404 if (!set) {
405 return NULL;
406 }
407
408 return create_gl_context(dc, extensions, contextType);}
409
410 SkWGLPbufferContext* SkWGLPbufferContext::Create(HDC parentDC, int msaaSampleCou nt,
411 SkWGLContextRequest contextType ) {
412 SkWGLExtensions extensions;
413 if (!extensions.hasExtension(parentDC, "WGL_ARB_pixel_format") ||
414 !extensions.hasExtension(parentDC, "WGL_ARB_pbuffer")) {
415 return NULL;
416 }
417
418 // try for single buffer first
419 for (int dblBuffer = 0; dblBuffer < 2; ++dblBuffer) {
420 int pixelFormatsToTry[] = { -1, -1 };
421 get_pixel_formats_to_try(parentDC, extensions, (0 != dblBuffer), msaaSam pleCount,
422 pixelFormatsToTry);
423 for (int f = 0; -1 != pixelFormatsToTry[f] && f < SK_ARRAY_COUNT(pixelFo rmatsToTry); ++f) {
424 HPBUFFER pbuf = extensions.createPbuffer(parentDC, pixelFormatsToTry [f], 1, 1, NULL);
425 if (0 != pbuf) {
426 HDC dc = extensions.getPbufferDC(pbuf);
427 if (NULL != dc) {
428 HGLRC glrc = create_gl_context(dc, extensions, contextType);
429 if (NULL != glrc) {
430 return SkNEW_ARGS(SkWGLPbufferContext, (pbuf, dc, glrc)) ;
431 }
432 extensions.releasePbufferDC(pbuf, dc);
433 }
434 extensions.destroyPbuffer(pbuf);
435 }
436 }
437 }
438 return NULL;
439 }
440
441 SkWGLPbufferContext::~SkWGLPbufferContext() {
442 SkASSERT(fExtensions.hasExtension(fDC, "WGL_ARB_pbuffer"));
443 wglDeleteContext(fGLRC);
444 fExtensions.releasePbufferDC(fPbuffer, fDC);
445 fExtensions.destroyPbuffer(fPbuffer);
446 }
447
448 SkWGLPbufferContext::SkWGLPbufferContext(HPBUFFER pbuffer, HDC dc, HGLRC glrc)
robertphillips 2014/06/30 20:03:33 tab these guys over?
bsalomon 2014/06/30 20:09:12 Done.
449 : fPbuffer(pbuffer)
450 , fDC(dc)
451 , fGLRC(glrc) {
452 }
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