aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops/GrDrawVerticesOp.h
blob: 4ff19cc4c27fd7262213d90f04af77f3dab46fe4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/*
 * Copyright 2015 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrDrawVerticesOp_DEFINED
#define GrDrawVerticesOp_DEFINED

#include "GrColor.h"
#include "GrMeshDrawOp.h"
#include "GrRenderTargetContext.h"
#include "GrTypes.h"
#include "SkMatrix.h"
#include "SkRect.h"
#include "SkTDArray.h"
#include "SkVertices.h"

#if GR_TEST_UTILS
#include "GrDrawOpTest.h"
#endif

class GrOpFlushState;
class SkVertices;
struct GrInitInvariantOutput;

class GrDrawVerticesOp final : public GrLegacyMeshDrawOp {
public:
    DEFINE_OP_CLASS_ID

    /**
     * Draw a SkVertices. The GrColor param is used if the vertices lack per-vertex color. If the
     * vertices lack local coords then the vertex positions are used as local coords. The primitive
     * type drawn is derived from the SkVertices object, unless overridePrimType is specified.
     * If gammaCorrect is true, the vertex colors will be linearized in the shader to get correct
     * rendering.
     */
    static std::unique_ptr<GrLegacyMeshDrawOp> Make(GrColor color, sk_sp<SkVertices>,
                                                    const SkMatrix& viewMatrix, bool gammaCorrect,
                                                    sk_sp<GrColorSpaceXform> colorSpaceXform,
                                                    GrPrimitiveType* overridePrimType = nullptr);

    const char* name() const override { return "DrawVerticesOp"; }

    SkString dumpInfo() const override {
        SkString string;
        string.appendf("PrimType: %d, MeshCount %d, VCount: %d, ICount: %d\n",
                      (int) fPrimitiveType, fMeshes.count(), fVertexCount, fIndexCount);
        string.append(DumpPipelineInfo(*this->pipeline()));
        string.append(INHERITED::dumpInfo());
        return string;
    }

private:
    enum class ColorArrayType {
        kPremulGrColor,
        kSkColor,
    };

    GrDrawVerticesOp(sk_sp<SkVertices>, GrPrimitiveType, GrColor, bool gammaCorrect,
                     sk_sp<GrColorSpaceXform>, const SkMatrix& viewMatrix);

    void getProcessorAnalysisInputs(GrProcessorAnalysisColor* color,
                                    GrProcessorAnalysisCoverage* coverage) const override;
    void applyPipelineOptimizations(const PipelineOptimizations&) override;
    void onPrepareDraws(Target*) const override;

    sk_sp<GrGeometryProcessor> makeGP(bool* hasColorAttribute, bool* hasLocalCoordAttribute) const;

    GrPrimitiveType primitiveType() const { return fPrimitiveType; }
    bool combinablePrimitive() const {
        return GrPrimitiveType::kTriangles == fPrimitiveType ||
               GrPrimitiveType::kLines == fPrimitiveType ||
               GrPrimitiveType::kPoints == fPrimitiveType;
    }

    bool onCombineIfPossible(GrOp* t, const GrCaps&) override;

    struct Mesh {
        GrColor fColor;  // Used if this->hasPerVertexColors() is false.
        sk_sp<SkVertices> fVertices;
        SkMatrix fViewMatrix;
        bool fIgnoreTexCoords;
        bool fIgnoreColors;

        bool hasExplicitLocalCoords() const {
            return fVertices->hasTexCoords() && !fIgnoreTexCoords;
        }

        bool hasPerVertexColors() const {
            return fVertices->hasColors() && !fIgnoreColors;
        }
    };

    bool isIndexed() const {
        // Consistency enforced in onCombineIfPossible.
        return fMeshes[0].fVertices->hasIndices();
    }

    bool requiresPerVertexColors() const {
        return SkToBool(kRequiresPerVertexColors_Flag & fFlags);
    }

    bool anyMeshHasExplicitLocalCoords() const {
        return SkToBool(kAnyMeshHasExplicitLocalCoords & fFlags);
    }

    bool pipelineRequiresLocalCoords() const {
        return SkToBool(kPipelineRequiresLocalCoords_Flag & fFlags);
    }

    bool hasMultipleViewMatrices() const {
        return SkToBool(kHasMultipleViewMatrices_Flag & fFlags);
    }

    enum Flags {
        kRequiresPerVertexColors_Flag = 0x1,
        kAnyMeshHasExplicitLocalCoords = 0x2,
        kPipelineRequiresLocalCoords_Flag = 0x4,
        kHasMultipleViewMatrices_Flag = 0x8

    };

    // GrPrimitiveType is more expressive than fVertices.mode() so it is used instead and we ignore
    // the SkVertices mode (though fPrimitiveType may have been inferred from it).
    GrPrimitiveType fPrimitiveType;
    uint32_t fFlags;
    int fVertexCount;
    int fIndexCount;
    ColorArrayType fColorArrayType;
    bool fLinearizeColors;
    sk_sp<GrColorSpaceXform> fColorSpaceXform;
    SkSTArray<1, Mesh, true> fMeshes;

    typedef GrLegacyMeshDrawOp INHERITED;

#if GR_TEST_UTILS
    GR_LEGACY_MESH_DRAW_OP_TEST_FRIEND(VerticesOp);
#endif
};

#endif