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 static constexpr int kMaxEdges = 8;
27
28 /**
29 * edges is a set of n edge equations where n is limited to kMaxEdges. It contains 3*n values.
30 * The edges should form a convex polygon. The positive half-plane is considered to be the
31 * inside. The equations should be normalized such that the first two coefficients are a unit
32 * 2d vector.
33 *
34 * Currently the edges are specified in device space. In the future we may prefer to specify
35 * them in src space. There are a number of ways this could be accomplished but we'd probably
36 * have to modify the effect/shaderbuilder interface to make it possible (e.g. give access
37 * to the view matrix or untransformed positions in the fragment shader).
38 */
39 static GrFPResult Make(std::unique_ptr<GrFragmentProcessor> inputFP,
40 GrClipEdgeType edgeType, int n, const SkScalar edges[]) {
41 if (n <= 0 || n > kMaxEdges) {
42 return GrFPFailure(std::move(inputFP));
43 }
44
45 return GrFPSuccess(std::unique_ptr<GrFragmentProcessor>(
46 new GrConvexPolyEffect(std::move(inputFP), 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, creation will fail.
52 */
53 static GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, GrClipEdgeType, const SkPath&);
54
55 /**
56 * Creates an effect that fills inside the rect with AA edges..
57 */
58 static GrFPResult Make(std::unique_ptr<GrFragmentProcessor>, 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(std::unique_ptr<GrFragmentProcessor> inputFP,
74 GrClipEdgeType edgeType,
75 int n, const SkScalar edges[]);
76 GrConvexPolyEffect(const GrConvexPolyEffect&);
77
78 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
79
80 void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
81
82 bool onIsEqual(const GrFragmentProcessor& other) const override;
83
84 GrClipEdgeType fEdgeType;
85 int fEdgeCount;
86 SkScalar fEdges[3 * kMaxEdges];
87
88 GR_DECLARE_FRAGMENT_PROCESSOR_TEST
89
90 typedef GrFragmentProcessor INHERITED;
91};
92
93
94#endif
95