@@ -706,7 +706,6 @@ class GPUCanvasContext(classes.GPUCanvasContext):
706706
707707 _surface_id = ffi .NULL
708708 _wgpu_config = None
709- _skip_present_screen = False
710709
711710 def __init__ (self , present_info : dict ):
712711 super ().__init__ (present_info )
@@ -930,8 +929,6 @@ def _create_texture_screen(self):
930929 # Clear buffer, so we only have to perform these checks when set_physical_size has been called.
931930 self ._new_physical_size = None
932931
933- # Prepare for obtaining a texture.
934- status_str_map = enum_int2str ["SurfaceGetCurrentTextureStatus" ]
935932 # H: nextInChain: WGPUChainedStruct *, texture: WGPUTexture, status: WGPUSurfaceGetCurrentTextureStatus
936933 surface_texture = new_struct_p (
937934 "WGPUSurfaceTexture *" ,
@@ -944,64 +941,61 @@ def _create_texture_screen(self):
944941 # H: void f(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture)
945942 libf .wgpuSurfaceGetCurrentTexture (self ._surface_id , surface_texture )
946943 status_int = surface_texture .status
947- status_str = status_str_map .get (status_int , "Unknown" )
948944 texture_id = surface_texture .texture
949945
950946 if status_int == lib .WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal :
951947 # Yay! Everything is good and we can render this frame.
952948 self ._number_of_successive_unsuccesful_textures = 0
949+ elif status_int == lib .WGPUSurfaceGetCurrentTextureStatus_Occluded :
950+ # Nothing is wrong, but this frame must be skipped
951+ self ._number_of_successive_unsuccesful_textures = 0
952+ raise classes .DrawCancelled ("Occluded" )
953953 elif status_int in [
954954 lib .WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal ,
955- lib .WGPUSurfaceGetCurrentTextureStatus_Timeout ,
956955 lib .WGPUSurfaceGetCurrentTextureStatus_Outdated ,
957956 lib .WGPUSurfaceGetCurrentTextureStatus_Lost ,
958957 ]:
958+ # We can try to re-configure in some cases
959959 if texture_id :
960960 # H: void f(WGPUTexture texture)
961961 libf .wgpuTextureRelease (texture_id )
962962 texture_id = 0
963- # Try to re-configure, if we can
964963 self ._configure_screen_real ()
965964 # H: void f(WGPUSurface surface, WGPUSurfaceTexture * surfaceTexture)
966965 libf .wgpuSurfaceGetCurrentTexture (self ._surface_id , surface_texture )
967966 status_int = surface_texture .status
968- status_str = status_str_map .get (status_int , "Unknown" )
969967 texture_id = surface_texture .texture
970968
971969 # If still not optimal, we need to make some decisions ...
972970 if status_int != lib .WGPUSurfaceGetCurrentTextureStatus_SuccessOptimal :
973971 # It's ok if we miss a sporadic frame during resizing, but warn if it becomes too much.
972+ status_str_map = enum_int2str ["SurfaceGetCurrentTextureStatus" ]
973+ status_str = status_str_map .get (status_int , "Unknown" )
974974 self ._number_of_successive_unsuccesful_textures += 1
975- if self ._number_of_successive_unsuccesful_textures > 5 :
976- n = self ._number_of_successive_unsuccesful_textures
977- self ._number_of_successive_unsuccesful_textures = 0
975+ n = self ._number_of_successive_unsuccesful_textures
976+ if (n % 100 == 0 ) or n in (5 , 12 , 25 , 50 ):
978977 logger .warning (
979978 f"No succesful surface texture obtained for { n } frames: { status_str !r} "
980979 )
980+
981981 # Decide what to do
982982 if status_int == lib .WGPUSurfaceGetCurrentTextureStatus_SuccessSuboptimal :
983983 # Can still use the texture
984984 pass
985- elif status_int in [
986- lib .WGPUSurfaceGetCurrentTextureStatus_Timeout ,
987- lib .WGPUSurfaceGetCurrentTextureStatus_Outdated ,
988- lib .WGPUSurfaceGetCurrentTextureStatus_Lost ,
989- ]:
990- # Use a dummy texture that we cannot present
991- if texture_id :
992- # H: void f(WGPUTexture texture)
993- libf .wgpuTextureRelease (texture_id )
994- texture_id = 0
995- self ._skip_present_screen = True
996- return self ._create_plain_texture ()
997985 else :
986+ # lib.WGPUSurfaceGetCurrentTextureStatus_Timeout,
987+ # lib.WGPUSurfaceGetCurrentTextureStatus_Outdated,
988+ # lib.WGPUSurfaceGetCurrentTextureStatus_Lost,
998989 # WGPUSurfaceGetCurrentTextureStatus_OutOfMemory
999990 # WGPUSurfaceGetCurrentTextureStatus_DeviceLost
1000991 # WGPUSurfaceGetCurrentTextureStatus_Error
1001- # This is something we cannot recover from.
1002- raise RuntimeError (
1003- f"Cannot get surface texture: { status_str } ({ status_int } )."
1004- )
992+
993+ # Skip the frame
994+ if texture_id :
995+ # H: void f(WGPUTexture texture)
996+ libf .wgpuTextureRelease (texture_id )
997+ texture_id = 0
998+ raise classes .DrawCancelled (f"{ status_str } ({ status_int } )" )
1005999
10061000 # I don't expect this to happen, but let's check just in case.
10071001 if not texture_id :
@@ -1046,29 +1040,11 @@ def _create_texture_screen(self):
10461040 device = self ._config ["device" ]
10471041 return GPUTexture (label , texture_id , device , tex_info )
10481042
1049- def _create_plain_texture (self ):
1050- # To have a dummy texture in case we have a size mismatch and must drop frames
1051- width , height = self ._physical_size
1052- width , height = max (width , 1 ), max (height , 1 )
1053-
1054- # Note that the label 'present' is used by read_texture() to determine
1055- # that it can use a shared copy buffer.
1056- device = self ._config ["device" ]
1057- return device .create_texture (
1058- label = "present" ,
1059- size = (width , height , 1 ),
1060- format = self ._config ["format" ],
1061- usage = self ._config ["usage" ] | flags .TextureUsage .COPY_SRC ,
1062- )
1063-
10641043 def _present_screen (self ):
1065- if self ._skip_present_screen :
1066- self ._skip_present_screen = False
1067- else :
1068- # H: WGPUStatus f(WGPUSurface surface)
1069- status = libf .wgpuSurfacePresent (self ._surface_id )
1070- if status != lib .WGPUStatus_Success :
1071- logger .warning ("wgpuSurfacePresent failed" )
1044+ # H: WGPUStatus f(WGPUSurface surface)
1045+ status = libf .wgpuSurfacePresent (self ._surface_id )
1046+ if status != lib .WGPUStatus_Success :
1047+ logger .warning ("wgpuSurfacePresent failed" )
10721048
10731049 def _release (self ):
10741050 self ._drop_texture ()
@@ -4213,6 +4189,10 @@ class GPUInternalError(classes.GPUInternalError, GPUError):
42134189 pass
42144190
42154191
4192+ class DrawCancelled (classes .DrawCancelled ):
4193+ pass
4194+
4195+
42164196# %%
42174197
42184198
0 commit comments