1 /* 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 8 #ifndef GrDrawVerticesOp_DEFINED 9 #define GrDrawVerticesOp_DEFINED 10 11 #include "GrColor.h" 12 #include "GrMeshDrawOp.h" 13 #include "GrRenderTargetContext.h" 14 #include "GrTypes.h" 15 #include "SkMatrix.h" 16 #include "SkRect.h" 17 #include "SkTDArray.h" 18 #include "SkVertices.h" 19 20 class GrOpFlushState; 21 class SkVertices; 22 struct GrInitInvariantOutput; 23 24 class GrDrawVerticesOp final : public GrMeshDrawOp { 25 public: 26 DEFINE_OP_CLASS_ID 27 28 enum { 29 kIgnoreTexCoords_VerticesFlag = 1 << 0, 30 kIgnoreColors_VerticesFlag = 1 << 1, 31 }; 32 33 /** 34 * The 'color' param is used if the 'colors' array is null. 'bounds' is the bounds of the 35 * 'positions' array (in local space prior to application of 'viewMatrix'). If 'indices' is null 36 * then 'indexCnt' must be zero and vice versa. In this case the vertices are indexed as 0, 1, 37 * ..., 'vertexCount' - 1. 'localCoords' are optional and if null the vertex positions are used 38 * as local coords. 'colorArrayType' specifies whether the colors are premul GrColors or 39 * unpremul SkColors. 40 */ 41 static std::unique_ptr<GrMeshDrawOp> Make(GrColor color, GrPrimitiveType primitiveType, 42 const SkMatrix& viewMatrix, const SkPoint* positions, 43 int vertexCount, const uint16_t* indices, 44 int indexCount, const uint32_t* colors, 45 const SkPoint* localCoords, const SkRect& bounds, 46 GrRenderTargetContext::ColorArrayType colorArrayType); 47 48 /** 49 * Draw a SkVertices. The GrColor param is used if the vertices lack per-vertex color or 'flags' 50 * indicates that the per-vertex color should be ignored. The 'flags' options are those 51 * specified by SkCanvas::VerticesFlags. If the vertices lack local coords or 'flags' indicates 52 * that they should be ignored then the vertex positions are used as local coords. 53 */ 54 static std::unique_ptr<GrMeshDrawOp> Make(GrColor color, sk_sp<SkVertices>, 55 const SkMatrix& viewMatrix); 56 57 const char* name() const override { return "DrawVerticesOp"; } 58 59 SkString dumpInfo() const override { 60 SkString string; 61 string.appendf("PrimType: %d, MeshCount %d, VCount: %d, ICount: %d\n", fPrimitiveType, 62 fMeshes.count(), fVertexCount, fIndexCount); 63 string.append(DumpPipelineInfo(*this->pipeline())); 64 string.append(INHERITED::dumpInfo()); 65 return string; 66 } 67 68 private: 69 GrDrawVerticesOp(sk_sp<SkVertices>, GrPrimitiveType, GrColor, 70 GrRenderTargetContext::ColorArrayType, const SkMatrix& viewMatrix, 71 uint32_t flags = 0); 72 73 void getFragmentProcessorAnalysisInputs(GrPipelineAnalysisColor* color, 74 GrPipelineAnalysisCoverage* coverage) const override; 75 void applyPipelineOptimizations(const GrPipelineOptimizations&) override; 76 void onPrepareDraws(Target*) const override; 77 78 sk_sp<GrGeometryProcessor> makeGP(bool* hasColorAttribute, bool* hasLocalCoordAttribute) const; 79 80 GrPrimitiveType primitiveType() const { return fPrimitiveType; } 81 bool combinablePrimitive() const { 82 return kTriangles_GrPrimitiveType == fPrimitiveType || 83 kLines_GrPrimitiveType == fPrimitiveType || 84 kPoints_GrPrimitiveType == fPrimitiveType; 85 } 86 87 bool onCombineIfPossible(GrOp* t, const GrCaps&) override; 88 89 struct Mesh { 90 GrColor fColor; // Used if this->hasPerVertexColors() is false. 91 sk_sp<SkVertices> fVertices; 92 SkMatrix fViewMatrix; 93 uint32_t fFlags; 94 95 bool hasExplicitLocalCoords() const { 96 return fVertices->hasTexCoords() && !(kIgnoreTexCoords_VerticesFlag & fFlags); 97 } 98 99 bool hasPerVertexColors() const { 100 return fVertices->hasColors() && !(kIgnoreColors_VerticesFlag & fFlags); 101 } 102 }; 103 104 bool isIndexed() const { 105 // Consistency enforced in onCombineIfPossible. 106 return fMeshes[0].fVertices->hasIndices(); 107 } 108 109 bool requiresPerVertexColors() const { 110 return SkToBool(kRequiresPerVertexColors_Flag & fFlags); 111 } 112 113 bool anyMeshHasExplicitLocalCoords() const { 114 return SkToBool(kAnyMeshHasExplicitLocalCoords & fFlags); 115 } 116 117 bool pipelineRequiresLocalCoords() const { 118 return SkToBool(kPipelineRequiresLocalCoords_Flag & fFlags); 119 } 120 121 bool hasMultipleViewMatrices() const { 122 return SkToBool(kHasMultipleViewMatrices_Flag & fFlags); 123 } 124 125 enum Flags { 126 kRequiresPerVertexColors_Flag = 0x1, 127 kAnyMeshHasExplicitLocalCoords = 0x2, 128 kPipelineRequiresLocalCoords_Flag = 0x4, 129 kHasMultipleViewMatrices_Flag = 0x8 130 131 }; 132 133 // GrPrimitiveType is more expressive than fVertices.mode() so it is used instead and we ignore 134 // the SkVertices mode (though fPrimitiveType may have been inferred from it). 135 GrPrimitiveType fPrimitiveType; 136 uint32_t fFlags; 137 int fVertexCount; 138 int fIndexCount; 139 GrRenderTargetContext::ColorArrayType fColorArrayType; 140 SkSTArray<1, Mesh, true> fMeshes; 141 142 typedef GrMeshDrawOp INHERITED; 143 }; 144 145 #endif 146