Сбрасывание к буферу окна

Если Ваша программа выводит на экран анимированный контент, потому что это - игра или другое основанное на мультимедиа приложение, Ваш код должен избежать обновлять Ваше содержание окна быстрее, чем экранная частота обновления. Рисование содержания к Вашему локальному буферу окна и сбрасывание того содержания на экран больше чем в 30 кадрах в секунду обычно являются пустой тратой процессорного времени. Большинство пользователей не может чувствовать обновления на уровнях, больше, чем более часто редко необходимы 30 кадров в секунду, таким образом сбрасывая.

Запросы сброса не отправляют данные в экран сразу. Вместо этого запросы сброса задерживаются, пока не пора обновить дисплей. В то время сервер окна объединяет обновления и продвигает изменения в видеокарте. Это новое “объединенное обновление” поведение может вызвать проблему производительности для приложений, пытающихся обновить их буферы окна более часто, чем экранная частота обновления. Рисование подпрограмм блокирует текущий поток, пока не был полностью сброшен буфер окна. С объединенными обновлениями это означает, что Ваш код мог блокировать для так же как 1/60-й из секунды.

Для предотвращения проблем производительности Вы никогда не должны рисовать или сбрасывать свои буферы окна быстрее, чем экранная частота обновления. Если Вы обычно рисуете свое содержание и затем сразу сбрасываете его на экран, можно использовать таймеры для уведомления кода, когда пора нарисовать. Просто установите таймер для увольнения в ту же частоту, как экранная частота обновления и иметь ее вызывает подпрограмму получения.

Определение, Сбрасывает ли Приложение Слишком Часто

Если приложение проводит больше времени, таща (или имеет сокращенную частоту кадров), тогда то же приложение, созданное и соединенное в предыдущей системе, это, вероятно, затрагивается объединенными обновлениями. Кварцевый Отладчик позволяет Вам обнаружить, может ли Ваше приложение испытывать проблемы из-за объединенных обновлений.

Используя кварцевую отладку для обнаружения объединенных обновлений

Кварцевая Отладка является средством отладки для Кварцевой графической системы с несколькими мощными функциями, чтобы помочь Вам идентифицировать много графических дисплеев и проблем производительности. Кварцевая Отладка является частью отдельного графического выпуска инструментов, который может быть загружен из XCode. Из XCode выберите Xcode> Open Developer Tool> More Developer Tools.

Чтобы определить, влияют ли объединенные обновления на Ваше приложение, Вы используете инструменты синхронизации луча и структурируете метр Кварцевой Отладки. С Вашим выполнением приложения запустите Кварцевую Отладку и сделайте следующее:

  1. Выберите Tools> Show Beam Sync Tools.

  2. В диалоговом окне Инструментов Синхронизации Луча выберите опцию Force Beam Synchronization. Это заставляет объединенные обновления использоваться всеми приложениями.

  3. Выберите Tools> Show Frame Meter.

Если Ваше приложение будет затронуто объединенными обновлениями, то его частота кадров будет ниже, когда будет включена синхронизация луча. Эта пониженная частота кадров будет часто совпадать с увеличенным использованием CPU также. Узнать больше об использовании Кварцевой Отладки, чтобы видеть, что влияние объединенных обновлений видит Графику Отладки с QuartzDebug.

Инструкции для рисования с объединенными обновлениями

Чтобы гарантировать, что производительность Вашего приложения не портится, когда объединенные обновления включены, необходимо следовать инструкциям, перечисленным в следующих разделах. Для дополнительных инструкций по получению посмотрите и Подсказки по Рисованию Какао.

Избегите сбрасывать к буферам непосредственно

При использовании Кварца необходимо избежать вызывать CGContextFlush вызвать автоматическое обновление окна. Вместо этого вызовите CGContextSynchronize позволять Кварцу определить подходящее время, в которое можно обновить окно.

При использовании Какао необходимо избегать использования display и его связанный метод для принуждения обновлений. Вместо этого используйте setNeedsDisplay: и setNeedsDisplayInRect: методы и позволяют циклу выполнения обработать обновления к тем областям во время следующего цикла обновления.

Если необходимо сбросить к буферам, используйте таймер для синхронизации циклов получения с экранной частотой обновления. Сбрасывание является также все еще надлежащим в случаях, где Ваше приложение должно вывести на экран некоторое содержание один раз и не может ожидать цикла событий, такой, выводя на экран экран-заставку.

Избегите сбрасывать слишком Часто

Приложения обычно не должны рисовать или сбрасывать быстрее, чем видит пользователь. Для большей части графики частота обновления 30 кадров в секунду достаточна для плавных переходов. Если Ваше программное обеспечение должно обновить на более быстром уровне, удостоверьтесь, что уровень не превышает частоту обновления экрана. Для получения информации о том, как получить экранную частоту обновления, посмотрите Получение Частоты обновления.

Минимизируйте время потраченное касание запоминающего устройства

В Ваших подпрограммах получения необходимо минимизировать количество времени между тем, когда Вы сначала касаетесь графического контекста и когда Вы сделаны с ним. Это могло бы означать разъединять Ваш механизм данных от графического механизма и реорганизовывать Ваш код для выполнения любых необходимых вычислений до получения. Путем выполнения любых необходимых вычислений сначала, Вы задерживаете точку, в которой необходимо фактически коснуться графического контекста. Если контекст в настоящее время сбрасывается, это может помочь минимизировать время, Ваше приложение тратит ожидание его.

Получение частоты обновления

Можно получить текущую экранную частоту обновления от Кварца. CGDisplayCurrentMode функционируйте возвращает словарь свойств дисплея. Частота обновления для указанного экрана связана с kCGDisplayRefreshRate ключ. Если значение этого ключа 0, экраном является LCD, и необходимо принять частоту обновления 60 Гц.

Перечисление 1 показывает демонстрационную функцию, получающую текущую частоту обновления для экрана.

Перечисление 1  , Получающее экранную частоту обновления

int GetMainScreenRefreshRate()
{
    CFDictionaryRef modeInfo;
    int refreshRate = 60; // Assume LCD screen
 
    modeInfo = CGDisplayCurrentMode(CGMainDisplayID());
 
    if (modeInfo)
    {
        CFNumberRef value = (CFNumberRef) CFDictionaryGetValue(modeInfo, kCGDisplayRefreshRate);
 
        if (value)
        {
            CFNumberGetValue(value, kCFNumberIntType, &refreshRate);
            if (refreshRate == 0)
                refreshRate = 60;
        }
    }
 
    return refreshRate;
}