Add a fast case for copying vertices in GrDrawVerticesOp.
authorBrian Salomon <bsalomon@google.com>
Tue, 7 Feb 2017 00:06:22 +0000 (19:06 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Tue, 7 Feb 2017 00:41:33 +0000 (00:41 +0000)
Uses Sk2f to apply a translation-only matrix when the vertex attributes contain only positions and colors.

We should look at how to generalize this for other draw vertices cases and other ops.

Change-Id: I5eb692982dc216b1c0a71209c969672b0562143c
Reviewed-on: https://skia-review.googlesource.com/8103
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
src/gpu/ops/GrDrawVerticesOp.cpp

index faef239..4c41bbf 100644 (file)
@@ -197,48 +197,71 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) const {
         }
     }
 
-    int indexOffset = 0;
     int vertexOffset = 0;
+    // We have a fast case below for uploading the vertex data when the matrix is translate
+    // only and there are colors but not local coords.
+    bool fastAttrs = hasColorAttribute && !hasLocalCoordsAttribute;
     for (int i = 0; i < instanceCount; i++) {
         const Mesh& mesh = fMeshes[i];
         if (indices) {
             int indexCount = mesh.fVertices->indexCount();
-            for (int j = 0; j < indexCount; ++j, ++indexOffset) {
-                *(indices + indexOffset) = mesh.fVertices->indices()[j] + vertexOffset;
+            for (int j = 0; j < indexCount; ++j) {
+                *indices++ = mesh.fVertices->indices()[j] + vertexOffset;
             }
         }
-
-        static constexpr size_t kColorOffset = sizeof(SkPoint);
-        size_t localCoordOffset =
-                hasColorAttribute ? kColorOffset + sizeof(uint32_t) : kColorOffset;
-
         int vertexCount = mesh.fVertices->vertexCount();
         const SkPoint* positions = mesh.fVertices->positions();
         const SkColor* colors = mesh.fVertices->colors();
         const SkPoint* localCoords = mesh.fVertices->texCoords();
-        for (int j = 0; j < vertexCount; ++j) {
+        bool fastMesh = (!this->hasMultipleViewMatrices() ||
+                         mesh.fViewMatrix.getType() <= SkMatrix::kTranslate_Mask) &&
+                        mesh.hasPerVertexColors();
+        if (fastAttrs && fastMesh) {
+            struct V {
+                SkPoint fPos;
+                uint32_t fColor;
+            };
+            SkASSERT(sizeof(V) == vertexStride);
+            V* v = (V*)verts;
+            Sk2f t(0, 0);
             if (this->hasMultipleViewMatrices()) {
-                mesh.fViewMatrix.mapPoints(((SkPoint*)verts), &positions[j], 1);
-            } else {
-                *((SkPoint*)verts) = positions[j];
+                t = Sk2f(mesh.fViewMatrix.getTranslateX(), mesh.fViewMatrix.getTranslateY());
             }
-            if (hasColorAttribute) {
-                if (mesh.hasPerVertexColors()) {
-                    *(uint32_t*)((intptr_t)verts + kColorOffset) = colors[j];
-                } else {
-                    *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColor;
-                }
+            for (int j = 0; j < vertexCount; ++j) {
+                Sk2f p = Sk2f::Load(positions++) + t;
+                p.store(&v[j].fPos);
+                v[j].fColor = colors[j];
             }
-            if (hasLocalCoordsAttribute) {
-                if (mesh.hasExplicitLocalCoords()) {
-                    *(SkPoint*)((intptr_t)verts + localCoordOffset) = localCoords[j];
+            verts = v + vertexCount;
+        } else {
+            static constexpr size_t kColorOffset = sizeof(SkPoint);
+            size_t localCoordOffset =
+                    hasColorAttribute ? kColorOffset + sizeof(uint32_t) : kColorOffset;
+
+            for (int j = 0; j < vertexCount; ++j) {
+                if (this->hasMultipleViewMatrices()) {
+                    mesh.fViewMatrix.mapPoints(((SkPoint*)verts), &positions[j], 1);
                 } else {
-                    *(SkPoint*)((intptr_t)verts + localCoordOffset) = positions[j];
+                    *((SkPoint*)verts) = positions[j];
+                }
+                if (hasColorAttribute) {
+                    if (mesh.hasPerVertexColors()) {
+                        *(uint32_t*)((intptr_t)verts + kColorOffset) = colors[j];
+                    } else {
+                        *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColor;
+                    }
+                }
+                if (hasLocalCoordsAttribute) {
+                    if (mesh.hasExplicitLocalCoords()) {
+                        *(SkPoint*)((intptr_t)verts + localCoordOffset) = localCoords[j];
+                    } else {
+                        *(SkPoint*)((intptr_t)verts + localCoordOffset) = positions[j];
+                    }
                 }
+                verts = (void*)((intptr_t)verts + vertexStride);
             }
-            verts = (void*)((intptr_t)verts + vertexStride);
-            vertexOffset++;
         }
+        vertexOffset += vertexCount;
     }
 
     GrMesh mesh;