Metal Render Loop оптимизация

Я ищу руководство о том, как правильно реализовать цикл рендеринга Metal. Мой цикл рендеринга получает поток видеокадров из AVPlayer,

Вот моя текущая реализация:

  1. CVDisplayLink запрашивает AVPlayerItemVideoOutput игрока в 60 Гц. Если есть новый кадр, это CVPixelBufferRef захватывается / сохраняется * как свойство MTKView к которому это будет оказано. (На этом этапе ранее захваченный видеокадр освобождается).
  2. мой MTKView настроен с isPaused а также enableSetNeedsDisplay в NO, Другими словами, внутренний таймер MTKView поручено периодически вызывать его drawRect метод.
  3. В drawRect Я сначала преобразовать вновь прибывших * CVPixelBuffer к MTLTexture, а затем происходит куча этапов рендеринга.
  4. Наконец я звоню presentDrawable в конце drawRect метод.

* Примечание: мьютексный доступ к CVPixelBufferRef контролируется спариванием dispatch_semaphore_wait а также dispatch_semaphore_signal,

Это правильный способ делать вещи? Это кажется довольно производительным, хотя некоторые кадры иногда пропускаются. С точки зрения времени, профилирование Xcode Metal говорит мне, что MTLCommandBuffer обычно занимает менее 3 мс для запуска.

Сказав это, я вижу некоторые альтернативные возможности:

  • угробить CVDisplayLink реализация и захватить кадры внутри drawRect
  • обратный процесс рендеринга; отобразить ранее захваченный кадр и визуализированный MTLTexture первый в drawRect метод, а затем commit этот металлический буфер команд и вызов presentDrawable в кратчайшие сроки. После этого снимите следующий видеокадр и проведите его через все этапы рендеринга до следующего drawRect позвонить (сделать это раньше drawRect выходит?).

Еще одна проблема: у меня сложилось впечатление, что оба CVDisplayLink а также drawRect методы не были запущены в главном потоке с этой конфигурацией. Меня беспокоит тот факт, что всякий раз, когда я отказываюсь от одного из меню приложения, возникает значительная задержка в доставке видеокадров - это симптоматично, когда основной поток выполняет обновления пользовательского интерфейса и блокируется. Такое же поведение наблюдается, когда на экране NSCollectionView перезагружается и его содержимое анимируется на экране. Это приводит меня к мысли, что мое предположение неверно. Как это может MTKView сделать рендеринг циклов, чтобы избежать этих проблем? Хотите знать, если все открытие / конфиг AVPlayer должен быть отключен от основного потока.

ОБНОВЛЕНИЕ № 1

Я исправил проблемы с заиканием " Другая проблема ", которые возникали при использовании NSMenu Предметы. Это было мое решение:

  1. Настройте каждый MTKView с isPaused=YES а также enableSetNeedsDisplay=NO, Это означает, что явное draw вызовы необходимы для представления, чтобы представить его содержание.
  2. Изнутри CVDisplayLink перезвонить, выдать draw позвонить в MTKView на dispatch_global_queue, таким образом:

__block MTKView *aView = ....;
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(aQueue, ^{ [aView draw]; });

0 ответов

Другие вопросы по тегам