scene: Update surface texture in preprocess()
If two items display image data, the item renderer needs to special case each item. It's not an extensible design, and my long term goal is to introduce a separate tree specifically to solve this problem and also help with computing the repaint damage automatically, instead of issuing scheduleRepaint()s manually. The first step is to refactor the item renderer so it merely takes the input data and renders it. At the moment, it's not exactly the case because surface textures are updated while painting the items, which inherently requires special casing. This change moves surface texture update code to the surface item so it's easier to refactor rendering code in the item renderer.
This commit is contained in:
parent
fdd338f02b
commit
883acb1f58
6 changed files with 20 additions and 42 deletions
|
@ -54,9 +54,6 @@ public:
|
|||
OpenGLBackend *backend() const;
|
||||
OpenGLSurfaceContents texture() const;
|
||||
|
||||
virtual bool create() = 0;
|
||||
virtual void update(const QRegion ®ion) = 0;
|
||||
|
||||
protected:
|
||||
OpenGLBackend *m_backend;
|
||||
OpenGLSurfaceContents m_texture;
|
||||
|
|
|
@ -25,9 +25,6 @@ public:
|
|||
QPainterBackend *backend() const;
|
||||
QImage image() const;
|
||||
|
||||
virtual bool create() = 0;
|
||||
virtual void update(const QRegion ®ion) = 0;
|
||||
|
||||
protected:
|
||||
QPainterBackend *m_backend;
|
||||
QImage m_image;
|
||||
|
|
|
@ -67,35 +67,6 @@ void ItemRendererOpenGL::setBlendEnabled(bool enabled)
|
|||
m_blendingEnabled = enabled;
|
||||
}
|
||||
|
||||
static OpenGLSurfaceContents bindSurfaceTexture(SurfaceItem *surfaceItem)
|
||||
{
|
||||
SurfacePixmap *surfacePixmap = surfaceItem->pixmap();
|
||||
auto platformSurfaceTexture =
|
||||
static_cast<OpenGLSurfaceTexture *>(surfacePixmap->texture());
|
||||
if (surfacePixmap->isDiscarded()) {
|
||||
return platformSurfaceTexture->texture();
|
||||
}
|
||||
|
||||
if (platformSurfaceTexture->texture().isValid()) {
|
||||
const QRegion region = surfaceItem->damage();
|
||||
if (!region.isEmpty()) {
|
||||
platformSurfaceTexture->update(region);
|
||||
surfaceItem->resetDamage();
|
||||
}
|
||||
} else {
|
||||
if (!surfacePixmap->isValid()) {
|
||||
return {};
|
||||
}
|
||||
if (!platformSurfaceTexture->create()) {
|
||||
qCDebug(KWIN_OPENGL) << "Failed to bind window";
|
||||
return {};
|
||||
}
|
||||
surfaceItem->resetDamage();
|
||||
}
|
||||
|
||||
return platformSurfaceTexture->texture();
|
||||
}
|
||||
|
||||
static RenderGeometry clipQuads(const Item *item, const ItemRendererOpenGL::RenderContext *context)
|
||||
{
|
||||
const WindowQuadList quads = item->quads();
|
||||
|
@ -201,8 +172,9 @@ void ItemRendererOpenGL::createRenderNode(Item *item, RenderContext *context)
|
|||
SurfacePixmap *pixmap = surfaceItem->pixmap();
|
||||
if (pixmap) {
|
||||
if (!geometry.isEmpty()) {
|
||||
OpenGLSurfaceTexture *surfaceTexture = static_cast<OpenGLSurfaceTexture *>(pixmap->texture());
|
||||
context->renderNodes.append(RenderNode{
|
||||
.texture = bindSurfaceTexture(surfaceItem),
|
||||
.texture = surfaceTexture->texture(),
|
||||
.geometry = geometry,
|
||||
.transformMatrix = context->transformStack.top(),
|
||||
.opacity = context->opacityStack.top(),
|
||||
|
|
|
@ -132,12 +132,6 @@ void ItemRendererQPainter::renderSurfaceItem(QPainter *painter, SurfaceItem *sur
|
|||
|
||||
QPainterSurfaceTexture *platformSurfaceTexture =
|
||||
static_cast<QPainterSurfaceTexture *>(surfaceTexture->texture());
|
||||
if (!platformSurfaceTexture->isValid()) {
|
||||
platformSurfaceTexture->create();
|
||||
} else {
|
||||
platformSurfaceTexture->update(surfaceItem->damage());
|
||||
}
|
||||
surfaceItem->resetDamage();
|
||||
|
||||
const OutputTransform surfaceToBufferTransform = surfaceItem->bufferTransform();
|
||||
const QSizeF transformedSize = surfaceToBufferTransform.map(surfaceItem->destinationSize());
|
||||
|
|
|
@ -216,6 +216,21 @@ void SurfaceItem::destroyPixmap()
|
|||
void SurfaceItem::preprocess()
|
||||
{
|
||||
updatePixmap();
|
||||
|
||||
if (SurfacePixmap *surfacePixmap = pixmap(); surfacePixmap && !surfacePixmap->isDiscarded()) {
|
||||
SurfaceTexture *surfaceTexture = surfacePixmap->texture();
|
||||
if (surfaceTexture->isValid()) {
|
||||
const QRegion region = damage();
|
||||
if (!region.isEmpty()) {
|
||||
surfaceTexture->update(region);
|
||||
resetDamage();
|
||||
}
|
||||
} else if (surfacePixmap->isValid()) {
|
||||
if (surfaceTexture->create()) {
|
||||
resetDamage();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WindowQuadList SurfaceItem::buildQuads() const
|
||||
|
|
|
@ -90,6 +90,9 @@ public:
|
|||
virtual ~SurfaceTexture();
|
||||
|
||||
virtual bool isValid() const = 0;
|
||||
|
||||
virtual bool create() = 0;
|
||||
virtual void update(const QRegion ®ion) = 0;
|
||||
};
|
||||
|
||||
class KWIN_EXPORT SurfacePixmap : public QObject
|
||||
|
|
Loading…
Reference in a new issue