@@ -405,6 +405,9 @@ def _create_native_swap_chain_if_needed(self):
405
405
return
406
406
self ._surface_size = psize
407
407
408
+ if self ._surface_id is None :
409
+ self ._surface_id = get_surface_id_from_canvas (canvas )
410
+
408
411
# logger.info(str((psize, canvas.get_logical_size(), canvas.get_pixel_ratio())))
409
412
410
413
# Set the present mode to determine vsync behavior.
@@ -421,8 +424,29 @@ def _create_native_swap_chain_if_needed(self):
421
424
# Also see:
422
425
# * https://github.com/gfx-rs/wgpu/blob/e54a36ee/wgpu-types/src/lib.rs#L2663-L2678
423
426
# * https://github.com/pygfx/wgpu-py/issues/256
427
+
424
428
present_mode = 2 if getattr (canvas , "_vsync" , True ) else 0
425
429
430
+ if self ._device :
431
+ # Get present mode
432
+ adapter_id = self ._device .adapter ._internal
433
+ c_count = ffi .new ("size_t *" )
434
+ # H: WGPUPresentMode const * f(WGPUSurface surface, WGPUAdapter adapter, size_t * count)
435
+ c_modes = lib .wgpuSurfaceGetSupportedPresentModes (
436
+ self ._surface_id , adapter_id , c_count
437
+ )
438
+ try :
439
+ count = c_count [0 ]
440
+ supported_modes = [1 * c_modes [i ] for i in range (count )]
441
+ finally :
442
+ t = ffi .typeof (c_modes )
443
+ # H: void f(void* ptr, size_t size, size_t align)
444
+ lib .wgpuFree (c_modes , count * ffi .sizeof (t ), ffi .alignof (t ))
445
+
446
+ # Use a supported one if our preference is not supported
447
+ if supported_modes and present_mode not in supported_modes :
448
+ present_mode = supported_modes [0 ]
449
+
426
450
# H: nextInChain: WGPUChainedStruct *, label: char *, usage: WGPUTextureUsageFlags/int, format: WGPUTextureFormat, width: int, height: int, presentMode: WGPUPresentMode
427
451
struct = new_struct_p (
428
452
"WGPUSwapChainDescriptor *" ,
@@ -435,9 +459,6 @@ def _create_native_swap_chain_if_needed(self):
435
459
# not used: label
436
460
)
437
461
438
- if self ._surface_id is None :
439
- self ._surface_id = get_surface_id_from_canvas (canvas )
440
-
441
462
# Destroy old one
442
463
if self ._internal is not None :
443
464
# H: void f(WGPUSwapChain swapChain)
@@ -448,6 +469,44 @@ def _create_native_swap_chain_if_needed(self):
448
469
self ._device ._internal , self ._surface_id , struct
449
470
)
450
471
472
+ def get_preferred_format (self , adapter ):
473
+ if self ._surface_id is None :
474
+ canvas = self ._get_canvas ()
475
+ self ._surface_id = get_surface_id_from_canvas (canvas )
476
+
477
+ # The C-call
478
+ c_count = ffi .new ("size_t *" )
479
+ # H: WGPUTextureFormat const * f(WGPUSurface surface, WGPUAdapter adapter, size_t * count)
480
+ c_formats = lib .wgpuSurfaceGetSupportedFormats (
481
+ self ._surface_id , adapter ._internal , c_count
482
+ )
483
+
484
+ # Convert to string formats
485
+ try :
486
+ count = c_count [0 ]
487
+ supported_format_ints = [c_formats [i ] for i in range (count )]
488
+ formats = []
489
+ for key in list (enums .TextureFormat ):
490
+ i = enummap [f"TextureFormat.{ key } " ]
491
+ if i in supported_format_ints :
492
+ formats .append (key )
493
+ finally :
494
+ t = ffi .typeof (c_formats )
495
+ # H: void f(void* ptr, size_t size, size_t align)
496
+ lib .wgpuFree (c_formats , count * ffi .sizeof (t ), ffi .alignof (t ))
497
+
498
+ # Select one
499
+ default = "bgra8unorm-srgb" # seems to be a good default
500
+ preferred = [f for f in formats if "srgb" in f ]
501
+ if default in formats :
502
+ return default
503
+ elif preferred :
504
+ return preferred [0 ]
505
+ elif formats :
506
+ return formats [0 ]
507
+ else :
508
+ return default
509
+
451
510
def _destroy (self ):
452
511
if self ._internal is not None and lib is not None :
453
512
self ._internal , internal = None , self ._internal
0 commit comments