Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: DpoHro от Июнь 19, 2008, 21:21



Название: Объединение регионов, тормоза...
Отправлено: 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 все работало быстро.
Реализовано было примерно также...


Название: Re: Объединение регионов, тормоза...
Отправлено: Tonal от Июнь 20, 2008, 10:35
А тормозит на винде?
Если в исходники смотреть, там вроде для винды регионы просто обёртка над WinAPI? Так что вроде тормозить сильно не должно.

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

Да, можно ещё взять стороннюю библиотеку работы с полигонами - например AGG или http://www.wykobi.com/index.html.


Название: Re: Объединение регионов, тормоза...
Отправлено: DpoHro от Июнь 20, 2008, 12:22
Да в винде тормоза, в других осях еще не пробовал.
Сторонние библиотеки незя ((
А вот с PainterPath надо попробовать, и еще на счет кеширования хорошая идея, хотя врядли поможет...

Вообще все это странно, не так уж и сложно должно быть справиться с объединением 100-200 треугольных регионов в один то...


Название: Re: Объединение регионов, тормоза...
Отправлено: pastor от Июнь 20, 2008, 12:40
Заюзай какую-нить профилирующую тулзу и посмотри где проблема.


Название: Re: Объединение регионов, тормоза...
Отправлено: Tonal от Июнь 20, 2008, 12:43
1) А ты уверен, что именно объединение регионов тормозит (под профилером гонял)?

2) Т.к. у тебя структура региона вполне регулярная, можно чуть усложнить алгоритм генерации региона:
Пусть тебе нужно заполнить квадрат со стороной dx*2^n - для этого нужно всего лишь заполнить квадрат со стороной dx*2^(n - 1), а потом объединить его и 3 сдвинутые копии. :)
При не очень тупой реализации объединения регионов получим выигрыш :).
На произвольный прямоугольник обобщить довольно просто.


Название: Re: Объединение регионов, тормоза...
Отправлено: DpoHro от Июнь 20, 2008, 12:49
1) А ты уверен, что именно объединение регионов тормозит (под профилером гонял)?

2) Т.к. у тебя структура региона вполне регулярная, можно чуть усложнить алгоритм генерации региона:
Пусть тебе нужно заполнить квадрат со стороной dx*2^n - для этого нужно всего лишь заполнить квадрат со стороной dx*2^(n - 1), а потом объединить его и 3 сдвинутые копии. :)
При не очень тупой реализации объединения регионов получим выигрыш :).
На произвольный прямоугольник обобщить довольно просто.
Чессговоря не допонял... Вроде как так и делаю, сначала считаю 1 потом сдвигом оного получаю один за другим регионы и объединяю их


Название: Re: Объединение регионов, тормоза...
Отправлено: Tonal от Июнь 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 в исходном варианте.

Другое дело, что и сами регионы становятся изрядно сложнее. Поэтому нужно тестировать.


Название: Re: Объединение регионов, тормоза...
Отправлено: DpoHro от Июнь 20, 2008, 19:26
просчет полигонов и объединение регионов происходит мнгновенно а вот тут
Код:
widget.setMask(reg);
Как раз время и теряется, причем тем больше чем больше сами эти единичные полигончики...
Собсно и в описании ф-ции есть на это нотис.
Но чтоже использовать, ведь на WinAPI все быстро работало, а в самой ф-ции вроде ничего сложного не происходит почему она так тормозит?
И что делать ?


Название: Re: Объединение регионов, тормоза...
Отправлено: pastor от Июнь 20, 2008, 23:22
Написать suggestion тролям, типа такого: Improve performance of QWidget::setMask on Windows (или на другой платформе).
И отправить ваш примерчик.


Название: Re: Объединение регионов, тормоза...
Отправлено: Tonal от Июнь 24, 2008, 10:34
Посмотрел в код setMask - вроде тоже довольно тонкая прослойка над WinApi.
Правда, в случае если твой виджет не имеет окна, маска используется ещё и для обновления окна родителя.
Может здесь тормоза?
Правда не ясно как это обойти.


Название: Re: Объединение регионов, тормоза...
Отправлено: lit-uriy от Июнь 24, 2008, 16:31
может это подойдет:
setUpdatesEnabled(false);
...
setUpdatesEnabled(true);