blob: 41033875517368b279145e0a31d816948256edf9 [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,
19 bool gammaCorrect,
20 sk_sp<GrColorSpaceXform> colorSpaceXform,
21 GrPrimitiveType* overridePrimType) {
Brian Salomon199fb872017-02-06 09:41:10 -050022 SkASSERT(vertices);
Brian Osmanae0c50c2017-05-25 16:56:34 -040023 GrPrimitiveType primType = overridePrimType ? *overridePrimType
24 : SkVertexModeToGrPrimitiveType(vertices->mode());
Robert Phillips7c525e62018-06-12 10:11:12 -040025 return Helper::FactoryHelper<GrDrawVerticesOp>(context, std::move(paint), std::move(vertices),
26 primType, aaType, gammaCorrect,
27 std::move(colorSpaceXform), viewMatrix);
Brian Salomon199fb872017-02-06 09:41:10 -050028}
29
Brian Salomonc2f42542017-07-12 14:11:22 -040030GrDrawVerticesOp::GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor color,
31 sk_sp<SkVertices> vertices, GrPrimitiveType primitiveType,
32 GrAAType aaType, bool gammaCorrect,
Brian Osmanfa6d8652017-05-31 09:37:27 -040033 sk_sp<GrColorSpaceXform> colorSpaceXform,
34 const SkMatrix& viewMatrix)
35 : INHERITED(ClassID())
Brian Salomonc2f42542017-07-12 14:11:22 -040036 , fHelper(helperArgs, aaType)
Brian Osmanfa6d8652017-05-31 09:37:27 -040037 , fPrimitiveType(primitiveType)
38 , fColorSpaceXform(std::move(colorSpaceXform)) {
Brian Salomon199fb872017-02-06 09:41:10 -050039 SkASSERT(vertices);
40
41 fVertexCount = vertices->vertexCount();
42 fIndexCount = vertices->indexCount();
Brian Osmanae0c50c2017-05-25 16:56:34 -040043 fColorArrayType = vertices->hasColors() ? ColorArrayType::kSkColor
44 : ColorArrayType::kPremulGrColor;
Brian Osmanfa6d8652017-05-31 09:37:27 -040045 // GrColor is linearized (and gamut converted) during paint conversion, but SkColors need to be
46 // handled in the shader
47 fLinearizeColors = gammaCorrect && vertices->hasColors();
joshualitt2771b562015-08-07 12:46:26 -070048
bsalomond92b4192016-06-30 07:59:23 -070049 Mesh& mesh = fMeshes.push_back();
50 mesh.fColor = color;
Brian Salomon3f363692017-02-02 21:05:19 -050051 mesh.fViewMatrix = viewMatrix;
Brian Salomon199fb872017-02-06 09:41:10 -050052 mesh.fVertices = std::move(vertices);
Brian Osman8a030552017-05-23 15:03:18 -040053 mesh.fIgnoreTexCoords = false;
54 mesh.fIgnoreColors = false;
joshualitt2771b562015-08-07 12:46:26 -070055
Brian Salomon199fb872017-02-06 09:41:10 -050056 fFlags = 0;
57 if (mesh.hasPerVertexColors()) {
58 fFlags |= kRequiresPerVertexColors_Flag;
joshualitt2771b562015-08-07 12:46:26 -070059 }
Brian Salomon199fb872017-02-06 09:41:10 -050060 if (mesh.hasExplicitLocalCoords()) {
61 fFlags |= kAnyMeshHasExplicitLocalCoords;
joshualitt2771b562015-08-07 12:46:26 -070062 }
63
bsalomon88cf17d2016-07-08 06:40:56 -070064 IsZeroArea zeroArea;
Chris Dalton3809bab2017-06-13 10:55:06 -060065 if (GrIsPrimTypeLines(primitiveType) || GrPrimitiveType::kPoints == primitiveType) {
bsalomon88cf17d2016-07-08 06:40:56 -070066 zeroArea = IsZeroArea::kYes;
67 } else {
68 zeroArea = IsZeroArea::kNo;
69 }
Brian Salomon199fb872017-02-06 09:41:10 -050070 this->setTransformedBounds(mesh.fVertices->bounds(), viewMatrix, HasAABloat::kNo, zeroArea);
joshualitt2771b562015-08-07 12:46:26 -070071}
72
Brian Salomonc2f42542017-07-12 14:11:22 -040073SkString GrDrawVerticesOp::dumpInfo() const {
74 SkString string;
75 string.appendf("PrimType: %d, MeshCount %d, VCount: %d, ICount: %d\n", (int)fPrimitiveType,
76 fMeshes.count(), fVertexCount, fIndexCount);
77 string += fHelper.dumpInfo();
78 string += INHERITED::dumpInfo();
79 return string;
joshualitt2771b562015-08-07 12:46:26 -070080}
81
Brian Salomonc2f42542017-07-12 14:11:22 -040082GrDrawOp::FixedFunctionFlags GrDrawVerticesOp::fixedFunctionFlags() const {
83 return fHelper.fixedFunctionFlags();
84}
85
86GrDrawOp::RequiresDstTexture GrDrawVerticesOp::finalize(const GrCaps& caps,
Brian Osman9a725dd2017-09-20 09:53:22 -040087 const GrAppliedClip* clip,
88 GrPixelConfigIsClamped dstIsClamped) {
Brian Salomonc2f42542017-07-12 14:11:22 -040089 GrProcessorAnalysisColor gpColor;
90 if (this->requiresPerVertexColors()) {
91 gpColor.setToUnknown();
92 } else {
93 gpColor.setToConstant(fMeshes.front().fColor);
94 }
Brian Osman9a725dd2017-09-20 09:53:22 -040095 auto result = fHelper.xpRequiresDstTexture(caps, clip, dstIsClamped,
96 GrProcessorAnalysisCoverage::kNone, &gpColor);
Brian Salomonc2f42542017-07-12 14:11:22 -040097 if (gpColor.isConstant(&fMeshes.front().fColor)) {
98 fMeshes.front().fIgnoreColors = true;
Brian Salomon199fb872017-02-06 09:41:10 -050099 fFlags &= ~kRequiresPerVertexColors_Flag;
Brian Osmanae0c50c2017-05-25 16:56:34 -0400100 fColorArrayType = ColorArrayType::kPremulGrColor;
Brian Osmanfa6d8652017-05-31 09:37:27 -0400101 fLinearizeColors = false;
joshualitt2771b562015-08-07 12:46:26 -0700102 }
Brian Salomonc2f42542017-07-12 14:11:22 -0400103 if (!fHelper.usesLocalCoords()) {
Brian Osman8a030552017-05-23 15:03:18 -0400104 fMeshes[0].fIgnoreTexCoords = true;
Brian Salomon199fb872017-02-06 09:41:10 -0500105 fFlags &= ~kAnyMeshHasExplicitLocalCoords;
bsalomon14eaaa62015-09-24 07:01:26 -0700106 }
Brian Salomonc2f42542017-07-12 14:11:22 -0400107 return result;
joshualitt2771b562015-08-07 12:46:26 -0700108}
109
Brian Salomon199fb872017-02-06 09:41:10 -0500110sk_sp<GrGeometryProcessor> GrDrawVerticesOp::makeGP(bool* hasColorAttribute,
111 bool* hasLocalCoordAttribute) const {
112 using namespace GrDefaultGeoProcFactory;
113 LocalCoords::Type localCoordsType;
Brian Salomonc2f42542017-07-12 14:11:22 -0400114 if (fHelper.usesLocalCoords()) {
Brian Salomon199fb872017-02-06 09:41:10 -0500115 // If we have multiple view matrices we will transform the positions into device space. We
116 // must then also provide untransformed positions as local coords.
117 if (this->anyMeshHasExplicitLocalCoords() || this->hasMultipleViewMatrices()) {
118 *hasLocalCoordAttribute = true;
119 localCoordsType = LocalCoords::kHasExplicit_Type;
120 } else {
121 *hasLocalCoordAttribute = false;
122 localCoordsType = LocalCoords::kUsePosition_Type;
123 }
124 } else {
125 localCoordsType = LocalCoords::kUnused_Type;
126 *hasLocalCoordAttribute = false;
127 }
128
129 Color color(fMeshes[0].fColor);
130 if (this->requiresPerVertexColors()) {
Brian Osmanae0c50c2017-05-25 16:56:34 -0400131 color.fType = (fColorArrayType == ColorArrayType::kPremulGrColor)
Brian Salomon199fb872017-02-06 09:41:10 -0500132 ? Color::kPremulGrColorAttribute_Type
133 : Color::kUnpremulSkColorAttribute_Type;
Brian Osmanfa6d8652017-05-31 09:37:27 -0400134 color.fLinearize = fLinearizeColors;
135 color.fColorSpaceXform = fColorSpaceXform;
Brian Salomon199fb872017-02-06 09:41:10 -0500136 *hasColorAttribute = true;
137 } else {
138 *hasColorAttribute = false;
139 };
140 const SkMatrix& vm = this->hasMultipleViewMatrices() ? SkMatrix::I() : fMeshes[0].fViewMatrix;
141 return GrDefaultGeoProcFactory::Make(color, Coverage::kSolid_Type, localCoordsType, vm);
142}
143
Brian Salomon91326c32017-08-09 16:02:19 -0400144void GrDrawVerticesOp::onPrepareDraws(Target* target) {
Brian Salomon199fb872017-02-06 09:41:10 -0500145 bool hasColorAttribute;
146 bool hasLocalCoordsAttribute;
147 sk_sp<GrGeometryProcessor> gp = this->makeGP(&hasColorAttribute, &hasLocalCoordsAttribute);
joshualitt2771b562015-08-07 12:46:26 -0700148 size_t vertexStride = gp->getVertexStride();
149
Brian Salomon199fb872017-02-06 09:41:10 -0500150 SkASSERT(vertexStride == sizeof(SkPoint) + (hasColorAttribute ? sizeof(uint32_t) : 0) +
151 (hasLocalCoordsAttribute ? sizeof(SkPoint) : 0));
joshualitt2771b562015-08-07 12:46:26 -0700152
bsalomond92b4192016-06-30 07:59:23 -0700153 int instanceCount = fMeshes.count();
joshualitt2771b562015-08-07 12:46:26 -0700154
cdalton397536c2016-03-25 12:15:03 -0700155 const GrBuffer* vertexBuffer;
joshualitt2771b562015-08-07 12:46:26 -0700156 int firstVertex;
157
bsalomon14eaaa62015-09-24 07:01:26 -0700158 void* verts = target->makeVertexSpace(vertexStride, fVertexCount, &vertexBuffer, &firstVertex);
joshualitt2771b562015-08-07 12:46:26 -0700159
160 if (!verts) {
161 SkDebugf("Could not allocate vertices\n");
162 return;
163 }
164
cdalton397536c2016-03-25 12:15:03 -0700165 const GrBuffer* indexBuffer = nullptr;
joshualitt2771b562015-08-07 12:46:26 -0700166 int firstIndex = 0;
167
halcanary96fcdcc2015-08-27 07:41:13 -0700168 uint16_t* indices = nullptr;
Brian Salomon199fb872017-02-06 09:41:10 -0500169 if (this->isIndexed()) {
bsalomon14eaaa62015-09-24 07:01:26 -0700170 indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex);
joshualitt2771b562015-08-07 12:46:26 -0700171
172 if (!indices) {
173 SkDebugf("Could not allocate indices\n");
174 return;
175 }
176 }
177
joshualitt2771b562015-08-07 12:46:26 -0700178 int vertexOffset = 0;
Brian Salomonfab30a32017-02-06 19:06:22 -0500179 // We have a fast case below for uploading the vertex data when the matrix is translate
180 // only and there are colors but not local coords.
181 bool fastAttrs = hasColorAttribute && !hasLocalCoordsAttribute;
joshualitt2771b562015-08-07 12:46:26 -0700182 for (int i = 0; i < instanceCount; i++) {
bsalomond92b4192016-06-30 07:59:23 -0700183 const Mesh& mesh = fMeshes[i];
bsalomon14eaaa62015-09-24 07:01:26 -0700184 if (indices) {
Brian Salomon199fb872017-02-06 09:41:10 -0500185 int indexCount = mesh.fVertices->indexCount();
Brian Salomonfab30a32017-02-06 19:06:22 -0500186 for (int j = 0; j < indexCount; ++j) {
187 *indices++ = mesh.fVertices->indices()[j] + vertexOffset;
joshualitt2771b562015-08-07 12:46:26 -0700188 }
189 }
Brian Salomon199fb872017-02-06 09:41:10 -0500190 int vertexCount = mesh.fVertices->vertexCount();
191 const SkPoint* positions = mesh.fVertices->positions();
192 const SkColor* colors = mesh.fVertices->colors();
193 const SkPoint* localCoords = mesh.fVertices->texCoords();
Brian Salomonfab30a32017-02-06 19:06:22 -0500194 bool fastMesh = (!this->hasMultipleViewMatrices() ||
195 mesh.fViewMatrix.getType() <= SkMatrix::kTranslate_Mask) &&
196 mesh.hasPerVertexColors();
197 if (fastAttrs && fastMesh) {
198 struct V {
199 SkPoint fPos;
200 uint32_t fColor;
201 };
202 SkASSERT(sizeof(V) == vertexStride);
203 V* v = (V*)verts;
204 Sk2f t(0, 0);
Brian Salomon199fb872017-02-06 09:41:10 -0500205 if (this->hasMultipleViewMatrices()) {
Brian Salomonfab30a32017-02-06 19:06:22 -0500206 t = Sk2f(mesh.fViewMatrix.getTranslateX(), mesh.fViewMatrix.getTranslateY());
joshualitt2771b562015-08-07 12:46:26 -0700207 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500208 for (int j = 0; j < vertexCount; ++j) {
209 Sk2f p = Sk2f::Load(positions++) + t;
210 p.store(&v[j].fPos);
211 v[j].fColor = colors[j];
212 }
213 verts = v + vertexCount;
214 } else {
215 static constexpr size_t kColorOffset = sizeof(SkPoint);
216 size_t localCoordOffset =
217 hasColorAttribute ? kColorOffset + sizeof(uint32_t) : kColorOffset;
218
219 for (int j = 0; j < vertexCount; ++j) {
220 if (this->hasMultipleViewMatrices()) {
221 mesh.fViewMatrix.mapPoints(((SkPoint*)verts), &positions[j], 1);
Brian Salomon3f363692017-02-02 21:05:19 -0500222 } else {
Brian Salomonfab30a32017-02-06 19:06:22 -0500223 *((SkPoint*)verts) = positions[j];
Brian Salomon199fb872017-02-06 09:41:10 -0500224 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500225 if (hasColorAttribute) {
226 if (mesh.hasPerVertexColors()) {
227 *(uint32_t*)((intptr_t)verts + kColorOffset) = colors[j];
228 } else {
229 *(uint32_t*)((intptr_t)verts + kColorOffset) = mesh.fColor;
230 }
Brian Salomon3f363692017-02-02 21:05:19 -0500231 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500232 if (hasLocalCoordsAttribute) {
233 if (mesh.hasExplicitLocalCoords()) {
234 *(SkPoint*)((intptr_t)verts + localCoordOffset) = localCoords[j];
235 } else {
236 *(SkPoint*)((intptr_t)verts + localCoordOffset) = positions[j];
237 }
238 }
239 verts = (void*)((intptr_t)verts + vertexStride);
joshualitt2771b562015-08-07 12:46:26 -0700240 }
joshualitt2771b562015-08-07 12:46:26 -0700241 }
Brian Salomonfab30a32017-02-06 19:06:22 -0500242 vertexOffset += vertexCount;
joshualitt2771b562015-08-07 12:46:26 -0700243 }
244
Chris Daltonbca46e22017-05-15 11:03:26 -0600245 GrMesh mesh(this->primitiveType());
Chris Dalton114a3c02017-05-26 15:17:19 -0600246 if (!indices) {
Chris Dalton1d616352017-05-31 12:51:23 -0600247 mesh.setNonIndexedNonInstanced(fVertexCount);
Chris Dalton114a3c02017-05-26 15:17:19 -0600248 } else {
Brian Salomon802cb312018-06-08 18:05:20 -0400249 mesh.setIndexed(indexBuffer, fIndexCount, firstIndex, 0, fVertexCount - 1,
250 GrPrimitiveRestart::kNo);
joshualitt2771b562015-08-07 12:46:26 -0700251 }
Chris Dalton114a3c02017-05-26 15:17:19 -0600252 mesh.setVertexData(vertexBuffer, firstVertex);
Brian Salomonc2f42542017-07-12 14:11:22 -0400253 target->draw(gp.get(), fHelper.makePipeline(target), mesh);
joshualitt2771b562015-08-07 12:46:26 -0700254}
255
Brian Salomonfc527d22016-12-14 21:07:01 -0500256bool GrDrawVerticesOp::onCombineIfPossible(GrOp* t, const GrCaps& caps) {
257 GrDrawVerticesOp* that = t->cast<GrDrawVerticesOp>();
bsalomonabd30f52015-08-13 13:34:48 -0700258
Brian Salomonc2f42542017-07-12 14:11:22 -0400259 if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) {
joshualitt2771b562015-08-07 12:46:26 -0700260 return false;
261 }
262
Brian Salomon53e4c3c2016-12-21 11:38:53 -0500263 if (!this->combinablePrimitive() || this->primitiveType() != that->primitiveType()) {
joshualitt2771b562015-08-07 12:46:26 -0700264 return false;
265 }
266
Mike Reedaa9e3322017-03-16 14:38:48 -0400267 if (fMeshes[0].fVertices->hasIndices() != that->fMeshes[0].fVertices->hasIndices()) {
joshualitt2771b562015-08-07 12:46:26 -0700268 return false;
269 }
270
Brian Salomon3de0aee2017-01-29 09:34:17 -0500271 if (fColorArrayType != that->fColorArrayType) {
272 return false;
273 }
274
Brian Osmanfa6d8652017-05-31 09:37:27 -0400275 if (fLinearizeColors != that->fLinearizeColors) {
276 return false;
277 }
278
Ben Wagner9bc36fd2018-06-15 14:23:36 -0400279 if (fVertexCount + that->fVertexCount > SkTo<int>(UINT16_MAX)) {
Brian Salomon3f363692017-02-02 21:05:19 -0500280 return false;
281 }
282
Brian Osmanfa6d8652017-05-31 09:37:27 -0400283 // NOTE: For SkColor vertex colors, the source color space is always sRGB, and the destination
284 // gamut is determined by the render target context. A mis-match should be impossible.
285 SkASSERT(GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get()));
286
Brian Salomon199fb872017-02-06 09:41:10 -0500287 // If either op required explicit local coords or per-vertex colors the combined mesh does. Same
288 // with multiple view matrices.
289 fFlags |= that->fFlags;
joshualitt2771b562015-08-07 12:46:26 -0700290
Brian Salomon199fb872017-02-06 09:41:10 -0500291 if (!this->requiresPerVertexColors() && this->fMeshes[0].fColor != that->fMeshes[0].fColor) {
292 fFlags |= kRequiresPerVertexColors_Flag;
293 }
Brian Salomon3f363692017-02-02 21:05:19 -0500294 // Check whether we are about to acquire a mesh with a different view matrix.
Brian Salomon199fb872017-02-06 09:41:10 -0500295 if (!this->hasMultipleViewMatrices() &&
296 !this->fMeshes[0].fViewMatrix.cheapEqualTo(that->fMeshes[0].fViewMatrix)) {
297 fFlags |= kHasMultipleViewMatrices_Flag;
Brian Salomon3f363692017-02-02 21:05:19 -0500298 }
299
bsalomond92b4192016-06-30 07:59:23 -0700300 fMeshes.push_back_n(that->fMeshes.count(), that->fMeshes.begin());
bsalomon14eaaa62015-09-24 07:01:26 -0700301 fVertexCount += that->fVertexCount;
302 fIndexCount += that->fIndexCount;
joshualitt2771b562015-08-07 12:46:26 -0700303
bsalomon88cf17d2016-07-08 06:40:56 -0700304 this->joinBounds(*that);
joshualitt2771b562015-08-07 12:46:26 -0700305 return true;
306}
307
308///////////////////////////////////////////////////////////////////////////////////////////////////
309
Hal Canary6f6961e2017-01-31 13:50:44 -0500310#if GR_TEST_UTILS
joshualitt2771b562015-08-07 12:46:26 -0700311
Brian Salomon5ec9def2016-12-20 15:34:05 -0500312#include "GrDrawOpTest.h"
joshualitt2771b562015-08-07 12:46:26 -0700313
314static uint32_t seed_vertices(GrPrimitiveType type) {
315 switch (type) {
Chris Dalton3809bab2017-06-13 10:55:06 -0600316 case GrPrimitiveType::kTriangles:
317 case GrPrimitiveType::kTriangleStrip:
joshualitt2771b562015-08-07 12:46:26 -0700318 return 3;
Chris Dalton3809bab2017-06-13 10:55:06 -0600319 case GrPrimitiveType::kPoints:
joshualitt2771b562015-08-07 12:46:26 -0700320 return 1;
Chris Dalton3809bab2017-06-13 10:55:06 -0600321 case GrPrimitiveType::kLines:
322 case GrPrimitiveType::kLineStrip:
joshualitt2771b562015-08-07 12:46:26 -0700323 return 2;
Chris Dalton3809bab2017-06-13 10:55:06 -0600324 case GrPrimitiveType::kLinesAdjacency:
325 return 4;
joshualitt2771b562015-08-07 12:46:26 -0700326 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400327 SK_ABORT("Incomplete switch\n");
joshualitt2771b562015-08-07 12:46:26 -0700328 return 0;
329}
330
331static uint32_t primitive_vertices(GrPrimitiveType type) {
332 switch (type) {
Chris Dalton3809bab2017-06-13 10:55:06 -0600333 case GrPrimitiveType::kTriangles:
joshualitt2771b562015-08-07 12:46:26 -0700334 return 3;
Chris Dalton3809bab2017-06-13 10:55:06 -0600335 case GrPrimitiveType::kLines:
joshualitt2771b562015-08-07 12:46:26 -0700336 return 2;
Chris Dalton3809bab2017-06-13 10:55:06 -0600337 case GrPrimitiveType::kTriangleStrip:
Chris Dalton3809bab2017-06-13 10:55:06 -0600338 case GrPrimitiveType::kPoints:
339 case GrPrimitiveType::kLineStrip:
joshualitt2771b562015-08-07 12:46:26 -0700340 return 1;
Chris Dalton3809bab2017-06-13 10:55:06 -0600341 case GrPrimitiveType::kLinesAdjacency:
342 return 4;
joshualitt2771b562015-08-07 12:46:26 -0700343 }
Ben Wagnerb4aab9a2017-08-16 10:53:04 -0400344 SK_ABORT("Incomplete switch\n");
joshualitt2771b562015-08-07 12:46:26 -0700345 return 0;
346}
347
348static SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
349 SkPoint p;
350 p.fX = random->nextRangeScalar(min, max);
351 p.fY = random->nextRangeScalar(min, max);
352 return p;
353}
354
355static void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max,
Brian Salomonfc527d22016-12-14 21:07:01 -0500356 SkRandom* random, SkTArray<SkPoint>* positions,
joshualitt2771b562015-08-07 12:46:26 -0700357 SkTArray<SkPoint>* texCoords, bool hasTexCoords,
Brian Salomon3de0aee2017-01-29 09:34:17 -0500358 SkTArray<uint32_t>* colors, bool hasColors,
359 SkTArray<uint16_t>* indices, bool hasIndices) {
joshualitt2771b562015-08-07 12:46:26 -0700360 for (uint32_t v = 0; v < count; v++) {
361 positions->push_back(random_point(random, min, max));
362 if (hasTexCoords) {
363 texCoords->push_back(random_point(random, min, max));
364 }
365 if (hasColors) {
366 colors->push_back(GrRandomColor(random));
367 }
368 if (hasIndices) {
Ben Wagnerb0897652018-06-15 15:37:57 +0000369 SkASSERT(maxVertex <= UINT16_MAX);
joshualitt2771b562015-08-07 12:46:26 -0700370 indices->push_back(random->nextULessThan((uint16_t)maxVertex));
371 }
372 }
373}
374
Brian Salomonc2f42542017-07-12 14:11:22 -0400375GR_DRAW_OP_TEST_DEFINE(GrDrawVerticesOp) {
Chris Daltonb894c2b2017-06-14 12:39:19 -0600376 GrPrimitiveType type;
377 do {
378 type = GrPrimitiveType(random->nextULessThan(kNumGrPrimitiveTypes));
379 } while (GrPrimTypeRequiresGeometryShaderSupport(type) &&
Brian Salomonc7fe0f72018-05-11 10:14:21 -0400380 !context->contextPriv().caps()->shaderCaps()->geometryShaderSupport());
Chris Daltonb894c2b2017-06-14 12:39:19 -0600381
joshualitt2771b562015-08-07 12:46:26 -0700382 uint32_t primitiveCount = random->nextRangeU(1, 100);
383
384 // TODO make 'sensible' indexbuffers
385 SkTArray<SkPoint> positions;
386 SkTArray<SkPoint> texCoords;
Brian Salomon3de0aee2017-01-29 09:34:17 -0500387 SkTArray<uint32_t> colors;
joshualitt2771b562015-08-07 12:46:26 -0700388 SkTArray<uint16_t> indices;
389
390 bool hasTexCoords = random->nextBool();
391 bool hasIndices = random->nextBool();
392 bool hasColors = random->nextBool();
Brian Osmanfa6d8652017-05-31 09:37:27 -0400393 bool linearizeColors = random->nextBool();
joshualitt2771b562015-08-07 12:46:26 -0700394
395 uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type);
396
397 static const SkScalar kMinVertExtent = -100.f;
398 static const SkScalar kMaxVertExtent = 100.f;
Brian Salomonfc527d22016-12-14 21:07:01 -0500399 randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, random,
400 &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices,
401 hasIndices);
joshualitt2771b562015-08-07 12:46:26 -0700402
403 for (uint32_t i = 1; i < primitiveCount; i++) {
404 randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
Brian Salomonfc527d22016-12-14 21:07:01 -0500405 random, &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices,
406 hasIndices);
joshualitt2771b562015-08-07 12:46:26 -0700407 }
408
409 SkMatrix viewMatrix = GrTest::TestMatrix(random);
joshualitt2771b562015-08-07 12:46:26 -0700410
Brian Osmanfa6d8652017-05-31 09:37:27 -0400411 sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(random);
Brian Osmanae0c50c2017-05-25 16:56:34 -0400412
413 static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode;
414 sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, vertexCount, positions.begin(),
415 texCoords.begin(), colors.begin(),
416 hasIndices ? indices.count() : 0,
417 indices.begin());
Brian Salomonc2f42542017-07-12 14:11:22 -0400418 GrAAType aaType = GrAAType::kNone;
419 if (GrFSAAType::kUnifiedMSAA == fsaaType && random->nextBool()) {
420 aaType = GrAAType::kMSAA;
421 }
Robert Phillips7c525e62018-06-12 10:11:12 -0400422 return GrDrawVerticesOp::Make(context, std::move(paint), std::move(vertices), viewMatrix,
423 aaType, linearizeColors, std::move(colorSpaceXform), &type);
joshualitt2771b562015-08-07 12:46:26 -0700424}
425
426#endif