Prefer QRegion::operator+=

`QRegion::operator|=` has some optimizations but it basically boils
down to

  QRegion result(*this);
  result.detach(); // it will make a copy because this is shared
  result.d->append(rect);
  return result;

On the other hand, `QRegion::operator+=` tries to add the new rect
in-place.
This commit is contained in:
Vlad Zahorodnii 2024-01-23 15:49:39 +02:00
parent f44484137e
commit 3bce89553c
18 changed files with 41 additions and 41 deletions

View file

@ -78,7 +78,7 @@ QRegion RenderViewport::mapToRenderTarget(const QRegion &logicalGeometry) const
{
QRegion ret;
for (const auto &rect : logicalGeometry) {
ret |= mapToRenderTarget(rect);
ret += mapToRenderTarget(rect);
}
return ret;
}
@ -109,7 +109,7 @@ QRegion RenderViewport::mapToRenderTargetTexture(const QRegion &logicalGeometry)
{
QRegion ret;
for (const auto &rect : logicalGeometry) {
ret |= mapToRenderTargetTexture(rect);
ret += mapToRenderTargetTexture(rect);
}
return ret;
}

View file

@ -305,7 +305,7 @@ QRegion ContrastEffect::contrastRegion(const EffectWindow *w) const
if (const auto it = m_windowData.find(w); it != m_windowData.end()) {
const QRegion &appRegion = it->second.contrastRegion;
if (!appRegion.isEmpty()) {
region |= appRegion.translated(w->contentsRect().topLeft().toPoint()) & w->decorationInnerRect().toRect();
region += appRegion.translated(w->contentsRect().topLeft().toPoint()) & w->decorationInnerRect().toRect();
} else {
// An empty region means that the blur effect should be enabled
// for the whole window.
@ -411,7 +411,7 @@ void ContrastEffect::drawWindow(const RenderTarget &renderTarget, const RenderVi
pt.y() + (r.y() - pt.y()) * data.yScale() + data.yTranslation());
const QPoint bottomRight(std::floor(topLeft.x() + r.width() * data.xScale()) - 1,
std::floor(topLeft.y() + r.height() * data.yScale()) - 1);
scaledShape |= QRect(QPoint(std::floor(topLeft.x()), std::floor(topLeft.y())), bottomRight);
scaledShape += QRect(QPoint(std::floor(topLeft.x()), std::floor(topLeft.y())), bottomRight);
}
shape = scaledShape & region;
@ -422,7 +422,7 @@ void ContrastEffect::drawWindow(const RenderTarget &renderTarget, const RenderVi
const QRectF t = QRectF(r).translated(data.xTranslation(), data.yTranslation());
const QPoint topLeft(std::ceil(t.x()), std::ceil(t.y()));
const QPoint bottomRight(std::floor(t.x() + t.width() - 1), std::floor(t.y() + t.height() - 1));
translated |= QRect(topLeft, bottomRight);
translated += QRect(topLeft, bottomRight);
}
shape = translated & region;
}

View file

