1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/ops/DrawVerticesOp.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/core/SkM44.h" 11cb93a386Sopenharmony_ci#include "src/core/SkArenaAlloc.h" 12cb93a386Sopenharmony_ci#include "src/core/SkDevice.h" 13cb93a386Sopenharmony_ci#include "src/core/SkMatrixPriv.h" 14cb93a386Sopenharmony_ci#include "src/core/SkVerticesPriv.h" 15cb93a386Sopenharmony_ci#include "src/gpu/BufferWriter.h" 16cb93a386Sopenharmony_ci#include "src/gpu/GrGeometryProcessor.h" 17cb93a386Sopenharmony_ci#include "src/gpu/GrOpFlushState.h" 18cb93a386Sopenharmony_ci#include "src/gpu/GrProgramInfo.h" 19cb93a386Sopenharmony_ci#include "src/gpu/SkGr.h" 20cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h" 21cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h" 22cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVarying.h" 23cb93a386Sopenharmony_ci#include "src/gpu/glsl/GrGLSLVertexGeoBuilder.h" 24cb93a386Sopenharmony_ci#include "src/gpu/ops/GrSimpleMeshDrawOpHelper.h" 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_cinamespace skgpu::v1::DrawVerticesOp { 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_cinamespace { 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_cienum class ColorArrayType { 31cb93a386Sopenharmony_ci kUnused, 32cb93a386Sopenharmony_ci kPremulGrColor, 33cb93a386Sopenharmony_ci kSkColor, 34cb93a386Sopenharmony_ci}; 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_cienum class LocalCoordsType { 37cb93a386Sopenharmony_ci kUnused, 38cb93a386Sopenharmony_ci kUsePosition, 39cb93a386Sopenharmony_ci kExplicit, 40cb93a386Sopenharmony_ci}; 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ciclass VerticesGP : public GrGeometryProcessor { 43cb93a386Sopenharmony_cipublic: 44cb93a386Sopenharmony_ci static GrGeometryProcessor* Make(SkArenaAlloc* arena, 45cb93a386Sopenharmony_ci LocalCoordsType localCoordsType, 46cb93a386Sopenharmony_ci ColorArrayType colorArrayType, 47cb93a386Sopenharmony_ci const SkPMColor4f& color, 48cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> colorSpaceXform, 49cb93a386Sopenharmony_ci const SkMatrix& viewMatrix) { 50cb93a386Sopenharmony_ci return arena->make([&](void* ptr) { 51cb93a386Sopenharmony_ci return new (ptr) VerticesGP(localCoordsType, colorArrayType, color, 52cb93a386Sopenharmony_ci std::move(colorSpaceXform), viewMatrix); 53cb93a386Sopenharmony_ci }); 54cb93a386Sopenharmony_ci } 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci const char* name() const override { return "VerticesGP"; } 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci SkString getShaderDfxInfo() const override { 59cb93a386Sopenharmony_ci SkString format; 60cb93a386Sopenharmony_ci format.printf("ShaderDfx_VerticesGP_%d_%d_%d_%d_%d", 61cb93a386Sopenharmony_ci fColorArrayType, GrColorSpaceXform::XformKey(fColorSpaceXform.get()), 62cb93a386Sopenharmony_ci fViewMatrix.isIdentity(), fViewMatrix.isScaleTranslate(), fViewMatrix.hasPerspective()); 63cb93a386Sopenharmony_ci return format; 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci const Attribute& positionAttr() const { return fAttributes[kPositionIndex]; } 67cb93a386Sopenharmony_ci const Attribute& colorAttr() const { return fAttributes[kColorIndex]; } 68cb93a386Sopenharmony_ci const Attribute& localCoordsAttr() const { return fAttributes[kLocalCoordsIndex]; } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci void addToKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override { 71cb93a386Sopenharmony_ci uint32_t key = 0; 72cb93a386Sopenharmony_ci key |= (fColorArrayType == ColorArrayType::kSkColor) ? 0x1 : 0; 73cb93a386Sopenharmony_ci key |= ProgramImpl::ComputeMatrixKey(caps, fViewMatrix) << 20; 74cb93a386Sopenharmony_ci b->add32(key); 75cb93a386Sopenharmony_ci b->add32(GrColorSpaceXform::XformKey(fColorSpaceXform.get())); 76cb93a386Sopenharmony_ci } 77cb93a386Sopenharmony_ci 78cb93a386Sopenharmony_ci std::unique_ptr<ProgramImpl> makeProgramImpl(const GrShaderCaps&) const override { 79cb93a386Sopenharmony_ci return std::make_unique<Impl>(); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ciprivate: 83cb93a386Sopenharmony_ci class Impl : public ProgramImpl { 84cb93a386Sopenharmony_ci public: 85cb93a386Sopenharmony_ci void setData(const GrGLSLProgramDataManager& pdman, 86cb93a386Sopenharmony_ci const GrShaderCaps& shaderCaps, 87cb93a386Sopenharmony_ci const GrGeometryProcessor& geomProc) override { 88cb93a386Sopenharmony_ci const VerticesGP& vgp = geomProc.cast<VerticesGP>(); 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_ci SetTransform(pdman, shaderCaps, fViewMatrixUniform, vgp.fViewMatrix, &fViewMatrix); 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ci if (!vgp.colorAttr().isInitialized() && vgp.fColor != fColor) { 93cb93a386Sopenharmony_ci pdman.set4fv(fColorUniform, 1, vgp.fColor.vec()); 94cb93a386Sopenharmony_ci fColor = vgp.fColor; 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci fColorSpaceHelper.setData(pdman, vgp.fColorSpaceXform.get()); 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci private: 101cb93a386Sopenharmony_ci void onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) override { 102cb93a386Sopenharmony_ci const VerticesGP& gp = args.fGeomProc.cast<VerticesGP>(); 103cb93a386Sopenharmony_ci GrGLSLVertexBuilder* vertBuilder = args.fVertBuilder; 104cb93a386Sopenharmony_ci GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; 105cb93a386Sopenharmony_ci GrGLSLVaryingHandler* varyingHandler = args.fVaryingHandler; 106cb93a386Sopenharmony_ci GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ci // emit attributes 109cb93a386Sopenharmony_ci varyingHandler->emitAttributes(gp); 110cb93a386Sopenharmony_ci 111cb93a386Sopenharmony_ci fColorSpaceHelper.emitCode(uniformHandler, gp.fColorSpaceXform.get(), 112cb93a386Sopenharmony_ci kVertex_GrShaderFlag); 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci // Setup pass through color 115cb93a386Sopenharmony_ci fragBuilder->codeAppendf("half4 %s;", args.fOutputColor); 116cb93a386Sopenharmony_ci if (gp.colorAttr().isInitialized()) { 117cb93a386Sopenharmony_ci GrGLSLVarying varying(kHalf4_GrSLType); 118cb93a386Sopenharmony_ci varyingHandler->addVarying("color", &varying); 119cb93a386Sopenharmony_ci vertBuilder->codeAppendf("half4 color = %s;", gp.colorAttr().name()); 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci // For SkColor, do a red/blue swap, possible color space conversion, and premul 122cb93a386Sopenharmony_ci if (gp.fColorArrayType == ColorArrayType::kSkColor) { 123cb93a386Sopenharmony_ci vertBuilder->codeAppend("color = color.bgra;"); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci SkString xformedColor; 126cb93a386Sopenharmony_ci vertBuilder->appendColorGamutXform(&xformedColor, "color", &fColorSpaceHelper); 127cb93a386Sopenharmony_ci vertBuilder->codeAppendf("color = %s;", xformedColor.c_str()); 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci vertBuilder->codeAppend("color = half4(color.rgb * color.a, color.a);"); 130cb93a386Sopenharmony_ci } 131cb93a386Sopenharmony_ci 132cb93a386Sopenharmony_ci vertBuilder->codeAppendf("%s = color;\n", varying.vsOut()); 133cb93a386Sopenharmony_ci fragBuilder->codeAppendf("%s = %s;", args.fOutputColor, varying.fsIn()); 134cb93a386Sopenharmony_ci } else { 135cb93a386Sopenharmony_ci this->setupUniformColor(fragBuilder, uniformHandler, args.fOutputColor, 136cb93a386Sopenharmony_ci &fColorUniform); 137cb93a386Sopenharmony_ci } 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci // Setup position 140cb93a386Sopenharmony_ci WriteOutputPosition(vertBuilder, 141cb93a386Sopenharmony_ci uniformHandler, 142cb93a386Sopenharmony_ci *args.fShaderCaps, 143cb93a386Sopenharmony_ci gpArgs, 144cb93a386Sopenharmony_ci gp.positionAttr().name(), 145cb93a386Sopenharmony_ci gp.fViewMatrix, 146cb93a386Sopenharmony_ci &fViewMatrixUniform); 147cb93a386Sopenharmony_ci 148cb93a386Sopenharmony_ci // emit transforms using either explicit local coords or positions 149cb93a386Sopenharmony_ci const auto& coordsAttr = gp.localCoordsAttr().isInitialized() ? gp.localCoordsAttr() 150cb93a386Sopenharmony_ci : gp.positionAttr(); 151cb93a386Sopenharmony_ci gpArgs->fLocalCoordVar = coordsAttr.asShaderVar(); 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci fragBuilder->codeAppendf("const half4 %s = half4(1);", args.fOutputCoverage); 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_ci private: 157cb93a386Sopenharmony_ci SkMatrix fViewMatrix = SkMatrix::InvalidMatrix(); 158cb93a386Sopenharmony_ci SkPMColor4f fColor = SK_PMColor4fILLEGAL; 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ci UniformHandle fViewMatrixUniform; 161cb93a386Sopenharmony_ci UniformHandle fColorUniform; 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ci GrGLSLColorSpaceXformHelper fColorSpaceHelper; 164cb93a386Sopenharmony_ci }; 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci VerticesGP(LocalCoordsType localCoordsType, 167cb93a386Sopenharmony_ci ColorArrayType colorArrayType, 168cb93a386Sopenharmony_ci const SkPMColor4f& color, 169cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> colorSpaceXform, 170cb93a386Sopenharmony_ci const SkMatrix& viewMatrix) 171cb93a386Sopenharmony_ci : INHERITED(kVerticesGP_ClassID) 172cb93a386Sopenharmony_ci , fColorArrayType(colorArrayType) 173cb93a386Sopenharmony_ci , fColor(color) 174cb93a386Sopenharmony_ci , fViewMatrix(viewMatrix) 175cb93a386Sopenharmony_ci , fColorSpaceXform(std::move(colorSpaceXform)) { 176cb93a386Sopenharmony_ci constexpr Attribute missingAttr; 177cb93a386Sopenharmony_ci fAttributes.push_back({"position", kFloat2_GrVertexAttribType, kFloat2_GrSLType}); 178cb93a386Sopenharmony_ci fAttributes.push_back(fColorArrayType != ColorArrayType::kUnused 179cb93a386Sopenharmony_ci ? MakeColorAttribute("inColor", false) 180cb93a386Sopenharmony_ci : missingAttr); 181cb93a386Sopenharmony_ci fAttributes.push_back(localCoordsType == LocalCoordsType::kExplicit 182cb93a386Sopenharmony_ci ? Attribute{"inLocalCoord", kFloat2_GrVertexAttribType, kFloat2_GrSLType} 183cb93a386Sopenharmony_ci : missingAttr); 184cb93a386Sopenharmony_ci 185cb93a386Sopenharmony_ci this->setVertexAttributes(fAttributes.data(), fAttributes.size()); 186cb93a386Sopenharmony_ci } 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ci enum { 189cb93a386Sopenharmony_ci kPositionIndex = 0, 190cb93a386Sopenharmony_ci kColorIndex = 1, 191cb93a386Sopenharmony_ci kLocalCoordsIndex = 2, 192cb93a386Sopenharmony_ci }; 193cb93a386Sopenharmony_ci 194cb93a386Sopenharmony_ci std::vector<Attribute> fAttributes; 195cb93a386Sopenharmony_ci ColorArrayType fColorArrayType; 196cb93a386Sopenharmony_ci SkPMColor4f fColor; 197cb93a386Sopenharmony_ci SkMatrix fViewMatrix; 198cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> fColorSpaceXform; 199cb93a386Sopenharmony_ci 200cb93a386Sopenharmony_ci using INHERITED = GrGeometryProcessor; 201cb93a386Sopenharmony_ci}; 202cb93a386Sopenharmony_ci 203cb93a386Sopenharmony_ciclass DrawVerticesOpImpl final : public GrMeshDrawOp { 204cb93a386Sopenharmony_ciprivate: 205cb93a386Sopenharmony_ci using Helper = GrSimpleMeshDrawOpHelper; 206cb93a386Sopenharmony_ci 207cb93a386Sopenharmony_cipublic: 208cb93a386Sopenharmony_ci DEFINE_OP_CLASS_ID 209cb93a386Sopenharmony_ci 210cb93a386Sopenharmony_ci DrawVerticesOpImpl(GrProcessorSet*, 211cb93a386Sopenharmony_ci const SkPMColor4f&, 212cb93a386Sopenharmony_ci sk_sp<SkVertices>, 213cb93a386Sopenharmony_ci GrPrimitiveType, 214cb93a386Sopenharmony_ci GrAAType, 215cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform>, 216cb93a386Sopenharmony_ci const SkMatrixProvider&); 217cb93a386Sopenharmony_ci 218cb93a386Sopenharmony_ci const char* name() const override { return "DrawVerticesOp"; } 219cb93a386Sopenharmony_ci 220cb93a386Sopenharmony_ci void visitProxies(const GrVisitProxyFunc& func) const override { 221cb93a386Sopenharmony_ci if (fProgramInfo) { 222cb93a386Sopenharmony_ci fProgramInfo->visitFPProxies(func); 223cb93a386Sopenharmony_ci } else { 224cb93a386Sopenharmony_ci fHelper.visitProxies(func); 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci 228cb93a386Sopenharmony_ci FixedFunctionFlags fixedFunctionFlags() const override; 229cb93a386Sopenharmony_ci 230cb93a386Sopenharmony_ci GrProcessorSet::Analysis finalize(const GrCaps&, const GrAppliedClip*, GrClampType) override; 231cb93a386Sopenharmony_ci 232cb93a386Sopenharmony_ciprivate: 233cb93a386Sopenharmony_ci GrProgramInfo* programInfo() override { return fProgramInfo; } 234cb93a386Sopenharmony_ci 235cb93a386Sopenharmony_ci void onCreateProgramInfo(const GrCaps*, 236cb93a386Sopenharmony_ci SkArenaAlloc*, 237cb93a386Sopenharmony_ci const GrSurfaceProxyView& writeView, 238cb93a386Sopenharmony_ci bool usesMSAASurface, 239cb93a386Sopenharmony_ci GrAppliedClip&&, 240cb93a386Sopenharmony_ci const GrDstProxyView&, 241cb93a386Sopenharmony_ci GrXferBarrierFlags renderPassXferBarriers, 242cb93a386Sopenharmony_ci GrLoadOp colorLoadOp) override; 243cb93a386Sopenharmony_ci 244cb93a386Sopenharmony_ci void onPrepareDraws(GrMeshDrawTarget*) override; 245cb93a386Sopenharmony_ci void onExecute(GrOpFlushState*, const SkRect& chainBounds) override; 246cb93a386Sopenharmony_ci#if GR_TEST_UTILS 247cb93a386Sopenharmony_ci SkString onDumpInfo() const override; 248cb93a386Sopenharmony_ci#endif 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_ci GrGeometryProcessor* makeGP(SkArenaAlloc*); 251cb93a386Sopenharmony_ci 252cb93a386Sopenharmony_ci GrPrimitiveType primitiveType() const { return fPrimitiveType; } 253cb93a386Sopenharmony_ci bool combinablePrimitive() const { 254cb93a386Sopenharmony_ci return GrPrimitiveType::kTriangles == fPrimitiveType || 255cb93a386Sopenharmony_ci GrPrimitiveType::kLines == fPrimitiveType || 256cb93a386Sopenharmony_ci GrPrimitiveType::kPoints == fPrimitiveType; 257cb93a386Sopenharmony_ci } 258cb93a386Sopenharmony_ci 259cb93a386Sopenharmony_ci CombineResult onCombineIfPossible(GrOp* t, SkArenaAlloc*, const GrCaps&) override; 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_ci struct Mesh { 262cb93a386Sopenharmony_ci SkPMColor4f fColor; // Used if this->hasPerVertexColors() is false. 263cb93a386Sopenharmony_ci sk_sp<SkVertices> fVertices; 264cb93a386Sopenharmony_ci SkMatrix fViewMatrix; 265cb93a386Sopenharmony_ci bool fIgnoreColors; 266cb93a386Sopenharmony_ci 267cb93a386Sopenharmony_ci bool hasPerVertexColors() const { 268cb93a386Sopenharmony_ci return fVertices->priv().hasColors() && !fIgnoreColors; 269cb93a386Sopenharmony_ci } 270cb93a386Sopenharmony_ci }; 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_ci bool isIndexed() const { 273cb93a386Sopenharmony_ci // Consistency enforced in onCombineIfPossible. 274cb93a386Sopenharmony_ci return fMeshes[0].fVertices->priv().hasIndices(); 275cb93a386Sopenharmony_ci } 276cb93a386Sopenharmony_ci 277cb93a386Sopenharmony_ci bool requiresPerVertexColors() const { 278cb93a386Sopenharmony_ci return fColorArrayType != ColorArrayType::kUnused; 279cb93a386Sopenharmony_ci } 280cb93a386Sopenharmony_ci 281cb93a386Sopenharmony_ci bool requiresPerVertexLocalCoords() const { 282cb93a386Sopenharmony_ci return fLocalCoordsType == LocalCoordsType::kExplicit; 283cb93a386Sopenharmony_ci } 284cb93a386Sopenharmony_ci 285cb93a386Sopenharmony_ci size_t vertexStride() const { 286cb93a386Sopenharmony_ci return sizeof(SkPoint) + 287cb93a386Sopenharmony_ci (this->requiresPerVertexColors() ? sizeof(uint32_t) : 0) + 288cb93a386Sopenharmony_ci (this->requiresPerVertexLocalCoords() ? sizeof(SkPoint) : 0); 289cb93a386Sopenharmony_ci } 290cb93a386Sopenharmony_ci 291cb93a386Sopenharmony_ci Helper fHelper; 292cb93a386Sopenharmony_ci SkSTArray<1, Mesh, true> fMeshes; 293cb93a386Sopenharmony_ci // GrPrimitiveType is more expressive than fVertices.mode() so it is used instead and we ignore 294cb93a386Sopenharmony_ci // the SkVertices mode (though fPrimitiveType may have been inferred from it). 295cb93a386Sopenharmony_ci GrPrimitiveType fPrimitiveType; 296cb93a386Sopenharmony_ci int fVertexCount; 297cb93a386Sopenharmony_ci int fIndexCount; 298cb93a386Sopenharmony_ci bool fMultipleViewMatrices; 299cb93a386Sopenharmony_ci LocalCoordsType fLocalCoordsType; 300cb93a386Sopenharmony_ci ColorArrayType fColorArrayType; 301cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> fColorSpaceXform; 302cb93a386Sopenharmony_ci 303cb93a386Sopenharmony_ci GrSimpleMesh* fMesh = nullptr; 304cb93a386Sopenharmony_ci GrProgramInfo* fProgramInfo = nullptr; 305cb93a386Sopenharmony_ci 306cb93a386Sopenharmony_ci using INHERITED = GrMeshDrawOp; 307cb93a386Sopenharmony_ci}; 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ciDrawVerticesOpImpl::DrawVerticesOpImpl(GrProcessorSet* processorSet, 310cb93a386Sopenharmony_ci const SkPMColor4f& color, 311cb93a386Sopenharmony_ci sk_sp<SkVertices> vertices, 312cb93a386Sopenharmony_ci GrPrimitiveType primitiveType, 313cb93a386Sopenharmony_ci GrAAType aaType, 314cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> colorSpaceXform, 315cb93a386Sopenharmony_ci const SkMatrixProvider& matrixProvider) 316cb93a386Sopenharmony_ci : INHERITED(ClassID()) 317cb93a386Sopenharmony_ci , fHelper(processorSet, aaType) 318cb93a386Sopenharmony_ci , fPrimitiveType(primitiveType) 319cb93a386Sopenharmony_ci , fMultipleViewMatrices(false) 320cb93a386Sopenharmony_ci , fColorSpaceXform(std::move(colorSpaceXform)) { 321cb93a386Sopenharmony_ci SkASSERT(vertices); 322cb93a386Sopenharmony_ci 323cb93a386Sopenharmony_ci SkVerticesPriv info(vertices->priv()); 324cb93a386Sopenharmony_ci 325cb93a386Sopenharmony_ci fVertexCount = info.vertexCount(); 326cb93a386Sopenharmony_ci fIndexCount = info.indexCount(); 327cb93a386Sopenharmony_ci fColorArrayType = info.hasColors() ? ColorArrayType::kSkColor 328cb93a386Sopenharmony_ci : ColorArrayType::kUnused; 329cb93a386Sopenharmony_ci fLocalCoordsType = info.hasTexCoords() ? LocalCoordsType::kExplicit 330cb93a386Sopenharmony_ci : LocalCoordsType::kUsePosition; 331cb93a386Sopenharmony_ci 332cb93a386Sopenharmony_ci Mesh& mesh = fMeshes.push_back(); 333cb93a386Sopenharmony_ci mesh.fColor = color; 334cb93a386Sopenharmony_ci mesh.fViewMatrix = matrixProvider.localToDevice(); 335cb93a386Sopenharmony_ci mesh.fVertices = std::move(vertices); 336cb93a386Sopenharmony_ci mesh.fIgnoreColors = false; 337cb93a386Sopenharmony_ci 338cb93a386Sopenharmony_ci IsHairline zeroArea; 339cb93a386Sopenharmony_ci if (GrIsPrimTypeLines(primitiveType) || GrPrimitiveType::kPoints == primitiveType) { 340cb93a386Sopenharmony_ci zeroArea = IsHairline::kYes; 341cb93a386Sopenharmony_ci } else { 342cb93a386Sopenharmony_ci zeroArea = IsHairline::kNo; 343cb93a386Sopenharmony_ci } 344cb93a386Sopenharmony_ci 345cb93a386Sopenharmony_ci this->setTransformedBounds(mesh.fVertices->bounds(), 346cb93a386Sopenharmony_ci mesh.fViewMatrix, 347cb93a386Sopenharmony_ci HasAABloat::kNo, 348cb93a386Sopenharmony_ci zeroArea); 349cb93a386Sopenharmony_ci} 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_ci#if GR_TEST_UTILS 352cb93a386Sopenharmony_ciSkString DrawVerticesOpImpl::onDumpInfo() const { 353cb93a386Sopenharmony_ci return SkStringPrintf("PrimType: %d, MeshCount %d, VCount: %d, ICount: %d\n%s", 354cb93a386Sopenharmony_ci (int)fPrimitiveType, fMeshes.count(), fVertexCount, fIndexCount, 355cb93a386Sopenharmony_ci fHelper.dumpInfo().c_str()); 356cb93a386Sopenharmony_ci} 357cb93a386Sopenharmony_ci#endif 358cb93a386Sopenharmony_ci 359cb93a386Sopenharmony_ciGrDrawOp::FixedFunctionFlags DrawVerticesOpImpl::fixedFunctionFlags() const { 360cb93a386Sopenharmony_ci return fHelper.fixedFunctionFlags(); 361cb93a386Sopenharmony_ci} 362cb93a386Sopenharmony_ci 363cb93a386Sopenharmony_ciGrProcessorSet::Analysis DrawVerticesOpImpl::finalize(const GrCaps& caps, 364cb93a386Sopenharmony_ci const GrAppliedClip* clip, 365cb93a386Sopenharmony_ci GrClampType clampType) { 366cb93a386Sopenharmony_ci GrProcessorAnalysisColor gpColor; 367cb93a386Sopenharmony_ci if (this->requiresPerVertexColors()) { 368cb93a386Sopenharmony_ci gpColor.setToUnknown(); 369cb93a386Sopenharmony_ci } else { 370cb93a386Sopenharmony_ci gpColor.setToConstant(fMeshes.front().fColor); 371cb93a386Sopenharmony_ci } 372cb93a386Sopenharmony_ci auto result = fHelper.finalizeProcessors(caps, clip, clampType, 373cb93a386Sopenharmony_ci GrProcessorAnalysisCoverage::kNone, &gpColor); 374cb93a386Sopenharmony_ci if (gpColor.isConstant(&fMeshes.front().fColor)) { 375cb93a386Sopenharmony_ci fMeshes.front().fIgnoreColors = true; 376cb93a386Sopenharmony_ci fColorArrayType = ColorArrayType::kUnused; 377cb93a386Sopenharmony_ci } 378cb93a386Sopenharmony_ci if (!fHelper.usesLocalCoords()) { 379cb93a386Sopenharmony_ci fLocalCoordsType = LocalCoordsType::kUnused; 380cb93a386Sopenharmony_ci } 381cb93a386Sopenharmony_ci return result; 382cb93a386Sopenharmony_ci} 383cb93a386Sopenharmony_ci 384cb93a386Sopenharmony_ciGrGeometryProcessor* DrawVerticesOpImpl::makeGP(SkArenaAlloc* arena) { 385cb93a386Sopenharmony_ci const SkMatrix& vm = fMultipleViewMatrices ? SkMatrix::I() : fMeshes[0].fViewMatrix; 386cb93a386Sopenharmony_ci 387cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> csxform = 388cb93a386Sopenharmony_ci (fColorArrayType == ColorArrayType::kSkColor) ? fColorSpaceXform : nullptr; 389cb93a386Sopenharmony_ci 390cb93a386Sopenharmony_ci auto gp = VerticesGP::Make(arena, fLocalCoordsType, fColorArrayType, fMeshes[0].fColor, 391cb93a386Sopenharmony_ci std::move(csxform), vm); 392cb93a386Sopenharmony_ci SkASSERT(this->vertexStride() == gp->vertexStride()); 393cb93a386Sopenharmony_ci return gp; 394cb93a386Sopenharmony_ci} 395cb93a386Sopenharmony_ci 396cb93a386Sopenharmony_civoid DrawVerticesOpImpl::onCreateProgramInfo(const GrCaps* caps, 397cb93a386Sopenharmony_ci SkArenaAlloc* arena, 398cb93a386Sopenharmony_ci const GrSurfaceProxyView& writeView, 399cb93a386Sopenharmony_ci bool usesMSAASurface, 400cb93a386Sopenharmony_ci GrAppliedClip&& appliedClip, 401cb93a386Sopenharmony_ci const GrDstProxyView& dstProxyView, 402cb93a386Sopenharmony_ci GrXferBarrierFlags renderPassXferBarriers, 403cb93a386Sopenharmony_ci GrLoadOp colorLoadOp) { 404cb93a386Sopenharmony_ci GrGeometryProcessor* gp = this->makeGP(arena); 405cb93a386Sopenharmony_ci fProgramInfo = fHelper.createProgramInfo(caps, arena, writeView, usesMSAASurface, 406cb93a386Sopenharmony_ci std::move(appliedClip), dstProxyView, gp, 407cb93a386Sopenharmony_ci this->primitiveType(), renderPassXferBarriers, 408cb93a386Sopenharmony_ci colorLoadOp); 409cb93a386Sopenharmony_ci} 410cb93a386Sopenharmony_ci 411cb93a386Sopenharmony_civoid DrawVerticesOpImpl::onPrepareDraws(GrMeshDrawTarget* target) { 412cb93a386Sopenharmony_ci // Allocate buffers. 413cb93a386Sopenharmony_ci size_t vertexStride = this->vertexStride(); 414cb93a386Sopenharmony_ci sk_sp<const GrBuffer> vertexBuffer; 415cb93a386Sopenharmony_ci int firstVertex = 0; 416cb93a386Sopenharmony_ci VertexWriter verts{ 417cb93a386Sopenharmony_ci target->makeVertexSpace(vertexStride, fVertexCount, &vertexBuffer, &firstVertex)}; 418cb93a386Sopenharmony_ci if (!verts) { 419cb93a386Sopenharmony_ci SkDebugf("Could not allocate vertices\n"); 420cb93a386Sopenharmony_ci return; 421cb93a386Sopenharmony_ci } 422cb93a386Sopenharmony_ci 423cb93a386Sopenharmony_ci sk_sp<const GrBuffer> indexBuffer; 424cb93a386Sopenharmony_ci int firstIndex = 0; 425cb93a386Sopenharmony_ci uint16_t* indices = nullptr; 426cb93a386Sopenharmony_ci if (this->isIndexed()) { 427cb93a386Sopenharmony_ci indices = target->makeIndexSpace(fIndexCount, &indexBuffer, &firstIndex); 428cb93a386Sopenharmony_ci if (!indices) { 429cb93a386Sopenharmony_ci SkDebugf("Could not allocate indices\n"); 430cb93a386Sopenharmony_ci return; 431cb93a386Sopenharmony_ci } 432cb93a386Sopenharmony_ci } 433cb93a386Sopenharmony_ci 434cb93a386Sopenharmony_ci // Copy data into the buffers. 435cb93a386Sopenharmony_ci bool hasColorAttribute = this->requiresPerVertexColors(); 436cb93a386Sopenharmony_ci bool hasLocalCoordsAttribute = this->requiresPerVertexLocalCoords(); 437cb93a386Sopenharmony_ci int vertexOffset = 0; 438cb93a386Sopenharmony_ci 439cb93a386Sopenharmony_ci for (const auto& mesh : fMeshes) { 440cb93a386Sopenharmony_ci SkVerticesPriv info(mesh.fVertices->priv()); 441cb93a386Sopenharmony_ci 442cb93a386Sopenharmony_ci // Copy data into the index buffer. 443cb93a386Sopenharmony_ci if (indices) { 444cb93a386Sopenharmony_ci int indexCount = info.indexCount(); 445cb93a386Sopenharmony_ci for (int i = 0; i < indexCount; ++i) { 446cb93a386Sopenharmony_ci *indices++ = info.indices()[i] + vertexOffset; 447cb93a386Sopenharmony_ci } 448cb93a386Sopenharmony_ci } 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_ci // Copy data into the vertex buffer. 451cb93a386Sopenharmony_ci int vertexCount = info.vertexCount(); 452cb93a386Sopenharmony_ci const SkPoint* positions = info.positions(); 453cb93a386Sopenharmony_ci const SkColor* colors = info.colors(); 454cb93a386Sopenharmony_ci const SkPoint* localCoords = info.texCoords() ? info.texCoords() : positions; 455cb93a386Sopenharmony_ci 456cb93a386Sopenharmony_ci // TODO4F: Preserve float colors 457cb93a386Sopenharmony_ci GrColor meshColor = mesh.fColor.toBytes_RGBA(); 458cb93a386Sopenharmony_ci 459cb93a386Sopenharmony_ci SkPoint* posBase = (SkPoint*)verts.ptr(); 460cb93a386Sopenharmony_ci 461cb93a386Sopenharmony_ci for (int i = 0; i < vertexCount; ++i) { 462cb93a386Sopenharmony_ci verts << positions[i]; 463cb93a386Sopenharmony_ci if (hasColorAttribute) { 464cb93a386Sopenharmony_ci verts << (mesh.hasPerVertexColors() ? colors[i] : meshColor); 465cb93a386Sopenharmony_ci } 466cb93a386Sopenharmony_ci if (hasLocalCoordsAttribute) { 467cb93a386Sopenharmony_ci verts << localCoords[i]; 468cb93a386Sopenharmony_ci } 469cb93a386Sopenharmony_ci } 470cb93a386Sopenharmony_ci 471cb93a386Sopenharmony_ci if (fMultipleViewMatrices) { 472cb93a386Sopenharmony_ci SkASSERT(!mesh.fViewMatrix.hasPerspective()); 473cb93a386Sopenharmony_ci SkMatrixPriv::MapPointsWithStride(mesh.fViewMatrix, posBase, vertexStride, 474cb93a386Sopenharmony_ci positions, sizeof(SkPoint), vertexCount); 475cb93a386Sopenharmony_ci } 476cb93a386Sopenharmony_ci 477cb93a386Sopenharmony_ci vertexOffset += vertexCount; 478cb93a386Sopenharmony_ci } 479cb93a386Sopenharmony_ci 480cb93a386Sopenharmony_ci SkASSERT(!fMesh); 481cb93a386Sopenharmony_ci fMesh = target->allocMesh(); 482cb93a386Sopenharmony_ci if (this->isIndexed()) { 483cb93a386Sopenharmony_ci fMesh->setIndexed(std::move(indexBuffer), fIndexCount, firstIndex, 0, fVertexCount - 1, 484cb93a386Sopenharmony_ci GrPrimitiveRestart::kNo, std::move(vertexBuffer), firstVertex); 485cb93a386Sopenharmony_ci } else { 486cb93a386Sopenharmony_ci fMesh->set(std::move(vertexBuffer), fVertexCount, firstVertex); 487cb93a386Sopenharmony_ci } 488cb93a386Sopenharmony_ci} 489cb93a386Sopenharmony_ci 490cb93a386Sopenharmony_civoid DrawVerticesOpImpl::onExecute(GrOpFlushState* flushState, const SkRect& chainBounds) { 491cb93a386Sopenharmony_ci if (!fProgramInfo) { 492cb93a386Sopenharmony_ci this->createProgramInfo(flushState); 493cb93a386Sopenharmony_ci } 494cb93a386Sopenharmony_ci 495cb93a386Sopenharmony_ci if (!fProgramInfo || !fMesh) { 496cb93a386Sopenharmony_ci return; 497cb93a386Sopenharmony_ci } 498cb93a386Sopenharmony_ci 499cb93a386Sopenharmony_ci flushState->bindPipelineAndScissorClip(*fProgramInfo, chainBounds); 500cb93a386Sopenharmony_ci flushState->bindTextures(fProgramInfo->geomProc(), nullptr, fProgramInfo->pipeline()); 501cb93a386Sopenharmony_ci flushState->drawMesh(*fMesh); 502cb93a386Sopenharmony_ci} 503cb93a386Sopenharmony_ci 504cb93a386Sopenharmony_ciGrOp::CombineResult DrawVerticesOpImpl::onCombineIfPossible(GrOp* t, 505cb93a386Sopenharmony_ci SkArenaAlloc*, 506cb93a386Sopenharmony_ci const GrCaps& caps) { 507cb93a386Sopenharmony_ci auto that = t->cast<DrawVerticesOpImpl>(); 508cb93a386Sopenharmony_ci 509cb93a386Sopenharmony_ci if (!fHelper.isCompatible(that->fHelper, caps, this->bounds(), that->bounds())) { 510cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 511cb93a386Sopenharmony_ci } 512cb93a386Sopenharmony_ci 513cb93a386Sopenharmony_ci if (!this->combinablePrimitive() || this->primitiveType() != that->primitiveType()) { 514cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 515cb93a386Sopenharmony_ci } 516cb93a386Sopenharmony_ci 517cb93a386Sopenharmony_ci if (this->isIndexed() != that->isIndexed()) { 518cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 519cb93a386Sopenharmony_ci } 520cb93a386Sopenharmony_ci 521cb93a386Sopenharmony_ci if (fVertexCount + that->fVertexCount > SkTo<int>(UINT16_MAX)) { 522cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 523cb93a386Sopenharmony_ci } 524cb93a386Sopenharmony_ci 525cb93a386Sopenharmony_ci // We can't mix draws that use SkColor vertex colors with those that don't. We can mix uniform 526cb93a386Sopenharmony_ci // color draws with GrColor draws (by expanding the uniform color into vertex color). 527cb93a386Sopenharmony_ci if ((fColorArrayType == ColorArrayType::kSkColor) != 528cb93a386Sopenharmony_ci (that->fColorArrayType == ColorArrayType::kSkColor)) { 529cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 530cb93a386Sopenharmony_ci } 531cb93a386Sopenharmony_ci 532cb93a386Sopenharmony_ci // If we're acquiring a mesh with a different view matrix, or an op that needed multiple view 533cb93a386Sopenharmony_ci // matrices, we need multiple view matrices. 534cb93a386Sopenharmony_ci bool needMultipleViewMatrices = 535cb93a386Sopenharmony_ci fMultipleViewMatrices || that->fMultipleViewMatrices || 536cb93a386Sopenharmony_ci !SkMatrixPriv::CheapEqual(this->fMeshes[0].fViewMatrix, that->fMeshes[0].fViewMatrix); 537cb93a386Sopenharmony_ci 538cb93a386Sopenharmony_ci // ... but we can't enable multiple view matrices if any of them have perspective, or our other 539cb93a386Sopenharmony_ci // varyings won't be interpolated correctly. 540cb93a386Sopenharmony_ci if (needMultipleViewMatrices && (this->fMeshes[0].fViewMatrix.hasPerspective() || 541cb93a386Sopenharmony_ci that->fMeshes[0].fViewMatrix.hasPerspective())) { 542cb93a386Sopenharmony_ci return CombineResult::kCannotCombine; 543cb93a386Sopenharmony_ci } else { 544cb93a386Sopenharmony_ci fMultipleViewMatrices = needMultipleViewMatrices; 545cb93a386Sopenharmony_ci } 546cb93a386Sopenharmony_ci 547cb93a386Sopenharmony_ci // If the other op already required per-vertex colors, the combined mesh does. 548cb93a386Sopenharmony_ci if (that->fColorArrayType == ColorArrayType::kPremulGrColor) { 549cb93a386Sopenharmony_ci fColorArrayType = ColorArrayType::kPremulGrColor; 550cb93a386Sopenharmony_ci } 551cb93a386Sopenharmony_ci 552cb93a386Sopenharmony_ci // If we combine meshes with different (uniform) colors, switch to per-vertex colors. 553cb93a386Sopenharmony_ci if (fColorArrayType == ColorArrayType::kUnused) { 554cb93a386Sopenharmony_ci SkASSERT(that->fColorArrayType == ColorArrayType::kUnused); 555cb93a386Sopenharmony_ci if (this->fMeshes[0].fColor != that->fMeshes[0].fColor) { 556cb93a386Sopenharmony_ci fColorArrayType = ColorArrayType::kPremulGrColor; 557cb93a386Sopenharmony_ci } 558cb93a386Sopenharmony_ci } 559cb93a386Sopenharmony_ci 560cb93a386Sopenharmony_ci // NOTE: For SkColor vertex colors, the source color space is always sRGB, and the destination 561cb93a386Sopenharmony_ci // gamut is determined by the render target context. A mis-match should be impossible. 562cb93a386Sopenharmony_ci SkASSERT(GrColorSpaceXform::Equals(fColorSpaceXform.get(), that->fColorSpaceXform.get())); 563cb93a386Sopenharmony_ci 564cb93a386Sopenharmony_ci // If the other op already required explicit local coords the combined mesh does. 565cb93a386Sopenharmony_ci if (that->fLocalCoordsType == LocalCoordsType::kExplicit) { 566cb93a386Sopenharmony_ci fLocalCoordsType = LocalCoordsType::kExplicit; 567cb93a386Sopenharmony_ci } 568cb93a386Sopenharmony_ci 569cb93a386Sopenharmony_ci // If we were planning to use positions for local coords but now have multiple view matrices, 570cb93a386Sopenharmony_ci // switch to explicit local coords. 571cb93a386Sopenharmony_ci if (fLocalCoordsType == LocalCoordsType::kUsePosition && fMultipleViewMatrices) { 572cb93a386Sopenharmony_ci fLocalCoordsType = LocalCoordsType::kExplicit; 573cb93a386Sopenharmony_ci } 574cb93a386Sopenharmony_ci 575cb93a386Sopenharmony_ci fMeshes.push_back_n(that->fMeshes.count(), that->fMeshes.begin()); 576cb93a386Sopenharmony_ci fVertexCount += that->fVertexCount; 577cb93a386Sopenharmony_ci fIndexCount += that->fIndexCount; 578cb93a386Sopenharmony_ci 579cb93a386Sopenharmony_ci return CombineResult::kMerged; 580cb93a386Sopenharmony_ci} 581cb93a386Sopenharmony_ci 582cb93a386Sopenharmony_cistatic GrPrimitiveType SkVertexModeToGrPrimitiveType(SkVertices::VertexMode mode) { 583cb93a386Sopenharmony_ci switch (mode) { 584cb93a386Sopenharmony_ci case SkVertices::kTriangles_VertexMode: 585cb93a386Sopenharmony_ci return GrPrimitiveType::kTriangles; 586cb93a386Sopenharmony_ci case SkVertices::kTriangleStrip_VertexMode: 587cb93a386Sopenharmony_ci return GrPrimitiveType::kTriangleStrip; 588cb93a386Sopenharmony_ci case SkVertices::kTriangleFan_VertexMode: 589cb93a386Sopenharmony_ci break; 590cb93a386Sopenharmony_ci } 591cb93a386Sopenharmony_ci SK_ABORT("Invalid mode"); 592cb93a386Sopenharmony_ci} 593cb93a386Sopenharmony_ci 594cb93a386Sopenharmony_ci} // anonymous namespace 595cb93a386Sopenharmony_ci 596cb93a386Sopenharmony_ciGrOp::Owner Make(GrRecordingContext* context, 597cb93a386Sopenharmony_ci GrPaint&& paint, 598cb93a386Sopenharmony_ci sk_sp<SkVertices> vertices, 599cb93a386Sopenharmony_ci const SkMatrixProvider& matrixProvider, 600cb93a386Sopenharmony_ci GrAAType aaType, 601cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> colorSpaceXform, 602cb93a386Sopenharmony_ci GrPrimitiveType* overridePrimType) { 603cb93a386Sopenharmony_ci SkASSERT(vertices); 604cb93a386Sopenharmony_ci GrPrimitiveType primType = overridePrimType 605cb93a386Sopenharmony_ci ? *overridePrimType 606cb93a386Sopenharmony_ci : SkVertexModeToGrPrimitiveType(vertices->priv().mode()); 607cb93a386Sopenharmony_ci return GrSimpleMeshDrawOpHelper::FactoryHelper<DrawVerticesOpImpl>(context, 608cb93a386Sopenharmony_ci std::move(paint), 609cb93a386Sopenharmony_ci std::move(vertices), 610cb93a386Sopenharmony_ci primType, 611cb93a386Sopenharmony_ci aaType, 612cb93a386Sopenharmony_ci std::move(colorSpaceXform), 613cb93a386Sopenharmony_ci matrixProvider); 614cb93a386Sopenharmony_ci} 615cb93a386Sopenharmony_ci 616cb93a386Sopenharmony_ci} // namespace skgpu::v1::DrawVerticesOp 617cb93a386Sopenharmony_ci 618cb93a386Sopenharmony_ci/////////////////////////////////////////////////////////////////////////////////////////////////// 619cb93a386Sopenharmony_ci 620cb93a386Sopenharmony_ci#if GR_TEST_UTILS 621cb93a386Sopenharmony_ci 622cb93a386Sopenharmony_ci#include "src/gpu/GrDrawOpTest.h" 623cb93a386Sopenharmony_ci 624cb93a386Sopenharmony_cistatic uint32_t seed_vertices(GrPrimitiveType type) { 625cb93a386Sopenharmony_ci switch (type) { 626cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangles: 627cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangleStrip: 628cb93a386Sopenharmony_ci return 3; 629cb93a386Sopenharmony_ci case GrPrimitiveType::kPoints: 630cb93a386Sopenharmony_ci return 1; 631cb93a386Sopenharmony_ci case GrPrimitiveType::kLines: 632cb93a386Sopenharmony_ci case GrPrimitiveType::kLineStrip: 633cb93a386Sopenharmony_ci return 2; 634cb93a386Sopenharmony_ci case GrPrimitiveType::kPatches: 635cb93a386Sopenharmony_ci case GrPrimitiveType::kPath: 636cb93a386Sopenharmony_ci SkASSERT(0); 637cb93a386Sopenharmony_ci return 0; 638cb93a386Sopenharmony_ci } 639cb93a386Sopenharmony_ci SK_ABORT("Incomplete switch\n"); 640cb93a386Sopenharmony_ci} 641cb93a386Sopenharmony_ci 642cb93a386Sopenharmony_cistatic uint32_t primitive_vertices(GrPrimitiveType type) { 643cb93a386Sopenharmony_ci switch (type) { 644cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangles: 645cb93a386Sopenharmony_ci return 3; 646cb93a386Sopenharmony_ci case GrPrimitiveType::kLines: 647cb93a386Sopenharmony_ci return 2; 648cb93a386Sopenharmony_ci case GrPrimitiveType::kTriangleStrip: 649cb93a386Sopenharmony_ci case GrPrimitiveType::kPoints: 650cb93a386Sopenharmony_ci case GrPrimitiveType::kLineStrip: 651cb93a386Sopenharmony_ci return 1; 652cb93a386Sopenharmony_ci case GrPrimitiveType::kPatches: 653cb93a386Sopenharmony_ci case GrPrimitiveType::kPath: 654cb93a386Sopenharmony_ci SkASSERT(0); 655cb93a386Sopenharmony_ci return 0; 656cb93a386Sopenharmony_ci } 657cb93a386Sopenharmony_ci SK_ABORT("Incomplete switch\n"); 658cb93a386Sopenharmony_ci} 659cb93a386Sopenharmony_ci 660cb93a386Sopenharmony_cistatic SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) { 661cb93a386Sopenharmony_ci SkPoint p; 662cb93a386Sopenharmony_ci p.fX = random->nextRangeScalar(min, max); 663cb93a386Sopenharmony_ci p.fY = random->nextRangeScalar(min, max); 664cb93a386Sopenharmony_ci return p; 665cb93a386Sopenharmony_ci} 666cb93a386Sopenharmony_ci 667cb93a386Sopenharmony_cistatic void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max, 668cb93a386Sopenharmony_ci SkRandom* random, SkTArray<SkPoint>* positions, 669cb93a386Sopenharmony_ci SkTArray<SkPoint>* texCoords, bool hasTexCoords, 670cb93a386Sopenharmony_ci SkTArray<uint32_t>* colors, bool hasColors, 671cb93a386Sopenharmony_ci SkTArray<uint16_t>* indices, bool hasIndices) { 672cb93a386Sopenharmony_ci for (uint32_t v = 0; v < count; v++) { 673cb93a386Sopenharmony_ci positions->push_back(random_point(random, min, max)); 674cb93a386Sopenharmony_ci if (hasTexCoords) { 675cb93a386Sopenharmony_ci texCoords->push_back(random_point(random, min, max)); 676cb93a386Sopenharmony_ci } 677cb93a386Sopenharmony_ci if (hasColors) { 678cb93a386Sopenharmony_ci colors->push_back(GrTest::RandomColor(random)); 679cb93a386Sopenharmony_ci } 680cb93a386Sopenharmony_ci if (hasIndices) { 681cb93a386Sopenharmony_ci SkASSERT(maxVertex <= UINT16_MAX); 682cb93a386Sopenharmony_ci indices->push_back(random->nextULessThan((uint16_t)maxVertex)); 683cb93a386Sopenharmony_ci } 684cb93a386Sopenharmony_ci } 685cb93a386Sopenharmony_ci} 686cb93a386Sopenharmony_ci 687cb93a386Sopenharmony_ciGR_DRAW_OP_TEST_DEFINE(DrawVerticesOp) { 688cb93a386Sopenharmony_ci GrPrimitiveType types[] = { 689cb93a386Sopenharmony_ci GrPrimitiveType::kTriangles, 690cb93a386Sopenharmony_ci GrPrimitiveType::kTriangleStrip, 691cb93a386Sopenharmony_ci GrPrimitiveType::kPoints, 692cb93a386Sopenharmony_ci GrPrimitiveType::kLines, 693cb93a386Sopenharmony_ci GrPrimitiveType::kLineStrip 694cb93a386Sopenharmony_ci }; 695cb93a386Sopenharmony_ci auto type = types[random->nextULessThan(SK_ARRAY_COUNT(types))]; 696cb93a386Sopenharmony_ci 697cb93a386Sopenharmony_ci uint32_t primitiveCount = random->nextRangeU(1, 100); 698cb93a386Sopenharmony_ci 699cb93a386Sopenharmony_ci // TODO make 'sensible' indexbuffers 700cb93a386Sopenharmony_ci SkTArray<SkPoint> positions; 701cb93a386Sopenharmony_ci SkTArray<SkPoint> texCoords; 702cb93a386Sopenharmony_ci SkTArray<uint32_t> colors; 703cb93a386Sopenharmony_ci SkTArray<uint16_t> indices; 704cb93a386Sopenharmony_ci 705cb93a386Sopenharmony_ci bool hasTexCoords = random->nextBool(); 706cb93a386Sopenharmony_ci bool hasIndices = random->nextBool(); 707cb93a386Sopenharmony_ci bool hasColors = random->nextBool(); 708cb93a386Sopenharmony_ci 709cb93a386Sopenharmony_ci uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type); 710cb93a386Sopenharmony_ci 711cb93a386Sopenharmony_ci static const SkScalar kMinVertExtent = -100.f; 712cb93a386Sopenharmony_ci static const SkScalar kMaxVertExtent = 100.f; 713cb93a386Sopenharmony_ci randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, random, 714cb93a386Sopenharmony_ci &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices, 715cb93a386Sopenharmony_ci hasIndices); 716cb93a386Sopenharmony_ci 717cb93a386Sopenharmony_ci for (uint32_t i = 1; i < primitiveCount; i++) { 718cb93a386Sopenharmony_ci randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent, 719cb93a386Sopenharmony_ci random, &positions, &texCoords, hasTexCoords, &colors, hasColors, &indices, 720cb93a386Sopenharmony_ci hasIndices); 721cb93a386Sopenharmony_ci } 722cb93a386Sopenharmony_ci 723cb93a386Sopenharmony_ci SkSimpleMatrixProvider matrixProvider(GrTest::TestMatrix(random)); 724cb93a386Sopenharmony_ci 725cb93a386Sopenharmony_ci sk_sp<GrColorSpaceXform> colorSpaceXform = GrTest::TestColorXform(random); 726cb93a386Sopenharmony_ci 727cb93a386Sopenharmony_ci static constexpr SkVertices::VertexMode kIgnoredMode = SkVertices::kTriangles_VertexMode; 728cb93a386Sopenharmony_ci sk_sp<SkVertices> vertices = SkVertices::MakeCopy(kIgnoredMode, vertexCount, positions.begin(), 729cb93a386Sopenharmony_ci texCoords.begin(), colors.begin(), 730cb93a386Sopenharmony_ci hasIndices ? indices.count() : 0, 731cb93a386Sopenharmony_ci indices.begin()); 732cb93a386Sopenharmony_ci GrAAType aaType = GrAAType::kNone; 733cb93a386Sopenharmony_ci if (numSamples > 1 && random->nextBool()) { 734cb93a386Sopenharmony_ci aaType = GrAAType::kMSAA; 735cb93a386Sopenharmony_ci } 736cb93a386Sopenharmony_ci return skgpu::v1::DrawVerticesOp::Make(context, 737cb93a386Sopenharmony_ci std::move(paint), 738cb93a386Sopenharmony_ci std::move(vertices), 739cb93a386Sopenharmony_ci matrixProvider, 740cb93a386Sopenharmony_ci aaType, 741cb93a386Sopenharmony_ci std::move(colorSpaceXform), 742cb93a386Sopenharmony_ci &type); 743cb93a386Sopenharmony_ci} 744cb93a386Sopenharmony_ci 745cb93a386Sopenharmony_ci#endif 746