scene: ensure OpenGL texture is updated after direct scanout
While direct scanout happens, the damage of the SurfaceItem is reset, which can cause the OpenGL texture to not be updated once direct scanout ends, and leave the texture outdated until the surface is damaged again. In order to fix that, make sure the texture is always fully updated after the SurfaceItem has been used in direct scanout.
This commit is contained in:
parent
501a45a869
commit
d49cb64231
5 changed files with 11 additions and 6 deletions
|
@ -149,6 +149,8 @@ bool EglGbmLayer::scanout(SurfaceItem *surfaceItem)
|
|||
m_dmabufFeedback.scanoutSuccessful(surface);
|
||||
m_currentDamage = surfaceItem->damage();
|
||||
surfaceItem->resetDamage();
|
||||
// ensure the pixmap is updated when direct scanout ends
|
||||
surfaceItem->destroyPixmap();
|
||||
return true;
|
||||
} else {
|
||||
m_dmabufFeedback.scanoutFailed(surface, formats);
|
||||
|
|
|
@ -162,6 +162,8 @@ bool VirtualEglGbmLayer::scanout(SurfaceItem *surfaceItem)
|
|||
// damage tracking for screen casting
|
||||
m_currentDamage = m_scanoutSurface == item->surface() ? surfaceItem->damage() : infiniteRegion();
|
||||
surfaceItem->resetDamage();
|
||||
// ensure the pixmap is updated when direct scanout ends
|
||||
surfaceItem->destroyPixmap();
|
||||
m_scanoutSurface = item->surface();
|
||||
m_currentBuffer = scanoutBuffer;
|
||||
return true;
|
||||
|
|
|
@ -105,6 +105,11 @@ void SurfaceItem::discardPixmap()
|
|||
addDamage(rect().toAlignedRect());
|
||||
}
|
||||
|
||||
void SurfaceItem::destroyPixmap()
|
||||
{
|
||||
m_pixmap.reset();
|
||||
}
|
||||
|
||||
void SurfaceItem::preprocess()
|
||||
{
|
||||
updatePixmap();
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
|
||||
void discardPixmap();
|
||||
void updatePixmap();
|
||||
void destroyPixmap();
|
||||
|
||||
SurfacePixmap *pixmap() const;
|
||||
SurfacePixmap *previousPixmap() const;
|
||||
|
|
|
@ -165,17 +165,12 @@ SurfaceItem *WorkspaceScene::scanoutCandidate() const
|
|||
break;
|
||||
}
|
||||
SurfaceItem *topMost = findTopMostSurface(windowItem->surfaceItem());
|
||||
auto pixmap = topMost->pixmap();
|
||||
if (!pixmap) {
|
||||
break;
|
||||
}
|
||||
pixmap->update();
|
||||
// the subsurface has to be able to cover the whole window
|
||||
if (topMost->position() != QPoint(0, 0)) {
|
||||
break;
|
||||
}
|
||||
// and it has to be completely opaque
|
||||
if (pixmap->hasAlphaChannel() && !topMost->opaque().contains(QRect(0, 0, window->width(), window->height()))) {
|
||||
if (!topMost->opaque().contains(QRect(0, 0, window->width(), window->height()))) {
|
||||
break;
|
||||
}
|
||||
candidate = topMost;
|
||||
|
|
Loading…
Reference in a new issue