Laggy PencilKit stroke response

We're noticing some odd behaviour using PencilKit in our app. Most of the time, the response it quite fluid. But at intervals (and depending on what kind of strokes we create), PencilKit freezes the whole app for up to several seconds. It will come to life again and continue as normal, but eventually repeat that behaviour. When it happens, it's usually accompanied by one or two lines of console output, e.g.:

2023-05-12 15:52:29.101996+0100 Spaces[51229:3635610] [] Did not have live interaction lock at end of stroke

2023-05-12 15:52:29.556467+0100 Spaces[51229:3630745] [] Drawing did change that is not in text.

I can't find any reference to these messages. They may have no bearing on the observed problem, but it might be a clue. Has anyone seen this behaviour or have any information about their meaning?

Post not yet marked as solved Up vote post of rwessel Down vote post of rwessel
763 views

Replies

Further to this issue, PencilKit rendering seems to occasionally become completely deadlocked. I've paused the app in Xcode and captured the thread stack trace (see attached). The main thread is waiting on a lock, and the threads associated with PencilKit rendering is likewise waiting at a lock (Thread 55 Queue : com.apple.pencilkit.renderer). I'm hoping this activity might point to something we've done wrong (or an approach to end/mitigate this behaviour). Or possibly point to other diagnostics we could run…

Key parts of the stack trace include:

Thread 1 Queue : com.apple.main-thread (serial)
#0	0x00000001c75b97bc in __ulock_wait ()
#1	0x00000001e7fdc010 in _os_unfair_lock_lock_slow ()
#2	0x00000001122f795c in GTMTLGuestAppClientUpdateCAMetalLayerInfo ()
#3	0x0000000112345a10 in +[GTCAMetalLayerInfo updateAll:] ()
#4	0x000000011232379c in CALayer_dealloc ()
#5	0x000000018a7dc0fc in -[CAMetalLayer dealloc] ()
#6	0x000000018a6cbedc in CA::release_objects(X::List<void const*>*) ()
#7	0x000000018a72901c in CA::release_root_if_unused(CA::Layer*, CA::Layer*, void*) ()
#8	0x000000018a7aeeb0 in x_hash_table_remove_if ()
#9	0x000000018a70e2fc in CA::Transaction::commit() ()
#10	0x000000018a6f8374 in CA::Transaction::flush_as_runloop_observer(bool) ()
#11	0x000000018921d324 in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#12	0x00000001891a74f0 in __CFRunLoopDoObservers ()
#13	0x000000018920728c in __CFRunLoopRun ()
#14	0x000000018920c4dc in CFRunLoopRunSpecific ()
#15	0x00000001c3b8735c in GSEventRunModal ()
#16	0x000000018b59837c in -[UIApplication _run] ()
#17	0x000000018b597fe0 in UIApplicationMain ()
#18	0x000000018cbda3d8 in ___lldb_unnamed_symbol70872 ()
#19	0x000000018cb409b0 in ___lldb_unnamed_symbol67491 ()
#20	0x000000018cb2aa54 in ___lldb_unnamed_symbol67036 ()
#21	0x00000001051a5078 in static SpacesApp.$main() at /Users/rwessel/Documents/Development/SpacesFix/Spaces/SwiftApp.swift:12
#22	0x00000001051a6094 in main ()
#23	0x00000001a8690dec in start ()
Thread 55 Queue : com.apple.pencilkit.renderer (serial)
#0	0x00000001c75b97bc in __ulock_wait ()
#1	0x00000001e7fdc010 in _os_unfair_lock_lock_slow ()
#2	0x0000000112322e3c in AllMetalLayers ()
#3	0x00000001122f7468 in GTMTLGuestAppClient_allCaptureObjectsUnsafe ()
#4	0x00000001122f842c in GTMTLGuestAppClientRemoveMTLCommandQueueInfo ()
#5	0x0000000112355b28 in -[CaptureMTLCommandQueue dealloc] ()
#6	0x00000001bc325f5c in -[PKMetalRenderer .cxx_destruct] ()
#7	0x00000001822aa0a4 in object_cxxDestructFromClass(objc_object*, objc_class*) ()
#8	0x00000001822aee00 in objc_destructInstance ()
#9	0x00000001822b84fc in _objc_rootDealloc ()
#10	0x00000001bc30f634 in -[PKMetalRenderer dealloc] ()
#11	0x00000001bc267978 in __37-[PKMetalRendererController teardown]_block_invoke_3 ()
#12	0x000000011303a038 in _dispatch_client_callout ()
#13	0x000000011304b814 in _dispatch_lane_barrier_sync_invoke_and_complete ()
#14	0x00000001bc26791c in __37-[PKMetalRendererController teardown]_block_invoke_2 ()
#15	0x0000000113038520 in _dispatch_call_block_and_release ()
#16	0x000000011303a038 in _dispatch_client_callout ()
#17	0x000000011303cb60 in _dispatch_queue_override_invoke ()
#18	0x000000011304e43c in _dispatch_root_queue_drain ()
#19	0x000000011304ee34 in _dispatch_worker_thread2 ()
#20	0x00000001e8072da0 in _pthread_wqthread ()