Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2013 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 GrPrimitiveProcessor_DEFINED
      9 #define GrPrimitiveProcessor_DEFINED
     10 
     11 #include "GrColor.h"
     12 #include "GrProcessor.h"
     13 #include "GrShaderVar.h"
     14 
     15 /*
     16  * The GrPrimitiveProcessor represents some kind of geometric primitive.  This includes the shape
     17  * of the primitive and the inherent color of the primitive.  The GrPrimitiveProcessor is
     18  * responsible for providing a color and coverage input into the Ganesh rendering pipeline.  Through
     19  * optimization, Ganesh may decide a different color, no color, and / or no coverage are required
     20  * from the GrPrimitiveProcessor, so the GrPrimitiveProcessor must be able to support this
     21  * functionality.
     22  *
     23  * There are two feedback loops between the GrFragmentProcessors, the GrXferProcessor, and the
     24  * GrPrimitiveProcessor. These loops run on the CPU and to determine known properties of the final
     25  * color and coverage inputs to the GrXferProcessor in order to perform optimizations that preserve
     26  * correctness. The GrDrawOp seeds these loops with initial color and coverage, in its
     27  * getFragmentProcessorAnalysisInputs implementation. These seed values are processed by the
     28  * subsequent
     29  * stages of the rendering pipeline and the output is then fed back into the GrDrawOp in
     30  * the applyPipelineOptimizations call, where the op can use the information to inform decisions
     31  * about GrPrimitiveProcessor creation.
     32  */
     33 
     34 class GrGLSLPrimitiveProcessor;
     35 
     36 struct GrInitInvariantOutput;
     37 
     38 /*
     39  * This class allows the GrPipeline to communicate information about the pipeline to a GrOp which
     40  * inform its decisions for GrPrimitiveProcessor setup. These are not properly part of the pipeline
     41  * because they reflect the specific inputs that the op provided to perform the analysis (e.g. that
     42  * the GrGeometryProcessor would output an opaque color).
     43  *
     44  * The pipeline analysis that produced this may have decided to elide some GrProcessors. However,
     45  * those elisions may depend upon changing the color output by the GrGeometryProcessor used by the
     46  * GrDrawOp. The op must check getOverrideColorIfSet() for this.
     47  */
     48 class GrPipelineOptimizations {
     49 public:
     50     /** Does the pipeline require access to (implicit or explicit) local coordinates? */
     51     bool readsLocalCoords() const {
     52         return SkToBool(kReadsLocalCoords_Flag & fFlags);
     53     }
     54 
     55     /** Does the pipeline allow the GrPrimitiveProcessor to combine color and coverage into one
     56         color output ? */
     57     bool canTweakAlphaForCoverage() const {
     58         return SkToBool(kCanTweakAlphaForCoverage_Flag & fFlags);
     59     }
     60 
     61     /** Does the pipeline require the GrPrimitiveProcessor to specify a specific color (and if
     62         so get the color)? */
     63     bool getOverrideColorIfSet(GrColor* overrideColor) const {
     64         if (SkToBool(kUseOverrideColor_Flag & fFlags)) {
     65             if (overrideColor) {
     66                 *overrideColor = fOverrideColor;
     67             }
     68             return true;
     69         }
     70         return false;
     71     }
     72 
     73 private:
     74     enum {
     75         // If this is not set the primitive processor need not produce local coordinates
     76         kReadsLocalCoords_Flag = 0x1,
     77 
     78         // If this flag is set then the primitive processor may produce color*coverage as
     79         // its color output (and not output a separate coverage).
     80         kCanTweakAlphaForCoverage_Flag = 0x2,
     81 
     82         // If this flag is set the GrPrimitiveProcessor must produce fOverrideColor as its
     83         // output color. If not set fOverrideColor is to be ignored.
     84         kUseOverrideColor_Flag = 0x4,
     85     };
     86 
     87     uint32_t    fFlags;
     88     GrColor     fOverrideColor;
     89 
     90     friend class GrPipeline; // To initialize this
     91 };
     92 
     93 /*
     94  * GrPrimitiveProcessor defines an interface which all subclasses must implement.  All
     95  * GrPrimitiveProcessors must proivide seed color and coverage for the Ganesh color / coverage
     96  * pipelines, and they must provide some notion of equality
     97  */
     98 class GrPrimitiveProcessor : public GrProcessor {
     99 public:
    100     // Only the GrGeometryProcessor subclass actually has a geo shader or vertex attributes, but
    101     // we put these calls on the base class to prevent having to cast
    102     virtual bool willUseGeoShader() const = 0;
    103 
    104     struct Attribute {
    105         Attribute()
    106             : fName(nullptr)
    107             , fType(kFloat_GrVertexAttribType)
    108             , fOffset(0) {}
    109         Attribute(const char* name, GrVertexAttribType type, GrSLPrecision precision)
    110             : fName(name)
    111             , fType(type)
    112             , fOffset(SkAlign4(GrVertexAttribTypeSize(type)))
    113             , fPrecision(precision) {}
    114         const char* fName;
    115         GrVertexAttribType fType;
    116         size_t fOffset;
    117         GrSLPrecision fPrecision;
    118     };
    119 
    120     int numAttribs() const { return fAttribs.count(); }
    121     const Attribute& getAttrib(int index) const { return fAttribs[index]; }
    122 
    123     // Returns the vertex stride of the GP.  A common use case is to request geometry from a
    124     // GrOpList based off of the stride, and to populate this memory using an implicit array of
    125     // structs.  In this case, it is best to assert the vertexstride == sizeof(VertexStruct).
    126     size_t getVertexStride() const { return fVertexStride; }
    127 
    128     /**
    129      * Computes a transformKey from an array of coord transforms. Will only look at the first
    130      * <numCoords> transforms in the array.
    131      *
    132      * TODO: A better name for this function  would be "compute" instead of "get".
    133      */
    134     uint32_t getTransformKey(const SkTArray<const GrCoordTransform*, true>& coords,
    135                              int numCoords) const;
    136 
    137     /**
    138      * Sets a unique key on the GrProcessorKeyBuilder that is directly associated with this geometry
    139      * processor's GL backend implementation.
    140      *
    141      * TODO: A better name for this function  would be "compute" instead of "get".
    142      */
    143     virtual void getGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const = 0;
    144 
    145 
    146     /** Returns a new instance of the appropriate *GL* implementation class
    147         for the given GrProcessor; caller is responsible for deleting
    148         the object. */
    149     virtual GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const = 0;
    150 
    151     virtual bool isPathRendering() const { return false; }
    152 
    153     /**
    154      * If non-null, overrides the dest color returned by GrGLSLFragmentShaderBuilder::dstColor().
    155      */
    156     virtual const char* getDestColorOverride() const { return nullptr; }
    157 
    158     virtual float getSampleShading() const {
    159         return 0.0;
    160     }
    161 
    162     /* Sub-class should override and return true if this primitive processor implements the distance
    163      * vector field, a field of vectors to the nearest point in the edge of the shape.  */
    164     virtual bool implementsDistanceVector() const { return false; }
    165 
    166 protected:
    167     GrPrimitiveProcessor() : fVertexStride(0) {}
    168 
    169     enum { kPreallocAttribCnt = 8 };
    170     SkSTArray<kPreallocAttribCnt, Attribute> fAttribs;
    171     size_t fVertexStride;
    172 
    173 private:
    174     void notifyRefCntIsZero() const final {}
    175     virtual bool hasExplicitLocalCoords() const = 0;
    176 
    177     typedef GrProcessor INHERITED;
    178 };
    179 
    180 #endif
    181