LINUX.ORG.RU

Qt секрет плавной анимации под linux и windows.

 , ,


0

1

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

Едет оно по таймеру QTimer(). В обработчике таймера ставится новое смещение и вызывается QWidget::update(). Интервал таймера задаётся в миллисекундах.

Странно то, что под linux плавность достигается при значении 1000.0/30.0 (типа 30 fps), а под windows при этом значении визуально движение не плавное - ну типа как при 15 fps. Ситуация для винды улучшается, если сократить интервал где-то до 1000.0/50.0. Проблема лечится с помощью #ifndef WIN32 ... #endif.

Почему так?

Попробуй еще на разных линуксах.

cdshines ★★★★★
()

делать анимацию по таймеру это вкорне неверно. анимацию надо делать в лупе, зависимой от dt занявших перерисовку

trashymichael ★★★
()
Ответ на: комментарий от batbko

А зачем лишние сущности? Мне целый animation framework городить только для того, чтобы стратица медленно ехала? Лучше уж компактный велосипед.

kiverattes ★☆
() автор топика
Ответ на: комментарий от trashymichael

Согласен, надо померять время работы paintEvent (-;

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 1)
Ответ на: комментарий от kiverattes

ну вообще я где-то год назад попробовал небольшую игрую потыкать на qt и питоне, в подробности шибко не вдавался, но как оказалось, и меня это оче удивило, таймеры для таких целей в qt это стандартно и почти единственно-верно

trashymichael ★★★
()
Ответ на: комментарий от kiverattes

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

batbko
()
Ответ на: комментарий от trashymichael

Не дошёл смысл сообщения ) Какие таймеры? QTimer?

kiverattes ★☆
() автор топика
Ответ на: комментарий от batbko

И с Qt 4.6 это часть QtGui, так что раз есть UI то есть и энимэйшн фреймворк.

И QTimeLine слишком низкоуровневое решение, проще использовать например QPropertyAnimation.

batbko
()
Ответ на: комментарий от batbko

Ну смотрите - у меня только простейший таймер и рабочая анимация, которая слегка глючит под виндой. Вы мне предлагается взять целый набор новых сущностей (animation framework) и тупо применить, не разбираясь почему не работает у меня и почему работает в animation framework - мне такой потребляцкий подход не очень нра :) Не сильно коррелирует в development-веткой форума.

kiverattes ★☆
() автор топика

У вас полностью страница перерисовывается? Попробуйте передвигать ранее нарисованное вверх и вызывать update(QRect) только того куска, который появился снизу. Делается с помощью двойной буферизации или QScrollArea.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

Забыл добавить, ваши значения FPS имеют мало смысла, если при этом одно ядро процессора, отвечающее за главный цикл, грузится на 100%. Проверьте.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

Страница полностью перерисовывается, но из готовых (штук 10) заранее отрендеренных QPixmap - ов, то есть это очень производительная перерисовка - налепить со смещением 10 готовых пиксельных буферов на экран. Рисующий поток нагружает единицы процентов ядра (core i5 2500K, видеокарта встроенная).

Причём эта ситуация с долями процента загрузки ядра имелась и на древнем core2duo T5600. Под виндой - загрузка та же. Снижение интервала QTimer() в винде добавляет плавности, т.е. камню есть куда греться.

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Тогда похоже на проблемы вертикальной синхронизации, которая на Линуксе отключена, а на Виндовз включена. И отрисованное на заднем буффере окно из-за микрозадержки показывается на следующей итерации, что уменьшает FPS до следующего кратного 60 значения — с 30 до 20.

Dendy ★★★★★
()
Ответ на: комментарий от kiverattes

Да именно это я и предлагаю, я предлагаю взять 1 (одну) новую(для вас) сущность, которую вы и так таскаете в зависимостях и инкапсулирующую вашу задачу в простой и удобный интерфейс и использовать её до тех пор пока она справляется со своей задачей.

А вот вы предлагаете сделать прорыв в велосипедостроении и плодить сущности(новые для всех остальных).

Что планируете делать при портировании под мак, или андроид например, расширять блок условной компиляции? Что прикажете делать другому разработчику если ему вдруг придется поддерживать ваш продукт, копаться в директивах препроцессора? Не удобней бы ему было бы читать документацию Qt или ваши исходники настолько прекрасны?

