Почему Quartz не выполняет двойную буферизацию моего drawInContext ()? - PullRequest
2 голосов
/ 09 августа 2010

Я рендеринг простой линии (линия с текстом в середине) в подклассе CALayer через drawInContext (). Я обновляю этот слой, когда пользователь выполняет жест, вызывая на нем setNeedsDisplay. Эффект, который я вижу, это то, что я мог бы ожидать, если бы не происходило двойной буферизации ... то есть я вижу части нового рендеринга, перекрывающиеся части старого рендеринга. Когда я прекращаю обновление (завершаю жест), система «догоняет», и я всегда вижу правильный конечный результат, но во время обновлений я вижу противоречивые результаты ... Этот эффект не тонкий, а иногда и экстремальный ... например, если я продолжаю обновлять достаточно быстро, я могу сохранять устаревшие части рисунка на экране в течение секунд , пока новые части рисуют впереди ...

Я совсем не понимаю этого. Если Quartz выполняет буферизацию, то кажется, что он не перетаскивает результат на экран целиком или неправильно вычисляет уязвимую область.

Вещи, которые я пробовал:

1) Я отключаю неявную анимацию и выполняю все рисование в транзакции CAT

2) Я не ошибаюсь в своем чертеже ... Это буквально две строки с текстом между ними ... Я никак не могу отрисовать промежуточные артефакты.

3) Я пытался ограничить частоту обновлений, пропуская большинство из них ... но даже при более низкой частоте я вижу артефакты до тех пор, пока не перестану обновлять и не позволю системе догнать.

4) Кстати, это происходит одинаково в симуляторе и на устройстве (iPad).

Нужно ли мне самому рисовать в буфере вне экрана и полностью копировать его на экран? Я думал, что прочитал, что Кварц делает это для меня.

Обновление: Как обычно, после нескольких часов удара головой о стену я нахожу (частичный) ответ через 5 минут после публикации вопроса. Я понял, что использую CATiledLayer для того, чтобы мой слой был перерисован при увеличении. Если я переключаю его обратно на обычный CALayer, глюки исчезают. Так что я думаю, что я вижу артефакты рендеринга отдельных плиток. Сейчас я пытаюсь понять, как с этим справиться ...

1 Ответ

0 голосов
/ 09 августа 2010

Итак, получается, что у меня было три проблемы:

1) CATiledLayer явно затухает в новом содержимом плитки со временем по умолчанию 0,25 секунды ... Это вызвало хаос в моем чертеже. Я переопределил это в моем подклассе CATiledLayer:

+ (CFTimeInterval)fadeDuration {
    NSLog(@"got fade duration");
    return 0;
}

2) Мне также пришлось настроить максимальный размер плитки (я установил его на 1024x1024, хотя я не знаю, какой размер он фактически использует).

3) Я периодически вносил коррективы в рамку моего слоя во время обновлений, и это, казалось, вызывало дополнительные проблемы для мозаичного слоя. Я делаю изменения, чтобы остановить это.

Со всеми этими изменениями производительность кажется приемлемой.

...