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 
name()57     const char* name() const override { return "DrawVerticesOp"; }
58 
dumpInfo()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 
primitiveType()80     GrPrimitiveType primitiveType() const { return fPrimitiveType; }
combinablePrimitive()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 
hasExplicitLocalCoordsMesh95         bool hasExplicitLocalCoords() const {
96             return fVertices->hasTexCoords() && !(kIgnoreTexCoords_VerticesFlag & fFlags);
97         }
98 
hasPerVertexColorsMesh99         bool hasPerVertexColors() const {
100             return fVertices->hasColors() && !(kIgnoreColors_VerticesFlag & fFlags);
101         }
102     };
103 
isIndexed()104     bool isIndexed() const {
105         // Consistency enforced in onCombineIfPossible.
106         return fMeshes[0].fVertices->hasIndices();
107     }
108 
requiresPerVertexColors()109     bool requiresPerVertexColors() const {
110         return SkToBool(kRequiresPerVertexColors_Flag & fFlags);
111     }
112 
anyMeshHasExplicitLocalCoords()113     bool anyMeshHasExplicitLocalCoords() const {
114         return SkToBool(kAnyMeshHasExplicitLocalCoords & fFlags);
115     }
116 
pipelineRequiresLocalCoords()117     bool pipelineRequiresLocalCoords() const {
118         return SkToBool(kPipelineRequiresLocalCoords_Flag & fFlags);
119     }
120 
hasMultipleViewMatrices()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