Вообщем вам конечно выбирать, но ИМХО если пользуешься фреймворком, то нужно что бы ваше решение вписывалось в него.

batbko
()
Ответ на: комментарий от batbko

я поддерживаю batbko, всегда лучше взять готовое, тем более от отцов, нюансов может быть очень много

trashymichael ★★★
()
Ответ на: комментарий от batbko

ТС спрашивает конкретный вопрос, а вы ему отвечаете что-то абстрактное про кроссплатформенность. Я с трудом понимаю, как Animation Framework должен решить его графическую проблему. QTimer/QTimeLine/Animation-классы — суть одно и то же и абсолютно развязаны с GUI, они просто генерируют формулу, по которой меняется значение со временем, о чём сообщается сигналами.

Чтобы чинить что-то нужно сначала понять суть проблемы, а тут все средства хороши, вплоть до пересборки Qt, прогон профилировщиком и #define private public.

Dendy ★★★★★
()
Ответ на: комментарий от Dendy

Что такое вертикальная синхронизация примерно представляю, а вот что-нибудь бы почитать на тему того, что она в линуксе отключена, а в виндовсе включена?

Следствием ли отключенной вертикальной синхронизации в линуксе является наблюдаемая иногда перерисовка чего-либо кусками/квадратами/квадратиками? Бывает видишь на мгновение, как разделённые по диагонали половинки какого-то окна отличаются содержимым или оно как-бы разбито в мозайку и часть элементов мозайки старые, а часть уже новые...

kiverattes ★☆
() автор топика
Ответ на: комментарий от kiverattes

Да, частичная перерисовка куска буфера называется «tearing». По идее должна выключаться в композитном менеджере.

Dendy ★★★★★
()
Ответ на: комментарий от kiverattes

Ну смотрите - у меня только простейший таймер и рабочая анимация, которая слегка глючит под виндой

А теперь попробуйте запустить это на машине с процессором слегка другой мощности. Что, под каждую конкретную машину будете время подбивать? Я уж не говорю о том, что у вас пересчёт положения может вызвать перерисовку контента - это раз, и перерисовка может произойти до срабатывания таймера, в результате чего один кадр точно потеряется - это два.

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

quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

1. Про процессоры разной мощности: запускал на core2duo T5600 1.86 - загрузка 1 ядра - единицы процентов.

2. Что значит «пересчёт положения может вызвать перерисовку контента»? Какой пересчёт? Как он вызовет перерисовку контента?

3. Как перерисовка произойдёт до срабатывания таймера? Какой кадр потеряется? Откуда потеряется? О каких кадрах вы говорите («положение виджета не каждый кадр обновляется»)? У меня видеопотока нет, мне кадры неоткуда терять :)

Про тормоза выше - на древнем core2duo 1.86 T5600 - единицы процентов загрузки ядра во время работы этой анимации. Можно сократить интервал между перерисовками - анимация будет идти ещё плавнее, хоть ~100 fps - нет узкого места в вычислительной мощи.

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 11)
Ответ на: комментарий от kiverattes

Что значит «пересчёт положения может вызвать перерисовку контента»?

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

Для исцеления байтосношательства рекомендую исходники класса. Авось откроете для себя парочку давно учтённых кем-то нюансов.

quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

Всё окно явно я не обновляю, вызываю update для конкретного виджета. Ввода нет, разворачивания окна нет, других событий нет - висит окно, его никто не тревожит. В linux анимация плавная, в windows - нет (-;

kiverattes ★☆
() автор топика
Последнее исправление: kiverattes (всего исправлений: 1)

Насколько я помню, в виндовс (как наследие доса) системный таймер тикает 18 раз в секунду. То-есть, если задавать не кратные этому значению интеравалы, события будут приходить неравномерно.

Если такой дискретности не достаточно, то нужно использовать какие-то «мультимедия таймеры» — я этим не пользовался, подробностей не скажу.

Так что, если не хочешь изучать глубины виндовс, не упирайся — используй то, с чем до тебя уже разобрались авторы Qt.

cdslow ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.