OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 17 Ноябрь, 2019 18:10

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 26 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 13:19 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Очень часто наблюдаем такую картину:

На форме располагаются несколько отображений-контейнеров с вложенными текстами (и различными контролами, как стандартными, так и нет). При вводе текста в один контейнер необходимо автоматически подогнать размер этого текст-вью под заданный размер. Подгонка делается банальным изменением контекста текствью при обработке сообщения EditMsg.

Так вот, эта самая подгонка приводит к заметным мерцаниям остальных контейнеров.

Если захватить изображение с экрана (я использую программу CamStudio, которая захватывает кадры с дискретностью 5 мсек), то при просмотре записи видно, как контейнер стирает своё изображение, оставляя серый фон. Так длится примерно 0.5 - 0.7 секунды, после чего контейнер перерисовывает себя заново.

Вот эта вот задержка и заметна глазу. Но не объяснима :(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 14:12 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Попробовал перетащить контейнеры с формы в обычный текстовый документ. Паразитные флики на соседних контейнерах прекратились, а продолжает фликать именно контейнер, в котором содержится форма и на ней текствью с вводимым с клавиатуры текстом.

То есть, изменение одной из внедряшек (простите, внедрённых отображений) на форме приводит к тому, что форма инициирует перерисовку остальных.

Но сама картина флика (стирание - пауза (визуально ощутимая) - перерисовка) остаётся прежней.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 18:11 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Видимо, так какое-то действие вынесено на Action, нет?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 19:51 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Action стоит вне последовательности "RemoveFrames - RestoreRoot"... А я наблюдаю ситуацию "затирание - визуальная пауза - отрисовка".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 20:14 

Зарегистрирован: Вторник, 29 Август, 2006 12:32
Сообщения: 2626
Откуда: Россия, Ярославль
В сложных отображениях внутри процедуры Restore может вызываться Views.InstallFrame, которая, в свою очередь инициирует отсылку сообщения, UpdateCaches только что внедрённому, а если внедрённое отображение тоже сложное, то обработка каскада таких сообщений может внести задержку.
Хотя, опять же неясно, если во время перерисовки мы находимся всё время внутри процедуры RestoreRoot то откуда берётся период визуальной паузы после затирания, ведь никаких средств для продолжения обработки сообщений виндовс не производится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 21:28 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Вырезал три кадра из видео. Первый кадр - непосредственно перед затиранием, второй - визуальная пауза, а третий - уже произошла перерисовка. На линейке времени видна продолжительность паузы - 0.6сек.


Вложения:
Комментарий к файлу: Клик по закладке непосредственно перед затиранием
flicks-1.png
flicks-1.png [ 162.43 КБ | Просмотров: 8263 ]
Комментарий к файлу: Пауза 0.6 сек.
flicks-2.png
flicks-2.png [ 152.64 КБ | Просмотров: 8263 ]
Комментарий к файлу: После паузы сразу же мгновенная отрисовка
flicks-3.png
flicks-3.png [ 161.86 КБ | Просмотров: 8262 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Среда, 16 Март, 2011 23:16 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Попробуйте пологироваться из главного цикла HostMenus.Loop? Сколько там тактов проходит между этими моментами?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 00:06 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Так у Вас же переключение между страницами Tab-View. Это может виндос глючить, а не Блэкбокс. Помню я однажды ещё в Дельфях нагородил мильён контролов в Tab-View и винда очень медленно перерисовывала переключение между его страницами.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 00:09 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Не, у товарищей ярославцев уже свои табы :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 00:53 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Посчитал количество итераций главного цикла, вот каким образом.

1) Завёл экспортированную переменную HostMenus.loopCount.
2) В цикле HostMenus.Loop инкрементирую INC(loopCount).
3) На форму визарда (где наблюдались паузы) вывел Edit Field и связал его с интерактором HostMenus.loopCount.
4) Запустил периодическое действие, которое выполняет Dialog.UpdateLInt(HostMenus.loopCount).
5) Заснял поведение формы визарда.

Результаты.

1) Фликов стало заметно меньше.
2) Счётчик показывает длительность визуальной паузы (описанной ранее) в размере 8-9 итераций. В основном, 9.
3) На видео не удалось поймать изменения счётчика в течение паузы. Значение счётчика меняется скачком по окончанию паузы в кадре, где происходит отрисовка.

Примерно так.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 01:11 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Не, с edit не пойдёт, Вы наблюдаете этот счётчик через гуёвые же штуки. А надо попечатать в лог чисто Services.Ticks() и посмотреть.

А 8-9 итераций как раз и даёт 0.6 с, ведь оконный цикл в винде получает управление от ОС с периодом где-то в 50мс.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 01:14 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Так ведь не сопоставить же содержимое лога с тем, что на видео. А в журнал нет смысла выводить, тот же гуй и получится.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 01:24 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Ну, в принципе и так ясно, что между моментами отрисовки проходит много оборотов оконного цикла... Теперь бы выяснить, откуда такой протормоз. Всё-таки что-то там в каркасе отложенно происходит... Пологировать, какие Action-ы выполняет Services за этот период?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 12:19 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Я хочу понять вот что.

