blob: 61696f5ea401eb92360e5895c0e51c193de8de86 [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"
joshualitt2771b562015-08-07 12:46:26 -07009#include "GrDefaultGeoProcFactory.h"
Brian Salomon742e31d2016-12-07 17:06:19 -050010#include "GrOpFlushState.h"
Brian Osman3b655982017-03-07 16:58:08 -050011#include "SkGr.h"
joshualitt2771b562015-08-07 12:46:26 -070012
Brian Salomonc2f42542017-07-12 14:11:22 -040013std::unique_ptr<GrDrawOp> GrDrawVerticesOp::Make(GrPaint&& paint,
14 sk_sp<SkVertices> vertices,
15 const SkMatrix& viewMatrix,
16 GrAAType aaType,
17 bool gammaCorrect,
18 sk_sp<GrColorSpaceXform> colorSpaceXform,
19 GrPrimitiveType* overridePrimType) {
Brian Salomon199fb872017-02-06 09:41:10 -050020 SkASSERT(vertices);
Brian Osmanae0c50c2017-05-25 16:56:34 -040021 GrPrimitiveType primType = overridePrimType ? *overridePrimType
22 : SkVertexModeToGrPrimitiveType(vertices->mode());
Brian Salomonc2f42542017-07-12 14:11:22 -040023 return Helper::FactoryHelper<GrDrawVerticesOp>(std::move(paint), std::move(vertices), primType,
24 aaType, gammaCorrect, std::move(colorSpaceXform),
25 viewMatrix);
Brian Salomon199fb872017-02-06 09:41:10 -050026}
27
Brian Salomonc2f42542017-07-12 14:11:22 -040028GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor color,
29 sk_sp<SkVertices> vertices, GrPrimitiveType primitiveType,
30 GrAAType aaType, bool gammaCorrect,
Brian Osmanfa6d8652017-05-31 09:37:27 -040031 sk_sp<GrColorSpaceXform> colorSpaceXform,
32 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;
Brian Osmanfa6d8652017-05-31 09:37:27 -040043 // GrColor is linearized (and gamut converted) during paint conversion, but SkColors need to be
44 // handled in the shader
45 fLinearizeColors = gammaCorrect && vertices->hasColors();
joshualitt2771b562015-08-07 12:46:26 -070046
bsalomond92b4192016-06-30 07:59:23 -070047 Mesh& mesh = fMeshes.push_back();
48 mesh.fColor = color;
Brian Salomon3f363692017-02-02 21:05:19 -050049 mesh.fViewMatrix = viewMatrix;
Brian Salomon199fb872017-02-06 09:41:10 -050050 mesh.fVertices = std::move(vertices);
Brian Osman8a030552017-05-23 15:03:18 -040051 mesh.fIgnoreTexCoords = false;
52 mesh.fIgnoreColors = false;
joshualitt2771b562015-08-07 12:46:26 -070053
Brian Salomon199fb872017-02-06 09:41:10 -050054 fFlags = 0;
55 if (mesh.hasPerVertexColors()) {
56 fFlags |= kRequiresPerVertexColors_Flag;
joshualitt2771b562015-08-07 12:46:26 -070057 }
Brian Salomon199fb872017-02-06 09:41:10 -050058 if (mesh.hasExplicitLocalCoords()) {
59 fFlags |= kAnyMeshHasExplicitLocalCoords;
joshualitt2771b562015-08-07 12:46:26 -070060 }
61
bsalomon88cf17d2016-07-08 06:40:56 -070062 IsZeroArea zeroArea;
Chris Dalton3809bab2017-06-13 10:55:06 -060063 if (GrIsPrimTypeLines(primitiveType) || GrPrimitiveType::kPoints == primitiveType) {
bsalomon88cf17d2016-07-08 06:40:56 -070064 zeroArea = IsZeroArea::kYes;
65 } else {
66 zeroArea = IsZeroArea::kNo;
67 }
Brian Salomon199fb872017-02-06 09:41:10 -050068 this->setTransformedBounds(mesh.fVertices->bounds(), viewMatrix, HasAABloat::kNo, zeroArea);
joshualitt2771b562015-08-07 12:46:26 -070069}
70
Brian Salomonc2f42542017-07-12 14:11:22 -040071SkString GrDrawVerticesOp::dumpInfo() const {
72 SkString string;
73 string.appendf("PrimType: %d, MeshCount %d, VCount: %d, ICount: %d\n", (int)fPrimitiveType,
74 fMeshes.count(), fVertexCount, fIndexCount);
75 string += fHelper.dumpInfo();
76 string += INHERITED::dumpInfo();
77 return string;
joshualitt2771b562015-08-07 12:46:26 -070078}
79
Brian Salomonc2f42542017-07-12 14:11:22 -040080GrDrawOp::FixedFunctionFlags GrDrawVerticesOp::fixedFunctionFlags() const {
81 return fHelper.fixedFunctionFlags();
82}
83
84GrDrawOp::RequiresDstTexture GrDrawVerticesOp::finalize(const GrCaps& caps,
Brian Osman9a725dd2017-09-20 09:53:22 -040085 const GrAppliedClip* clip,
86 GrPixelConfigIsClamped dstIsClamped) {
Brian Salomonc2f42542017-07-12 14:11:22 -040087 GrProcessorAnalysisColor gpColor;
88 if (this->requiresPerVertexColors()) {
89 gpColor.setToUnknown();
90 } else {
91 gpColor.setToConstant(fMeshes.front().fColor);
92 }
Brian Osman9a725dd2017-09-20 09:53:22 -040093 auto result = fHelper.xpRequiresDstTexture(caps, clip, dstIsClamped,
94 GrProcessorAnalysisCoverage::kNone, &gpColor);
Brian Salomonc2f42542017-07-12 14:11:22 -040095 if (gpColor.isConstant(&fMeshes.front().fColor)) {
96 fMeshes.front().fIgnoreColors = true;
Brian Salomon199fb872017-02-06 09:41:10 -050097 fFlags &= ~kRequiresPerVertexColors_Flag;
Brian Osmanae0c50c2017-05-25 16:56:34 -040098 fColorArrayType = ColorArrayType::kPremulGrColor;
Brian Osmanfa6d8652017-05-31 09:37:27 -040099 fLinearizeColors = false;
joshualitt2771b562015-08-07 12:46:26 -0700100 }
Brian Salomonc2f42542017-07-12 14:11:22 -0400101 if (!fHelper.usesLocalCoords()) {
Brian Osman8a030552017-05-23 15:03:18 -0400102 fMeshes[0].fIgnoreTexCoords = true;
Brian Salomon199fb872017-02-06 09:41:10 -0500103 fFlags &= ~kAnyMeshHasExplicitLocalCoords;
bsalomon14eaaa62015-09-24 07:01:26 -0700104 }
Brian Salomonc2f42542017-07-12 14:11:22 -0400105 return result;
joshualitt2771b562015-08-07 12:46:26 -0700106}
107
Brian Salomon199fb872017-02-06 09:41:10 -0500108sk_sp<GrGeometryProcessor> GrDrawVerticesOp::makeGP(bool* hasColorAttribute,
109 bool* hasLocalCoordAttribute) const {
110 using namespace GrDefaultGeoProcFactory;
111 LocalCoords::Type localCoordsType;
Brian Salomonc2f42542017-07-12 14:11:22 -0400112 if (fHelper.usesLocalCoords()) {
Brian Salomon199fb872017-02-06 09:41:10 -0500113 // If we have multiple view matrices we will transform the positions into device space. We
114 // must then also provide untransformed positions as local coords.
115 if (this->anyMeshHasExplicitLocalCoords() || this->hasMultipleViewMatrices()) {
116 *hasLocalCoordAttribute = true;
117 localCoordsType = LocalCoords::kHasExplicit_Type;
118 } else {
119 *hasLocalCoordAttribute = false;
120 localCoordsType = LocalCoords::kUsePosition_Type;
121 }
122 } else {
123 localCoordsType = LocalCoords::kUnused_Type;
124 *hasLocalCoordAttribute = false;
125 }
126
127 Color color(fMeshes[0].fColor);
128 if (this->requiresPerVertexColors()) {
Brian Osmanae0c50c2017-05-25 16:56:34 -0400129 color.fType = (fColorArrayType == ColorArrayType::kPremulGrColor)
Brian Salomon199fb872017-02-06 09:41:10 -0500130 ? Color::kPremulGrColorAttribute_Type
131 : Color::kUnpremulSkColorAttribute_Type;
Brian Osmanfa6d8652017-05-31 09:37:27 -0400132 color.fLinearize = fLinearizeColors;
133 color.fColorSpaceXform = fColorSpaceXform;
Brian Salomon199fb872017-02-06 09:41:10 -0500134 *hasColorAttribute = true;
135 } else {
136 *hasColorAttribute = false;
137 };
138 const SkMatrix& vm = this->hasMultipleViewMatrices() ? SkMatrix::I() : fMeshes[0].fViewMatrix;
139 return GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, vm);
140}
141
Brian Salomon91326c32017-08-09 16:02:19 -0400142void GrDrawVerticesOp::onPrepareDraws(Target* target) {
Brian Salomon199fb872017-02-06 09:41:10 -0500143 bool hasColorAttribute;
144 bool hasLocalCoordsAttribute;
145 sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute, &hasLocalCoordsAttribute);
joshualitt2771b562015-08-07 12:46:26 -0700146 size_t vertexStride = gp->getVertexStride();
147
Brian Salomon199fb872017-02-06 09:41:10 -0500148 SkASSERT(vertexStride == sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) +
149 (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0));
joshualitt2771b562015-08-07 12:46:26 -0700150
bsalomond92b4192016-06-30 07:59:23 -0700151 int instanceCount = fMeshes.count();
joshualitt2771b562015-08-07 12:46:26 -0700152
cdalton397536c2016-03-25 12:15:03 -0700153 const GrBuffer* vertexBuffer;
joshualitt2771b562015-08-07 12:46:26 -0700154 int firstVertex;
155
bsalomon14eaaa62015-09-24 07:01:26 -0700156 void* verts = target->makeVertexSpace(vertexStride, fVertexCount, &vertexBuffer, &firstVertex);
joshualitt2771b562015-08-07 12:46:26 -0700157
158 if (!verts) {
159 SkDebugf("Could not allocate vertices\n");
160 return;
161 }
162
cdalton397536c2016-03-25 12:15:03 -0700163 const GrBuffer* indexBuffer = nullptr;
joshualitt2771b562015-08-07 12:46:26 -0700164 int firstIndex = 0;
165
halcanary96fcdcc2015-08-27 07:41:13 -0700166 uint16_t* indices = nullptr;
Brian Salomon199fb872017-02-06 09:41:10 -0500167 if (this->isIndexed()) {
bsalomon14eaaa62015-09-24 07:01:26 -0700168 indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex);
joshualitt2771b562015-08-07 12:46:26 -0700169
170 if (!indices) {
171 SkDebugf("Could not allocate indices\n");
172 return;
173 }
174 }
175
joshualitt2771b562015-08-07 12:46:26 -0700176 int vertexOffset = 0;
Brian Salomonfab30a32017-02-06 19:06:22 -0500177 // We have a fast case below for uploading the vertex data when the matrix is translate
178 // only and there are colors but not local coords.
179 bool fastAttrs = hasColorAttribute && !hasLocalCoordsAttribute;
joshualitt2771b562015-08-07 12:46:26 -0700180 for (int i = 0; i < instanceCount; i++) {
bsalomond92b4192016-06-30 07:59:23 -0700181 const Mesh& mesh = fMeshes[i];
bsalomon14eaaa62015-09-24 07:01:26 -0700182 if (indices) {
Brian Salomon199fb872017-02-06 09:41:10 -0500183 int indexCount = mesh.fVertices->indexCount();
Brian Salomonfab30a32017-02-06 19:06:22 -0500184 for (int j = 0; j < indexCount; ++j) {
185 *indices++ = mesh.fVertices->indices()[j] + vertexOffset;
joshualitt2771b562015-08-07 12:46:26 -0700186 }
187 }
Brian Salomon199fb872017-02-06 09:41:10 -0500188 int vertexCount = mesh.fVertices->vertexCount();
189 const SkPoint* positions = mesh.fVertices->positions();
190 const SkColor* colors = mesh.fVertices->colors();
191 const SkPoint* localCoords = mesh.fVertices->texCoords();
Brian Salomonfab30a32017-02-06 19:06:22 -0500192 bool fastMesh = (!this->hasMultipleViewMatrices() ||
193 mesh.fViewMatrix.getType() <= SkMatrix::kTranslate_Mask) &&
194 mesh.hasPerVertexColors();
195 if (fastAttrs && fastMesh) {
196 struct V {
197 SkPoint fPos;
198 uint32_t fColor;
199 };
200 SkASSERT(sizeof(V) == vertexStride);
201 V* v = (V*)verts;
202 Sk2f t(0, 0);
Brian Salomon199fb872017-02-06 09:41:10 -0500203 if (this->hasMultipleViewMatrices()) {
Brian Salomonfab30a32017-02-06 19:06:22 -0500204 t = Sk2f(mesh.fViewMatrix.getTranslateX(), mesh.fViewMatrix.getTranslateY());
joshualitt2771b562015-08-07 12:46:26 -0700205 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500206 for (int j = 0; j < vertexCount; ++j) {
207 Sk2f p = Sk2f::Load(positions++) + t;
208 p.store(&v[j].fPos);
209 v[j].fColor = colors[j];
210 }
211 verts = v + vertexCount;
212 } else {
213 static constexpr size_t kColorOffset = sizeof(SkPoint);
214 size_t localCoordOffset =
215 hasColorAttribute ? kColorOffset + sizeof(uint32_t) : kColorOffset;
216
217 for (int j = 0; j < vertexCount; ++j) {
218 if (this->hasMultipleViewMatrices()) {
219 mesh.fViewMatrix.mapPoints(((SkPoint*)verts), &positions[j], 1);
Brian Salomon3f363692017-02-02 21:05:19 -0500220 } else {
Brian Salomonfab30a32017-02-06 19:06:22 -0500221 *((SkPoint*)verts) = positions[j];
Brian Salomon199fb872017-02-06 09:41:10 -0500222 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500223 if (hasColorAttribute) {
224 if (mesh.hasPerVertexColors()) {
225 *(uint32_t*)((intptr_t)verts + kColorOffset) = colors[j];
226 } else {
227 *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColor;
228 }
Brian Salomon3f363692017-02-02 21:05:19 -0500229 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500230 if (hasLocalCoordsAttribute) {
231 if (mesh.hasExplicitLocalCoords()) {
232 *(SkPoint*)((intptr_t)verts + localCoordOffset) = localCoords[j];
233 } else {
234 *(SkPoint*)((intptr_t)verts + localCoordOffset) = positions[j];
235 }
236 }
237 verts = (void*)((intptr_t)verts + vertexStride);
joshualitt2771b562015-08-07 12:46:26 -0700238 }
joshualitt2771b562015-08-07 12:46:26 -0700239 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500240 vertexOffset += vertexCount;
joshualitt2771b562015-08-07 12:46:26 -0700241 }
242
Chris Daltonbca46e22017-05-15 11:03:26 -0600243 GrMesh mesh(this->primitiveType());
Chris Dalton114a3c02017-05-26 15:17:19 -0600244 if (!indices) {
Chris Dalton1d616352017-05-31 12:51:23 -0600245 mesh.setNonIndexedNonInstanced(fVertexCount);
Chris Dalton114a3c02017-05-26 15:17:19 -0600246 } else {
247 mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1);
joshualitt2771b562015-08-07 12:46:26 -0700248 }
Chris Dalton114a3c02017-05-26 15:17:19 -0600249 mesh.setVertexData(vertexBuffer, firstVertex);
Brian Salomonc2f42542017-07-12 14:11:22 -0400250 target->draw(gp.get(), fHelper.makePipeline(target), mesh);
joshualitt2771b562015-08-07 12:46:26 -0700251}
252
Brian Salomonfc527d22016-12-14 21:07:01 -0500253bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
254 GrDrawVerticesOp* that = t->cast<GrDrawVerticesOp>();
bsalomonabd30f52015-08-13 13:34:48 -0700255
Brian Salomonc2f42542017-07-12 14:11:22 -0400256 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
joshualitt2771b562015-08-07 12:46:26 -0700257 return false;
258 }
259
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500260 if (!this->combinablePrimitive() || this->primitiveType() != that->primitiveType()) {
joshualitt2771b562015-08-07 12:46:26 -0700261 return false;
262 }
263
Mike Reedaa9e3322017-03-16 14:38:48 -0400264 if (fMeshes[0].fVertices->hasIndices() != that->fMeshes[0].fVertices->hasIndices()) {
joshualitt2771b562015-08-07 12:46:26 -0700265 return false;
266 }
267
Brian Salomon3de0aee2017-01-29 09:34:17 -0500268 if (fColorArrayType != that->fColorArrayType) {
269 return false;
270 }
271
Brian Osmanfa6d8652017-05-31 09:37:27 -0400272 if (fLinearizeColors != that->fLinearizeColors) {
273 return false;
274 }
275
Brian Salomon199fb872017-02-06 09:41:10 -0500276 if (fVertexCount + that->fVertexCount > SK_MaxU16) {
Brian Salomon3f363692017-02-02 21:05:19 -0500277 return false;
278 }
279
Brian Osmanfa6d8652017-05-31 09:37:27 -0400280 // NOTE: For SkColor vertex colors, the source color space is always sRGB, and the destination
281 // gamut is determined by the render target context. A mis-match should be impossible.
282 SkASSERT(GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get()));
283
Brian Salomon199fb872017-02-06 09:41:10 -0500284 // If either op required explicit local coords or per-vertex colors the combined mesh does. Same
285 // with multiple view matrices.
286 fFlags |= that->fFlags;
joshualitt2771b562015-08-07 12:46:26 -0700287
Brian Salomon199fb872017-02-06 09:41:10 -0500288 if (!this->requiresPerVertexColors() && this->fMeshes[0].fColor != that->fMeshes[0].fColor) {
289 fFlags |= kRequiresPerVertexColors_Flag;
290 }
Brian Salomon3f363692017-02-02 21:05:19 -0500291 // Check whether we are about to acquire a mesh with a different view matrix.
Brian Salomon199fb872017-02-06 09:41:10 -0500292 if (!this->hasMultipleViewMatrices() &&
293 !this->fMeshes[0].fViewMatrix.cheapEqualTo(that->fMeshes[0].fViewMatrix)) {
294 fFlags |= kHasMultipleViewMatrices_Flag;
Brian Salomon3f363692017-02-02 21:05:19 -0500295 }
296
bsalomond92b4192016-06-30 07:59:23 -0700297 fMeshes.push_back_n(that->fMeshes.count(), that->fMeshes.begin());
bsalomon14eaaa62015-09-24 07:01:26 -0700298 fVertexCount += that->fVertexCount;
299 fIndexCount += that->fIndexCount;
joshualitt2771b562015-08-07 12:46:26 -0700300
bsalomon88cf17d2016-07-08 06:40:56 -0700301 this->joinBounds(*that);
joshualitt2771b562015-08-07 12:46:26 -0700302 return true;
303}
304
305///////////////////////////////////////////////////////////////////////////////////////////////////
306
Hal Canary6f6961e2017-01-31 13:50:44 -0500307#if GR_TEST_UTILS
joshualitt2771b562015-08-07 12:46:26 -0700308
Brian Salomon5ec9def2016-12-20 15:34:05 -0500309#include "GrDrawOpTest.h"
joshualitt2771b562015-08-07 12:46:26 -0700310
311static uint32_t seed_vertices(GrPrimitiveType type) {
312 switch (type) {
Chris Dalton3809bab2017-06-13 10:55:06 -0600313 case GrPrimitiveType::kTriangles:
314 case GrPrimitiveType::kTriangleStrip:
315 case GrPrimitiveType::kTriangleFan:
joshualitt2771b562015-08-07 12:46:26 -0700316 return 3;
Chris Dalton3809bab2017-06-13 10:55:06 -0600317 case GrPrimitiveType::kPoints:
joshualitt2771b562015-08-07 12:46:26 -0700318 return 1;
Chris Dalton3809bab2017-06-13 10:55:06 -0600319 case GrPrimitiveType::kLines:
320 case GrPrimitiveType::kLineStrip:
joshualitt2771b562015-08-07 12:46:26 -0700321 return 2;
Chris Dalton3809bab2017-06-13 10:55:06 -0600322 case GrPrimitiveType::kLinesAdjacency:
323 return 4;
joshualitt2771b562015-08-07 12:46:26 -0700324 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400325 SK_ABORT("Incomplete switch\n");
joshualitt2771b562015-08-07 12:46:26 -0700326 return 0;
327}
328
329static uint32_t primitive_vertices(GrPrimitiveType type) {
330 switch (type) {
Chris Dalton3809bab2017-06-13 10:55:06 -0600331 case GrPrimitiveType::kTriangles:
joshualitt2771b562015-08-07 12:46:26 -0700332 return 3;
Chris Dalton3809bab2017-06-13 10:55:06 -0600333 case GrPrimitiveType::kLines:
joshualitt2771b562015-08-07 12:46:26 -0700334 return 2;
Chris Dalton3809bab2017-06-13 10:55:06 -0600335 case GrPrimitiveType::kTriangleStrip:
336 case GrPrimitiveType::kTriangleFan:
337 case GrPrimitiveType::kPoints:
338 case GrPrimitiveType::kLineStrip:
joshualitt2771b562015-08-07 12:46:26 -0700339 return 1;
Chris Dalton3809bab2017-06-13 10:55:06 -0600340 case GrPrimitiveType::kLinesAdjacency:
341 return 4;
joshualitt2771b562015-08-07 12:46:26 -0700342 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400343 SK_ABORT("Incomplete switch\n");
joshualitt2771b562015-08-07 12:46:26 -0700344 return 0;
345}
346
347static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
348 SkPoint p;
349 p.fX = random->nextRangeScalar(min, max);
350 p.fY = random->nextRangeScalar(min, max);
351 return p;
352}
353
354static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max,
Brian Salomonfc527d22016-12-14 21:07:01 -0500355 SkRandom* random, SkTArray<SkPoint>* positions,
joshualitt2771b562015-08-07 12:46:26 -0700356 SkTArray<SkPoint>* texCoords, bool hasTexCoords,
Brian Salomon3de0aee2017-01-29 09:34:17 -0500357 SkTArray<uint32_t>* colors, bool hasColors,
358 SkTArray<uint16_t>* indices, bool hasIndices) {
joshualitt2771b562015-08-07 12:46:26 -0700359 for (uint32_t v = 0; v < count; v++) {
360 positions->push_back(random_point(random, min, max));
361 if (hasTexCoords) {
362 texCoords->push_back(random_point(random, min, max));
363 }
364 if (hasColors) {
365 colors->push_back(GrRandomColor(random));
366 }
367 if (hasIndices) {
368 SkASSERT(maxVertex <= SK_MaxU16);
369 indices->push_back(random->nextULessThan((uint16_t)maxVertex));
370 }
371 }
372}
373
Brian Salomonc2f42542017-07-12 14:11:22 -0400374GR_DRAW_OP_TEST_DEFINE(GrDrawVerticesOp) {
Chris Daltonb894c2b2017-06-14 12:39:19 -0600375 GrPrimitiveType type;
376 do {
377 type = GrPrimitiveType(random->nextULessThan(kNumGrPrimitiveTypes));
378 } while (GrPrimTypeRequiresGeometryShaderSupport(type) &&
379 !context->caps()->shaderCaps()->geometryShaderSupport());
380
joshualitt2771b562015-08-07 12:46:26 -0700381 uint32_t primitiveCount = random->nextRangeU(1, 100);
382
383 // TODO make 'sensible' indexbuffers
384 SkTArray<SkPoint> positions;
385 SkTArray<SkPoint> texCoords;
Brian Salomon3de0aee2017-01-29 09:34:17 -0500386 SkTArray<uint32_t> colors;
joshualitt2771b562015-08-07 12:46:26 -0700387 SkTArray<uint16_t> indices;
388
389 bool hasTexCoords = random->nextBool();
390 bool hasIndices = random->nextBool();
391 bool hasColors = random->nextBool();
Brian Osmanfa6d8652017-05-31 09:37:27 -0400392 bool linearizeColors = random->nextBool();
joshualitt2771b562015-08-07 12:46:26 -0700393
394 uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type);
395
396 static const SkScalar kMinVertExtent = -100.f;
397 static const SkScalar kMaxVertExtent = 100.f;
Brian Salomonfc527d22016-12-14 21:07:01 -0500398 randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, random,
399 &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices,
400 hasIndices);
joshualitt2771b562015-08-07 12:46:26 -0700401
402 for (uint32_t i = 1; i < primitiveCount; i++) {
403 randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
Brian Salomonfc527d22016-12-14 21:07:01 -0500404 random, &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices,
405 hasIndices);
joshualitt2771b562015-08-07 12:46:26 -0700406 }
407
408 SkMatrix viewMatrix = GrTest::TestMatrix(random);
joshualitt2771b562015-08-07 12:46:26 -0700409
Brian Osmanfa6d8652017-05-31 09:37:27 -0400410 sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(random);
Brian Osmanae0c50c2017-05-25 16:56:34 -0400411
412 static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
413 sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, vertexCount, positions.begin(),
414 texCoords.begin(), colors.begin(),
415 hasIndices ? indices.count() : 0,
416 indices.begin());
Brian Salomonc2f42542017-07-12 14:11:22 -0400417 GrAAType aaType = GrAAType::kNone;
418 if (GrFSAAType::kUnifiedMSAA == fsaaType && random->nextBool()) {
419 aaType = GrAAType::kMSAA;
420 }
421 return GrDrawVerticesOp::Make(std::move(paint), std::move(vertices), viewMatrix, aaType,
422 linearizeColors, std::move(colorSpaceXform), &type);
joshualitt2771b562015-08-07 12:46:26 -0700423}
424
425#endif