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 GrDrawBatch_DEFINED
9#define GrDrawBatch_DEFINED
10
11#include "GrBatch.h"
12#include "GrPipeline.h"
13
14struct GrInitInvariantOutput;
15
16/**
17 * GrDrawBatches are flushed in two phases (preDraw, and draw). In preDraw uploads to GrGpuResources
18 * and draws are determined and scheduled. They are issued in the draw phase. GrBatchToken is used
19 * to sequence the uploads relative to each other and to draws.
20 **/
21
22typedef uint64_t GrBatchToken;
23
24class GrBatchUploader : public SkRefCnt {
25public:
26    class TextureUploader;
27
28    GrBatchUploader(GrBatchToken lastUploadToken) : fLastUploadToken(lastUploadToken) {}
29    GrBatchToken lastUploadToken() const { return fLastUploadToken; }
30    virtual void upload(TextureUploader*)=0;
31
32private:
33    GrBatchToken fLastUploadToken;
34};
35
36/**
37 * Base class for GrBatches that draw. These batches have a GrPipeline installed by GrDrawTarget.
38 */
39class GrDrawBatch : public GrBatch {
40public:
41    class Target;
42
43    GrDrawBatch(uint32_t classID);
44    ~GrDrawBatch() override;
45
46    /**
47     * Fills in a structure informing the XP of overrides to its normal behavior.
48     */
49    void getPipelineOptimizations(GrPipelineOptimizations* override) const;
50
51    const GrPipeline* pipeline() const {
52        SkASSERT(fPipelineInstalled);
53        return reinterpret_cast<const GrPipeline*>(fPipelineStorage.get());
54    }
55
56    bool installPipeline(const GrPipeline::CreateArgs&);
57
58    // TODO no GrPrimitiveProcessors yet read fragment position
59    bool willReadFragmentPosition() const { return false; }
60
61    uint32_t renderTargetUniqueID() const final {
62        SkASSERT(fPipelineInstalled);
63        return this->pipeline()->getRenderTarget()->getUniqueID();
64    }
65
66    GrRenderTarget* renderTarget() const final {
67        SkASSERT(fPipelineInstalled);
68        return this->pipeline()->getRenderTarget();
69    }
70
71    SkString dumpInfo() const override {
72        SkString string;
73        string.appendf("RT: %d\n", this->renderTargetUniqueID());
74        string.append("ColorStages:\n");
75        for (int i = 0; i < this->pipeline()->numColorFragmentProcessors(); i++) {
76            string.appendf("\t\t%s\n\t\t%s\n",
77                           this->pipeline()->getColorFragmentProcessor(i).name(),
78                           this->pipeline()->getColorFragmentProcessor(i).dumpInfo().c_str());
79        }
80        string.append("CoverageStages:\n");
81        for (int i = 0; i < this->pipeline()->numCoverageFragmentProcessors(); i++) {
82            string.appendf("\t\t%s\n\t\t%s\n",
83                           this->pipeline()->getCoverageFragmentProcessor(i).name(),
84                           this->pipeline()->getCoverageFragmentProcessor(i).dumpInfo().c_str());
85        }
86        string.appendf("XP: %s\n", this->pipeline()->getXferProcessor().name());
87        return string;
88    }
89
90protected:
91    virtual void computePipelineOptimizations(GrInitInvariantOutput* color,
92                                              GrInitInvariantOutput* coverage,
93                                              GrBatchToXPOverrides* overrides) const = 0;
94
95private:
96    /**
97     * initBatchTracker is a hook for the some additional overrides / optimization possibilities
98     * from the GrXferProcessor.
99     */
100    virtual void initBatchTracker(const GrXPOverridesForBatch&) = 0;
101
102protected:
103    SkTArray<SkAutoTUnref<GrBatchUploader>, true>   fInlineUploads;
104
105private:
106    SkAlignedSTStorage<1, GrPipeline>               fPipelineStorage;
107    bool                                            fPipelineInstalled;
108    typedef GrBatch INHERITED;
109};
110
111#endif
112