scene: Improve window quad management
At the moment, we handle window quads inefficiently. Window quads from all items are merged into a single list just to be broken up again. This change removes window quads from libkwineffects. This allows us to handle window quads efficiently. Furthermore, we could optimize methods such as WindowVertex::left() and so on. KWin spends reasonable amount of time in those methods when many windows have to be composited. It's a necessary prerequisite for making wl_surface painting code role agnostic.icc-effect-5.26.4
parent
a6268595fb
commit
49744cfc53
|
@ -24,7 +24,6 @@ class MockEffectWindow : public EffectWindow
|
|||
Q_OBJECT
|
||||
public:
|
||||
MockEffectWindow(QObject *parent = nullptr);
|
||||
WindowQuadList buildQuads() const override;
|
||||
QVariant data(int role) const override;
|
||||
QRect decorationInnerRect() const override;
|
||||
void deleteProperty(long int atom) const override;
|
||||
|
@ -273,11 +272,6 @@ MockEffectWindow::MockEffectWindow(QObject *parent)
|
|||
{
|
||||
}
|
||||
|
||||
WindowQuadList MockEffectWindow::buildQuads() const
|
||||
{
|
||||
return WindowQuadList();
|
||||
}
|
||||
|
||||
QVariant MockEffectWindow::data(int role) const
|
||||
{
|
||||
Q_UNUSED(role)
|
||||
|
|
|
@ -206,7 +206,7 @@ WindowQuadList DecorationItem::buildQuads() const
|
|||
const int u1 = (x1 + offsets[i].x()) * textureScale;
|
||||
const int v1 = (y1 + offsets[i].y()) * textureScale;
|
||||
|
||||
WindowQuad quad(const_cast<DecorationItem *>(this));
|
||||
WindowQuad quad;
|
||||
quad.setUVAxisSwapped(swap);
|
||||
|
||||
if (swap) {
|
||||
|
|
|
@ -2083,11 +2083,6 @@ EffectWindowList EffectWindowImpl::mainWindows() const
|
|||
return {};
|
||||
}
|
||||
|
||||
WindowQuadList EffectWindowImpl::buildQuads() const
|
||||
{
|
||||
return sceneWindow()->buildQuads();
|
||||
}
|
||||
|
||||
void EffectWindowImpl::setData(int role, const QVariant &data)
|
||||
{
|
||||
if (!data.isNull())
|
||||
|
|
|
@ -488,8 +488,6 @@ public:
|
|||
EffectWindow* transientFor() override;
|
||||
EffectWindowList mainWindows() const override;
|
||||
|
||||
WindowQuadList buildQuads() const override;
|
||||
|
||||
void minimize() override;
|
||||
void unminimize() override;
|
||||
void closeWindow() override;
|
||||
|
|
|
@ -228,7 +228,6 @@ WindowPaintData::WindowPaintData(EffectWindow* w, const QMatrix4x4 &screenProjec
|
|||
, d(new WindowPaintDataPrivate())
|
||||
{
|
||||
d->screenProjectionMatrix = screenProjectionMatrix;
|
||||
quads = w->buildQuads();
|
||||
setOpacity(w->opacity());
|
||||
setSaturation(1.0);
|
||||
setBrightness(1.0);
|
||||
|
@ -238,7 +237,6 @@ WindowPaintData::WindowPaintData(EffectWindow* w, const QMatrix4x4 &screenProjec
|
|||
|
||||
WindowPaintData::WindowPaintData(const WindowPaintData &other)
|
||||
: PaintData()
|
||||
, quads(other.quads)
|
||||
, shader(other.shader)
|
||||
, d(new WindowPaintDataPrivate())
|
||||
{
|
||||
|
|
|
@ -2412,11 +2412,6 @@ public:
|
|||
*/
|
||||
virtual bool isSkipSwitcher() const = 0;
|
||||
|
||||
/**
|
||||
* Returns the unmodified window quad list. Can also be used to force rebuilding.
|
||||
*/
|
||||
virtual WindowQuadList buildQuads() const = 0;
|
||||
|
||||
void setMinimized(bool minimize);
|
||||
virtual void minimize() = 0;
|
||||
virtual void unminimize() = 0;
|
||||
|
@ -2596,13 +2591,12 @@ private:
|
|||
class KWINEFFECTS_EXPORT WindowQuad
|
||||
{
|
||||
public:
|
||||
explicit WindowQuad(void *userData = nullptr);
|
||||
WindowQuad();
|
||||
WindowQuad makeSubQuad(double x1, double y1, double x2, double y2) const;
|
||||
WindowVertex& operator[](int index);
|
||||
const WindowVertex& operator[](int index) const;
|
||||
void setUVAxisSwapped(bool value) { uvSwapped = value; }
|
||||
bool uvAxisSwapped() const { return uvSwapped; }
|
||||
void *userData() const;
|
||||
double left() const;
|
||||
double right() const;
|
||||
double top() const;
|
||||
|
@ -2616,7 +2610,6 @@ public:
|
|||
private:
|
||||
friend class WindowQuadList;
|
||||
WindowVertex verts[ 4 ];
|
||||
void *m_userData;
|
||||
bool uvSwapped;
|
||||
};
|
||||
|
||||
|
@ -2647,7 +2640,6 @@ public:
|
|||
* I.e. window will definitely cover it's clip region
|
||||
*/
|
||||
QRegion clip;
|
||||
WindowQuadList quads;
|
||||
/**
|
||||
* Simple helper that sets data to say the window will be painted as non-opaque.
|
||||
* Takes also care of changing the regions.
|
||||
|
@ -3009,8 +3001,6 @@ public:
|
|||
*/
|
||||
QMatrix4x4 screenProjectionMatrix() const;
|
||||
|
||||
WindowQuadList quads;
|
||||
|
||||
/**
|
||||
* Shader to be used for rendering, if any.
|
||||
*/
|
||||
|
@ -3798,9 +3788,8 @@ void WindowVertex::setY(double y)
|
|||
***************************************************************/
|
||||
|
||||
inline
|
||||
WindowQuad::WindowQuad(void *userData)
|
||||
: m_userData(userData)
|
||||
, uvSwapped(false)
|
||||
WindowQuad::WindowQuad()
|
||||
: uvSwapped(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -3818,12 +3807,6 @@ const WindowVertex& WindowQuad::operator[](int index) const
|
|||
return verts[ index ];
|
||||
}
|
||||
|
||||
inline
|
||||
void *WindowQuad::userData() const
|
||||
{
|
||||
return m_userData;
|
||||
}
|
||||
|
||||
inline
|
||||
bool WindowQuad::isTransformed() const
|
||||
{
|
||||
|
|
|
@ -1110,94 +1110,33 @@ OpenGLWindow::~OpenGLWindow()
|
|||
{
|
||||
}
|
||||
|
||||
static QMatrix4x4 transformation(const QPoint &position, int mask, const WindowPaintData &data)
|
||||
static QMatrix4x4 transformation(const Item *item, const OpenGLWindow::RenderContext *context)
|
||||
{
|
||||
const QPoint position = item->rootPosition();
|
||||
QMatrix4x4 matrix;
|
||||
matrix.translate(position.x(), position.y());
|
||||
|
||||
if (!(mask & Scene::PAINT_WINDOW_TRANSFORMED))
|
||||
if (!(context->paintFlags & Scene::PAINT_WINDOW_TRANSFORMED))
|
||||
return matrix;
|
||||
|
||||
matrix.translate(data.translation());
|
||||
const QVector3D scale = data.scale();
|
||||
const WindowPaintData *data = &context->paintData;
|
||||
matrix.translate(data->translation());
|
||||
const QVector3D scale = data->scale();
|
||||
matrix.scale(scale.x(), scale.y(), scale.z());
|
||||
|
||||
if (data.rotationAngle() == 0.0)
|
||||
if (data->rotationAngle() == 0.0)
|
||||
return matrix;
|
||||
|
||||
// Apply the rotation
|
||||
// cannot use data.rotation.applyTo(&matrix) as QGraphicsRotation uses projectedRotate to map back to 2D
|
||||
matrix.translate(data.rotationOrigin());
|
||||
const QVector3D axis = data.rotationAxis();
|
||||
matrix.rotate(data.rotationAngle(), axis.x(), axis.y(), axis.z());
|
||||
matrix.translate(-data.rotationOrigin());
|
||||
matrix.translate(data->rotationOrigin());
|
||||
const QVector3D axis = data->rotationAxis();
|
||||
matrix.rotate(data->rotationAngle(), axis.x(), axis.y(), axis.z());
|
||||
matrix.translate(-data->rotationOrigin());
|
||||
|
||||
return matrix;
|
||||
}
|
||||
|
||||
bool OpenGLWindow::beginRenderWindow(int mask, const QRegion ®ion, WindowPaintData &data)
|
||||
{
|
||||
if (region.isEmpty())
|
||||
return false;
|
||||
|
||||
m_hardwareClipping = region != infiniteRegion() && (mask & Scene::PAINT_WINDOW_TRANSFORMED) && !(mask & Scene::PAINT_SCREEN_TRANSFORMED);
|
||||
if (region != infiniteRegion() && !m_hardwareClipping) {
|
||||
WindowQuadList quads;
|
||||
quads.reserve(data.quads.count());
|
||||
|
||||
// split all quads in bounding rect with the actual rects in the region
|
||||
for (const WindowQuad &quad : qAsConst(data.quads)) {
|
||||
const Item *item = static_cast<const Item *>(quad.userData());
|
||||
|
||||
const QPoint position = item->rootPosition();
|
||||
for (const QRect &r : region) {
|
||||
const QRectF rf(r.translated(-position));
|
||||
const QRectF quadRect(QPointF(quad.left(), quad.top()), QPointF(quad.right(), quad.bottom()));
|
||||
const QRectF &intersected = rf.intersected(quadRect);
|
||||
if (intersected.isValid()) {
|
||||
if (quadRect == intersected) {
|
||||
// case 1: completely contains, include and do not check other rects
|
||||
quads << quad;
|
||||
break;
|
||||
}
|
||||
// case 2: intersection
|
||||
quads << quad.makeSubQuad(intersected.left(), intersected.top(), intersected.right(), intersected.bottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
data.quads = quads;
|
||||
}
|
||||
|
||||
if (data.quads.isEmpty())
|
||||
return false;
|
||||
|
||||
if (surfaceItem() && !surfaceItem()->damage().isEmpty()) { // only relevant on X11
|
||||
m_scene->insertWait();
|
||||
}
|
||||
|
||||
if (m_hardwareClipping) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
const GLVertexAttrib attribs[] = {
|
||||
{ VA_Position, 2, GL_FLOAT, offsetof(GLVertex2D, position) },
|
||||
{ VA_TexCoord, 2, GL_FLOAT, offsetof(GLVertex2D, texcoord) },
|
||||
};
|
||||
|
||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||
vbo->reset();
|
||||
vbo->setAttribLayout(attribs, 2, sizeof(GLVertex2D));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLWindow::endRenderWindow()
|
||||
{
|
||||
if (m_hardwareClipping) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
QVector4D OpenGLWindow::modulate(float opacity, float brightness) const
|
||||
{
|
||||
const float a = opacity;
|
||||
|
@ -1245,44 +1184,78 @@ static GLTexture *bindSurfaceTexture(SurfaceItem *surfaceItem)
|
|||
return platformSurfaceTexture->texture();
|
||||
}
|
||||
|
||||
void OpenGLWindow::createRenderNode(Item *item, RenderContext *context, int mask, const WindowPaintData &data)
|
||||
static WindowQuadList clipQuads(const Item *item, const OpenGLWindow::RenderContext *context)
|
||||
{
|
||||
const WindowQuadList quads = item->quads();
|
||||
if (context->clip != infiniteRegion() && !context->hardwareClipping) {
|
||||
const QPoint offset = item->rootPosition();
|
||||
|
||||
WindowQuadList ret;
|
||||
ret.reserve(quads.count());
|
||||
|
||||
// split all quads in bounding rect with the actual rects in the region
|
||||
for (const WindowQuad &quad : qAsConst(quads)) {
|
||||
for (const QRect &r : qAsConst(context->clip)) {
|
||||
const QRectF rf(r.translated(-offset));
|
||||
const QRectF quadRect(QPointF(quad.left(), quad.top()), QPointF(quad.right(), quad.bottom()));
|
||||
const QRectF &intersected = rf.intersected(quadRect);
|
||||
if (intersected.isValid()) {
|
||||
if (quadRect == intersected) {
|
||||
// case 1: completely contains, include and do not check other rects
|
||||
ret << quad;
|
||||
break;
|
||||
}
|
||||
// case 2: intersection
|
||||
ret << quad.makeSubQuad(intersected.left(), intersected.top(), intersected.right(), intersected.bottom());
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
return quads;
|
||||
}
|
||||
|
||||
void OpenGLWindow::createRenderNode(Item *item, RenderContext *context)
|
||||
{
|
||||
if (auto shadowItem = qobject_cast<ShadowItem *>(item)) {
|
||||
WindowQuadList quads = context->quads.value(item);
|
||||
WindowQuadList quads = clipQuads(item, context);
|
||||
if (!quads.isEmpty()) {
|
||||
SceneOpenGLShadow *shadow = static_cast<SceneOpenGLShadow *>(shadowItem->shadow());
|
||||
context->renderNodes.append(RenderNode{
|
||||
.texture = shadow->shadowTexture(),
|
||||
.quads = quads,
|
||||
.transformMatrix = transformation(item->rootPosition(), mask, data),
|
||||
.opacity = data.opacity(),
|
||||
.transformMatrix = transformation(item, context),
|
||||
.opacity = context->paintData.opacity(),
|
||||
.hasAlpha = true,
|
||||
.coordinateType = NormalizedCoordinates,
|
||||
});
|
||||
}
|
||||
} else if (auto decorationItem = qobject_cast<DecorationItem *>(item)) {
|
||||
WindowQuadList quads = context->quads.value(item);
|
||||
WindowQuadList quads = clipQuads(item, context);
|
||||
if (!quads.isEmpty()) {
|
||||
auto renderer = static_cast<const SceneOpenGLDecorationRenderer *>(decorationItem->renderer());
|
||||
context->renderNodes.append(RenderNode{
|
||||
.texture = renderer->texture(),
|
||||
.quads = quads,
|
||||
.transformMatrix = transformation(item->rootPosition(), mask, data),
|
||||
.opacity = data.opacity(),
|
||||
.transformMatrix = transformation(item, context),
|
||||
.opacity = context->paintData.opacity(),
|
||||
.hasAlpha = true,
|
||||
.coordinateType = UnnormalizedCoordinates,
|
||||
});
|
||||
}
|
||||
} else if (auto surfaceItem = qobject_cast<SurfaceItem *>(item)) {
|
||||
WindowQuadList quads = context->quads.value(item);
|
||||
WindowQuadList quads = clipQuads(item, context);
|
||||
if (!quads.isEmpty()) {
|
||||
if (!surfaceItem->damage().isEmpty()) { // only relevant on X11
|
||||
m_scene->insertWait();
|
||||
}
|
||||
SurfacePixmap *pixmap = surfaceItem->pixmap();
|
||||
if (pixmap) {
|
||||
context->renderNodes.append(RenderNode{
|
||||
.texture = bindSurfaceTexture(surfaceItem),
|
||||
.quads = quads,
|
||||
.transformMatrix = transformation(item->rootPosition(), mask, data),
|
||||
.opacity = data.opacity(),
|
||||
.transformMatrix = transformation(item, context),
|
||||
.opacity = context->paintData.opacity(),
|
||||
.hasAlpha = pixmap->hasAlphaChannel(),
|
||||
.coordinateType = UnnormalizedCoordinates,
|
||||
});
|
||||
|
@ -1293,7 +1266,7 @@ void OpenGLWindow::createRenderNode(Item *item, RenderContext *context, int mask
|
|||
const QList<Item *> childItems = item->childItems();
|
||||
for (Item *childItem : childItems) {
|
||||
if (childItem->isVisible()) {
|
||||
createRenderNode(childItem, context, mask ,data);
|
||||
createRenderNode(childItem, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1322,11 +1295,27 @@ QMatrix4x4 OpenGLWindow::modelViewProjectionMatrix(int mask, const WindowPaintDa
|
|||
return scene->projectionMatrix() * mvMatrix;
|
||||
}
|
||||
|
||||
void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPaintData &_data)
|
||||
void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPaintData &data)
|
||||
{
|
||||
WindowPaintData data = _data;
|
||||
if (!beginRenderWindow(mask, region, data))
|
||||
if (region.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RenderContext renderContext {
|
||||
.paintFlags = mask,
|
||||
.clip = region,
|
||||
.paintData = data,
|
||||
.hardwareClipping = region != infiniteRegion() && (mask & Scene::PAINT_WINDOW_TRANSFORMED) && !(mask & Scene::PAINT_SCREEN_TRANSFORMED),
|
||||
};
|
||||
createRenderNode(windowItem(), &renderContext);
|
||||
|
||||
int quadCount = 0;
|
||||
for (const RenderNode &node : qAsConst(renderContext.renderNodes)) {
|
||||
quadCount += node.quads.count();
|
||||
}
|
||||
if (!quadCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLShader *shader = data.shader;
|
||||
GLenum filter;
|
||||
|
@ -1356,22 +1345,24 @@ void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPai
|
|||
}
|
||||
shader->setUniform(GLShader::Saturation, data.saturation());
|
||||
|
||||
RenderContext renderContext;
|
||||
// TODO: This is somewhat inefficient, remove window quads from the public api.
|
||||
for (const WindowQuad &quad : qAsConst(data.quads)) {
|
||||
Item *item = static_cast<Item *>(quad.userData());
|
||||
Q_ASSERT(item);
|
||||
renderContext.quads[item].append(quad);
|
||||
}
|
||||
createRenderNode(windowItem(), &renderContext, mask, data);
|
||||
|
||||
const bool indexedQuads = GLVertexBuffer::supportsIndexedQuads();
|
||||
const GLenum primitiveType = indexedQuads ? GL_QUADS : GL_TRIANGLES;
|
||||
const int verticesPerQuad = indexedQuads ? 4 : 6;
|
||||
const size_t size = verticesPerQuad * quadCount * sizeof(GLVertex2D);
|
||||
|
||||
const size_t size = verticesPerQuad * data.quads.count() * sizeof(GLVertex2D);
|
||||
if (renderContext.hardwareClipping) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
const GLVertexAttrib attribs[] = {
|
||||
{ VA_Position, 2, GL_FLOAT, offsetof(GLVertex2D, position) },
|
||||
{ VA_TexCoord, 2, GL_FLOAT, offsetof(GLVertex2D, texcoord) },
|
||||
};
|
||||
|
||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||
vbo->reset();
|
||||
vbo->setAttribLayout(attribs, 2, sizeof(GLVertex2D));
|
||||
|
||||
GLVertex2D *map = (GLVertex2D *) vbo->map(size);
|
||||
|
||||
for (int i = 0, v = 0; i < renderContext.renderNodes.count(); i++) {
|
||||
|
@ -1417,7 +1408,7 @@ void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPai
|
|||
renderNode.texture->bind();
|
||||
|
||||
vbo->draw(region, primitiveType, renderNode.firstVertex,
|
||||
renderNode.vertexCount, m_hardwareClipping);
|
||||
renderNode.vertexCount, renderContext.hardwareClipping);
|
||||
}
|
||||
|
||||
vbo->unbindArrays();
|
||||
|
@ -1427,7 +1418,9 @@ void OpenGLWindow::performPaint(int mask, const QRegion ®ion, const WindowPai
|
|||
if (!data.shader)
|
||||
ShaderManager::instance()->popShader();
|
||||
|
||||
endRenderWindow();
|
||||
if (renderContext.hardwareClipping) {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<GLTexture> OpenGLWindow::windowTexture()
|
||||
|
|
|
@ -147,7 +147,10 @@ public:
|
|||
struct RenderContext
|
||||
{
|
||||
QVector<RenderNode> renderNodes;
|
||||
QHash<Item *, WindowQuadList> quads;
|
||||
const int paintFlags;
|
||||
const QRegion clip;
|
||||
const WindowPaintData &paintData;
|
||||
const bool hardwareClipping;
|
||||
};
|
||||
|
||||
OpenGLWindow(Toplevel *toplevel, SceneOpenGL *scene);
|
||||
|
@ -160,12 +163,9 @@ private:
|
|||
QMatrix4x4 modelViewProjectionMatrix(int mask, const WindowPaintData &data) const;
|
||||
QVector4D modulate(float opacity, float brightness) const;
|
||||
void setBlendEnabled(bool enabled);
|
||||
void createRenderNode(Item *item, RenderContext *context, int mask, const WindowPaintData &data);
|
||||
bool beginRenderWindow(int mask, const QRegion ®ion, WindowPaintData &data);
|
||||
void endRenderWindow();
|
||||
void createRenderNode(Item *item, RenderContext *context);
|
||||
|
||||
SceneOpenGL *m_scene;
|
||||
bool m_hardwareClipping = false;
|
||||
bool m_blendingEnabled = false;
|
||||
};
|
||||
|
||||
|
|
|
@ -252,18 +252,12 @@ void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &)
|
|||
w->resetPaintingEnabled();
|
||||
data.paint = infiniteRegion(); // no clipping, so doesn't really matter
|
||||
data.clip = QRegion();
|
||||
data.quads = w->buildQuads();
|
||||
// preparation step
|
||||
effects->prePaintWindow(effectWindow(w), data, m_expectedPresentTimestamp);
|
||||
#if !defined(QT_NO_DEBUG)
|
||||
if (data.quads.isTransformed()) {
|
||||
qFatal("Pre-paint calls are not allowed to transform quads!");
|
||||
}
|
||||
#endif
|
||||
if (!w->isPaintingEnabled()) {
|
||||
continue;
|
||||
}
|
||||
phase2.append({w, infiniteRegion(), data.clip, data.mask, data.quads});
|
||||
phase2.append({w, infiniteRegion(), data.clip, data.mask,});
|
||||
}
|
||||
|
||||
damaged_region = QRegion(QRect {{}, screens()->size()});
|
||||
|
@ -279,7 +273,7 @@ void Scene::paintGenericScreen(int orig_mask, const ScreenPaintData &)
|
|||
paintBackground(infiniteRegion());
|
||||
}
|
||||
Q_FOREACH (const Phase2Data & d, phase2) {
|
||||
paintWindow(d.window, d.mask, d.region, d.quads);
|
||||
paintWindow(d.window, d.mask, d.region);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -351,20 +345,14 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion)
|
|||
data.clip |= window->decorationShape().translated(window->pos());
|
||||
}
|
||||
|
||||
data.quads = window->buildQuads();
|
||||
// preparation step
|
||||
effects->prePaintWindow(effectWindow(window), data, m_expectedPresentTimestamp);
|
||||
#if !defined(QT_NO_DEBUG)
|
||||
if (data.quads.isTransformed()) {
|
||||
qFatal("Pre-paint calls are not allowed to transform quads!");
|
||||
}
|
||||
#endif
|
||||
if (!window->isPaintingEnabled()) {
|
||||
continue;
|
||||
}
|
||||
dirtyArea |= data.paint;
|
||||
// Schedule the window for painting
|
||||
phase2data.append({ window, data.paint, data.clip, data.mask, data.quads });
|
||||
phase2data.append({ window, data.paint, data.clip, data.mask, });
|
||||
}
|
||||
|
||||
// Save the part of the repaint region that's exclusively rendered to
|
||||
|
@ -434,7 +422,7 @@ void Scene::paintSimpleScreen(int orig_mask, const QRegion ®ion)
|
|||
paintedArea |= data->region;
|
||||
data->region = paintedArea;
|
||||
|
||||
paintWindow(data->window, data->mask, data->region, data->quads);
|
||||
paintWindow(data->window, data->mask, data->region);
|
||||
}
|
||||
|
||||
if (fullRepaint) {
|
||||
|
@ -504,7 +492,7 @@ void Scene::clearStackingOrder()
|
|||
|
||||
static Scene::Window *s_recursionCheck = nullptr;
|
||||
|
||||
void Scene::paintWindow(Window* w, int mask, const QRegion &_region, const WindowQuadList &quads)
|
||||
void Scene::paintWindow(Window* w, int mask, const QRegion &_region)
|
||||
{
|
||||
// no painting outside visible screen (and no transformations)
|
||||
const QRegion region = _region & QRect({0, 0}, screens()->size());
|
||||
|
@ -520,7 +508,6 @@ void Scene::paintWindow(Window* w, int mask, const QRegion &_region, const Windo
|
|||
}
|
||||
|
||||
WindowPaintData data(w->window()->effectWindow(), screenProjectionMatrix());
|
||||
data.quads = quads;
|
||||
effects->paintWindow(effectWindow(w), mask, region, data);
|
||||
// paint thumbnails on top of window
|
||||
paintWindowThumbnails(w, region, data.opacity(), data.brightness(), data.saturation());
|
||||
|
@ -872,25 +859,6 @@ void Scene::Window::disablePainting(int reason)
|
|||
disable_painting |= reason;
|
||||
}
|
||||
|
||||
static void buildQuadsHelper(const Item *item, WindowQuadList *ret)
|
||||
{
|
||||
*ret += item->quads();
|
||||
|
||||
const QList<Item *> childItems = item->childItems();
|
||||
for (const Item *childItem : childItems) {
|
||||
if (childItem->isVisible()) {
|
||||
buildQuadsHelper(childItem, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WindowQuadList Scene::Window::buildQuads() const
|
||||
{
|
||||
WindowQuadList ret;
|
||||
buildQuadsHelper(windowItem(), &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Scene::Window::preprocess(Item *item)
|
||||
{
|
||||
item->preprocess();
|
||||
|
|
|
@ -232,7 +232,7 @@ protected:
|
|||
// called after all effects had their paintWindow() called
|
||||
void finalPaintWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data);
|
||||
// shared implementation, starts painting the window
|
||||
virtual void paintWindow(Window* w, int mask, const QRegion ®ion, const WindowQuadList &quads);
|
||||
virtual void paintWindow(Window* w, int mask, const QRegion ®ion);
|
||||
// called after all effects had their drawWindow() called
|
||||
virtual void finalDrawWindow(EffectWindowImpl* w, int mask, const QRegion ®ion, WindowPaintData& data);
|
||||
// let the scene decide whether it's better to paint more of the screen, eg. in order to allow a buffer swap
|
||||
|
@ -248,7 +248,6 @@ protected:
|
|||
QRegion region;
|
||||
QRegion clip;
|
||||
int mask = 0;
|
||||
WindowQuadList quads;
|
||||
};
|
||||
// The region which actually has been painted by paintScreen() and should be
|
||||
// copied from the buffer to the screen. I.e. the region returned from Scene::paintScreen().
|
||||
|
@ -339,7 +338,6 @@ public:
|
|||
bool isOpaque() const;
|
||||
QRegion decorationShape() const;
|
||||
void updateToplevel(Deleted *deleted);
|
||||
WindowQuadList buildQuads() const;
|
||||
void referencePreviousPixmap();
|
||||
void unreferencePreviousPixmap();
|
||||
void preprocess(Item *item);
|
||||
|
|
|
@ -152,14 +152,13 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
|
||||
WindowQuadList quads;
|
||||
quads.reserve(8);
|
||||
void *tag = const_cast<ShadowItem *>(this);
|
||||
|
||||
if (topLeftRect.isValid()) {
|
||||
tx1 = 0.0;
|
||||
ty1 = 0.0;
|
||||
tx2 = topLeftRect.width() / width;
|
||||
ty2 = topLeftRect.height() / height;
|
||||
WindowQuad topLeftQuad(tag);
|
||||
WindowQuad topLeftQuad;
|
||||
topLeftQuad[0] = WindowVertex(topLeftRect.left(), topLeftRect.top(), tx1, ty1);
|
||||
topLeftQuad[1] = WindowVertex(topLeftRect.right(), topLeftRect.top(), tx2, ty1);
|
||||
topLeftQuad[2] = WindowVertex(topLeftRect.right(), topLeftRect.bottom(), tx2, ty2);
|
||||
|
@ -172,7 +171,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
ty1 = 0.0;
|
||||
tx2 = 1.0;
|
||||
ty2 = topRightRect.height() / height;
|
||||
WindowQuad topRightQuad(tag);
|
||||
WindowQuad topRightQuad;
|
||||
topRightQuad[0] = WindowVertex(topRightRect.left(), topRightRect.top(), tx1, ty1);
|
||||
topRightQuad[1] = WindowVertex(topRightRect.right(), topRightRect.top(), tx2, ty1);
|
||||
topRightQuad[2] = WindowVertex(topRightRect.right(), topRightRect.bottom(), tx2, ty2);
|
||||
|
@ -185,7 +184,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
tx2 = 1.0;
|
||||
ty1 = 1.0 - bottomRightRect.height() / height;
|
||||
ty2 = 1.0;
|
||||
WindowQuad bottomRightQuad(tag);
|
||||
WindowQuad bottomRightQuad;
|
||||
bottomRightQuad[0] = WindowVertex(bottomRightRect.left(), bottomRightRect.top(), tx1, ty1);
|
||||
bottomRightQuad[1] = WindowVertex(bottomRightRect.right(), bottomRightRect.top(), tx2, ty1);
|
||||
bottomRightQuad[2] = WindowVertex(bottomRightRect.right(), bottomRightRect.bottom(), tx2, ty2);
|
||||
|
@ -198,7 +197,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
tx2 = bottomLeftRect.width() / width;
|
||||
ty1 = 1.0 - bottomLeftRect.height() / height;
|
||||
ty2 = 1.0;
|
||||
WindowQuad bottomLeftQuad(tag);
|
||||
WindowQuad bottomLeftQuad;
|
||||
bottomLeftQuad[0] = WindowVertex(bottomLeftRect.left(), bottomLeftRect.top(), tx1, ty1);
|
||||
bottomLeftQuad[1] = WindowVertex(bottomLeftRect.right(), bottomLeftRect.top(), tx2, ty1);
|
||||
bottomLeftQuad[2] = WindowVertex(bottomLeftRect.right(), bottomLeftRect.bottom(), tx2, ty2);
|
||||
|
@ -231,7 +230,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
ty1 = 0.0;
|
||||
tx2 = tx1 + top.width() / width;
|
||||
ty2 = topRect.height() / height;
|
||||
WindowQuad topQuad(tag);
|
||||
WindowQuad topQuad;
|
||||
topQuad[0] = WindowVertex(topRect.left(), topRect.top(), tx1, ty1);
|
||||
topQuad[1] = WindowVertex(topRect.right(), topRect.top(), tx2, ty1);
|
||||
topQuad[2] = WindowVertex(topRect.right(), topRect.bottom(), tx2, ty2);
|
||||
|
@ -244,7 +243,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
ty1 = shadowMargins.top() / height;
|
||||
tx2 = 1.0;
|
||||
ty2 = ty1 + right.height() / height;
|
||||
WindowQuad rightQuad(tag);
|
||||
WindowQuad rightQuad;
|
||||
rightQuad[0] = WindowVertex(rightRect.left(), rightRect.top(), tx1, ty1);
|
||||
rightQuad[1] = WindowVertex(rightRect.right(), rightRect.top(), tx2, ty1);
|
||||
rightQuad[2] = WindowVertex(rightRect.right(), rightRect.bottom(), tx2, ty2);
|
||||
|
@ -257,7 +256,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
ty1 = 1.0 - bottomRect.height() / height;
|
||||
tx2 = tx1 + bottom.width() / width;
|
||||
ty2 = 1.0;
|
||||
WindowQuad bottomQuad(tag);
|
||||
WindowQuad bottomQuad;
|
||||
bottomQuad[0] = WindowVertex(bottomRect.left(), bottomRect.top(), tx1, ty1);
|
||||
bottomQuad[1] = WindowVertex(bottomRect.right(), bottomRect.top(), tx2, ty1);
|
||||
bottomQuad[2] = WindowVertex(bottomRect.right(), bottomRect.bottom(), tx2, ty2);
|
||||
|
@ -270,7 +269,7 @@ WindowQuadList ShadowItem::buildQuads() const
|
|||
ty1 = shadowMargins.top() / height;
|
||||
tx2 = leftRect.width() / width;
|
||||
ty2 = ty1 + left.height() / height;
|
||||
WindowQuad leftQuad(tag);
|
||||
WindowQuad leftQuad;
|
||||
leftQuad[0] = WindowVertex(leftRect.left(), leftRect.top(), tx1, ty1);
|
||||
leftQuad[1] = WindowVertex(leftRect.right(), leftRect.top(), tx2, ty1);
|
||||
leftQuad[2] = WindowVertex(leftRect.right(), leftRect.bottom(), tx2, ty2);
|
||||
|
|
|
@ -120,7 +120,7 @@ WindowQuadList SurfaceItem::buildQuads() const
|
|||
quads.reserve(region.rectCount());
|
||||
|
||||
for (const QRectF rect : region) {
|
||||
WindowQuad quad(const_cast<SurfaceItem *>(this));
|
||||
WindowQuad quad;
|
||||
|
||||
const QPointF bufferTopLeft = mapToBuffer(rect.topLeft());
|
||||
const QPointF bufferTopRight = mapToBuffer(rect.topRight());
|
||||
|
|
Loading…
Reference in New Issue