@@ -341,11 +341,23 @@ impl Context {
341341 self . surface_data . scale
342342 }
343343
344+ // Acquiring the next drawable during presentation can block the display-link
345+ // callback on tvOS. Keep the previous surface until the next operation needs
346+ // to draw, then retain its contents when swapping the backing texture.
347+ #[ inline]
348+ fn ensure_metal_drawable ( & mut self ) {
349+ #[ cfg( all( feature = "metal" , target_os = "tvos" ) ) ]
350+ if self . metal_context . as_ref ( ) . is_some_and ( |c| !c. has_current_drawable ( ) ) {
351+ Self :: acquire_drawable ( self ) ;
352+ }
353+ }
354+
344355 #[ inline]
345356 pub fn with_canvas < F > ( & mut self , f : F )
346357 where
347358 F : FnOnce ( & skia_safe:: Canvas ) ,
348359 {
360+ self . ensure_metal_drawable ( ) ;
349361 f ( self . surface . canvas ( ) ) ;
350362 }
351363
@@ -354,6 +366,7 @@ impl Context {
354366 where
355367 F : FnOnce ( & skia_safe:: Canvas , & mut Path ) ,
356368 {
369+ self . ensure_metal_drawable ( ) ;
357370 f ( self . surface . canvas ( ) , & mut self . path ) ;
358371 self . surface_state = self . surface_state | SurfaceState :: Pending ;
359372 }
@@ -363,6 +376,7 @@ impl Context {
363376 where
364377 F : FnOnce ( & skia_safe:: Canvas ) ,
365378 {
379+ self . ensure_metal_drawable ( ) ;
366380 f ( self . surface . canvas ( ) ) ;
367381 self . surface_state = self . surface_state | SurfaceState :: Pending ;
368382 }
@@ -372,6 +386,7 @@ impl Context {
372386 where
373387 F : FnOnce ( & skia_safe:: Canvas , & Paint ) ,
374388 {
389+ self . ensure_metal_drawable ( ) ;
375390 f ( self . surface . canvas ( ) , & self . state . paint ) ;
376391 self . surface_state = self . surface_state | SurfaceState :: Pending ;
377392 }
@@ -388,6 +403,7 @@ impl Context {
388403 where
389404 F : FnOnce ( & skia_safe:: Canvas ) ,
390405 {
406+ self . ensure_metal_drawable ( ) ;
391407 f ( self . surface . canvas ( ) ) ;
392408 self . surface_state = self . surface_state | SurfaceState :: Pending ;
393409 }
@@ -545,6 +561,7 @@ impl Context {
545561 where
546562 F : Fn ( & skia_safe:: Canvas , & skia_safe:: Paint , & mut Path ) ,
547563 {
564+ self . ensure_metal_drawable ( ) ;
548565 let blend = self . state . global_composite_operation . get_blend_mode ( ) ;
549566 // Fast path: most draw calls use SrcOver (the default)
550567 if !matches ! (
@@ -606,6 +623,7 @@ impl Context {
606623 where
607624 F : Fn ( & skia_safe:: Canvas , & skia_safe:: Paint ) ,
608625 {
626+ self . ensure_metal_drawable ( ) ;
609627 let blend = self . state . global_composite_operation . get_blend_mode ( ) ;
610628 // Fast path: most draw calls use SrcOver (the default)
611629 if !matches ! (
@@ -663,6 +681,7 @@ impl Context {
663681 where
664682 F : Fn ( & skia_safe:: Canvas , & skia_safe:: Paint , & Font ) ,
665683 {
684+ self . ensure_metal_drawable ( ) ;
666685 let blend = self . state . global_composite_operation . get_blend_mode ( ) ;
667686 if !matches ! (
668687 blend,
0 commit comments