kwin: Optimize WindowQuadList::makeRegularGrid()
Instead of looping over every quad for every grid cell and checking for possible intersections, loop over the quads once and compute the top left corner of the first intersecting grid cell. Then loop over all the intersecting cells from that point and create the sub quads. This new algorithm also preserves the order of the quads in the original list.
This commit is contained in:
parent
b5b7fac056
commit
006529d8b2
1 changed files with 36 additions and 23 deletions
|
@ -1039,40 +1039,53 @@ WindowQuadList WindowQuadList::makeRegularGrid(int xSubdivisions, int ySubdivisi
|
|||
{
|
||||
if (empty())
|
||||
return *this;
|
||||
// find the bounding rectangle
|
||||
double left = first().left();
|
||||
double right = first().right();
|
||||
double top = first().top();
|
||||
|
||||
// Find the bounding rectangle
|
||||
double left = first().left();
|
||||
double right = first().right();
|
||||
double top = first().top();
|
||||
double bottom = first().bottom();
|
||||
foreach (const WindowQuad & quad, *this) {
|
||||
|
||||
foreach (const WindowQuad &quad, *this) {
|
||||
#ifndef NDEBUG
|
||||
if (quad.isTransformed())
|
||||
kFatal(1212) << "Splitting quads is allowed only in pre-paint calls!" ;
|
||||
kFatal(1212) << "Splitting quads is allowed only in pre-paint calls!";
|
||||
#endif
|
||||
left = qMin(left, quad.left());
|
||||
right = qMax(right, quad.right());
|
||||
top = qMin(top, quad.top());
|
||||
left = qMin(left, quad.left());
|
||||
right = qMax(right, quad.right());
|
||||
top = qMin(top, quad.top());
|
||||
bottom = qMax(bottom, quad.bottom());
|
||||
}
|
||||
|
||||
double xincrement = (right - left) / xSubdivisions;
|
||||
double yincrement = (bottom - top) / ySubdivisions;
|
||||
double xIncrement = (right - left) / xSubdivisions;
|
||||
double yIncrement = (bottom - top) / ySubdivisions;
|
||||
|
||||
WindowQuadList ret;
|
||||
for (double y = top;
|
||||
y < bottom;
|
||||
y += yincrement) {
|
||||
for (double x = left;
|
||||
x < right;
|
||||
x += xincrement) {
|
||||
foreach (const WindowQuad & quad, *this) {
|
||||
if (QRectF(QPointF(quad.left(), quad.top()), QPointF(quad.right(), quad.bottom()))
|
||||
.intersects(QRectF(x, y, xincrement, yincrement))) {
|
||||
ret.append(quad.makeSubQuad(qMax(x, quad.left()), qMax(y, quad.top()),
|
||||
qMin(quad.right(), x + xincrement), qMin(quad.bottom(), y + yincrement)));
|
||||
}
|
||||
|
||||
foreach (const WindowQuad &quad, *this) {
|
||||
const double quadLeft = quad.left();
|
||||
const double quadRight = quad.right();
|
||||
const double quadTop = quad.top();
|
||||
const double quadBottom = quad.bottom();
|
||||
|
||||
// Compute the top-left corner of the first intersecting grid cell
|
||||
const double xBegin = left + qFloor((quadLeft - left) / xIncrement) * xIncrement;
|
||||
const double yBegin = top + qFloor((quadTop - top) / yIncrement) * yIncrement;
|
||||
|
||||
// Loop over all intersecting cells and add sub-quads
|
||||
for (double y = yBegin; y < quadBottom; y += yIncrement) {
|
||||
const double y0 = qMax(y, quadTop);
|
||||
const double y1 = qMin(quadBottom, y + yIncrement);
|
||||
|
||||
for (double x = xBegin; x < quadRight; x += xIncrement) {
|
||||
const double x0 = qMax(x, quadLeft);
|
||||
const double x1 = qMin(quadRight, x + xIncrement);
|
||||
|
||||
ret.append(quad.makeSubQuad(x0, y0, x1, y1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue