diff --git a/src/libkwineffects/kwineffects.cpp b/src/libkwineffects/kwineffects.cpp index 939a316aa3..7ed401d363 100644 --- a/src/libkwineffects/kwineffects.cpp +++ b/src/libkwineffects/kwineffects.cpp @@ -941,9 +941,7 @@ WindowQuadList WindowQuadList::makeRegularGrid(int xSubdivisions, int ySubdivisi void RenderGeometry::copy(std::span destination) { Q_ASSERT(int(destination.size()) >= size()); - for (std::size_t i = 0; i < destination.size(); ++i) { - destination[i] = at(i); - } + std::copy(cbegin(), cend(), destination.begin()); } void RenderGeometry::appendWindowVertex(const WindowVertex &windowVertex, qreal deviceScale) diff --git a/src/libkwineffects/kwinglutils.h b/src/libkwineffects/kwinglutils.h index 68ac7c4e9a..ccd8c39ca2 100644 --- a/src/libkwineffects/kwinglutils.h +++ b/src/libkwineffects/kwinglutils.h @@ -19,6 +19,8 @@ #include #include +#include + /** @addtogroup kwineffects */ /** @{ */ @@ -627,7 +629,15 @@ public: * It is assumed that the GL_ARRAY_BUFFER_BINDING will not be changed while * the buffer object is mapped. */ - GLvoid *map(size_t size); + template + std::optional> map(size_t count) + { + if (const auto m = map(sizeof(T) * count)) { + return std::span(reinterpret_cast(m), count); + } else { + return std::nullopt; + } + } /** * Flushes the mapped buffer range and unmaps the buffer. @@ -740,6 +750,8 @@ public: static const GLVertexAttrib GLVertex3DLayout[2]; private: + GLvoid *map(size_t size); + const std::unique_ptr d; }; diff --git a/src/libkwineffects/kwinoffscreeneffect.cpp b/src/libkwineffects/kwinoffscreeneffect.cpp index e202ba8754..46023dac5a 100644 --- a/src/libkwineffects/kwinoffscreeneffect.cpp +++ b/src/libkwineffects/kwinoffscreeneffect.cpp @@ -167,8 +167,11 @@ void OffscreenData::paint(const RenderTarget &renderTarget, const RenderViewport } geometry.postProcessTextureCoordinates(m_texture->matrix(NormalizedCoordinates)); - GLVertex2D *map = static_cast(vbo->map(geometry.count() * sizeof(GLVertex2D))); - geometry.copy(std::span(map, geometry.count())); + const auto map = vbo->map(geometry.size()); + if (!map) { + return; + } + geometry.copy(*map); vbo->unmap(); vbo->bindArrays(); diff --git a/src/plugins/backgroundcontrast/contrast.cpp b/src/plugins/backgroundcontrast/contrast.cpp index ee141bdf51..306b9be5d3 100644 --- a/src/plugins/backgroundcontrast/contrast.cpp +++ b/src/plugins/backgroundcontrast/contrast.cpp @@ -310,9 +310,9 @@ QRegion ContrastEffect::contrastRegion(const EffectWindow *w) const return region; } -void ContrastEffect::uploadRegion(QVector2D *&map, const QRegion ®ion, qreal scale) +void ContrastEffect::uploadRegion(std::span map, const QRegion ®ion, qreal scale) { - Q_ASSERT(map); + size_t index = 0; for (const QRect &r : region) { const auto deviceRect = scaledRect(r, scale); const QVector2D topLeft = roundVector(QVector2D(deviceRect.x(), deviceRect.y())); @@ -321,14 +321,14 @@ void ContrastEffect::uploadRegion(QVector2D *&map, const QRegion ®ion, qreal const QVector2D bottomRight = roundVector(QVector2D(deviceRect.x() + deviceRect.width(), deviceRect.y() + deviceRect.height())); // First triangle - *(map++) = topRight; - *(map++) = topLeft; - *(map++) = bottomLeft; + map[index++] = topRight; + map[index++] = topLeft; + map[index++] = bottomLeft; // Second triangle - *(map++) = bottomLeft; - *(map++) = bottomRight; - *(map++) = topRight; + map[index++] = bottomLeft; + map[index++] = bottomRight; + map[index++] = topRight; } } @@ -339,11 +339,11 @@ bool ContrastEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion ®ion, return false; } - QVector2D *map = (QVector2D *)vbo->map(vertexCount * sizeof(QVector2D)); + const auto map = vbo->map(vertexCount); if (!map) { return false; } - uploadRegion(map, region, scale); + uploadRegion(*map, region, scale); vbo->unmap(); const GLVertexAttrib layout[] = { diff --git a/src/plugins/backgroundcontrast/contrast.h b/src/plugins/backgroundcontrast/contrast.h index 4b6238cd93..7624b5671c 100644 --- a/src/plugins/backgroundcontrast/contrast.h +++ b/src/plugins/backgroundcontrast/contrast.h @@ -60,7 +60,7 @@ private: bool shouldContrast(const EffectWindow *w, int mask, const WindowPaintData &data) const; void updateContrastRegion(EffectWindow *w); void doContrast(const RenderTarget &renderTarget, const RenderViewport &viewport, EffectWindow *w, const QRegion &shape, const QRect &screen, const float opacity, const QMatrix4x4 &screenProjection); - void uploadRegion(QVector2D *&map, const QRegion ®ion, qreal scale); + void uploadRegion(std::span map, const QRegion ®ion, qreal scale); Q_REQUIRED_RESULT bool uploadGeometry(GLVertexBuffer *vbo, const QRegion ®ion, qreal scale); private: diff --git a/src/plugins/blur/blur.cpp b/src/plugins/blur/blur.cpp index f7b116eb70..af9cf2e062 100644 --- a/src/plugins/blur/blur.cpp +++ b/src/plugins/blur/blur.cpp @@ -496,9 +496,8 @@ QRegion BlurEffect::blurRegion(const EffectWindow *w) const return region; } -void BlurEffect::uploadRegion(QVector2D *&map, const QRegion ®ion) +void BlurEffect::uploadRegion(const std::span map, size_t &index, const QRegion ®ion) { - Q_ASSERT(map); for (const QRect &r : region) { const QVector2D topLeft(r.x(), r.y()); const QVector2D topRight((r.x() + r.width()), r.y()); @@ -506,14 +505,14 @@ void BlurEffect::uploadRegion(QVector2D *&map, const QRegion ®ion) const QVector2D bottomRight((r.x() + r.width()), (r.y() + r.height())); // First triangle - *(map++) = topRight; - *(map++) = topLeft; - *(map++) = bottomLeft; + map[index++] = topRight; + map[index++] = topLeft; + map[index++] = bottomLeft; // Second triangle - *(map++) = bottomLeft; - *(map++) = bottomRight; - *(map++) = topRight; + map[index++] = bottomLeft; + map[index++] = bottomRight; + map[index++] = topRight; } } @@ -524,13 +523,14 @@ bool BlurEffect::uploadGeometry(GLVertexBuffer *vbo, const QRegion &expandedBlur return false; } - QVector2D *map = (QVector2D *)vbo->map(vertexCount * sizeof(QVector2D)); + auto map = vbo->map(vertexCount); if (!map) { return false; } - uploadRegion(map, expandedBlurRegion); - uploadRegion(map, blurRegion); + size_t index = 0; + uploadRegion(*map, index, expandedBlurRegion); + uploadRegion(*map, index, blurRegion); vbo->unmap(); diff --git a/src/plugins/blur/blur.h b/src/plugins/blur/blur.h index 50adf9f1be..9ca5f607ba 100644 --- a/src/plugins/blur/blur.h +++ b/src/plugins/blur/blur.h @@ -84,7 +84,7 @@ private: bool shouldBlur(const EffectWindow *w, int mask, const WindowPaintData &data) const; void updateBlurRegion(EffectWindow *w); void doBlur(const RenderTarget &renderTarget, const RenderViewport &viewport, const QRegion &shape, const QRect &screen, const float opacity, bool isDock, QRect windowRect); - void uploadRegion(QVector2D *&map, const QRegion ®ion); + void uploadRegion(const std::span map, size_t &index, const QRegion ®ion); Q_REQUIRED_RESULT bool uploadGeometry(GLVertexBuffer *vbo, const QRegion &expandedBlurRegion, const QRegion &blurRegion); void generateNoiseTexture(); void screenAdded(EffectScreen *screen); diff --git a/src/plugins/screentransform/screentransform.cpp b/src/plugins/screentransform/screentransform.cpp index d959294197..0559d79ac6 100644 --- a/src/plugins/screentransform/screentransform.cpp +++ b/src/plugins/screentransform/screentransform.cpp @@ -128,7 +128,11 @@ static GLVertexBuffer *texturedRectVbo(const QRectF &geometry, qreal scale) }; vbo->setAttribLayout(attribs, 2, sizeof(GLVertex2D)); - auto map = static_cast(vbo->map(6 * sizeof(GLVertex2D))); + const auto opt = vbo->map(6); + if (!opt) { + return nullptr; + } + const auto map = *opt; auto deviceGeometry = scaledRect(geometry, scale); @@ -222,6 +226,11 @@ void ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); + GLVertexBuffer *vbo = texturedRectVbo(lerp(it->m_oldGeometry, screenRect, blendFactor), scale); + if (!vbo) { + return; + } + ShaderManager *sm = ShaderManager::instance(); sm->pushShader(m_shader.get()); m_shader->setUniform(m_modelViewProjectioMatrixLocation, modelViewProjectionMatrix); @@ -229,7 +238,6 @@ void ScreenTransformEffect::paintScreen(const RenderTarget &renderTarget, const m_shader->setUniform(m_currentTextureLocation, 0); m_shader->setUniform(m_previousTextureLocation, 1); - GLVertexBuffer *vbo = texturedRectVbo(lerp(it->m_oldGeometry, screenRect, blendFactor), scale); vbo->bindArrays(); vbo->draw(GL_TRIANGLES, 0, 6); vbo->unbindArrays(); diff --git a/src/scene/itemrenderer_opengl.cpp b/src/scene/itemrenderer_opengl.cpp index f18fc6bc6a..eeb7fd8902 100644 --- a/src/scene/itemrenderer_opengl.cpp +++ b/src/scene/itemrenderer_opengl.cpp @@ -281,8 +281,6 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend return; } - const size_t size = totalVertexCount * sizeof(GLVertex2D); - ShaderTraits shaderTraits = ShaderTrait::MapTexture | ShaderTrait::TransformColorspace; if (data.brightness() != 1.0) { @@ -296,7 +294,10 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend vbo->reset(); vbo->setAttribLayout(GLVertexBuffer::GLVertex2DLayout, 2, sizeof(GLVertex2D)); - GLVertex2D *map = (GLVertex2D *)vbo->map(size); + const auto map = vbo->map(totalVertexCount); + if (!map) { + return; + } for (int i = 0, v = 0; i < renderContext.renderNodes.count(); i++) { RenderNode &renderNode = renderContext.renderNodes[i]; @@ -313,7 +314,7 @@ void ItemRendererOpenGL::renderItem(const RenderTarget &renderTarget, const Rend renderNode.geometry.postProcessTextureCoordinates(renderNode.texture->matrix(renderNode.coordinateType)); - renderNode.geometry.copy(std::span(&map[v], renderNode.geometry.count())); + renderNode.geometry.copy(map->subspan(v)); v += renderNode.geometry.count(); }