blob: ad5aba2b2c8e255d43c0ee7ec69e627754044e14 [file] [log] [blame]
joshualitt2771b562015-08-07 12:46:26 -07001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Brian Salomonfc527d22016-12-14 21:07:01 -05008#include "GrDrawVerticesOp.h"
Brian Salomonc7fe0f72018-05-11 10:14:21 -04009#include "GrCaps.h"
joshualitt2771b562015-08-07 12:46:26 -070010#include "GrDefaultGeoProcFactory.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050011#include "GrOpFlushState.h"
Brian Osman3b655982017-03-07 16:58:08 -050012#include "SkGr.h"
joshualitt2771b562015-08-07 12:46:26 -070013
Robert Phillips7c525e62018-06-12 10:11:12 -040014std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrContext* context,
15 GrPaint&& paint,
Brian Salomonc2f42542017-07-12 14:11:22 -040016 sk_sp<SkVertices> vertices,
17 const SkMatrix& viewMatrix,
18 GrAAType aaType,
Brian Salomonc2f42542017-07-12 14:11:22 -040019 sk_sp<GrColorSpaceXform> colorSpaceXform,
20 GrPrimitiveType* overridePrimType) {
Brian Salomon199fb872017-02-06 09:41:10 -050021 SkASSERT(vertices);
Brian Osmanae0c50c2017-05-25 16:56:34 -040022 GrPrimitiveType primType = overridePrimType ? *overridePrimType
23 : SkVertexModeToGrPrimitiveType(vertices->mode());
Robert Phillips7c525e62018-06-12 10:11:12 -040024 return Helper::FactoryHelper<GrDrawVerticesOp>(context, std::move(paint), std::move(vertices),
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +000025 primType, aaType, std::move(colorSpaceXform),
26 viewMatrix);
Brian Salomon199fb872017-02-06 09:41:10 -050027}
28
Brian Salomonc2f42542017-07-12 14:11:22 -040029GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor color,
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +000030 sk_sp<SkVertices> vertices, GrPrimitiveType primitiveType,
31 GrAAType aaType, sk_sp<GrColorSpaceXform> colorSpaceXform,
Brian Osmanfa6d8652017-05-31 09:37:27 -040032 const SkMatrix& viewMatrix)
33 : INHERITED(ClassID())
Brian Salomonc2f42542017-07-12 14:11:22 -040034 , fHelper(helperArgs, aaType)
Brian Osmanfa6d8652017-05-31 09:37:27 -040035 , fPrimitiveType(primitiveType)
36 , fColorSpaceXform(std::move(colorSpaceXform)) {
Brian Salomon199fb872017-02-06 09:41:10 -050037 SkASSERT(vertices);
38
39 fVertexCount = vertices->vertexCount();
40 fIndexCount = vertices->indexCount();
Brian Osmanae0c50c2017-05-25 16:56:34 -040041 fColorArrayType = vertices->hasColors() ? ColorArrayType::kSkColor
42 : ColorArrayType::kPremulGrColor;
joshualitt2771b562015-08-07 12:46:26 -070043
bsalomond92b4192016-06-30 07:59:23 -070044 Mesh& mesh = fMeshes.push_back();
45 mesh.fColor = color;
Brian Salomon3f363692017-02-02 21:05:19 -050046 mesh.fViewMatrix = viewMatrix;
Brian Salomon199fb872017-02-06 09:41:10 -050047 mesh.fVertices = std::move(vertices);
Brian Osman8a030552017-05-23 15:03:18 -040048 mesh.fIgnoreTexCoords = false;
49 mesh.fIgnoreColors = false;
joshualitt2771b562015-08-07 12:46:26 -070050
Brian Salomon199fb872017-02-06 09:41:10 -050051 fFlags = 0;
52 if (mesh.hasPerVertexColors()) {
53 fFlags |= kRequiresPerVertexColors_Flag;
joshualitt2771b562015-08-07 12:46:26 -070054 }
Brian Salomon199fb872017-02-06 09:41:10 -050055 if (mesh.hasExplicitLocalCoords()) {
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +000056 fFlags |= kAnyMeshHasExplicitLocalCoords;
joshualitt2771b562015-08-07 12:46:26 -070057 }
58
bsalomon88cf17d2016-07-08 06:40:56 -070059 IsZeroArea zeroArea;
Chris Dalton3809bab2017-06-13 10:55:06 -060060 if (GrIsPrimTypeLines(primitiveType) || GrPrimitiveType::kPoints == primitiveType) {
bsalomon88cf17d2016-07-08 06:40:56 -070061 zeroArea = IsZeroArea::kYes;
62 } else {
63 zeroArea = IsZeroArea::kNo;
64 }
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +000065 this->setTransformedBounds(mesh.fVertices->bounds(), viewMatrix, HasAABloat::kNo, zeroArea);
joshualitt2771b562015-08-07 12:46:26 -070066}
67
Brian Salomonc2f42542017-07-12 14:11:22 -040068SkString GrDrawVerticesOp::dumpInfo() const {
69 SkString string;
70 string.appendf("PrimType: %d, MeshCount %d, VCount: %d, ICount: %d\n", (int)fPrimitiveType,
71 fMeshes.count(), fVertexCount, fIndexCount);
72 string += fHelper.dumpInfo();
73 string += INHERITED::dumpInfo();
74 return string;
joshualitt2771b562015-08-07 12:46:26 -070075}
76
Brian Salomonc2f42542017-07-12 14:11:22 -040077GrDrawOp::FixedFunctionFlags GrDrawVerticesOp::fixedFunctionFlags() const {
78 return fHelper.fixedFunctionFlags();
79}
80
81GrDrawOp::RequiresDstTexture GrDrawVerticesOp::finalize(const GrCaps& caps,
Brian Osman9a725dd2017-09-20 09:53:22 -040082 const GrAppliedClip* clip,
83 GrPixelConfigIsClamped dstIsClamped) {
Brian Salomonc2f42542017-07-12 14:11:22 -040084 GrProcessorAnalysisColor gpColor;
85 if (this->requiresPerVertexColors()) {
86 gpColor.setToUnknown();
87 } else {
88 gpColor.setToConstant(fMeshes.front().fColor);
89 }
Brian Osman9a725dd2017-09-20 09:53:22 -040090 auto result = fHelper.xpRequiresDstTexture(caps, clip, dstIsClamped,
91 GrProcessorAnalysisCoverage::kNone, &gpColor);
Brian Salomonc2f42542017-07-12 14:11:22 -040092 if (gpColor.isConstant(&fMeshes.front().fColor)) {
93 fMeshes.front().fIgnoreColors = true;
Brian Salomon199fb872017-02-06 09:41:10 -050094 fFlags &= ~kRequiresPerVertexColors_Flag;
Brian Osmanae0c50c2017-05-25 16:56:34 -040095 fColorArrayType = ColorArrayType::kPremulGrColor;
joshualitt2771b562015-08-07 12:46:26 -070096 }
Brian Salomonc2f42542017-07-12 14:11:22 -040097 if (!fHelper.usesLocalCoords()) {
Brian Osman8a030552017-05-23 15:03:18 -040098 fMeshes[0].fIgnoreTexCoords = true;
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +000099 fFlags &= ~kAnyMeshHasExplicitLocalCoords;
bsalomon14eaaa62015-09-24 07:01:26 -0700100 }
Brian Salomonc2f42542017-07-12 14:11:22 -0400101 return result;
joshualitt2771b562015-08-07 12:46:26 -0700102}
103
Brian Salomon199fb872017-02-06 09:41:10 -0500104sk_sp<GrGeometryProcessor> GrDrawVerticesOp::makeGP(bool* hasColorAttribute,
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000105 bool* hasLocalCoordAttribute) const {
Brian Salomon199fb872017-02-06 09:41:10 -0500106 using namespace GrDefaultGeoProcFactory;
107 LocalCoords::Type localCoordsType;
Brian Salomonc2f42542017-07-12 14:11:22 -0400108 if (fHelper.usesLocalCoords()) {
Brian Salomon199fb872017-02-06 09:41:10 -0500109 // If we have multiple view matrices we will transform the positions into device space. We
110 // must then also provide untransformed positions as local coords.
111 if (this->anyMeshHasExplicitLocalCoords() || this->hasMultipleViewMatrices()) {
112 *hasLocalCoordAttribute = true;
113 localCoordsType = LocalCoords::kHasExplicit_Type;
114 } else {
115 *hasLocalCoordAttribute = false;
116 localCoordsType = LocalCoords::kUsePosition_Type;
117 }
118 } else {
119 localCoordsType = LocalCoords::kUnused_Type;
120 *hasLocalCoordAttribute = false;
121 }
122
123 Color color(fMeshes[0].fColor);
124 if (this->requiresPerVertexColors()) {
Brian Osman08a50e02018-06-15 15:06:48 -0400125 if (fColorArrayType == ColorArrayType::kPremulGrColor) {
126 color.fType = Color::kPremulGrColorAttribute_Type;
127 } else {
128 color.fType = Color::kUnpremulSkColorAttribute_Type;
129 color.fColorSpaceXform = fColorSpaceXform;
130 }
Brian Salomon199fb872017-02-06 09:41:10 -0500131 *hasColorAttribute = true;
132 } else {
133 *hasColorAttribute = false;
134 };
135 const SkMatrix& vm = this->hasMultipleViewMatrices() ? SkMatrix::I() : fMeshes[0].fViewMatrix;
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000136 return GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, vm);
Brian Salomon199fb872017-02-06 09:41:10 -0500137}
138
Brian Salomon91326c32017-08-09 16:02:19 -0400139void GrDrawVerticesOp::onPrepareDraws(Target* target) {
Brian Salomon199fb872017-02-06 09:41:10 -0500140 bool hasColorAttribute;
141 bool hasLocalCoordsAttribute;
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000142 sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute, &hasLocalCoordsAttribute);
joshualitt2771b562015-08-07 12:46:26 -0700143
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000144 size_t vertexStride = sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) +
145 (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0);
Brian Salomon92be2f72018-06-19 14:33:47 -0400146 SkASSERT(vertexStride == gp->debugOnly_vertexStride());
joshualitt2771b562015-08-07 12:46:26 -0700147
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000148 int instanceCount = fMeshes.count();
149
150 const GrBuffer* vertexBuffer;
151 int firstVertex;
152
bsalomon14eaaa62015-09-24 07:01:26 -0700153 void* verts = target->makeVertexSpace(vertexStride, fVertexCount, &vertexBuffer, &firstVertex);
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000154
joshualitt2771b562015-08-07 12:46:26 -0700155 if (!verts) {
156 SkDebugf("Could not allocate vertices\n");
157 return;
158 }
159
cdalton397536c2016-03-25 12:15:03 -0700160 const GrBuffer* indexBuffer = nullptr;
joshualitt2771b562015-08-07 12:46:26 -0700161 int firstIndex = 0;
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000162
halcanary96fcdcc2015-08-27 07:41:13 -0700163 uint16_t* indices = nullptr;
Brian Salomon199fb872017-02-06 09:41:10 -0500164 if (this->isIndexed()) {
bsalomon14eaaa62015-09-24 07:01:26 -0700165 indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex);
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000166
joshualitt2771b562015-08-07 12:46:26 -0700167 if (!indices) {
168 SkDebugf("Could not allocate indices\n");
169 return;
170 }
171 }
172
joshualitt2771b562015-08-07 12:46:26 -0700173 int vertexOffset = 0;
Brian Salomonfab30a32017-02-06 19:06:22 -0500174 // We have a fast case below for uploading the vertex data when the matrix is translate
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000175 // only and there are colors but not local coords.
176 bool fastAttrs = hasColorAttribute && !hasLocalCoordsAttribute;
joshualitt2771b562015-08-07 12:46:26 -0700177 for (int i = 0; i < instanceCount; i++) {
bsalomond92b4192016-06-30 07:59:23 -0700178 const Mesh& mesh = fMeshes[i];
bsalomon14eaaa62015-09-24 07:01:26 -0700179 if (indices) {
Brian Salomon199fb872017-02-06 09:41:10 -0500180 int indexCount = mesh.fVertices->indexCount();
Brian Salomonfab30a32017-02-06 19:06:22 -0500181 for (int j = 0; j < indexCount; ++j) {
182 *indices++ = mesh.fVertices->indices()[j] + vertexOffset;
joshualitt2771b562015-08-07 12:46:26 -0700183 }
184 }
Brian Salomon199fb872017-02-06 09:41:10 -0500185 int vertexCount = mesh.fVertices->vertexCount();
186 const SkPoint* positions = mesh.fVertices->positions();
187 const SkColor* colors = mesh.fVertices->colors();
188 const SkPoint* localCoords = mesh.fVertices->texCoords();
Brian Salomonfab30a32017-02-06 19:06:22 -0500189 bool fastMesh = (!this->hasMultipleViewMatrices() ||
190 mesh.fViewMatrix.getType() <= SkMatrix::kTranslate_Mask) &&
191 mesh.hasPerVertexColors();
192 if (fastAttrs && fastMesh) {
193 struct V {
194 SkPoint fPos;
195 uint32_t fColor;
196 };
197 SkASSERT(sizeof(V) == vertexStride);
198 V* v = (V*)verts;
199 Sk2f t(0, 0);
Brian Salomon199fb872017-02-06 09:41:10 -0500200 if (this->hasMultipleViewMatrices()) {
Brian Salomonfab30a32017-02-06 19:06:22 -0500201 t = Sk2f(mesh.fViewMatrix.getTranslateX(), mesh.fViewMatrix.getTranslateY());
joshualitt2771b562015-08-07 12:46:26 -0700202 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500203 for (int j = 0; j < vertexCount; ++j) {
204 Sk2f p = Sk2f::Load(positions++) + t;
205 p.store(&v[j].fPos);
206 v[j].fColor = colors[j];
207 }
208 verts = v + vertexCount;
209 } else {
210 static constexpr size_t kColorOffset = sizeof(SkPoint);
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000211 size_t localCoordOffset =
212 hasColorAttribute ? kColorOffset + sizeof(uint32_t) : kColorOffset;
Brian Salomonfab30a32017-02-06 19:06:22 -0500213
214 for (int j = 0; j < vertexCount; ++j) {
215 if (this->hasMultipleViewMatrices()) {
216 mesh.fViewMatrix.mapPoints(((SkPoint*)verts), &positions[j], 1);
Brian Salomon3f363692017-02-02 21:05:19 -0500217 } else {
Brian Salomonfab30a32017-02-06 19:06:22 -0500218 *((SkPoint*)verts) = positions[j];
Brian Salomon199fb872017-02-06 09:41:10 -0500219 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500220 if (hasColorAttribute) {
221 if (mesh.hasPerVertexColors()) {
222 *(uint32_t*)((intptr_t)verts + kColorOffset) = colors[j];
223 } else {
224 *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColor;
225 }
Brian Salomon3f363692017-02-02 21:05:19 -0500226 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500227 if (hasLocalCoordsAttribute) {
228 if (mesh.hasExplicitLocalCoords()) {
229 *(SkPoint*)((intptr_t)verts + localCoordOffset) = localCoords[j];
230 } else {
231 *(SkPoint*)((intptr_t)verts + localCoordOffset) = positions[j];
232 }
233 }
234 verts = (void*)((intptr_t)verts + vertexStride);
joshualitt2771b562015-08-07 12:46:26 -0700235 }
joshualitt2771b562015-08-07 12:46:26 -0700236 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500237 vertexOffset += vertexCount;
joshualitt2771b562015-08-07 12:46:26 -0700238 }
239
Chris Daltonbca46e22017-05-15 11:03:26 -0600240 GrMesh mesh(this->primitiveType());
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000241 if (!indices) {
Ruiqi Maob6307342018-07-03 11:38:15 -0400242 mesh.setNonIndexedNonInstanced(fVertexCount);
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000243 } else {
244 mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1,
245 GrPrimitiveRestart::kNo);
joshualitt2771b562015-08-07 12:46:26 -0700246 }
Chris Dalton114a3c02017-05-26 15:17:19 -0600247 mesh.setVertexData(vertexBuffer, firstVertex);
Brian Salomon49348902018-06-26 09:12:38 -0400248 auto pipe = fHelper.makePipeline(target);
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000249 target->draw(gp.get(), pipe.fPipeline, pipe.fFixedDynamicState, mesh);
joshualitt2771b562015-08-07 12:46:26 -0700250}
251
Brian Salomonfc527d22016-12-14 21:07:01 -0500252bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
253 GrDrawVerticesOp* that = t->cast<GrDrawVerticesOp>();
bsalomonabd30f52015-08-13 13:34:48 -0700254
Brian Salomonc2f42542017-07-12 14:11:22 -0400255 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
joshualitt2771b562015-08-07 12:46:26 -0700256 return false;
257 }
258
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500259 if (!this->combinablePrimitive() || this->primitiveType() != that->primitiveType()) {
joshualitt2771b562015-08-07 12:46:26 -0700260 return false;
261 }
262
Mike Reedaa9e3322017-03-16 14:38:48 -0400263 if (fMeshes[0].fVertices->hasIndices() != that->fMeshes[0].fVertices->hasIndices()) {
joshualitt2771b562015-08-07 12:46:26 -0700264 return false;
265 }
266
Brian Salomon3de0aee2017-01-29 09:34:17 -0500267 if (fColorArrayType != that->fColorArrayType) {
268 return false;
269 }
270
Ben Wagner9bc36fd2018-06-15 14:23:36 -0400271 if (fVertexCount + that->fVertexCount > SkTo<int>(UINT16_MAX)) {
Brian Salomon3f363692017-02-02 21:05:19 -0500272 return false;
273 }
274
Brian Osmanfa6d8652017-05-31 09:37:27 -0400275 // NOTE: For SkColor vertex colors, the source color space is always sRGB, and the destination
276 // gamut is determined by the render target context. A mis-match should be impossible.
277 SkASSERT(GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get()));
278
Brian Salomon199fb872017-02-06 09:41:10 -0500279 // If either op required explicit local coords or per-vertex colors the combined mesh does. Same
280 // with multiple view matrices.
281 fFlags |= that->fFlags;
joshualitt2771b562015-08-07 12:46:26 -0700282
Brian Salomon199fb872017-02-06 09:41:10 -0500283 if (!this->requiresPerVertexColors() && this->fMeshes[0].fColor != that->fMeshes[0].fColor) {
284 fFlags |= kRequiresPerVertexColors_Flag;
285 }
Brian Salomon3f363692017-02-02 21:05:19 -0500286 // Check whether we are about to acquire a mesh with a different view matrix.
Brian Salomon199fb872017-02-06 09:41:10 -0500287 if (!this->hasMultipleViewMatrices() &&
288 !this->fMeshes[0].fViewMatrix.cheapEqualTo(that->fMeshes[0].fViewMatrix)) {
289 fFlags |= kHasMultipleViewMatrices_Flag;
Brian Salomon3f363692017-02-02 21:05:19 -0500290 }
291
bsalomond92b4192016-06-30 07:59:23 -0700292 fMeshes.push_back_n(that->fMeshes.count(), that->fMeshes.begin());
bsalomon14eaaa62015-09-24 07:01:26 -0700293 fVertexCount += that->fVertexCount;
294 fIndexCount += that->fIndexCount;
joshualitt2771b562015-08-07 12:46:26 -0700295
bsalomon88cf17d2016-07-08 06:40:56 -0700296 this->joinBounds(*that);
joshualitt2771b562015-08-07 12:46:26 -0700297 return true;
298}
299
300///////////////////////////////////////////////////////////////////////////////////////////////////
301
Hal Canary6f6961e2017-01-31 13:50:44 -0500302#if GR_TEST_UTILS
joshualitt2771b562015-08-07 12:46:26 -0700303
Brian Salomon5ec9def2016-12-20 15:34:05 -0500304#include "GrDrawOpTest.h"
joshualitt2771b562015-08-07 12:46:26 -0700305
306static uint32_t seed_vertices(GrPrimitiveType type) {
307 switch (type) {
Chris Dalton3809bab2017-06-13 10:55:06 -0600308 case GrPrimitiveType::kTriangles:
309 case GrPrimitiveType::kTriangleStrip:
joshualitt2771b562015-08-07 12:46:26 -0700310 return 3;
Chris Dalton3809bab2017-06-13 10:55:06 -0600311 case GrPrimitiveType::kPoints:
joshualitt2771b562015-08-07 12:46:26 -0700312 return 1;
Chris Dalton3809bab2017-06-13 10:55:06 -0600313 case GrPrimitiveType::kLines:
314 case GrPrimitiveType::kLineStrip:
joshualitt2771b562015-08-07 12:46:26 -0700315 return 2;
Chris Dalton3809bab2017-06-13 10:55:06 -0600316 case GrPrimitiveType::kLinesAdjacency:
317 return 4;
joshualitt2771b562015-08-07 12:46:26 -0700318 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400319 SK_ABORT("Incomplete switch\n");
joshualitt2771b562015-08-07 12:46:26 -0700320 return 0;
321}
322
323static uint32_t primitive_vertices(GrPrimitiveType type) {
324 switch (type) {
Chris Dalton3809bab2017-06-13 10:55:06 -0600325 case GrPrimitiveType::kTriangles:
joshualitt2771b562015-08-07 12:46:26 -0700326 return 3;
Chris Dalton3809bab2017-06-13 10:55:06 -0600327 case GrPrimitiveType::kLines:
joshualitt2771b562015-08-07 12:46:26 -0700328 return 2;
Chris Dalton3809bab2017-06-13 10:55:06 -0600329 case GrPrimitiveType::kTriangleStrip:
Chris Dalton3809bab2017-06-13 10:55:06 -0600330 case GrPrimitiveType::kPoints:
331 case GrPrimitiveType::kLineStrip:
joshualitt2771b562015-08-07 12:46:26 -0700332 return 1;
Chris Dalton3809bab2017-06-13 10:55:06 -0600333 case GrPrimitiveType::kLinesAdjacency:
334 return 4;
joshualitt2771b562015-08-07 12:46:26 -0700335 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400336 SK_ABORT("Incomplete switch\n");
joshualitt2771b562015-08-07 12:46:26 -0700337 return 0;
338}
339
340static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
341 SkPoint p;
342 p.fX = random->nextRangeScalar(min, max);
343 p.fY = random->nextRangeScalar(min, max);
344 return p;
345}
346
347static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max,
Brian Salomonfc527d22016-12-14 21:07:01 -0500348 SkRandom* random, SkTArray<SkPoint>* positions,
joshualitt2771b562015-08-07 12:46:26 -0700349 SkTArray<SkPoint>* texCoords, bool hasTexCoords,
Brian Salomon3de0aee2017-01-29 09:34:17 -0500350 SkTArray<uint32_t>* colors, bool hasColors,
351 SkTArray<uint16_t>* indices, bool hasIndices) {
joshualitt2771b562015-08-07 12:46:26 -0700352 for (uint32_t v = 0; v < count; v++) {
353 positions->push_back(random_point(random, min, max));
354 if (hasTexCoords) {
355 texCoords->push_back(random_point(random, min, max));
356 }
357 if (hasColors) {
358 colors->push_back(GrRandomColor(random));
359 }
360 if (hasIndices) {
Ben Wagnerb0897652018-06-15 15:37:57 +0000361 SkASSERT(maxVertex <= UINT16_MAX);
joshualitt2771b562015-08-07 12:46:26 -0700362 indices->push_back(random->nextULessThan((uint16_t)maxVertex));
363 }
364 }
365}
366
Brian Salomonc2f42542017-07-12 14:11:22 -0400367GR_DRAW_OP_TEST_DEFINE(GrDrawVerticesOp) {
Chris Daltonb894c2b2017-06-14 12:39:19 -0600368 GrPrimitiveType type;
369 do {
370 type = GrPrimitiveType(random->nextULessThan(kNumGrPrimitiveTypes));
371 } while (GrPrimTypeRequiresGeometryShaderSupport(type) &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400372 !context->contextPriv().caps()->shaderCaps()->geometryShaderSupport());
Chris Daltonb894c2b2017-06-14 12:39:19 -0600373
joshualitt2771b562015-08-07 12:46:26 -0700374 uint32_t primitiveCount = random->nextRangeU(1, 100);
375
376 // TODO make 'sensible' indexbuffers
377 SkTArray<SkPoint> positions;
378 SkTArray<SkPoint> texCoords;
Brian Salomon3de0aee2017-01-29 09:34:17 -0500379 SkTArray<uint32_t> colors;
joshualitt2771b562015-08-07 12:46:26 -0700380 SkTArray<uint16_t> indices;
381
382 bool hasTexCoords = random->nextBool();
383 bool hasIndices = random->nextBool();
384 bool hasColors = random->nextBool();
385
386 uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type);
387
388 static const SkScalar kMinVertExtent = -100.f;
389 static const SkScalar kMaxVertExtent = 100.f;
Brian Salomonfc527d22016-12-14 21:07:01 -0500390 randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, random,
391 &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices,
392 hasIndices);
joshualitt2771b562015-08-07 12:46:26 -0700393
394 for (uint32_t i = 1; i < primitiveCount; i++) {
395 randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
Brian Salomonfc527d22016-12-14 21:07:01 -0500396 random, &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices,
397 hasIndices);
joshualitt2771b562015-08-07 12:46:26 -0700398 }
399
400 SkMatrix viewMatrix = GrTest::TestMatrix(random);
joshualitt2771b562015-08-07 12:46:26 -0700401
Brian Osmanfa6d8652017-05-31 09:37:27 -0400402 sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(random);
Brian Osmanae0c50c2017-05-25 16:56:34 -0400403
404 static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
405 sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, vertexCount, positions.begin(),
406 texCoords.begin(), colors.begin(),
407 hasIndices ? indices.count() : 0,
408 indices.begin());
Brian Salomonc2f42542017-07-12 14:11:22 -0400409 GrAAType aaType = GrAAType::kNone;
410 if (GrFSAAType::kUnifiedMSAA == fsaaType && random->nextBool()) {
411 aaType = GrAAType::kMSAA;
412 }
Ruiqi Maoc05aa7d2018-07-03 21:18:07 +0000413 return GrDrawVerticesOp::Make(context, std::move(paint), std::move(vertices), viewMatrix,
414 aaType, std::move(colorSpaceXform), &type);
joshualitt2771b562015-08-07 12:46:26 -0700415}
416
417#endif