From dbbda2112952942a8449e14801b8ef7e6f34a114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Thu, 21 Mar 2013 20:22:29 +0100 Subject: [PATCH] kwin: Support quads in makeInterleavedArrays() A new type parameter is added for specifying the primitive type. --- libkwineffects/kwineffects.cpp | 163 ++++++++++++++++++++++----------- libkwineffects/kwineffects.h | 2 +- scene_opengl.cpp | 4 +- 3 files changed, 115 insertions(+), 54 deletions(-) diff --git a/libkwineffects/kwineffects.cpp b/libkwineffects/kwineffects.cpp index 51485c5200..b0634b12c3 100644 --- a/libkwineffects/kwineffects.cpp +++ b/libkwineffects/kwineffects.cpp @@ -1063,7 +1063,15 @@ WindowQuadList WindowQuadList::makeRegularGrid(int xSubdivisions, int ySubdivisi return ret; } -void WindowQuadList::makeInterleavedArrays(GLVertex2D *vertices, const QMatrix4x4 &textureMatrix) const +#ifndef GL_TRIANGLES +# define GL_TRIANGLES 0x0004 +#endif + +#ifndef GL_QUADS +# define GL_QUADS 0x0007 +#endif + +void WindowQuadList::makeInterleavedArrays(unsigned int type, GLVertex2D *vertices, const QMatrix4x4 &textureMatrix) const { // Since we know that the texture matrix just scales and translates // we can use this information to optimize the transformation @@ -1072,64 +1080,117 @@ void WindowQuadList::makeInterleavedArrays(GLVertex2D *vertices, const QMatrix4x GLVertex2D *vertex = vertices; -#ifdef HAVE_SSE2 - if (!(intptr_t(vertex) & 0xf)) { - for (int i = 0; i < count(); i++) { - const WindowQuad &quad = at(i); - KWIN_ALIGN(16) GLVertex2D v[4]; + assert(type == GL_QUADS || type == GL_TRIANGLES); - for (int j = 0; j < 4; j++) { - const WindowVertex &wv = quad[j]; - - v[j].position = QVector2D(wv.x(), wv.y()); - v[j].texcoord = QVector2D(wv.u(), wv.v()) * coeff + offset; - } - - const __m128i *srcP = (const __m128i *) &v; - __m128i *dstP = (__m128i *) vertex; - - __m128i src[4]; - src[0] = _mm_load_si128(&srcP[0]); // Top-left - src[1] = _mm_load_si128(&srcP[1]); // Top-right - src[2] = _mm_load_si128(&srcP[2]); // Bottom-right - src[3] = _mm_load_si128(&srcP[3]); // Bottom-left - - // First triangle - _mm_stream_si128(&dstP[0], src[1]); // Top-right - _mm_stream_si128(&dstP[1], src[0]); // Top-left - _mm_stream_si128(&dstP[2], src[3]); // Bottom-left - - // Second triangle - _mm_stream_si128(&dstP[3], src[3]); // Bottom-left - _mm_stream_si128(&dstP[4], src[2]); // Bottom-right - _mm_stream_si128(&dstP[5], src[1]); // Top-right - - vertex += 6; - } - } else -#endif + switch (type) { - for (int i = 0; i < count(); i++) { - const WindowQuad &quad = at(i); - GLVertex2D v[4]; // Four unique vertices / quad + case GL_QUADS: +#ifdef HAVE_SSE2 + if (!(intptr_t(vertex) & 0xf)) { + for (int i = 0; i < count(); i++) { + const WindowQuad &quad = at(i); + KWIN_ALIGN(16) GLVertex2D v[4]; - for (int j = 0; j < 4; j++) { - const WindowVertex &wv = quad[j]; + for (int j = 0; j < 4; j++) { + const WindowVertex &wv = quad[j]; - v[j].position = QVector2D(wv.x(), wv.y()); - v[j].texcoord = QVector2D(wv.u(), wv.v()) * coeff + offset; + v[j].position = QVector2D(wv.x(), wv.y()); + v[j].texcoord = QVector2D(wv.u(), wv.v()) * coeff + offset; + } + + const __m128i *srcP = (const __m128i *) &v; + __m128i *dstP = (__m128i *) vertex; + + _mm_stream_si128(&dstP[0], _mm_load_si128(&srcP[0])); // Top-left + _mm_stream_si128(&dstP[1], _mm_load_si128(&srcP[1])); // Top-right + _mm_stream_si128(&dstP[2], _mm_load_si128(&srcP[2])); // Bottom-right + _mm_stream_si128(&dstP[3], _mm_load_si128(&srcP[3])); // Bottom-left + + vertex += 4; } + } else +#endif // HAVE_SSE2 + { + for (int i = 0; i < count(); i++) { + const WindowQuad &quad = at(i); - // First triangle - *(vertex++) = v[1]; // Top-right - *(vertex++) = v[0]; // Top-left - *(vertex++) = v[3]; // Bottom-left + for (int j = 0; j < 4; j++) { + const WindowVertex &wv = quad[j]; - // Second triangle - *(vertex++) = v[3]; // Bottom-left - *(vertex++) = v[2]; // Bottom-right - *(vertex++) = v[1]; // Top-right + GLVertex2D v; + v.position = QVector2D(wv.x(), wv.y()); + v.texcoord = QVector2D(wv.u(), wv.v()) * coeff + offset; + + *(vertex++) = v; + } + } } + break; + + case GL_TRIANGLES: +#ifdef HAVE_SSE2 + if (!(intptr_t(vertex) & 0xf)) { + for (int i = 0; i < count(); i++) { + const WindowQuad &quad = at(i); + KWIN_ALIGN(16) GLVertex2D v[4]; + + for (int j = 0; j < 4; j++) { + const WindowVertex &wv = quad[j]; + + v[j].position = QVector2D(wv.x(), wv.y()); + v[j].texcoord = QVector2D(wv.u(), wv.v()) * coeff + offset; + } + + const __m128i *srcP = (const __m128i *) &v; + __m128i *dstP = (__m128i *) vertex; + + __m128i src[4]; + src[0] = _mm_load_si128(&srcP[0]); // Top-left + src[1] = _mm_load_si128(&srcP[1]); // Top-right + src[2] = _mm_load_si128(&srcP[2]); // Bottom-right + src[3] = _mm_load_si128(&srcP[3]); // Bottom-left + + // First triangle + _mm_stream_si128(&dstP[0], src[1]); // Top-right + _mm_stream_si128(&dstP[1], src[0]); // Top-left + _mm_stream_si128(&dstP[2], src[3]); // Bottom-left + + // Second triangle + _mm_stream_si128(&dstP[3], src[3]); // Bottom-left + _mm_stream_si128(&dstP[4], src[2]); // Bottom-right + _mm_stream_si128(&dstP[5], src[1]); // Top-right + + vertex += 6; + } + } else +#endif // HAVE_SSE2 + { + for (int i = 0; i < count(); i++) { + const WindowQuad &quad = at(i); + GLVertex2D v[4]; // Four unique vertices / quad + + for (int j = 0; j < 4; j++) { + const WindowVertex &wv = quad[j]; + + v[j].position = QVector2D(wv.x(), wv.y()); + v[j].texcoord = QVector2D(wv.u(), wv.v()) * coeff + offset; + } + + // First triangle + *(vertex++) = v[1]; // Top-right + *(vertex++) = v[0]; // Top-left + *(vertex++) = v[3]; // Bottom-left + + // Second triangle + *(vertex++) = v[3]; // Bottom-left + *(vertex++) = v[2]; // Bottom-right + *(vertex++) = v[1]; // Top-right + } + } + break; + + default: + break; } } diff --git a/libkwineffects/kwineffects.h b/libkwineffects/kwineffects.h index 0bd809ceb2..2b83bbd451 100644 --- a/libkwineffects/kwineffects.h +++ b/libkwineffects/kwineffects.h @@ -1758,7 +1758,7 @@ public: WindowQuadList select(WindowQuadType type) const; WindowQuadList filterOut(WindowQuadType type) const; bool smoothNeeded() const; - void makeInterleavedArrays(GLVertex2D *vertices, const QMatrix4x4 &matrix) const; + void makeInterleavedArrays(unsigned int type, GLVertex2D *vertices, const QMatrix4x4 &matrix) const; void makeArrays(float** vertices, float** texcoords, const QSizeF &size, bool yInverted) const; bool isTransformed() const; }; diff --git a/scene_opengl.cpp b/scene_opengl.cpp index 66a7a8c762..c6bc64dd37 100644 --- a/scene_opengl.cpp +++ b/scene_opengl.cpp @@ -1275,7 +1275,7 @@ void SceneOpenGL::Window::renderQuads(int, const QRegion& region, const WindowQu vbo->setVertexCount(quads.count() * 6); GLVertex2D *map = (GLVertex2D *) vbo->map(quads.count() * 6 * sizeof(GLVertex2D)); - quads.makeInterleavedArrays(map, matrix); + quads.makeInterleavedArrays(GL_TRIANGLES, map, matrix); vbo->unmap(); vbo->render(region, GL_TRIANGLES, m_hardwareClipping); @@ -1450,7 +1450,7 @@ void SceneOpenGL2Window::performPaint(int mask, QRegion region, WindowPaintData const QMatrix4x4 matrix = nodes[i].texture->matrix(nodes[i].coordinateType); - quads[i].makeInterleavedArrays(&map[v], matrix); + quads[i].makeInterleavedArrays(GL_TRIANGLES, &map[v], matrix); v += quads[i].count() * 6; }