Home | History | Annotate | Download | only in effects
      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 GrConvexPolyEffect_DEFINED
      9 #define GrConvexPolyEffect_DEFINED
     10 
     11 #include "GrCaps.h"
     12 #include "GrFragmentProcessor.h"
     13 #include "GrProcessor.h"
     14 #include "GrTypesPriv.h"
     15 
     16 class GrInvariantOutput;
     17 class SkPath;
     18 
     19 /**
     20  * An effect that renders a convex polygon. It is intended to be used as a coverage effect.
     21  * Bounding geometry is rendered and the effect computes coverage based on the fragment's
     22  * position relative to the polygon.
     23  */
     24 class GrConvexPolyEffect : public GrFragmentProcessor {
     25 public:
     26     enum {
     27         kMaxEdges = 8,
     28     };
     29 
     30     /**
     31      * edges is a set of n edge equations where n is limited to kMaxEdges. It contains 3*n values.
     32      * The edges should form a convex polygon. The positive half-plane is considered to be the
     33      * inside. The equations should be normalized such that the first two coefficients are a unit
     34      * 2d vector.
     35      *
     36      * Currently the edges are specified in device space. In the future we may prefer to specify
     37      * them in src space. There are a number of ways this could be accomplished but we'd probably
     38      * have to modify the effect/shaderbuilder interface to make it possible (e.g. give access
     39      * to the view matrix or untransformed positions in the fragment shader).
     40      */
     41     static GrFragmentProcessor* Create(GrPrimitiveEdgeType edgeType, int n,
     42                                        const SkScalar edges[]) {
     43         if (n <= 0 || n > kMaxEdges || kHairlineAA_GrProcessorEdgeType == edgeType) {
     44             return nullptr;
     45         }
     46         return new GrConvexPolyEffect(edgeType, n, edges);
     47     }
     48 
     49     /**
     50      * Creates an effect that clips against the path. If the path is not a convex polygon, is
     51      * inverse filled, or has too many edges, this will return nullptr. If offset is non-nullptr, then
     52      * the path is translated by the vector.
     53      */
     54     static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkPath&,
     55                                        const SkVector* offset = nullptr);
     56 
     57     /**
     58      * Creates an effect that fills inside the rect with AA edges..
     59      */
     60     static GrFragmentProcessor* Create(GrPrimitiveEdgeType, const SkRect&);
     61 
     62     virtual ~GrConvexPolyEffect();
     63 
     64     const char* name() const override { return "ConvexPoly"; }
     65 
     66     GrPrimitiveEdgeType getEdgeType() const { return fEdgeType; }
     67 
     68     int getEdgeCount() const { return fEdgeCount; }
     69 
     70     const SkScalar* getEdges() const { return fEdges; }
     71 
     72 private:
     73     GrConvexPolyEffect(GrPrimitiveEdgeType edgeType, int n, const SkScalar edges[]);
     74 
     75     GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
     76 
     77     void onGetGLSLProcessorKey(const GrGLSLCaps&, GrProcessorKeyBuilder*) const override;
     78 
     79     bool onIsEqual(const GrFragmentProcessor& other) const override;
     80 
     81     void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
     82 
     83     GrPrimitiveEdgeType    fEdgeType;
     84     int                    fEdgeCount;
     85     SkScalar               fEdges[3 * kMaxEdges];
     86 
     87     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
     88 
     89     typedef GrFragmentProcessor INHERITED;
     90 };
     91 
     92 
     93 #endif
     94