@ -394,7 +394,7 @@ QRegion BlurEffect::blurRegion(EffectWindow *w) const
if (frame.has_value()) {
region = frame.value();
}
region |= content->translated(w->contentsRect().topLeft().toPoint()) & w->decorationInnerRect().toRect();
region += content->translated(w->contentsRect().topLeft().toPoint()) & w->decorationInnerRect().toRect();
}
} else if (frame.has_value()) {
region = frame.value();
@ -424,7 +424,7 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::
// to blur an area partially we have to shrink the opaque area of a window
QRegion newOpaque;
for (const QRect &rect : data.opaque) {
newOpaque |= rect.adjusted(m_expandSize, m_expandSize, -m_expandSize, -m_expandSize);
newOpaque += rect.adjusted(m_expandSize, m_expandSize, -m_expandSize, -m_expandSize);
}
data.opaque = newOpaque;
@ -435,7 +435,7 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::
// if we have to paint a non-opaque part of this window that intersects with the
// currently blurred region we have to redraw the whole region
if ((data.paint - oldOpaque).intersects(m_currentBlur)) {
data.paint |= m_currentBlur;
data.paint += m_currentBlur;
}
// in case this window has regions to be blurred
@ -444,18 +444,18 @@ void BlurEffect::prePaintWindow(EffectWindow *w, WindowPrePaintData &data, std::
// if this window or a window underneath the blurred area is painted again we have to
// blur everything
if (m_paintedArea.intersects(blurArea) || data.paint.intersects(blurArea)) {
data.paint |= blurArea;
data.paint += blurArea;
// we have to check again whether we do not damage a blurred area
// of a window
if (blurArea.intersects(m_currentBlur)) {
data.paint |= m_currentBlur;
data.paint += m_currentBlur;
}
}
m_currentBlur |= blurArea;
m_currentBlur += blurArea;
m_paintedArea -= data.opaque;
m_paintedArea |= data.paint;
m_paintedArea += data.paint;
}
bool BlurEffect::shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const
@ -545,7 +545,7 @@ void BlurEffect::blur(const RenderTarget &renderTarget, const RenderViewport &vi
pt.y() + (r.y() - pt.y()) * data.yScale() + data.yTranslation());
const QPoint bottomRight(std::floor(topLeft.x() + r.width() * data.xScale()) - 1,
std::floor(topLeft.y() + r.height() * data.yScale()) - 1);
scaledShape |= QRect(QPoint(std::floor(topLeft.x()), std::floor(topLeft.y())), bottomRight);
scaledShape += QRect(QPoint(std::floor(topLeft.x()), std::floor(topLeft.y())), bottomRight);
}
blurShape = scaledShape;
} else if (data.xTranslation() || data.yTranslation()) {
@ -554,7 +554,7 @@ void BlurEffect::blur(const RenderTarget &renderTarget, const RenderViewport &vi
const QRectF t = QRectF(r).translated(data.xTranslation(), data.yTranslation());
const QPoint topLeft(std::ceil(t.x()), std::ceil(t.y()));
const QPoint bottomRight(std::floor(t.x() + t.width() - 1), std::floor(t.y() + t.height() - 1));
translated |= QRect(topLeft, bottomRight);
translated += QRect(topLeft, bottomRight);
}
blurShape = translated;
}

View file

@ -111,7 +111,7 @@ void MagnifierEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::mill
effects->prePaintScreen(data, presentTime);
if (m_zoom != 1.0) {
data.paint |= magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH);
data.paint += magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH);
}
}

View file

@ -201,9 +201,9 @@ void MouseClickEffect::repaint()
QRegion dirtyRegion;
const int radius = m_ringMaxSize + m_lineWidth;
for (auto &click : m_clicks) {
dirtyRegion |= QRect(click->m_pos.x() - radius, click->m_pos.y() - radius, 2 * radius, 2 * radius);
dirtyRegion += QRect(click->m_pos.x() - radius, click->m_pos.y() - radius, 2 * radius, 2 * radius);
if (click->m_frame) {
dirtyRegion |= click->m_frame->geometry();
dirtyRegion += click->m_frame->geometry();
}
}
effects->addRepaint(dirtyRegion);
@ -212,7 +212,7 @@ void MouseClickEffect::repaint()
QRegion dirtyRegion;
const int radius = m_ringMaxSize + m_lineWidth;
for (const auto &event : std::as_const(m_tabletTools)) {
dirtyRegion |= QRect(event.m_globalPosition.x() - radius, event.m_globalPosition.y() - radius, 2 * radius, 2 * radius);
dirtyRegion += QRect(event.m_globalPosition.x() - radius, event.m_globalPosition.y() - radius, 2 * radius, 2 * radius);
}
effects->addRepaint(dirtyRegion);
}

View file

