Какие части UIKit, Core Graphics, Core Animation, OpenGL разрешены не в основном потоке?

В моем приложении на основе OpenGL-ES 1.1 я использую CALayers в качестве источника текстур OpenGL. Эти CALayer состоят из CGImage и текста, отображаемого с помощью CoreGraphics. Другой источник текстур OpenGL - это снимок экрана UIView, сделанный с использованием -[CALAyer renderInContext:] и UIGraphicsGetImageFromCurrentImageContext. В настоящее время я полностью использую основной поток.

Последний случай, в частности, очень плох, потому что он останавливает рендеринг OpenGL на все время, необходимое для создания UIView и его снимка экрана.

Теперь я подумываю переместить код OpenGL в отдельный поток в надежде обойти эту блокировку. В идеале снимок экрана должен быть сделан в другом потоке (при необходимости, в основном потоке), чем рендеринг OpenGL.

Мне не удалось найти в документации полное описание того, что требует запуска в основном потоке, а что нет. Я нашел несколько комментариев в примечания к выпуску iOS 4 и некоторые комментарии в конкретных методах UIKit, но мне не хватает полной картины.

Код работает на iOS 4.x или выше.


person Ortwin Gentz    schedule 29.12.2010    source источник


Ответы (2)


Вы можете рисовать с OpenGL ES в фоновом потоке, если вы не пытаетесь одновременно получить доступ к контексту OpenGL из другого потока. Подробнее см. Технические вопросы и ответы QA1612 от Apple.

Я столкнулся с рядом проблем с обновлением содержимого CALayer из фонового потока, поэтому я работаю со слоями в основном потоке. В любом случае Core Animation запускает свою анимацию в фоновом потоке.

Я никогда не обновлял что-либо, связанное с UIKit, из фонового потока, но некоторые аспекты рисования в UIKit были сделаны потокобезопасными в 4.0. Дэвид Дункан комментирует здесь этот рисунок, контекст теперь безопасен для потоков.

В вашем случае я бы не увидел проблемы с запуском рендеринга OpenGL ES в фоновом потоке (возможно, с использованием очереди последовательной отправки в GCD, чтобы предотвратить доступ к контексту сразу из нескольких потоков), а затем выполнение захвата изображения на другом .

person Brad Larson    schedule 29.12.2010

Базовая анимация обычно является потокобезопасной, но UIKit и OpenGL ES (по крайней мере, на iOS) не являются потокобезопасными. UIKit должен использоваться только в основном потоке, а OpenGL ES должен последовательно использоваться в одном потоке (обычно в основном потоке).

person Jonathan Grynspan    schedule 29.12.2010
comment
Как вы думаете, сработает ли переместить OpenGL в фоновый поток, а остальное оставить в основном потоке? А как насчет кода Core Graphics, который генерирует некоторые текстуры? Могу ли я перенести это в ветку OpenGL? - person Ortwin Gentz; 29.12.2010
comment
Pure Core Graphics / Quartz можно использовать в рабочем потоке, но не всегда безопасно пересекать границы потока. Все, что использует UIKit (например, функции UIGraphics...), должно по-прежнему выполняться в основном потоке. - person Jonathan Grynspan; 29.12.2010
comment
OpenGL является потокобезопасным, вы просто не можете использовать один и тот же контекст в нескольких потоках или совместно использовать ресурсы между разными контекстами, если они не находятся в общей группе. Ознакомьтесь с документацией для EAGLSharegroup (developer.apple.com/library/ ios / documentation / OpenGLES /). - person Tommy; 07.07.2011
comment
Да, но я был упрощен. :) - person Jonathan Grynspan; 07.07.2011
comment
Это неправильно, некоторые части UIKit также являются потокобезопасными: Из Apple doku: по большей части классы UIKit должны использоваться только из основного потока приложения. Это особенно верно для классов, производных от UIResponder или связанных с любым способом манипулирования пользовательским интерфейсом вашего приложения. - person Pascalius; 21.09.2012
comment
@Pascalius: если вы не запомнили, какие конкретные части UIKit являются потокобезопасными (а вы нет), безопаснее полностью избежать проблемы. - person Jonathan Grynspan; 21.09.2012
comment
@JonathanGrynspan На самом деле да, так как рисование iOS4 в графическом контексте в UIKit безопасно. В частности: подпрограммы, используемые для доступа и управления графическим контекстом, теперь могут правильно обрабатывать контексты, находящиеся в разных потоках. Рисование строк и изображений теперь является потокобезопасным. Теперь можно безопасно использовать объекты цвета и шрифта в нескольких потоках. UIGraphicsBeginImageContextWithOptions также является потокобезопасным. - person Pascalius; 21.09.2012