Почему CATiledLayers рисуют в одном потоке в 10.14 и 10.15? - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть приложение macOS (коммерческий ГИС-пакет), которое поставляется с 2009 года и использует CATiledLayer для рисования больших площадей для представления карты. У меня не было проблем с этим с первых дней Core Animation. Однако, похоже, что с 10.14 и теперь с 10.15 мой CATiledLayer рисует в одном потоке.

Мой -drawLayer:inContext: делегат вызывается из фонового потока, а не из основного потока. Тем не менее, он вызывается последовательно с каждой плиткой, которую нужно нарисовать. В результате получается очень скучающая машина и огромное падение производительности по сравнению с той же версией, запущенной в 10.13 и более ранних версиях. В 10.13 и ранее drawLayer:inContext вызывается в нескольких потоках с несколькими контекстами для рисования тайлов.

Слой находится в подклассе NSView.

Очередь называется CADispatch Group (serial), а стек до вызова нашего метода делегата:

Thread 138 Queue : CA DispatchGroup (serial)
#0 0x00000001001c6a0e in -[MapView drawLayer:inContext:] 
#1 0x00007fff3f2d19fc in -[CALayer drawInContext:] ()
#2 0x00007fff3f3b6f6a in tiled_layer_render(_CAImageProvider*, unsigned int, unsigned int, unsigned int, unsigned int, void*) ()
#3 0x00007fff3f454871 in CAImageProviderThread(unsigned int*, bool) ()
#4 0x0000000107c42826 in _dispatch_client_callout ()
#5 0x0000000107c49dd7 in _dispatch_lane_serial_drain ()
#6 0x0000000107c4ab90 in _dispatch_lane_invoke ()
#7 0x0000000107c57fe0 in _dispatch_workloop_worker_thread ()
#8 0x0000000107cd0361 in _pthread_wqthread ()
#9 0x0000000107ccf49b in start_wqthread ()

В надежде найти что-то тривиальное, например зависимость от настроек в View, Я создал совершенно новое, неукрашенное окно, в котором нет ничего, кроме MapView.

Я уверен, что вызывается только один поток, поскольку у меня есть защищенный счетчик (предшествующий этой проблеме), который растет пропорционально рисуются 10.13.6, но остаются только 1 на 10.15.4 и 10.14.6. (Кроме того, я печатаю идентификатор потока, и это один и тот же поток при каждом последовательном вызове в соответствии с 10.14 и 10.15).

Я попытался уменьшить стек CALayer для подкласса NSView, чтобы он представлял собой только один CALayer с моим CATiledLayer внутри (ранее здесь был стек других слоев), но это не имело никакого эффекта.

NSView загружается с NIB как часть NSWindow (это не изменилось в десятилетия), но я попытался изменить предыдущее создание экземпляра CALayer (добавив CALayer и настройку wantLayer)

Я смог воспроизвести это на нашей предыдущей версии доставки (связано с 10.7) и против версии, связанной с 10,13. Симптомы те же.

Я ищу другие предложения на данный момент. Что-то изменилось при запуске этого в 10.14 и 10.15, и я не смог найти индикатор в примечаниях к выпуску.

Любые признаки того, что мы делаем неправильно, или что работает против MacOS 10.14+ будет принята с благодарностью.

...