Russian Qt Forum
Ноябрь 25, 2024, 06:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Объединение регионов, тормоза...  (Прочитано 7854 раз)
DpoHro
Гость
« : Июнь 19, 2008, 21:21 »

Реализовываю некий эффект появления виджета.
Смысл, например как в PowerPoint "появить" виджет.

Как я это делаю:
Дана некоторая зернистость N в зависимости от которой эффект на виджете повторяется N раз по высоте и N раз по ширине.
В потоке в зависимости от заданного времени выполнения насчитывается полигон по которому создается единичный полигон который будет использоваться для создания всего региона.
Затем он размножается на весь виджет в цикле:

Код примерно такой (пишу прямо тут так как сорсов под рукой сейчас нет):
Код:
while(true)
{
...
QRegion reg;
for (long i=0; i<N; i++)
for (long j=0; j<N; j++)
{
  QRegionF plTemplateTemp(plTemplate);
  plTemplateTemp.translate(dx*i,dy*j);
  reg = reg.united(QRegion(plTemplateTemp));
}

widget.setMask(reg);
...
msleep(1);
if (...) return;
}

plTemplate - это тот расчитанный выше полигончик базовый. При его расчете тормазов нет точно так как там все просто...

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

Что делать не знаю, когда это же было написано на WinAPI все работало быстро.
Реализовано было примерно также...
Записан
Tonal
Гость
« Ответ #1 : Июнь 20, 2008, 10:35 »

А тормозит на винде?
Если в исходники смотреть, там вроде для винды регионы просто обёртка над WinAPI? Так что вроде тормозить сильно не должно.

Можно ещё попробовать работать не с регионами а с PainterPath или с QPolygonF.
Ну и вынести эти расчёты в другой поток и кешировать.

Да, можно ещё взять стороннюю библиотеку работы с полигонами - например AGG или http://www.wykobi.com/index.html.
« Последнее редактирование: Июнь 20, 2008, 10:40 от Tonal » Записан
DpoHro
Гость
« Ответ #2 : Июнь 20, 2008, 12:22 »

Да в винде тормоза, в других осях еще не пробовал.
Сторонние библиотеки незя ((
А вот с PainterPath надо попробовать, и еще на счет кеширования хорошая идея, хотя врядли поможет...

Вообще все это странно, не так уж и сложно должно быть справиться с объединением 100-200 треугольных регионов в один то...
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Июнь 20, 2008, 12:40 »

Заюзай какую-нить профилирующую тулзу и посмотри где проблема.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Tonal
Гость
« Ответ #4 : Июнь 20, 2008, 12:43 »

1) А ты уверен, что именно объединение регионов тормозит (под профилером гонял)?

2) Т.к. у тебя структура региона вполне регулярная, можно чуть усложнить алгоритм генерации региона:
Пусть тебе нужно заполнить квадрат со стороной dx*2^n - для этого нужно всего лишь заполнить квадрат со стороной dx*2^(n - 1), а потом объединить его и 3 сдвинутые копии. Улыбающийся
При не очень тупой реализации объединения регионов получим выигрыш Улыбающийся.
На произвольный прямоугольник обобщить довольно просто.
Записан
DpoHro
Гость
« Ответ #5 : Июнь 20, 2008, 12:49 »

1) А ты уверен, что именно объединение регионов тормозит (под профилером гонял)?

2) Т.к. у тебя структура региона вполне регулярная, можно чуть усложнить алгоритм генерации региона:
Пусть тебе нужно заполнить квадрат со стороной dx*2^n - для этого нужно всего лишь заполнить квадрат со стороной dx*2^(n - 1), а потом объединить его и 3 сдвинутые копии. Улыбающийся
При не очень тупой реализации объединения регионов получим выигрыш Улыбающийся.
На произвольный прямоугольник обобщить довольно просто.
Чессговоря не допонял... Вроде как так и делаю, сначала считаю 1 потом сдвигом оного получаю один за другим регионы и объединяю их
Записан
Tonal
Гость
« Ответ #6 : Июнь 20, 2008, 18:32 »

Для квадрата со стороной dx*2^n
Код:
QRegion res(plTemplate);
for (int tdx = dx; dx < width; tdx += tdx) {
  QRegion tmp(res);
  tmp.translate(tdx, 0);
  res += tmp();
  tmp.translate(-tdx, tdx);
  res += tmp();
  tmp.translate(tdx, 0);
  res += tmp();
}
Идея в том, что ты на каждой итерации работаешь со всё более большими регионами.
Т.е. количество итераций у тебя log2(width/dx) а не width/dx в исходном варианте.

Другое дело, что и сами регионы становятся изрядно сложнее. Поэтому нужно тестировать.
« Последнее редактирование: Июнь 20, 2008, 18:35 от Tonal » Записан
DpoHro
Гость
« Ответ #7 : Июнь 20, 2008, 19:26 »

просчет полигонов и объединение регионов происходит мнгновенно а вот тут
Код:
widget.setMask(reg);
Как раз время и теряется, причем тем больше чем больше сами эти единичные полигончики...
Собсно и в описании ф-ции есть на это нотис.
Но чтоже использовать, ведь на WinAPI все быстро работало, а в самой ф-ции вроде ничего сложного не происходит почему она так тормозит?
И что делать ?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Июнь 20, 2008, 23:22 »

Написать suggestion тролям, типа такого: Improve performance of QWidget::setMask on Windows (или на другой платформе).
И отправить ваш примерчик.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Tonal
Гость
« Ответ #9 : Июнь 24, 2008, 10:34 »

Посмотрел в код setMask - вроде тоже довольно тонкая прослойка над WinApi.
Правда, в случае если твой виджет не имеет окна, маска используется ещё и для обновления окна родителя.
Может здесь тормоза?
Правда не ясно как это обойти.
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #10 : Июнь 24, 2008, 16:31 »

может это подойдет:
setUpdatesEnabled(false);
...
setUpdatesEnabled(true);
Записан

Юра.
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.106 секунд. Запросов: 23.