Fix scheduling repaints in Effect::prePaintScreen()
If a repaint is scheduled in the prePaintScreen() function, we want it to be applied in the next frame, not the current one. Currently, it doesn't work like this because prePaintScreen() runs first then the Compositor gathers repaints and resets them. This is important to qtquick effects that use qtquick3d as some items in qtquick3d schedule repaints for the next frame after synchronizing, i.e. in OffscreenQuickView::update() which is called in prePaintScreen() by QuickSceneEffect.
This commit is contained in:
parent
735d8c9da3
commit
0f7369ed1b
10 changed files with 34 additions and 54 deletions
|
@ -157,7 +157,10 @@ void Compositor::composite(RenderLoop *renderLoop)
|
|||
|
||||
if (superLayer->needsRepaint()) {
|
||||
renderLoop->beginPaint();
|
||||
prePaintPass(superLayer);
|
||||
|
||||
QRegion surfaceDamage = primaryLayer->repaints();
|
||||
primaryLayer->resetRepaints();
|
||||
prePaintPass(superLayer, &surfaceDamage);
|
||||
|
||||
SurfaceItem *scanoutCandidate = superLayer->delegate()->scanoutCandidate();
|
||||
renderLoop->setFullscreenSurface(scanoutCandidate);
|
||||
|
@ -175,10 +178,6 @@ void Compositor::composite(RenderLoop *renderLoop)
|
|||
}
|
||||
|
||||
if (!directScanout) {
|
||||
QRegion surfaceDamage = primaryLayer->repaints();
|
||||
primaryLayer->resetRepaints();
|
||||
preparePaintPass(superLayer, &surfaceDamage);
|
||||
|
||||
if (auto beginInfo = primaryLayer->beginFrame()) {
|
||||
auto &[renderTarget, repaint] = beginInfo.value();
|
||||
|
||||
|
@ -219,12 +218,23 @@ void Compositor::framePass(RenderLayer *layer)
|
|||
}
|
||||
}
|
||||
|
||||
void Compositor::prePaintPass(RenderLayer *layer)
|
||||
void Compositor::prePaintPass(RenderLayer *layer, QRegion *damage)
|
||||
{
|
||||
layer->delegate()->prePaint();
|
||||
if (const QRegion repaints = layer->repaints(); !repaints.isEmpty()) {
|
||||
*damage += layer->mapToGlobal(repaints);
|
||||
layer->resetRepaints();
|
||||
}
|
||||
|
||||
const QRegion repaints = layer->delegate()->prePaint();
|
||||
if (!repaints.isEmpty()) {
|
||||
*damage += layer->mapToGlobal(repaints);
|
||||
}
|
||||
|
||||
const auto sublayers = layer->sublayers();
|
||||
for (RenderLayer *sublayer : sublayers) {
|
||||
prePaintPass(sublayer);
|
||||
if (sublayer->isVisible()) {
|
||||
prePaintPass(sublayer, damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -232,20 +242,9 @@ void Compositor::postPaintPass(RenderLayer *layer)
|
|||
{
|
||||
layer->delegate()->postPaint();
|
||||
const auto sublayers = layer->sublayers();
|
||||
for (RenderLayer *sublayer : sublayers) {
|
||||
postPaintPass(sublayer);
|
||||
}
|
||||
}
|
||||
|
||||
void Compositor::preparePaintPass(RenderLayer *layer, QRegion *repaint)
|
||||
{
|
||||
// TODO: Cull opaque region.
|
||||
*repaint += layer->mapToGlobal(layer->repaints() + layer->delegate()->repaints());
|
||||
layer->resetRepaints();
|
||||
const auto sublayers = layer->sublayers();
|
||||
for (RenderLayer *sublayer : sublayers) {
|
||||
if (sublayer->isVisible()) {
|
||||
preparePaintPass(sublayer, repaint);
|
||||
postPaintPass(sublayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -146,9 +146,8 @@ protected:
|
|||
void addSuperLayer(RenderLayer *layer);
|
||||
void removeSuperLayer(RenderLayer *layer);
|
||||
|
||||
void prePaintPass(RenderLayer *layer);
|
||||
void prePaintPass(RenderLayer *layer, QRegion *damage);
|
||||
void postPaintPass(RenderLayer *layer);
|
||||
void preparePaintPass(RenderLayer *layer, QRegion *repaint);
|
||||
void paintPass(RenderLayer *layer, const RenderTarget &renderTarget, const QRegion ®ion);
|
||||
void framePass(RenderLayer *layer);
|
||||
|
||||
|
|
|
@ -19,17 +19,13 @@ void RenderLayerDelegate::setLayer(RenderLayer *layer)
|
|||
m_layer = layer;
|
||||
}
|
||||
|
||||
QRegion RenderLayerDelegate::repaints() const
|
||||
{
|
||||
return QRegion();
|
||||
}
|
||||
|
||||
void RenderLayerDelegate::frame()
|
||||
{
|
||||
}
|
||||
|
||||
void RenderLayerDelegate::prePaint()
|
||||
QRegion RenderLayerDelegate::prePaint()
|
||||
{
|
||||
return QRegion();
|
||||
}
|
||||
|
||||
void RenderLayerDelegate::postPaint()
|
||||
|
|
|
@ -29,11 +29,6 @@ public:
|
|||
RenderLayer *layer() const;
|
||||
void setLayer(RenderLayer *layer);
|
||||
|
||||
/**
|
||||
* Returns the repaints schduled for the next frame.
|
||||
*/
|
||||
virtual QRegion repaints() const;
|
||||
|
||||
/**
|
||||
* This function is called by the compositor after compositing the frame.
|
||||
*/
|
||||
|
@ -43,7 +38,7 @@ public:
|
|||
* This function is called by the compositor before starting painting. Reimplement
|
||||
* this function to do frame initialization.
|
||||
*/
|
||||
virtual void prePaint();
|
||||
virtual QRegion prePaint();
|
||||
|
||||
/**
|
||||
* This function is called by the compositor after finishing painting. Reimplement
|
||||
|
|
|
@ -41,10 +41,11 @@ static void resetRepaintsHelper(Item *item, SceneDelegate *delegate)
|
|||
}
|
||||
}
|
||||
|
||||
void CursorScene::prePaint(SceneDelegate *delegate)
|
||||
QRegion CursorScene::prePaint(SceneDelegate *delegate)
|
||||
{
|
||||
resetRepaintsHelper(m_rootItem.get(), delegate);
|
||||
m_paintedOutput = delegate->output();
|
||||
return QRegion();
|
||||
}
|
||||
|
||||
void CursorScene::postPaint()
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
explicit CursorScene(std::unique_ptr<ItemRenderer> &&renderer);
|
||||
~CursorScene() override;
|
||||
|
||||
void prePaint(SceneDelegate *delegate) override;
|
||||
QRegion prePaint(SceneDelegate *delegate) override;
|
||||
void postPaint() override;
|
||||
void paint(const RenderTarget &renderTarget, const QRegion ®ion) override;
|
||||
|
||||
|
|
|
@ -24,19 +24,14 @@ SceneDelegate::~SceneDelegate()
|
|||
m_scene->removeDelegate(this);
|
||||
}
|
||||
|
||||
QRegion SceneDelegate::repaints() const
|
||||
{
|
||||
return m_scene->damage().translated(-viewport().topLeft());
|
||||
}
|
||||
|
||||
SurfaceItem *SceneDelegate::scanoutCandidate() const
|
||||
{
|
||||
return m_scene->scanoutCandidate();
|
||||
}
|
||||
|
||||
void SceneDelegate::prePaint()
|
||||
QRegion SceneDelegate::prePaint()
|
||||
{
|
||||
m_scene->prePaint(this);
|
||||
return m_scene->prePaint(this);
|
||||
}
|
||||
|
||||
void SceneDelegate::postPaint()
|
||||
|
|
|
@ -29,10 +29,9 @@ public:
|
|||
qreal scale() const;
|
||||
QRect viewport() const;
|
||||
|
||||
QRegion repaints() const override;
|
||||
SurfaceItem *scanoutCandidate() const override;
|
||||
void frame() override;
|
||||
void prePaint() override;
|
||||
QRegion prePaint() override;
|
||||
void postPaint() override;
|
||||
void paint(const RenderTarget &renderTarget, const QRegion ®ion) override;
|
||||
|
||||
|
@ -83,7 +82,7 @@ public:
|
|||
void removeDelegate(SceneDelegate *delegate);
|
||||
|
||||
virtual SurfaceItem *scanoutCandidate() const;
|
||||
virtual void prePaint(SceneDelegate *delegate) = 0;
|
||||
virtual QRegion prePaint(SceneDelegate *delegate) = 0;
|
||||
virtual void postPaint() = 0;
|
||||
virtual void paint(const RenderTarget &renderTarget, const QRegion ®ion) = 0;
|
||||
virtual void frame(SceneDelegate *delegate);
|
||||
|
|
|
@ -139,11 +139,6 @@ Item *WorkspaceScene::containerItem() const
|
|||
return m_containerItem.get();
|
||||
}
|
||||
|
||||
QRegion WorkspaceScene::damage() const
|
||||
{
|
||||
return m_paintContext.damage;
|
||||
}
|
||||
|
||||
static SurfaceItem *findTopMostSurface(SurfaceItem *item)
|
||||
{
|
||||
const QList<Item *> children = item->childItems();
|
||||
|
@ -215,7 +210,7 @@ void WorkspaceScene::frame(SceneDelegate *delegate)
|
|||
}
|
||||
}
|
||||
|
||||
void WorkspaceScene::prePaint(SceneDelegate *delegate)
|
||||
QRegion WorkspaceScene::prePaint(SceneDelegate *delegate)
|
||||
{
|
||||
createStackingOrder();
|
||||
|
||||
|
@ -260,6 +255,8 @@ void WorkspaceScene::prePaint(SceneDelegate *delegate)
|
|||
} else {
|
||||
preparePaintSimpleScreen();
|
||||
}
|
||||
|
||||
return m_paintContext.damage.translated(-delegate->viewport().topLeft());
|
||||
}
|
||||
|
||||
static void resetRepaintsHelper(Item *item, SceneDelegate *delegate)
|
||||
|
|
|
@ -55,9 +55,8 @@ public:
|
|||
|
||||
Item *containerItem() const;
|
||||
|
||||
QRegion damage() const override;
|
||||
SurfaceItem *scanoutCandidate() const override;
|
||||
void prePaint(SceneDelegate *delegate) override;
|
||||
QRegion prePaint(SceneDelegate *delegate) override;
|
||||
void postPaint() override;
|
||||
void paint(const RenderTarget &renderTarget, const QRegion ®ion) override;
|
||||
void frame(SceneDelegate *delegate) override;
|
||||
|
|
Loading…
Reference in a new issue