kwin: Optimize WindowQuadList::makeGrid()

This is the same optimization that was done in makeRegularGrid()
in 45782d387ab894c682b4ccc220e596c8b72c4167.
This commit is contained in:
Fredrik Höglund 2013-09-09 17:28:46 +02:00
parent 006529d8b2
commit 76adeb6a13

View file

@ -997,41 +997,54 @@ WindowQuadList WindowQuadList::splitAtY(double y) const
return ret; return ret;
} }
WindowQuadList WindowQuadList::makeGrid(int maxquadsize) const WindowQuadList WindowQuadList::makeGrid(int maxQuadSize) const
{ {
if (empty()) if (empty())
return *this; return *this;
// find the bounding rectangle
double left = first().left(); // Find the bounding rectangle
double right = first().right(); double left = first().left();
double top = first().top(); double right = first().right();
double top = first().top();
double bottom = first().bottom(); double bottom = first().bottom();
foreach (const WindowQuad & quad, *this) {
foreach (const WindowQuad &quad, *this) {
#ifndef NDEBUG #ifndef NDEBUG
if (quad.isTransformed()) 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 #endif
left = qMin(left, quad.left()); left = qMin(left, quad.left());
right = qMax(right, quad.right()); right = qMax(right, quad.right());
top = qMin(top, quad.top()); top = qMin(top, quad.top());
bottom = qMax(bottom, quad.bottom()); bottom = qMax(bottom, quad.bottom());
} }
WindowQuadList ret; WindowQuadList ret;
for (double x = left;
x < right; foreach (const WindowQuad &quad, *this) {
x += maxquadsize) { const double quadLeft = quad.left();
for (double y = top; const double quadRight = quad.right();
y < bottom; const double quadTop = quad.top();
y += maxquadsize) { const double quadBottom = quad.bottom();
foreach (const WindowQuad & quad, *this) {
if (QRectF(QPointF(quad.left(), quad.top()), QPointF(quad.right(), quad.bottom())) // Compute the top-left corner of the first intersecting grid cell
.intersects(QRectF(x, y, maxquadsize, maxquadsize))) { const double xBegin = left + qFloor((quadLeft - left) / maxQuadSize) * maxQuadSize;
ret.append(quad.makeSubQuad(qMax(x, quad.left()), qMax(y, quad.top()), const double yBegin = top + qFloor((quadTop - top) / maxQuadSize) * maxQuadSize;
qMin(quad.right(), x + maxquadsize), qMin(quad.bottom(), y + maxquadsize)));
} // Loop over all intersecting cells and add sub-quads
for (double y = yBegin; y < quadBottom; y += maxQuadSize) {
const double y0 = qMax(y, quadTop);
const double y1 = qMin(quadBottom, y + maxQuadSize);
for (double x = xBegin; x < quadRight; x += maxQuadSize) {
const double x0 = qMax(x, quadLeft);
const double x1 = qMin(quadRight, x + maxQuadSize);
ret.append(quad.makeSubQuad(x0, y0, x1, y1));
} }
} }
} }
return ret; return ret;
} }