Как понимаю, общий принцип отрисовки отражён в процедуре Views.ValidateRoot:

1. Удаляются ненужные фреймы (вызов RemoveFrames).
2. Дерево фреймов перестраивается (вызов RestoreRoot).
2.1. Внутри RestoreRoot вызывается рекурсивная процедура RestoreFrame, которая обходит дерево фреймов и для каждого привязанного к фрейму отображения вызывает метод v.Restore.

На кадрах из видео мы видим, как возникает эффект флика: совершенно нормально отрисовывается контейнер (форма), а внедрённый в него виджет отрисовывается не сразу.

Получается, что сам контейнер как бы не даёт отрисовать внедрёнку? Не могу пока сформулировать точнее, сумбур в мыслях.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 13:15 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Обнаружил забавную штуку.

В методе Restore формы посчитал количество вызовов InstallFrame и заснял видео на визарде.

Так вот, как только переключаю на закладку с 17 элементами (страничка Контакты), то в лог тут же попадает именно 17 вызовов InstallFrame. Но дальше форма пустая - держится пауза!

И по окончании паузы, форма перерисовывается ещё раз, выводя опять же 17 вызовов InstallFrame.

Вопрос - куда деваются отображения, которых форма пытается инсталлировать с помощью InstallFrame?

Примечание: в лог выводятся ширина и высота формы (для идентификации в кадре) и подсчитанное количество вызовов InstallFrame.


Вложения:
Комментарий к файлу: Клик по закладке, начало паузы, а форма уже инсталлировала 17 внедрёнок.
form1.png
form1.png [ 66.9 КБ | Просмотров: 8169 ]
Комментарий к файлу: Форма перерисовалась
form2.png
form2.png [ 79.42 КБ | Просмотров: 8169 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 14:45 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9155
Откуда: Россия, Орёл
Может, затирается чем-то? В FormView.Restore есть ещё MarkRect после InstallFrames, может, оно трёт? Закомментируйте и проверьте?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Четверг, 17 Март, 2011 17:13 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Проверил, MarkRect не затирает.

У меня возникло подозрение, что только что инсталлированные на форму вьюхи не рисуются сразу же только потому, что их фреймы ещё не попали в общее дерево. А когда на следующем цикле происходит вызов RestoreRoot, эти фреймы уже лежат на пути обхода RestoreFrame, которая и дёргает за v.Restore.

Ведь внедрение вьюх на форму происходит только в FormViews.View.Restore(). Выходит, что отрисовка самих внедрёнок делается на следующей итерации.

P.S. Хотя, я, наверное, не прав. Вот кусочек из RestoreFrame:

Код:
v.Restore(f, l, t, r, b);
            g := f.down;
            WHILE g # NIL DO   (* loop over all subframes to handle overlaps *)
               dx := f.gx - g.gx; dy := f.gy - g.gy;
               RestoreFrame(g, l + dx, t + dy, r + dx, b + dy);
               g := g.next
            END;


То есть, сперва вызывается Restore, а затем на крайний вьюхин фрейм напускается рекурсивно RestoreFrame.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Пятница, 18 Март, 2011 20:22 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Провёл ещё один эксперимент, используя логирование в память (накопленные данные переписываются в журнал позже).

Бросил на форму свою вьюху, которая в методе Restore делает запись в лог. Зафиксировал в логе моменты:
- когда форма инсталлирует эту самую вьюху,
- когда в процедуре Views.RestoreFrames обходятся все инсталлированные на форму фреймы
- когда вызывается метод Restore моей вьюхи.

Заснял на видео, где чётко видно, что во время визуальной паузы метод Restore моей вьюхи вызывается два раза. А самой вьюхи не видно, она не рисуется.

Я-то думал, что каркас каким-то образом откладывает обработку фрейма инсталлированного отображения. Ан нет, всё чётко - инсталлировали, перебрали, вызвали Restore.

Остаётся только WinApi. Тут я пас. То, что происходит между вызовами WinApi.SaveDC и WinApi.RestoreDC, выводится в видимые пиксели с приличной, ощутимой глазу задержкой. А почему - не знаю.

P.S. Хе-хе, для таких исследований пошаговый отладчик - самое то :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Пятница, 18 Март, 2011 22:16 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Кстати, да. Недавно в другом месте тоже таоке мнение слышал: для написания программы отладчик не использую, нужен только чтобы разобраться с каким-нибудь чужим кодом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: И снова о мерцании.
СообщениеДобавлено: Пятница, 18 Март, 2011 23:14 

Зарегистрирован: Четверг, 17 Ноябрь, 2005 11:51
Сообщения: 2932
Откуда: г. Ярославль
Вот ещё что никак не уложится в голове.

Отрисовка формы делается в процессе рекурсивного обхода RestoreFrame, как и все остальные фреймы.

Мерцание хорошо заметно на форме, и ещё лучше видно, когда форма в режиме разметки - с сеточкой.

Получается, что сеточка отрисовывается до начала паузы, а остальные фреймы с формы - уже после окончания паузы.

А буфер-то закрывается только один раз, в RestoreRoot, сразу по окончании обхода RestoreRoot. Каким образом сеточка успевает нарисоваться раньше остальных фреймов?


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 26 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB