scene: Pad damage if scale factor is fractional
Floating point arithmetic and/or the use of GL_LINEAR in the pipeline, may result in visual glitches due to rounding (errors). As a short-term fix until a proper (more involved) solution is in place for Plasma 6, pad the damage slightly in all directions to alleviate those effects.
This commit is contained in:
parent
9ac6f71662
commit
56f6bab0c3
1 changed files with 26 additions and 5 deletions
|
@ -241,14 +241,29 @@ static void resetRepaintsHelper(Item *item, SceneDelegate *delegate)
|
|||
}
|
||||
}
|
||||
|
||||
static void accumulateRepaints(Item *item, SceneDelegate *delegate, QRegion *repaints)
|
||||
static void accumulateRepaints(Item *item, SceneDelegate *delegate, QRegion *repaints, const bool padDamage)
|
||||
{
|
||||
*repaints += item->repaints(delegate);
|
||||
if (!padDamage) {
|
||||
*repaints += item->repaints(delegate);
|
||||
} else {
|
||||
const auto padding = 1;
|
||||
|
||||
for (const QRect region : item->repaints(delegate)) {
|
||||
if (region.isEmpty() || region == infiniteRegion()) {
|
||||
*repaints += region;
|
||||
continue;
|
||||
}
|
||||
|
||||
*repaints += QRect{region.x() - padding, region.y() - padding,
|
||||
region.width() + 2 * padding, region.height() + 2 * padding};
|
||||
}
|
||||
}
|
||||
|
||||
item->resetRepaints(delegate);
|
||||
|
||||
const auto childItems = item->childItems();
|
||||
for (Item *childItem : childItems) {
|
||||
accumulateRepaints(childItem, delegate, repaints);
|
||||
accumulateRepaints(childItem, delegate, repaints, padDamage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,11 +290,17 @@ void WorkspaceScene::preparePaintGenericScreen()
|
|||
|
||||
void WorkspaceScene::preparePaintSimpleScreen()
|
||||
{
|
||||
// if a fractional scale factor is used, pad the damage to avoid visual
|
||||
// glitches due to rounding errors (floating point arithmetic) and/or the
|
||||
// use of GL_LINEAR in the pipeline
|
||||
const auto scale = painted_screen->scale();
|
||||
const bool padDamage = std::trunc(scale) != scale;
|
||||
|
||||
for (WindowItem *windowItem : std::as_const(stacking_order)) {
|
||||
Window *window = windowItem->window();
|
||||
WindowPrePaintData data;
|
||||
data.mask = m_paintContext.mask;
|
||||
accumulateRepaints(windowItem, painted_delegate, &data.paint);
|
||||
accumulateRepaints(windowItem, painted_delegate, &data.paint, padDamage);
|
||||
|
||||
// Clip out the decoration for opaque windows; the decoration is drawn in the second pass.
|
||||
if (window->opacity() == 1.0) {
|
||||
|
@ -314,7 +335,7 @@ void WorkspaceScene::preparePaintSimpleScreen()
|
|||
}
|
||||
|
||||
if (m_dndIcon) {
|
||||
accumulateRepaints(m_dndIcon.get(), painted_delegate, &m_paintContext.damage);
|
||||
accumulateRepaints(m_dndIcon.get(), painted_delegate, &m_paintContext.damage, padDamage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue