From 617f3b9000efd7cd709f00779168e4cd9cfaecf5 Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Sat, 2 Sep 2023 16:48:04 +0200 Subject: [PATCH] libkwineffects/glvertexbuffer: add a better helper for uploading vertices --- src/libkwineffects/glvertexbuffer.cpp | 17 -------- src/libkwineffects/glvertexbuffer.h | 45 ++++++++++++++++----- src/libkwineffects/kwingltexture.cpp | 38 ++++++++++-------- src/plugins/magnifier/magnifier.cpp | 52 ++++++++++++------------- src/plugins/mouseclick/mouseclick.cpp | 6 +-- src/plugins/mousemark/mousemark.cpp | 10 ++--- src/plugins/showpaint/showpaint.cpp | 16 ++++---- src/plugins/snaphelper/snaphelper.cpp | 28 ++++++------- src/plugins/touchpoints/touchpoints.cpp | 8 ++-- 9 files changed, 118 insertions(+), 102 deletions(-) diff --git a/src/libkwineffects/glvertexbuffer.cpp b/src/libkwineffects/glvertexbuffer.cpp index 56b7ee061c..930c7daa29 100644 --- a/src/libkwineffects/glvertexbuffer.cpp +++ b/src/libkwineffects/glvertexbuffer.cpp @@ -456,23 +456,6 @@ void GLVertexBuffer::setData(const void *data, size_t size) unmap(); } -void GLVertexBuffer::setData(int vertexCount, int dim, const float *vertices, const float *texcoords) -{ - const GLVertexAttrib layout[] = { - {VA_Position, dim, GL_FLOAT, 0}, - {VA_TexCoord, 2, GL_FLOAT, int(dim * sizeof(float))}}; - - int stride = (texcoords ? dim + 2 : dim) * sizeof(float); - int attribCount = texcoords ? 2 : 1; - - setAttribLayout(layout, attribCount, stride); - setVertexCount(vertexCount); - - GLvoid *ptr = map(vertexCount * stride); - d->interleaveArrays((float *)ptr, dim, vertices, texcoords, vertexCount); - unmap(); -} - GLvoid *GLVertexBuffer::map(size_t size) { d->mappedSize = size; diff --git a/src/libkwineffects/glvertexbuffer.h b/src/libkwineffects/glvertexbuffer.h index ebca027ec9..f54a5bf79f 100644 --- a/src/libkwineffects/glvertexbuffer.h +++ b/src/libkwineffects/glvertexbuffer.h @@ -9,12 +9,14 @@ SPDX-License-Identifier: GPL-2.0-or-later */ #pragma once +#include "kwineffects.h" #include "libkwineffects/kwinglutils_export.h" #include #include #include #include +#include #include namespace KWin @@ -104,15 +106,40 @@ public: */ void setVertexCount(int count); - /** - * Sets the vertex data. - * @param numberVertices The number of vertices in the arrays - * @param dim The dimension of the vertices: 2 for x/y, 3 for x/y/z - * @param vertices The vertices, size must equal @a numberVertices * @a dim - * @param texcoords The texture coordinates for each vertex. - * Size must equal 2 * @a numberVertices. - */ - void setData(int numberVertices, int dim, const float *vertices, const float *texcoords); + // clang-format off + template + requires std::is_same, GLVertex2D>::value + void setVertices(const T &range) + { + setData(range.data(), range.size() * sizeof(GLVertex2D)); + setVertexCount(range.size()); + setAttribLayout(GLVertex2DLayout, 2, sizeof(GLVertex2D)); + } + + template + requires std::is_same, GLVertex3D>::value + void setVertices(const T &range) + { + setData(range.data(), range.size() * sizeof(GLVertex3D)); + setVertexCount(range.size()); + setAttribLayout(GLVertex3DLayout, 2, sizeof(GLVertex3D)); + } + + template + requires std::is_same, QVector2D>::value + void setVertices(const T &range) + { + setData(range.data(), range.size() * sizeof(QVector2D)); + setVertexCount(range.size()); + static constexpr GLVertexAttrib layout{ + .index = VA_Position, + .size = 2, + .type = GL_FLOAT, + .relativeOffset = 0, + }; + setAttribLayout(&layout, 1, sizeof(QVector2D)); + } + // clang-format on /** * Maps an unused range of the data store into the client's address space. diff --git a/src/libkwineffects/kwingltexture.cpp b/src/libkwineffects/kwingltexture.cpp index 681d2f366d..5c832abb4c 100644 --- a/src/libkwineffects/kwingltexture.cpp +++ b/src/libkwineffects/kwingltexture.cpp @@ -353,15 +353,6 @@ void GLTexture::render(const QRectF &source, const QRegion ®ion, const QSizeF if (destinationSize != d->m_cachedSize || d->m_cachedSource != source) { d->m_cachedSize = destinationSize; d->m_cachedSource = source; - if (!d->m_vbo) { - d->m_vbo = std::make_unique(KWin::GLVertexBuffer::Static); - } - - const float verts[4 * 2] = { - 0.0f, 0.0f, - 0.0f, float(destinationSize.height()), - float(destinationSize.width()), 0.0f, - float(destinationSize.width()), float(destinationSize.height())}; const float texWidth = (target() == GL_TEXTURE_RECTANGLE_ARB) ? width() : 1.0f; const float texHeight = (target() == GL_TEXTURE_RECTANGLE_ARB) ? height() : 1.0f; @@ -381,13 +372,28 @@ void GLTexture::render(const QRectF &source, const QRegion ®ion, const QSizeF const QPointF p3 = textureMat.map(QPointF(source.x() + source.width(), source.y())); const QPointF p4 = textureMat.map(QPointF(source.x() + source.width(), source.y() + source.height())); - const float texcoords[4 * 2] = { - float(p1.x()), float(p1.y()), - float(p2.x()), float(p2.y()), - float(p3.x()), float(p3.y()), - float(p4.x()), float(p4.y())}; - - d->m_vbo->setData(4, 2, verts, texcoords); + if (!d->m_vbo) { + d->m_vbo = std::make_unique(KWin::GLVertexBuffer::Static); + } + const std::array data{ + GLVertex2D{ + .position = QVector2D(0, 0), + .texcoord = QVector2D(p1), + }, + GLVertex2D{ + .position = QVector2D(0, destinationSize.height()), + .texcoord = QVector2D(p2), + }, + GLVertex2D{ + .position = QVector2D(destinationSize.width(), 0), + .texcoord = QVector2D(p3), + }, + GLVertex2D{ + .position = QVector2D(destinationSize.width(), destinationSize.height()), + .texcoord = QVector2D(p4), + }, + }; + d->m_vbo->setVertices(data); } bind(); d->m_vbo->render(region, GL_TRIANGLE_STRIP, hardwareClipping); diff --git a/src/plugins/magnifier/magnifier.cpp b/src/plugins/magnifier/magnifier.cpp index a18877db03..4f7a4f9637 100644 --- a/src/plugins/magnifier/magnifier.cpp +++ b/src/plugins/magnifier/magnifier.cpp @@ -138,37 +138,37 @@ void MagnifierEffect::paintScreen(const RenderTarget &renderTarget, const Render QRectF areaF = scaledRect(area, scale); const QRectF frame = scaledRect(area.adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH), scale); - QVector verts; + QVector verts; verts.reserve(4 * 6 * 2); // top frame - verts << frame.right() << frame.top(); - verts << frame.left() << frame.top(); - verts << frame.left() << areaF.top(); - verts << frame.left() << areaF.top(); - verts << frame.right() << areaF.top(); - verts << frame.right() << frame.top(); + verts.push_back(QVector2D(frame.right(), frame.top())); + verts.push_back(QVector2D(frame.left(), frame.top())); + verts.push_back(QVector2D(frame.left(), areaF.top())); + verts.push_back(QVector2D(frame.left(), areaF.top())); + verts.push_back(QVector2D(frame.right(), areaF.top())); + verts.push_back(QVector2D(frame.right(), frame.top())); // left frame - verts << areaF.left() << frame.top(); - verts << frame.left() << frame.top(); - verts << frame.left() << frame.bottom(); - verts << frame.left() << frame.bottom(); - verts << areaF.left() << frame.bottom(); - verts << areaF.left() << frame.top(); + verts.push_back(QVector2D(areaF.left(), frame.top())); + verts.push_back(QVector2D(frame.left(), frame.top())); + verts.push_back(QVector2D(frame.left(), frame.bottom())); + verts.push_back(QVector2D(frame.left(), frame.bottom())); + verts.push_back(QVector2D(areaF.left(), frame.bottom())); + verts.push_back(QVector2D(areaF.left(), frame.top())); // right frame - verts << frame.right() << frame.top(); - verts << areaF.right() << frame.top(); - verts << areaF.right() << frame.bottom(); - verts << areaF.right() << frame.bottom(); - verts << frame.right() << frame.bottom(); - verts << frame.right() << frame.top(); + verts.push_back(QVector2D(frame.right(), frame.top())); + verts.push_back(QVector2D(areaF.right(), frame.top())); + verts.push_back(QVector2D(areaF.right(), frame.bottom())); + verts.push_back(QVector2D(areaF.right(), frame.bottom())); + verts.push_back(QVector2D(frame.right(), frame.bottom())); + verts.push_back(QVector2D(frame.right(), frame.top())); // bottom frame - verts << frame.right() << areaF.bottom(); - verts << frame.left() << areaF.bottom(); - verts << frame.left() << frame.bottom(); - verts << frame.left() << frame.bottom(); - verts << frame.right() << frame.bottom(); - verts << frame.right() << areaF.bottom(); - vbo->setData(verts.size() / 2, 2, verts.constData(), nullptr); + verts.push_back(QVector2D(frame.right(), areaF.bottom())); + verts.push_back(QVector2D(frame.left(), areaF.bottom())); + verts.push_back(QVector2D(frame.left(), frame.bottom())); + verts.push_back(QVector2D(frame.left(), frame.bottom())); + verts.push_back(QVector2D(frame.right(), frame.bottom())); + verts.push_back(QVector2D(frame.right(), areaF.bottom())); + vbo->setVertices(verts); ShaderBinder binder(ShaderTrait::UniformColor); binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, viewport.projectionMatrix()); diff --git a/src/plugins/mouseclick/mouseclick.cpp b/src/plugins/mouseclick/mouseclick.cpp index 71261fa914..6b342b0ed5 100644 --- a/src/plugins/mouseclick/mouseclick.cpp +++ b/src/plugins/mouseclick/mouseclick.cpp @@ -279,17 +279,17 @@ void MouseClickEffect::drawCircleGl(const RenderViewport &viewport, const QColor vbo->reset(); vbo->setUseColor(true); vbo->setColor(color); - QVector verts; + QVector verts; verts.reserve(num_segments * 2); for (int ii = 0; ii < num_segments; ++ii) { - verts << (x + cx) * scale << (y + cy) * scale; // output vertex + verts.push_back(QVector2D((x + cx) * scale, (y + cy) * scale)); // output vertex // apply the rotation matrix t = x; x = c * x - s * y; y = s * t + c * y; } - vbo->setData(verts.size() / 2, 2, verts.data(), nullptr); + vbo->setVertices(verts); vbo->render(GL_LINE_LOOP); } diff --git a/src/plugins/mousemark/mousemark.cpp b/src/plugins/mousemark/mousemark.cpp index f73d1a27a2..f13bffe4af 100644 --- a/src/plugins/mousemark/mousemark.cpp +++ b/src/plugins/mousemark/mousemark.cpp @@ -123,23 +123,23 @@ void MouseMarkEffect::paintScreen(const RenderTarget &renderTarget, const Render ShaderBinder binder(ShaderTrait::UniformColor | ShaderTrait::TransformColorspace); binder.shader()->setUniform(GLShader::ModelViewProjectionMatrix, viewport.projectionMatrix()); binder.shader()->setColorspaceUniformsFromSRGB(renderTarget.colorDescription()); - QVector verts; + QVector verts; for (const Mark &mark : std::as_const(marks)) { verts.clear(); verts.reserve(mark.size() * 2); for (const QPointF &p : std::as_const(mark)) { - verts << p.x() * scale << p.y() * scale; + verts.push_back(QVector2D(p.x() * scale, p.y() * scale)); } - vbo->setData(verts.size() / 2, 2, verts.data(), nullptr); + vbo->setVertices(verts); vbo->render(GL_LINE_STRIP); } if (!drawing.isEmpty()) { verts.clear(); verts.reserve(drawing.size() * 2); for (const QPointF &p : std::as_const(drawing)) { - verts << p.x() * scale << p.y() * scale; + verts.push_back(QVector2D(p.x() * scale, p.y() * scale)); } - vbo->setData(verts.size() / 2, 2, verts.data(), nullptr); + vbo->setVertices(verts); vbo->render(GL_LINE_STRIP); } glLineWidth(1.0); diff --git a/src/plugins/showpaint/showpaint.cpp b/src/plugins/showpaint/showpaint.cpp index 27f2f842b6..07d3192940 100644 --- a/src/plugins/showpaint/showpaint.cpp +++ b/src/plugins/showpaint/showpaint.cpp @@ -75,18 +75,18 @@ void ShowPaintEffect::paintGL(const QMatrix4x4 &projection, qreal scale) QColor color = s_colors[m_colorIndex]; color.setAlphaF(s_alpha); vbo->setColor(color); - QVector verts; + QVector verts; verts.reserve(m_painted.rectCount() * 12); for (const QRect &r : m_painted) { const auto deviceRect = scaledRect(r, scale); - verts << deviceRect.x() + deviceRect.width() << deviceRect.y(); - verts << deviceRect.x() << deviceRect.y(); - verts << deviceRect.x() << deviceRect.y() + deviceRect.height(); - verts << deviceRect.x() << deviceRect.y() + deviceRect.height(); - verts << deviceRect.x() + deviceRect.width() << deviceRect.y() + deviceRect.height(); - verts << deviceRect.x() + deviceRect.width() << deviceRect.y(); + verts.push_back(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y())); + verts.push_back(QVector2D(deviceRect.x(), deviceRect.y())); + verts.push_back(QVector2D(deviceRect.x(), deviceRect.y() + deviceRect.height())); + verts.push_back(QVector2D(deviceRect.x(), deviceRect.y() + deviceRect.height())); + verts.push_back(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y() + deviceRect.height())); + verts.push_back(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y())); } - vbo->setData(verts.count() / 2, 2, verts.data(), nullptr); + vbo->setVertices(verts); vbo->render(GL_TRIANGLES); glDisable(GL_BLEND); } diff --git a/src/plugins/snaphelper/snaphelper.cpp b/src/plugins/snaphelper/snaphelper.cpp index f63123938a..8acd3de007 100644 --- a/src/plugins/snaphelper/snaphelper.cpp +++ b/src/plugins/snaphelper/snaphelper.cpp @@ -117,7 +117,7 @@ void SnapHelperEffect::paintScreen(const RenderTarget &renderTarget, const Rende vbo->setColor(color); glLineWidth(s_lineWidth); - QVector verts; + QVector verts; verts.reserve(screens.count() * 24); for (EffectScreen *screen : screens) { const QRectF rect = effects->clientArea(ScreenArea, screen, effects->currentDesktop()); @@ -127,30 +127,30 @@ void SnapHelperEffect::paintScreen(const RenderTarget &renderTarget, const Rende const int halfHeight = m_geometry.height() / 2; // Center vertical line. - verts << (rect.x() + rect.width() / 2) * scale << rect.y() * scale; - verts << (rect.x() + rect.width() / 2) * scale << (rect.y() + rect.height()) * scale; + verts.push_back(QVector2D((rect.x() + rect.width() / 2) * scale, rect.y() * scale)); + verts.push_back(QVector2D((rect.x() + rect.width() / 2) * scale, (rect.y() + rect.height()) * scale)); // Center horizontal line. - verts << rect.x() * scale << (rect.y() + rect.height() / 2) * scale; - verts << (rect.x() + rect.width()) * scale << (rect.y() + rect.height() / 2) * scale; + verts.push_back(QVector2D(rect.x() * scale, (rect.y() + rect.height() / 2) * scale)); + verts.push_back(QVector2D((rect.x() + rect.width()) * scale, (rect.y() + rect.height() / 2) * scale)); // Top edge of the window outline. - verts << (midX - halfWidth - s_lineWidth / 2) * scale << (midY - halfHeight) * scale; - verts << (midX + halfWidth + s_lineWidth / 2) * scale << (midY - halfHeight) * scale; + verts.push_back(QVector2D((midX - halfWidth - s_lineWidth / 2) * scale, (midY - halfHeight) * scale)); + verts.push_back(QVector2D((midX + halfWidth + s_lineWidth / 2) * scale, (midY - halfHeight) * scale)); // Right edge of the window outline. - verts << (midX + halfWidth) * scale << (midY - halfHeight + s_lineWidth / 2) * scale; - verts << (midX + halfWidth) * scale << (midY + halfHeight - s_lineWidth / 2) * scale; + verts.push_back(QVector2D((midX + halfWidth) * scale, (midY - halfHeight + s_lineWidth / 2) * scale)); + verts.push_back(QVector2D((midX + halfWidth) * scale, (midY + halfHeight - s_lineWidth / 2) * scale)); // Bottom edge of the window outline. - verts << (midX + halfWidth + s_lineWidth / 2) * scale << (midY + halfHeight) * scale; - verts << (midX - halfWidth - s_lineWidth / 2) * scale << (midY + halfHeight) * scale; + verts.push_back(QVector2D((midX + halfWidth + s_lineWidth / 2) * scale, (midY + halfHeight) * scale)); + verts.push_back(QVector2D((midX - halfWidth - s_lineWidth / 2) * scale, (midY + halfHeight) * scale)); // Left edge of the window outline. - verts << (midX - halfWidth) * scale << (midY + halfHeight - s_lineWidth / 2) * scale; - verts << (midX - halfWidth) * scale << (midY - halfHeight + s_lineWidth / 2) * scale; + verts.push_back(QVector2D((midX - halfWidth) * scale, (midY + halfHeight - s_lineWidth / 2) * scale)); + verts.push_back(QVector2D((midX - halfWidth) * scale, (midY - halfHeight + s_lineWidth / 2) * scale)); } - vbo->setData(verts.count() / 2, 2, verts.data(), nullptr); + vbo->setVertices(verts); vbo->render(GL_LINES); glDisable(GL_BLEND); diff --git a/src/plugins/touchpoints/touchpoints.cpp b/src/plugins/touchpoints/touchpoints.cpp index 28bba1bb26..56ef7b02fc 100644 --- a/src/plugins/touchpoints/touchpoints.cpp +++ b/src/plugins/touchpoints/touchpoints.cpp @@ -205,17 +205,17 @@ void TouchPointsEffect::drawCircleGl(const RenderViewport &viewport, const QColo vbo->reset(); vbo->setUseColor(true); vbo->setColor(color); - QVector verts; - verts.reserve(num_segments * 2); + QVector verts; + verts.reserve(num_segments); for (int ii = 0; ii < num_segments; ++ii) { - verts << (x + cx) * scale << (y + cy) * scale; // output vertex + verts.push_back(QVector2D((x + cx) * scale, (y + cy) * scale)); // apply the rotation matrix t = x; x = c * x - s * y; y = s * t + c * y; } - vbo->setData(verts.size() / 2, 2, verts.data(), nullptr); + vbo->setVertices(verts); vbo->render(GL_LINE_LOOP); }