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 "include/private/GrTypesPriv.h"
12#include "src/gpu/GrCaps.h"
13#include "src/gpu/GrFragmentProcessor.h"
14#include "src/gpu/GrProcessor.h"
15
16class GrInvariantOutput;
17class 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 */
24class GrConvexPolyEffect : public GrFragmentProcessor {
25public:
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 std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, int n,
42 const SkScalar edges[]) {
43 if (n <= 0 || n > kMaxEdges || GrClipEdgeType::kHairlineAA == edgeType) {
44 return nullptr;
45 }
46 return std::unique_ptr<GrFragmentProcessor>(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.
52 */
53 static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&);
54
55 /**
56 * Creates an effect that fills inside the rect with AA edges..
57 */
58 static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&);
59
60 ~GrConvexPolyEffect() override;
61
62 const char* name() const override { return "ConvexPoly"; }
63
64 std::unique_ptr<GrFragmentProcessor> clone() const override;
65
66 GrClipEdgeType getEdgeType() const { return fEdgeType; }
67
68 int getEdgeCount() const { return fEdgeCount; }
69
70 const SkScalar* getEdges() const { return fEdges; }
71
72private:
73 GrConvexPolyEffect(GrClipEdgeType edgeType, int n, const SkScalar edges[]);
74 GrConvexPolyEffect(const GrConvexPolyEffect&);
75
76 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
77
78 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
79
80 bool onIsEqual(const GrFragmentProcessor& other) const override;
81
82 GrClipEdgeType fEdgeType;
83 int fEdgeCount;
84 SkScalar fEdges[3 * kMaxEdges];
85
86 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
87
88 typedef GrFragmentProcessor INHERITED;
89};
90
91
92#endif
93