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 "GrSimpleMeshDrawOpHelper.h"
15 #include "GrTypes.h"
16 #include "SkMatrix.h"
17 #include "SkRect.h"
18 #include "SkTDArray.h"
19 #include "SkVertices.h"
20 
21 class GrOpFlushState;
22 class SkVertices;
23 struct GrInitInvariantOutput;
24 
25 class GrDrawVerticesOp final : public GrMeshDrawOp {
26 private:
27     using Helper = GrSimpleMeshDrawOpHelper;
28 
29 public:
30     DEFINE_OP_CLASS_ID
31 
32     /**
33      * Draw a SkVertices. The GrPaint param's color is used if the vertices lack per-vertex color.
34      * If the vertices lack local coords then the vertex positions are used as local coords. The
35      * primitive type drawn is derived from the SkVertices object, unless overridePrimType is
36      * specified.
37      */
38     static std::unique_ptr<GrDrawOp> Make(GrContext* context,
39                                           GrPaint&&,
40                                           sk_sp<SkVertices>,
41                                           const SkVertices::Bone bones[],
42                                           int boneCount,
43                                           const SkMatrix& viewMatrix,
44                                           GrAAType,
45                                           sk_sp<GrColorSpaceXform>,
46                                           GrPrimitiveType* overridePrimType = nullptr);
47 
48     GrDrawVerticesOp(const Helper::MakeArgs&, const SkPMColor4f&, sk_sp<SkVertices>,
49                      const SkVertices::Bone bones[], int boneCount, GrPrimitiveType, GrAAType,
50                      sk_sp<GrColorSpaceXform>, const SkMatrix& viewMatrix);
51 
name()52     const char* name() const override { return "DrawVerticesOp"; }
53 
visitProxies(const VisitProxyFunc & func,VisitorType)54     void visitProxies(const VisitProxyFunc& func, VisitorType) const override {
55         fHelper.visitProxies(func);
56     }
57 
58 #ifdef SK_DEBUG
59     SkString dumpInfo() const override;
60 #endif
61 
62     FixedFunctionFlags fixedFunctionFlags() const override;
63 
64     GrProcessorSet::Analysis finalize(const GrCaps& caps, const GrAppliedClip* clip) override;
65 
66 private:
67     enum class ColorArrayType {
68         kPremulGrColor,
69         kSkColor,
70     };
71 
72     void onPrepareDraws(Target*) override;
73 
74     void drawVolatile(Target*);
75     void drawNonVolatile(Target*);
76 
77     void fillBuffers(bool hasColorAttribute,
78                      bool hasLocalCoordsAttribute,
79                      bool hasBoneAttribute,
80                      size_t vertexStride,
81                      void* verts,
82                      uint16_t* indices) const;
83 
84     void drawVertices(Target*,
85                       sk_sp<const GrGeometryProcessor>,
86                       sk_sp<const GrBuffer> vertexBuffer,
87                       int firstVertex,
88                       sk_sp<const GrBuffer> indexBuffer,
89                       int firstIndex);
90 
91     sk_sp<GrGeometryProcessor> makeGP(const GrShaderCaps* shaderCaps,
92                                       bool* hasColorAttribute,
93                                       bool* hasLocalCoordAttribute,
94                                       bool* hasBoneAttribute) const;
95 
primitiveType()96     GrPrimitiveType primitiveType() const { return fPrimitiveType; }
combinablePrimitive()97     bool combinablePrimitive() const {
98         return GrPrimitiveType::kTriangles == fPrimitiveType ||
99                GrPrimitiveType::kLines == fPrimitiveType ||
100                GrPrimitiveType::kPoints == fPrimitiveType;
101     }
102 
103     CombineResult onCombineIfPossible(GrOp* t, const GrCaps&) override;
104 
105     struct Mesh {
106         SkPMColor4f fColor;  // Used if this->hasPerVertexColors() is false.
107         sk_sp<SkVertices> fVertices;
108         SkMatrix fViewMatrix;
109         bool fIgnoreTexCoords;
110         bool fIgnoreColors;
111         bool fIgnoreBones;
112 
hasExplicitLocalCoordsMesh113         bool hasExplicitLocalCoords() const {
114             return fVertices->hasTexCoords() && !fIgnoreTexCoords;
115         }
116 
hasPerVertexColorsMesh117         bool hasPerVertexColors() const {
118             return fVertices->hasColors() && !fIgnoreColors;
119         }
120 
hasBonesMesh121         bool hasBones() const {
122             return fVertices->hasBones() && !fIgnoreBones;
123         }
124     };
125 
isIndexed()126     bool isIndexed() const {
127         // Consistency enforced in onCombineIfPossible.
128         return fMeshes[0].fVertices->hasIndices();
129     }
130 
requiresPerVertexColors()131     bool requiresPerVertexColors() const {
132         return SkToBool(kRequiresPerVertexColors_Flag & fFlags);
133     }
134 
anyMeshHasExplicitLocalCoords()135     bool anyMeshHasExplicitLocalCoords() const {
136         return SkToBool(kAnyMeshHasExplicitLocalCoords_Flag & fFlags);
137     }
138 
hasMultipleViewMatrices()139     bool hasMultipleViewMatrices() const {
140         return SkToBool(kHasMultipleViewMatrices_Flag & fFlags);
141     }
142 
hasBones()143     bool hasBones() const {
144         return SkToBool(kHasBones_Flag & fFlags);
145     }
146 
147     enum Flags {
148         kRequiresPerVertexColors_Flag       = 0x1,
149         kAnyMeshHasExplicitLocalCoords_Flag = 0x2,
150         kHasMultipleViewMatrices_Flag       = 0x4,
151         kHasBones_Flag                      = 0x8,
152     };
153 
154     Helper fHelper;
155     SkSTArray<1, Mesh, true> fMeshes;
156     std::vector<SkVertices::Bone> fBones; // Bone transformation matrices.
157     // GrPrimitiveType is more expressive than fVertices.mode() so it is used instead and we ignore
158     // the SkVertices mode (though fPrimitiveType may have been inferred from it).
159     GrPrimitiveType fPrimitiveType;
160     uint32_t fFlags;
161     int fVertexCount;
162     int fIndexCount;
163     ColorArrayType fColorArrayType;
164     sk_sp<GrColorSpaceXform> fColorSpaceXform;
165 
166     typedef GrMeshDrawOp INHERITED;
167 };
168 
169 #endif
170