Home | History | Annotate | Download | only in glsl
      1 /*
      2  * Copyright 2014 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 GrGLSLFragmentShaderBuilder_DEFINED
      9 #define GrGLSLFragmentShaderBuilder_DEFINED
     10 
     11 #include "GrGLSLShaderBuilder.h"
     12 
     13 #include "glsl/GrGLSLProcessorTypes.h"
     14 
     15 class GrRenderTarget;
     16 class GrGLSLVarying;
     17 
     18 /*
     19  * This base class encapsulates the common functionality which all processors use to build fragment
     20  * shaders.
     21  */
     22 class GrGLSLFragmentBuilder : public GrGLSLShaderBuilder {
     23 public:
     24     GrGLSLFragmentBuilder(GrGLSLProgramBuilder* program) : INHERITED(program) {}
     25     virtual ~GrGLSLFragmentBuilder() {}
     26 
     27     /**
     28      * Use of these features may require a GLSL extension to be enabled. Shaders may not compile
     29      * if code is added that uses one of these features without calling enableFeature()
     30      */
     31     enum GLSLFeature {
     32         kStandardDerivatives_GLSLFeature = kLastGLSLPrivateFeature + 1,
     33         kPixelLocalStorage_GLSLFeature
     34     };
     35 
     36     /**
     37      * If the feature is supported then true is returned and any necessary #extension declarations
     38      * are added to the shaders. If the feature is not supported then false will be returned.
     39      */
     40     virtual bool enableFeature(GLSLFeature) = 0;
     41 
     42     /**
     43      * This returns a variable name to access the 2D, perspective correct version of the coords in
     44      * the fragment shader. If the coordinates at index are 3-dimensional, it immediately emits a
     45      * perspective divide into the fragment shader (xy / z) to convert them to 2D.
     46      */
     47     virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords, int index) = 0;
     48 
     49 
     50     /** Returns a variable name that represents the position of the fragment in the FS. The position
     51         is in device space (e.g. 0,0 is the top left and pixel centers are at half-integers). */
     52     virtual const char* fragmentPosition() = 0;
     53 
     54     // TODO: remove this method.
     55     void declAppendf(const char* fmt, ...);
     56 
     57 private:
     58     typedef GrGLSLShaderBuilder INHERITED;
     59 };
     60 
     61 /*
     62  * This class is used by fragment processors to build their fragment code.
     63  */
     64 class GrGLSLFPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
     65 public:
     66     /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
     67     GrGLSLFPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
     68 
     69     /**
     70      * Subtracts sample coverage from the fragment. Any sample whose corresponding bit is not found
     71      * in the mask will not be written out to the framebuffer.
     72      *
     73      * @param mask      int that contains the sample mask. Bit N corresponds to the Nth sample.
     74      * @param invert    perform a bit-wise NOT on the provided mask before applying it?
     75      *
     76      * Requires GLSL support for sample variables.
     77      */
     78     virtual void maskSampleCoverage(const char* mask, bool invert = false) = 0;
     79 
     80     /**
     81      * Fragment procs with child procs should call these functions before/after calling emitCode
     82      * on a child proc.
     83      */
     84     virtual void onBeforeChildProcEmitCode() = 0;
     85     virtual void onAfterChildProcEmitCode() = 0;
     86 
     87     virtual const SkString& getMangleString() const = 0;
     88 };
     89 
     90 /*
     91  * This class is used by primitive processors to build their fragment code.
     92  */
     93 class GrGLSLPPFragmentBuilder : public GrGLSLFPFragmentBuilder {
     94 public:
     95     /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
     96     GrGLSLPPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
     97 
     98     /**
     99      * Overrides the fragment's sample coverage. The provided mask determines which samples will now
    100      * be written out to the framebuffer. Note that this mask can be reduced by a future call to
    101      * maskSampleCoverage.
    102      *
    103      * If a primitive processor uses this method, it must guarantee that every codepath through the
    104      * shader overrides the sample mask at some point.
    105      *
    106      * @param mask    int that contains the new coverage mask. Bit N corresponds to the Nth sample.
    107      *
    108      * Requires NV_sample_mask_override_coverage.
    109      */
    110     virtual void overrideSampleCoverage(const char* mask) = 0;
    111 };
    112 
    113 /*
    114  * This class is used by Xfer processors to build their fragment code.
    115  */
    116 class GrGLSLXPFragmentBuilder : virtual public GrGLSLFragmentBuilder {
    117 public:
    118     /** Appease the compiler; the derived class initializes GrGLSLFragmentBuilder. */
    119     GrGLSLXPFragmentBuilder() : GrGLSLFragmentBuilder(nullptr) {}
    120 
    121     virtual bool hasCustomColorOutput() const = 0;
    122     virtual bool hasSecondaryOutput() const = 0;
    123 
    124     /** Returns the variable name that holds the color of the destination pixel. This may be nullptr
    125      * if no effect advertised that it will read the destination. */
    126     virtual const char* dstColor() = 0;
    127 
    128     /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with
    129         this shader. It is only legal to call this method with an advanced blend equation, and only
    130         if these equations are supported. */
    131     virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0;
    132 };
    133 
    134 /*
    135  * This class implements the various fragment builder interfaces.
    136  */
    137 class GrGLSLFragmentShaderBuilder : public GrGLSLPPFragmentBuilder, public GrGLSLXPFragmentBuilder {
    138 public:
    139     typedef uint8_t FragPosKey;
    140 
    141     /** Returns a key for reading the fragment location. This should only be called if there is an
    142        effect that will requires the fragment position. If the fragment position is not required,
    143        the key is 0. */
    144     static FragPosKey KeyForFragmentPosition(const GrRenderTarget* dst);
    145 
    146     GrGLSLFragmentShaderBuilder(GrGLSLProgramBuilder* program, uint8_t fragPosKey);
    147 
    148     // Shared GrGLSLFragmentBuilder interface.
    149     bool enableFeature(GLSLFeature) override;
    150     virtual SkString ensureFSCoords2D(const GrGLSLTransformedCoordsArray& coords,
    151                                       int index) override;
    152     const char* fragmentPosition() override;
    153 
    154     // GrGLSLFPFragmentBuilder interface.
    155     void maskSampleCoverage(const char* mask, bool invert = false) override;
    156     void overrideSampleCoverage(const char* mask) override;
    157     const SkString& getMangleString() const override { return fMangleString; }
    158     void onBeforeChildProcEmitCode() override;
    159     void onAfterChildProcEmitCode() override;
    160 
    161     // GrGLSLXPFragmentBuilder interface.
    162     bool hasCustomColorOutput() const override { return fHasCustomColorOutput; }
    163     bool hasSecondaryOutput() const override { return fHasSecondaryOutput; }
    164     const char* dstColor() override;
    165     void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override;
    166 
    167 private:
    168     // Private public interface, used by GrGLProgramBuilder to build a fragment shader
    169     void enableCustomOutput();
    170     void enableSecondaryOutput();
    171     const char* getPrimaryColorOutputName() const;
    172     const char* getSecondaryColorOutputName() const;
    173 
    174     // As GLSLProcessors emit code, there are some conditions we need to verify.  We use the below
    175     // state to track this.  The reset call is called per processor emitted.
    176     bool hasReadDstColor() const { return fHasReadDstColor; }
    177     bool hasReadFragmentPosition() const { return fHasReadFragmentPosition; }
    178     void reset() {
    179         fHasReadDstColor = false;
    180         fHasReadFragmentPosition = false;
    181     }
    182 
    183     static const char* DeclaredColorOutputName() { return "fsColorOut"; }
    184     static const char* DeclaredSecondaryColorOutputName() { return "fsSecondaryColorOut"; }
    185 
    186     /*
    187      * An internal call for GrGLProgramBuilder to use to add varyings to the vertex shader
    188      */
    189     void addVarying(GrGLSLVarying*, GrSLPrecision);
    190 
    191     void onFinalize() override;
    192 
    193     // Interpretation of FragPosKey when generating code
    194     enum {
    195         kNoFragPosRead_FragPosKey           = 0,  // The fragment positition will not be needed.
    196         kTopLeftFragPosRead_FragPosKey      = 0x1,// Read frag pos relative to top-left.
    197         kBottomLeftFragPosRead_FragPosKey   = 0x2,// Read frag pos relative to bottom-left.
    198     };
    199 
    200     static const char* kDstTextureColorName;
    201 
    202     /*
    203      * State that tracks which child proc in the proc tree is currently emitting code.  This is
    204      * used to update the fMangleString, which is used to mangle the names of uniforms and functions
    205      * emitted by the proc.  fSubstageIndices is a stack: its count indicates how many levels deep
    206      * we are in the tree, and its second-to-last value is the index of the child proc at that
    207      * level which is currently emitting code. For example, if fSubstageIndices = [3, 1, 2, 0], that
    208      * means we're currently emitting code for the base proc's 3rd child's 1st child's 2nd child.
    209      */
    210     SkTArray<int> fSubstageIndices;
    211 
    212     /*
    213      * The mangle string is used to mangle the names of uniforms/functions emitted by the child
    214      * procs so no duplicate uniforms/functions appear in the generated shader program. The mangle
    215      * string is simply based on fSubstageIndices. For example, if fSubstageIndices = [3, 1, 2, 0],
    216      * then the manglestring will be "_c3_c1_c2", and any uniform/function emitted by that proc will
    217      * have "_c3_c1_c2" appended to its name, which can be interpreted as "base proc's 3rd child's
    218      * 1st child's 2nd child".
    219      */
    220     SkString fMangleString;
    221 
    222     bool fSetupFragPosition;
    223     bool fTopLeftFragPosRead;
    224     bool fHasCustomColorOutput;
    225     int  fCustomColorOutputIndex;
    226     bool fHasSecondaryOutput;
    227     bool fHasInitializedSampleMask;
    228 
    229     // some state to verify shaders and effects are consistent, this is reset between effects by
    230     // the program creator
    231     bool fHasReadDstColor;
    232     bool fHasReadFragmentPosition;
    233 
    234     friend class GrGLSLProgramBuilder;
    235     friend class GrGLProgramBuilder;
    236 };
    237 
    238 #endif
    239