@ -98,7 +98,7 @@ void OutputLocatorEffect::hide()
QRegion repaintRegion;
for (const auto &[screen, scene] : m_scenesByScreens) {
repaintRegion |= scene->geometry();
repaintRegion += scene->geometry();
}
m_scenesByScreens.clear();

View file

@ -95,7 +95,7 @@ void BackingStore::flush(QWindow *window, const QRegion &region, const QPoint &o
const qreal scale = platformWindow->devicePixelRatio();
QRegion bufferDamage;
for (const QRect &rect : region) {
bufferDamage |= QRectF(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale).toAlignedRect();
bufferDamage += QRectF(rect.x() * scale, rect.y() * scale, rect.width() * scale, rect.height() * scale).toAlignedRect();
}
internalWindow->present(InternalWindowFrame{

View file

@ -455,7 +455,7 @@ void ScreenCastStream::recordFrame(const QRegion &_damagedRegion)
Q_ASSERT(!m_stopped);
if (!m_streaming) {
m_pendingDamages |= damagedRegion;
m_pendingDamages += damagedRegion;
return;
}
@ -463,7 +463,7 @@ void ScreenCastStream::recordFrame(const QRegion &_damagedRegion)
auto frameInterval = (1000. * m_videoFormat.max_framerate.denom / m_videoFormat.max_framerate.num);
auto lastSentAgo = m_lastSent.msecsTo(QDateTime::currentDateTimeUtc());
if (lastSentAgo < frameInterval) {
m_pendingDamages |= damagedRegion;
m_pendingDamages += damagedRegion;
if (!m_pendingFrame.isActive()) {
m_pendingFrame.start(frameInterval - lastSentAgo);
}
@ -590,7 +590,7 @@ void ScreenCastStream::recordFrame(const QRegion &_damagedRegion)
damagedRegion += QRegion{m_cursor.lastRect.toAlignedRect()} | cursorRect.toAlignedRect();
m_cursor.lastRect = cursorRect;
} else {
damagedRegion |= m_cursor.lastRect.toAlignedRect();
damagedRegion += m_cursor.lastRect.toAlignedRect();
m_cursor.lastRect = {};
}
}

View file

@ -61,7 +61,7 @@ void ShowPaintEffect::paintScreen(const RenderTarget &renderTarget, const Render
void ShowPaintEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
{
m_painted |= region;
m_painted += region;
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
}

View file

@ -79,16 +79,16 @@ inline QRegion buildClipRegion(const QPoint &pos, int w, int h)
const QSize screenSize = effects->virtualScreenSize();
QRegion r = QRect(pos, screenSize);
if (effects->optionRollOverDesktops()) {
r |= (r & QRect(-w, 0, w, h)).translated(w, 0); // W
r |= (r & QRect(w, 0, w, h)).translated(-w, 0); // E
r += (r & QRect(-w, 0, w, h)).translated(w, 0); // W
r += (r & QRect(w, 0, w, h)).translated(-w, 0); // E
r |= (r & QRect(0, -h, w, h)).translated(0, h); // N
r |= (r & QRect(0, h, w, h)).translated(0, -h); // S
r += (r & QRect(0, -h, w, h)).translated(0, h); // N
r += (r & QRect(0, h, w, h)).translated(0, -h); // S
r |= (r & QRect(-w, -h, w, h)).translated(w, h); // NW
r |= (r & QRect(w, -h, w, h)).translated(-w, h); // NE
r |= (r & QRect(w, h, w, h)).translated(-w, -h); // SE
r |= (r & QRect(-w, h, w, h)).translated(w, -h); // SW
r += (r & QRect(-w, -h, w, h)).translated(w, h); // NW
r += (r & QRect(w, -h, w, h)).translated(-w, h); // NE
r += (r & QRect(w, h, w, h)).translated(-w, -h); // SE
r += (r & QRect(-w, h, w, h)).translated(w, -h); // SW
}
return r;
}

View file

@ -74,7 +74,7 @@ void ThumbnailAsideEffect::paintScreen(const RenderTarget &renderTarget, const R
void ThumbnailAsideEffect::paintWindow(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, int mask, QRegion region, WindowPaintData &data)
{
effects->paintWindow(renderTarget, viewport, w, mask, region, data);
painted |= region;
painted += region;
}
void ThumbnailAsideEffect::slotWindowDamaged(EffectWindow *w)

View file

@ -170,7 +170,7 @@ void TouchPointsEffect::repaint()
QRegion dirtyRegion;
const int radius = m_ringMaxSize + m_lineWidth;
for (auto it = m_points.constBegin(), end = m_points.constEnd(); it != end; ++it) {
dirtyRegion |= QRect(it->pos.x() - radius, it->pos.y() - radius, 2 * radius, 2 * radius);
dirtyRegion += QRect(it->pos.x() - radius, it->pos.y() - radius, 2 * radius, 2 * radius);
}
effects->addRepaint(dirtyRegion);
}

View file

@ -94,7 +94,7 @@ void TrackMouseEffect::prePaintScreen(ScreenPrePaintData &data, std::chrono::mil
m_angle = ((t.second() % 4) * m_angleBase) + (t.msec() / 1000.0 * m_angleBase);
m_lastRect[0].moveCenter(cursorPos().toPoint());
m_lastRect[1].moveCenter(cursorPos().toPoint());
data.paint |= m_lastRect[0].adjusted(-1, -1, 1, 1);
data.paint += m_lastRect[0].adjusted(-1, -1, 1, 1);
effects->prePaintScreen(data, presentTime);
}

View file

@ -168,7 +168,7 @@ QRegion SurfaceItemX11::opaque() const
{
QRegion shapeRegion;
for (const QRectF &shapePart : shape()) {
shapeRegion |= shapePart.toRect();
shapeRegion += shapePart.toRect();
}
if (!m_window->hasAlpha()) {
return shapeRegion;

View file

@ -325,7 +325,7 @@ void WorkspaceScene::preparePaintSimpleScreen()
const DecorationItem *decorationItem = windowItem->decorationItem();
if (decorationItem) {
data.opaque |= decorationItem->mapToGlobal(decorationItem->opaque());
data.opaque += decorationItem->mapToGlobal(decorationItem->opaque());
}
}

View file

@ -68,7 +68,7 @@ public:
QRegion region;
if (bufferAge > 0 && bufferAge <= m_log.size()) {
for (int i = 0; i < bufferAge - 1; ++i) {
region |= m_log[i];
region += m_log[i];
}
} else {
region = fallback;

View file

@ -302,7 +302,7 @@ void SurfaceInterfacePrivate::surface_attach(Resource *resource, struct ::wl_res
void SurfaceInterfacePrivate::surface_damage(Resource *, int32_t x, int32_t y, int32_t width, int32_t height)
{
pending->damage |= QRect(x, y, width, height);
pending->damage += QRect(x, y, width, height);
}
void SurfaceInterfacePrivate::surface_frame(Resource *resource, uint32_t callback)
@ -396,7 +396,7 @@ void SurfaceInterfacePrivate::surface_set_buffer_scale(Resource *resource, int32
void SurfaceInterfacePrivate::surface_damage_buffer(Resource *resource, int32_t x, int32_t y, int32_t width, int32_t height)
{
pending->bufferDamage |= QRect(x, y, width, height);
pending->bufferDamage += QRect(x, y, width, height);
}
void SurfaceInterfacePrivate::surface_offset(Resource *resource, int32_t x, int32_t y)

View file

@ -5037,7 +5037,7 @@ void X11Window::getWmOpaqueRegion()
const auto rects = info->opaqueRegion();
QRegion new_opaque_region;
for (const auto &r : rects) {
new_opaque_region |= Xcb::fromXNative(QRect(r.pos.x, r.pos.y, r.size.width, r.size.height)).toRect();
new_opaque_region += Xcb::fromXNative(QRect(r.pos.x, r.pos.y, r.size.width, r.size.height)).toRect();
}
opaque_region = new_opaque_region;
}