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 GrTestBatch_DEFINED
9#define GrTestBatch_DEFINED
10
11#include "GrBatch.h"
12#include "GrVertexBuffer.h"
13
14/*
15 * A simple batch only for testing purposes which actually doesn't batch at all, but can fit into
16 * the batch pipeline and generate arbitrary geometry
17 */
18class GrTestBatch : public GrBatch {
19public:
20    struct Geometry {
21        GrColor fColor;
22    };
23
24    virtual const char* name() const override = 0;
25
26    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
27        // When this is called on a batch, there is only one geometry bundle
28        out->setKnownFourComponents(this->geoData(0)->fColor);
29    }
30
31    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
32        out->setUnknownSingleComponent();
33    }
34
35    void initBatchTracker(const GrPipelineInfo& init) override {
36        // Handle any color overrides
37        if (init.fColorIgnored) {
38            this->geoData(0)->fColor = GrColor_ILLEGAL;
39        } else if (GrColor_ILLEGAL != init.fOverrideColor) {
40            this->geoData(0)->fColor = init.fOverrideColor;
41        }
42
43        // setup batch properties
44        fBatch.fColorIgnored = init.fColorIgnored;
45        fBatch.fColor = this->geoData(0)->fColor;
46        fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
47        fBatch.fCoverageIgnored = init.fCoverageIgnored;
48    }
49
50    void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
51        batchTarget->initDraw(fGeometryProcessor, pipeline);
52
53        // TODO this is hacky, but the only way we have to initialize the GP is to use the
54        // GrPipelineInfo struct so we can generate the correct shader.  Once we have GrBatch
55        // everywhere we can remove this nastiness
56        GrPipelineInfo init;
57        init.fColorIgnored = fBatch.fColorIgnored;
58        init.fOverrideColor = GrColor_ILLEGAL;
59        init.fCoverageIgnored = fBatch.fCoverageIgnored;
60        init.fUsesLocalCoords = fBatch.fUsesLocalCoords;
61        fGeometryProcessor->initBatchTracker(batchTarget->currentBatchTracker(), init);
62
63        this->onGenerateGeometry(batchTarget, pipeline);
64    }
65
66protected:
67    GrTestBatch(const GrGeometryProcessor* gp, const SkRect& bounds) {
68        fGeometryProcessor.reset(SkRef(gp));
69
70        this->setBounds(bounds);
71    }
72
73    const GrGeometryProcessor* geometryProcessor() const { return fGeometryProcessor; }
74
75private:
76    virtual Geometry* geoData(int index) = 0;
77    virtual const Geometry* geoData(int index) const = 0;
78
79    bool onCombineIfPossible(GrBatch* t) override {
80        return false;
81    }
82
83    virtual void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) = 0;
84
85    struct BatchTracker {
86        GrColor fColor;
87        bool fUsesLocalCoords;
88        bool fColorIgnored;
89        bool fCoverageIgnored;
90    };
91
92    SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor;
93    BatchTracker fBatch;
94};
95
96#endif
97