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 GrPipeline_DEFINED
9#define GrPipeline_DEFINED
10
11#include "GrColor.h"
12#include "GrGpu.h"
13#include "GrPendingFragmentStage.h"
14#include "GrProgramDesc.h"
15#include "GrStencil.h"
16#include "GrTypesPriv.h"
17#include "SkMatrix.h"
18#include "SkRefCnt.h"
19
20class GrBatch;
21class GrDeviceCoordTexture;
22class GrPipelineBuilder;
23
24/**
25 * Class that holds an optimized version of a GrPipelineBuilder. It is meant to be an immutable
26 * class, and contains all data needed to set the state for a gpu draw.
27 */
28class GrPipeline {
29public:
30    SK_DECLARE_INST_COUNT(GrPipeline)
31
32    GrPipeline(const GrPipelineBuilder&,
33               const GrProcOptInfo& colorPOI,
34               const GrProcOptInfo& coveragePOI,
35               const GrDrawTargetCaps&,
36               const GrScissorState&,
37               const GrDeviceCoordTexture* dstCopy);
38
39    /*
40     * Returns true if these pipelines are equivalent.
41     */
42    bool isEqual(const GrPipeline& that) const;
43
44    /// @}
45
46    ///////////////////////////////////////////////////////////////////////////
47    /// @name GrFragmentProcessors
48
49
50    int numColorFragmentStages() const { return fNumColorStages; }
51    int numCoverageFragmentStages() const { return fFragmentStages.count() - fNumColorStages; }
52    int numFragmentStages() const { return fFragmentStages.count(); }
53
54    const GrXferProcessor* getXferProcessor() const { return fXferProcessor.get(); }
55
56    const GrPendingFragmentStage& getColorStage(int idx) const {
57        SkASSERT(idx < this->numColorFragmentStages());
58        return fFragmentStages[idx];
59    }
60    const GrPendingFragmentStage& getCoverageStage(int idx) const {
61        SkASSERT(idx < this->numCoverageFragmentStages());
62        return fFragmentStages[fNumColorStages + idx];
63    }
64    const GrPendingFragmentStage& getFragmentStage(int idx) const {
65        return fFragmentStages[idx];
66    }
67
68    /// @}
69
70    /**
71     * Retrieves the currently set render-target.
72     *
73     * @return    The currently set render target.
74     */
75    GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
76
77    const GrStencilSettings& getStencil() const { return fStencilSettings; }
78
79    const GrScissorState& getScissorState() const { return fScissorState; }
80
81    bool isDitherState() const { return SkToBool(fFlags & kDither_Flag); }
82    bool isHWAntialiasState() const { return SkToBool(fFlags & kHWAA_Flag); }
83    bool snapVerticesToPixelCenters() const { return SkToBool(fFlags & kSnapVertices_Flag); }
84    // Skip any draws that refer to this pipeline (they should be a no-op).
85    bool mustSkip() const { return NULL == this->getRenderTarget(); }
86
87    /**
88     * Gets whether the target is drawing clockwise, counterclockwise,
89     * or both faces.
90     * @return the current draw face(s).
91     */
92    GrPipelineBuilder::DrawFace getDrawFace() const { return fDrawFace; }
93
94
95    ///////////////////////////////////////////////////////////////////////////
96
97    bool readsFragPosition() const { return fReadsFragPosition; }
98
99    const GrPipelineInfo& getInitBatchTracker() const { return fInitBT; }
100
101private:
102    /**
103     * Alter the program desc and inputs (attribs and processors) based on the blend optimization.
104     */
105    void adjustProgramFromOptimizations(const GrPipelineBuilder& ds,
106                                        GrXferProcessor::OptFlags,
107                                        const GrProcOptInfo& colorPOI,
108                                        const GrProcOptInfo& coveragePOI,
109                                        int* firstColorStageIdx,
110                                        int* firstCoverageStageIdx);
111
112    /**
113     * Calculates the primary and secondary output types of the shader. For certain output types
114     * the function may adjust the blend coefficients. After this function is called the src and dst
115     * blend coeffs will represent those used by backend API.
116     */
117    void setOutputStateInfo(const GrPipelineBuilder& ds, GrXferProcessor::OptFlags,
118                            const GrDrawTargetCaps&);
119
120    enum Flags {
121        kDither_Flag            = 0x1,
122        kHWAA_Flag              = 0x2,
123        kSnapVertices_Flag      = 0x4,
124    };
125
126    typedef GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> RenderTarget;
127    typedef SkSTArray<8, GrPendingFragmentStage> FragmentStageArray;
128    typedef GrPendingProgramElement<const GrXferProcessor> ProgramXferProcessor;
129    RenderTarget                        fRenderTarget;
130    GrScissorState                      fScissorState;
131    GrStencilSettings                   fStencilSettings;
132    GrPipelineBuilder::DrawFace         fDrawFace;
133    uint32_t                            fFlags;
134    ProgramXferProcessor                fXferProcessor;
135    FragmentStageArray                  fFragmentStages;
136    bool                                fReadsFragPosition;
137    GrPipelineInfo                      fInitBT;
138
139    // This function is equivalent to the offset into fFragmentStages where coverage stages begin.
140    int                                 fNumColorStages;
141
142    GrProgramDesc fDesc;
143
144    typedef SkRefCnt INHERITED;
145};
146
147#endif
148