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
21class GrOpFlushState;
22class SkVertices;
23struct GrInitInvariantOutput;
24
25class GrDrawVerticesOp final : public GrMeshDrawOp {
26private:
27    using Helper = GrSimpleMeshDrawOpHelper;
28
29public:
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. If gammaCorrect is true, the vertex colors will be linearized in the shader to get
37     * correct rendering.
38     */
39    static std::unique_ptr<GrDrawOp> Make(GrPaint&&, sk_sp<SkVertices>, const SkMatrix& viewMatrix,
40                                          GrAAType, bool gammaCorrect, sk_sp<GrColorSpaceXform>,
41                                          GrPrimitiveType* overridePrimType = nullptr);
42
43    GrDrawVerticesOp(const Helper::MakeArgs& helperArgs, GrColor, sk_sp<SkVertices>,
44                     GrPrimitiveType, GrAAType, bool gammaCorrect, sk_sp<GrColorSpaceXform>,
45                     const SkMatrix& viewMatrix);
46
47    const char* name() const override { return "DrawVerticesOp"; }
48
49    void visitProxies(const VisitProxyFunc& func) const override {
50        fHelper.visitProxies(func);
51    }
52
53    SkString dumpInfo() const override;
54
55    FixedFunctionFlags fixedFunctionFlags() const override;
56
57    RequiresDstTexture finalize(const GrCaps& caps, const GrAppliedClip* clip,
58                                GrPixelConfigIsClamped dstIsClamped) override;
59
60private:
61    enum class ColorArrayType {
62        kPremulGrColor,
63        kSkColor,
64    };
65
66    void onPrepareDraws(Target*) override;
67
68    sk_sp<GrGeometryProcessor> makeGP(bool* hasColorAttribute, bool* hasLocalCoordAttribute) const;
69
70    GrPrimitiveType primitiveType() const { return fPrimitiveType; }
71    bool combinablePrimitive() const {
72        return GrPrimitiveType::kTriangles == fPrimitiveType ||
73               GrPrimitiveType::kLines == fPrimitiveType ||
74               GrPrimitiveType::kPoints == fPrimitiveType;
75    }
76
77    bool onCombineIfPossible(GrOp* t, const GrCaps&) override;
78
79    struct Mesh {
80        GrColor fColor;  // Used if this->hasPerVertexColors() is false.
81        sk_sp<SkVertices> fVertices;
82        SkMatrix fViewMatrix;
83        bool fIgnoreTexCoords;
84        bool fIgnoreColors;
85
86        bool hasExplicitLocalCoords() const {
87            return fVertices->hasTexCoords() && !fIgnoreTexCoords;
88        }
89
90        bool hasPerVertexColors() const {
91            return fVertices->hasColors() && !fIgnoreColors;
92        }
93    };
94
95    bool isIndexed() const {
96        // Consistency enforced in onCombineIfPossible.
97        return fMeshes[0].fVertices->hasIndices();
98    }
99
100    bool requiresPerVertexColors() const {
101        return SkToBool(kRequiresPerVertexColors_Flag & fFlags);
102    }
103
104    bool anyMeshHasExplicitLocalCoords() const {
105        return SkToBool(kAnyMeshHasExplicitLocalCoords & fFlags);
106    }
107
108    bool hasMultipleViewMatrices() const {
109        return SkToBool(kHasMultipleViewMatrices_Flag & fFlags);
110    }
111
112    enum Flags {
113        kRequiresPerVertexColors_Flag = 0x1,
114        kAnyMeshHasExplicitLocalCoords = 0x2,
115        kHasMultipleViewMatrices_Flag = 0x4
116
117    };
118
119    Helper fHelper;
120    SkSTArray<1, Mesh, true> fMeshes;
121    // GrPrimitiveType is more expressive than fVertices.mode() so it is used instead and we ignore
122    // the SkVertices mode (though fPrimitiveType may have been inferred from it).
123    GrPrimitiveType fPrimitiveType;
124    uint32_t fFlags;
125    int fVertexCount;
126    int fIndexCount;
127    ColorArrayType fColorArrayType;
128    bool fLinearizeColors;
129    sk_sp<GrColorSpaceXform> fColorSpaceXform;
130
131    typedef GrMeshDrawOp INHERITED;
132};
133
134#endif
135