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 GrGLSLXferProcessor_DEFINED
9#define GrGLSLXferProcessor_DEFINED
10
11#include "glsl/GrGLSLProgramDataManager.h"
12#include "glsl/GrGLSLTextureSampler.h"
13
14class GrXferProcessor;
15class GrGLSLCaps;
16class GrGLSLUniformHandler;
17class GrGLSLXPBuilder;
18class GrGLSLXPFragmentBuilder;
19
20class GrGLSLXferProcessor {
21public:
22    GrGLSLXferProcessor() {}
23    virtual ~GrGLSLXferProcessor() {}
24
25    typedef GrGLSLTextureSampler::TextureSamplerArray TextureSamplerArray;
26    struct EmitArgs {
27        EmitArgs(GrGLSLXPFragmentBuilder* fragBuilder,
28                 GrGLSLUniformHandler* uniformHandler,
29                 const GrGLSLCaps* caps,
30                 const GrXferProcessor& xp,
31                 const char* inputColor,
32                 const char* inputCoverage,
33                 const char* outputPrimary,
34                 const char* outputSecondary,
35                 const TextureSamplerArray& samplers,
36                 const bool usePLSDstRead)
37            : fXPFragBuilder(fragBuilder)
38            , fUniformHandler(uniformHandler)
39            , fGLSLCaps(caps)
40            , fXP(xp)
41            , fInputColor(inputColor)
42            , fInputCoverage(inputCoverage)
43            , fOutputPrimary(outputPrimary)
44            , fOutputSecondary(outputSecondary)
45            , fSamplers(samplers)
46            , fUsePLSDstRead(usePLSDstRead) {}
47
48        GrGLSLXPFragmentBuilder* fXPFragBuilder;
49        GrGLSLUniformHandler* fUniformHandler;
50        const GrGLSLCaps* fGLSLCaps;
51        const GrXferProcessor& fXP;
52        const char* fInputColor;
53        const char* fInputCoverage;
54        const char* fOutputPrimary;
55        const char* fOutputSecondary;
56        const TextureSamplerArray& fSamplers;
57        bool fUsePLSDstRead;
58    };
59    /**
60     * This is similar to emitCode() in the base class, except it takes a full shader builder.
61     * This allows the effect subclass to emit vertex code.
62     */
63    void emitCode(const EmitArgs&);
64
65    /** A GrGLSLXferProcessor instance can be reused with any GrGLSLXferProcessor that produces
66        the same stage key; this function reads data from a GrGLSLXferProcessor and uploads any
67        uniform variables required  by the shaders created in emitCode(). The GrXferProcessor
68        parameter is guaranteed to be of the same type that created this GrGLSLXferProcessor and
69        to have an identical processor key as the one that created this GrGLSLXferProcessor. This
70        function calls onSetData on the subclass of GrGLSLXferProcessor
71     */
72    void setData(const GrGLSLProgramDataManager& pdm, const GrXferProcessor& xp);
73
74protected:
75    static void DefaultCoverageModulation(GrGLSLXPFragmentBuilder* fragBuilder,
76                                          const char* srcCoverage,
77                                          const char* dstColor,
78                                          const char* outColor,
79                                          const char* outColorSecondary,
80                                          const GrXferProcessor& proc);
81
82private:
83    /**
84     * Called by emitCode() when the XP will not be performing a dst read. This method is
85     * responsible for both blending and coverage. A subclass only needs to implement this method if
86     * it can construct a GrXferProcessor that will not read the dst color.
87     */
88    virtual void emitOutputsForBlendState(const EmitArgs&) {
89        SkFAIL("emitOutputsForBlendState not implemented.");
90    }
91
92    /**
93     * Called by emitCode() when the XP will perform a dst read. This method only needs to supply
94     * the blending logic. The base class applies coverage. A subclass only needs to implement this
95     * method if it can construct a GrXferProcessor that reads the dst color.
96     */
97    virtual void emitBlendCodeForDstRead(GrGLSLXPFragmentBuilder*,
98                                         GrGLSLUniformHandler*,
99                                         const char* srcColor,
100                                         const char* srcCoverage,
101                                         const char* dstColor,
102                                         const char* outColor,
103                                         const char* outColorSecondary,
104                                         const GrXferProcessor&) {
105        SkFAIL("emitBlendCodeForDstRead not implemented.");
106    }
107
108    virtual void onSetData(const GrGLSLProgramDataManager&, const GrXferProcessor&) = 0;
109
110    GrGLSLProgramDataManager::UniformHandle fDstTopLeftUni;
111    GrGLSLProgramDataManager::UniformHandle fDstScaleUni;
112};
113#endif
114