aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-02-02 21:05:19 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-03 02:34:37 +0000
commit3f36369a94d2c49c91bcd0249bf351da36a6d40d (patch)
tree3e97eaefd6056a22c05b6639a0c8fbf3b2003838 /src
parent8c88a371b47dd650a9052ffaf421c5cf897edd26 (diff)
Batch across matrix changes in drawVertices and add GM to test.
Change-Id: I6b08d37781e3c715a1d9d8c9729667ec78625836 Reviewed-on: https://skia-review.googlesource.com/7949 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/ops/GrDrawVerticesOp.cpp96
-rw-r--r--src/gpu/ops/GrDrawVerticesOp.h5
2 files changed, 65 insertions, 36 deletions
diff --git a/src/gpu/ops/GrDrawVerticesOp.cpp b/src/gpu/ops/GrDrawVerticesOp.cpp
index 2b63804ee7..43093cee5b 100644
--- a/src/gpu/ops/GrDrawVerticesOp.cpp
+++ b/src/gpu/ops/GrDrawVerticesOp.cpp
@@ -11,28 +11,33 @@
#include "GrInvariantOutput.h"
#include "GrOpFlushState.h"
-static sk_sp<GrGeometryProcessor> set_vertex_attributes(
- bool hasLocalCoords,
- int* colorOffset,
- GrRenderTargetContext::ColorArrayType colorArrayType,
- int* texOffset,
- const SkMatrix& viewMatrix) {
+static sk_sp<GrGeometryProcessor> make_gp(bool clientProvidedLocalCoords,
+ bool pipelineReadsLocalCoords,
+ GrRenderTargetContext::ColorArrayType colorArrayType,
+ bool multipleViewMatrices,
+ const SkMatrix& viewMatrixIfCommon,
+ bool* hasLocalCoordAttribute) {
using namespace GrDefaultGeoProcFactory;
- *texOffset = -1;
- *colorOffset = -1;
-
- LocalCoords::Type localCoordsType =
- hasLocalCoords ? LocalCoords::kHasExplicit_Type : LocalCoords::kUsePosition_Type;
- *colorOffset = sizeof(SkPoint);
- if (hasLocalCoords) {
- *texOffset = sizeof(SkPoint) + sizeof(uint32_t);
+ LocalCoords::Type localCoordsType;
+ if (pipelineReadsLocalCoords) {
+ if (clientProvidedLocalCoords || multipleViewMatrices) {
+ *hasLocalCoordAttribute = true;
+ localCoordsType = LocalCoords::kHasExplicit_Type;
+ } else {
+ *hasLocalCoordAttribute = false;
+ localCoordsType = LocalCoords::kUsePosition_Type;
+ }
+ } else {
+ localCoordsType = LocalCoords::kUnused_Type;
+ *hasLocalCoordAttribute = false;
}
+
Color::Type colorType =
(colorArrayType == GrRenderTargetContext::ColorArrayType::kPremulGrColor)
? Color::kPremulGrColorAttribute_Type
: Color::kUnpremulSkColorAttribute_Type;
- return GrDefaultGeoProcFactory::Make(colorType, Coverage::kSolid_Type, localCoordsType,
- viewMatrix);
+ const SkMatrix& vm = multipleViewMatrices ? SkMatrix::I() : viewMatrixIfCommon;
+ return GrDefaultGeoProcFactory::Make(colorType, Coverage::kSolid_Type, localCoordsType, vm);
}
GrDrawVerticesOp::GrDrawVerticesOp(GrColor color, GrPrimitiveType primitiveType,
@@ -44,9 +49,9 @@ GrDrawVerticesOp::GrDrawVerticesOp(GrColor color, GrPrimitiveType primitiveType,
: INHERITED(ClassID()) {
SkASSERT(positions);
- fViewMatrix = viewMatrix;
Mesh& mesh = fMeshes.push_back();
mesh.fColor = color;
+ mesh.fViewMatrix = viewMatrix;
mesh.fPositions.append(vertexCount, positions);
if (indices) {
@@ -98,20 +103,21 @@ void GrDrawVerticesOp::applyPipelineOptimizations(const GrPipelineOptimizations&
fVariableColor = false;
fColorArrayType = GrRenderTargetContext::ColorArrayType::kPremulGrColor;
}
- if (!optimizations.readsLocalCoords()) {
+ if (!(fPipelineNeedsLocalCoords = optimizations.readsLocalCoords())) {
fMeshes[0].fLocalCoords.reset();
}
}
void GrDrawVerticesOp::onPrepareDraws(Target* target) const {
- bool hasLocalCoords = !fMeshes[0].fLocalCoords.isEmpty();
- int colorOffset = -1, texOffset = -1;
- sk_sp<GrGeometryProcessor> gp(set_vertex_attributes(hasLocalCoords, &colorOffset,
- fColorArrayType, &texOffset, fViewMatrix));
+ bool clientLocalCoords = !fMeshes[0].fLocalCoords.isEmpty();
+ bool hasLocalCoordAttribute;
+ sk_sp<GrGeometryProcessor> gp =
+ make_gp(clientLocalCoords, fPipelineNeedsLocalCoords, fColorArrayType,
+ fMultipleViewMatrices, fMeshes[0].fViewMatrix, &hasLocalCoordAttribute);
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride ==
- sizeof(SkPoint) + (hasLocalCoords ? sizeof(SkPoint) : 0) + sizeof(uint32_t));
+ sizeof(SkPoint) + (hasLocalCoordAttribute ? sizeof(SkPoint) : 0) + sizeof(uint32_t));
int instanceCount = fMeshes.count();
@@ -142,23 +148,35 @@ void GrDrawVerticesOp::onPrepareDraws(Target* target) const {
int vertexOffset = 0;
for (int i = 0; i < instanceCount; i++) {
const Mesh& mesh = fMeshes[i];
-
- // TODO we can actually cache this interleaved and then just memcopy
+ // Currently we require all meshes to either have explicit local coords or not, though it
+ // wouldn't be hard to allow them to mix.
+ SkASSERT(clientLocalCoords == !mesh.fLocalCoords.isEmpty());
if (indices) {
for (int j = 0; j < mesh.fIndices.count(); ++j, ++indexOffset) {
*(indices + indexOffset) = mesh.fIndices[j] + vertexOffset;
}
}
+ static constexpr size_t kColorOffset = sizeof(SkPoint);
+ static constexpr size_t kLocalCoordOffset = kColorOffset + sizeof(uint32_t);
+
for (int j = 0; j < mesh.fPositions.count(); ++j) {
- *((SkPoint*)verts) = mesh.fPositions[j];
+ if (fMultipleViewMatrices) {
+ mesh.fViewMatrix.mapPoints(((SkPoint*)verts), &mesh.fPositions[j], 1);
+ } else {
+ *((SkPoint*)verts) = mesh.fPositions[j];
+ }
if (mesh.fColors.isEmpty()) {
- *(uint32_t*)((intptr_t)verts + colorOffset) = mesh.fColor;
+ *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColor;
} else {
- *(uint32_t*)((intptr_t)verts + colorOffset) = mesh.fColors[j];
+ *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColors[j];
}
- if (hasLocalCoords) {
- *(SkPoint*)((intptr_t)verts + texOffset) = mesh.fLocalCoords[j];
+ if (hasLocalCoordAttribute) {
+ if (clientLocalCoords) {
+ *(SkPoint*)((intptr_t)verts + kLocalCoordOffset) = mesh.fLocalCoords[j];
+ } else {
+ *(SkPoint*)((intptr_t)verts + kLocalCoordOffset) = mesh.fPositions[j];
+ }
}
verts = (void*)((intptr_t)verts + vertexStride);
vertexOffset++;
@@ -188,15 +206,13 @@ bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
return false;
}
- // We currently use a uniform viewmatrix for this op.
- if (!fViewMatrix.cheapEqualTo(that->fViewMatrix)) {
- return false;
- }
if (fMeshes[0].fIndices.isEmpty() != that->fMeshes[0].fIndices.isEmpty()) {
return false;
}
+ // This could be relaxed by using positions for the one that doesn't already have explicit
+ // local coordindates.
if (fMeshes[0].fLocalCoords.isEmpty() != that->fMeshes[0].fLocalCoords.isEmpty()) {
return false;
}
@@ -205,12 +221,24 @@ bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
return false;
}
+ if (fIndexCount + that->fIndexCount > SK_MaxU16) {
+ return false;
+ }
+
if (!fVariableColor) {
if (that->fVariableColor || that->fMeshes[0].fColor != fMeshes[0].fColor) {
fVariableColor = true;
}
}
+ // Check whether we are about to acquire a mesh with a different view matrix.
+ if (!fMultipleViewMatrices) {
+ if (that->fMultipleViewMatrices ||
+ !fMeshes[0].fViewMatrix.cheapEqualTo(that->fMeshes[0].fViewMatrix)) {
+ fMultipleViewMatrices = true;
+ }
+ }
+
fMeshes.push_back_n(that->fMeshes.count(), that->fMeshes.begin());
fVertexCount += that->fVertexCount;
fIndexCount += that->fIndexCount;
diff --git a/src/gpu/ops/GrDrawVerticesOp.h b/src/gpu/ops/GrDrawVerticesOp.h
index 38b1a47e6c..a2560af774 100644
--- a/src/gpu/ops/GrDrawVerticesOp.h
+++ b/src/gpu/ops/GrDrawVerticesOp.h
@@ -70,15 +70,16 @@ private:
SkTDArray<uint16_t> fIndices;
SkTDArray<uint32_t> fColors;
SkTDArray<SkPoint> fLocalCoords;
+ SkMatrix fViewMatrix;
};
GrPrimitiveType fPrimitiveType;
- SkMatrix fViewMatrix;
bool fVariableColor;
int fVertexCount;
int fIndexCount;
+ bool fMultipleViewMatrices = false;
+ bool fPipelineNeedsLocalCoords;
GrRenderTargetContext::ColorArrayType fColorArrayType;
-
SkSTArray<1, Mesh, true> fMeshes;
typedef GrMeshDrawOp INHERITED;