Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
GrClip Class Referenceabstract

#include <GrClip.h>

Inheritance diagram for GrClip:
GrHardClip LazyProxyTest::Clip skgpu::ganesh::ClipStack GrFixedClip skgpu::ganesh::StencilClip

Classes

struct  PreClipResult
 

Public Types

enum class  Effect { kClipped , kUnclipped , kClippedOut }
 
enum class  BoundsType { kExterior , kInterior }
 

Public Member Functions

virtual ~GrClip ()
 
virtual SkIRect getConservativeBounds () const =0
 
virtual Effect apply (GrRecordingContext *, skgpu::ganesh::SurfaceDrawContext *, GrDrawOp *, GrAAType, GrAppliedClip *, SkRect *bounds) const =0
 
virtual PreClipResult preApply (const SkRect &drawBounds, GrAA aa) const
 

Static Public Member Functions

static bool IsInsideClip (const SkIRect &innerClipBounds, const SkRect &drawBounds, GrAA aa)
 
static bool IsOutsideClip (const SkIRect &outerClipBounds, const SkRect &drawBounds, GrAA aa)
 
static SkIRect GetPixelIBounds (const SkRect &bounds, GrAA aa, BoundsType mode=BoundsType::kExterior)
 
static bool IsPixelAligned (const SkRect &rect)
 

Static Public Attributes

static constexpr SkScalar kBoundsTolerance = 1e-3f
 
static constexpr SkScalar kHalfPixelRoundingTolerance = 5e-2f
 

Detailed Description

GrClip is an abstract base class for applying a clip. It constructs a clip mask if necessary, and fills out a GrAppliedClip instructing the caller on how to set up the draw state.

Definition at line 29 of file GrClip.h.

Member Enumeration Documentation

◆ BoundsType

enum class GrClip::BoundsType
strong
Enumerator
kExterior 

Returns the tightest integer pixel bounding box such that the rasterization of a shape contained in the analytic 'bounds', using the 'aa' method, will only have non-zero coverage for pixels inside the returned bounds. Pixels outside the bounds will either not be touched, or will have 0 coverage that creates no visual change.

kInterior 

Returns the largest integer pixel bounding box such that were 'bounds' to be rendered as a solid fill using 'aa', every pixel in the returned bounds will have full coverage.

This effectively determines the pixels that are definitely covered by a draw or clip. It effectively performs the opposite operations as GetOuterPixelBounds. It rounds in instead of out for coverage AA and non-AA near pixel centers.

Definition at line 144 of file GrClip.h.

144 {
145 /**
146 * Returns the tightest integer pixel bounding box such that the rasterization of a shape
147 * contained in the analytic 'bounds', using the 'aa' method, will only have non-zero
148 * coverage for pixels inside the returned bounds. Pixels outside the bounds will either
149 * not be touched, or will have 0 coverage that creates no visual change.
150 */
151 kExterior,
152 /**
153 * Returns the largest integer pixel bounding box such that were 'bounds' to be rendered as
154 * a solid fill using 'aa', every pixel in the returned bounds will have full coverage.
155 *
156 * This effectively determines the pixels that are definitely covered by a draw or clip. It
157 * effectively performs the opposite operations as GetOuterPixelBounds. It rounds in instead
158 * of out for coverage AA and non-AA near pixel centers.
159 */
161 };

◆ Effect

enum class GrClip::Effect
strong
Enumerator
kClipped 
kUnclipped 
kClippedOut 

Definition at line 31 of file GrClip.h.

31 {
32 // The clip conservatively modifies the draw's coverage but doesn't eliminate the draw
34 // The clip definitely does not modify the draw's coverage and the draw can be performed
35 // without clipping (beyond the automatic device bounds clip).
37 // The clip definitely eliminates all of the draw's coverage and the draw can be skipped
39 };

Constructor & Destructor Documentation

◆ ~GrClip()

virtual GrClip::~GrClip ( )
inlinevirtual

Definition at line 56 of file GrClip.h.

56{}

Member Function Documentation

◆ apply()

virtual Effect GrClip::apply ( GrRecordingContext ,
skgpu::ganesh::SurfaceDrawContext ,
GrDrawOp ,
GrAAType  ,
GrAppliedClip ,
SkRect bounds 
) const
pure virtual

This computes a GrAppliedClip from the clip which in turn can be used to build a GrPipeline. To determine the appropriate clipping implementation the GrClip subclass must know whether the draw will enable HW AA or uses the stencil buffer. On input 'bounds' is a conservative bounds of the draw that is to be clipped. If kClipped or kUnclipped is returned, the 'bounds' will have been updated to be contained within the clip bounds (or the device's, for wide-open clips). If kNoDraw is returned, 'bounds' and the applied clip are in an undetermined state and should be ignored (and the draw should be skipped).

Implemented in GrHardClip, skgpu::ganesh::ClipStack, and LazyProxyTest::Clip.

◆ getConservativeBounds()

virtual SkIRect GrClip::getConservativeBounds ( ) const
pure virtual

Compute a conservative pixel bounds restricted to the given render target dimensions. The returned bounds represent the limits of pixels that can be drawn; anything outside of the bounds will be entirely clipped out.

Implemented in GrFixedClip, skgpu::ganesh::StencilClip, LazyProxyTest::Clip, and skgpu::ganesh::ClipStack.

◆ GetPixelIBounds()

static SkIRect GrClip::GetPixelIBounds ( const SkRect bounds,
GrAA  aa,
BoundsType  mode = BoundsType::kExterior 
)
inlinestatic

Convert the analytic bounds of a shape into an integer pixel bounds, where the given aa type is used when the shape is rendered. The bounds mode can be used to query exterior or interior pixel boundaries. Interior bounds only make sense when its know that the analytic bounds are filled completely.

NOTE: When using kExterior_Bounds, some coverage-AA rendering methods may still touch a pixel center outside of these bounds but will evaluate to 0 coverage. This is visually acceptable, but an additional outset of 1px should be used for dst proxy access.

Definition at line 173 of file GrClip.h.

174 {
175 auto roundLow = [aa](float v) {
176 v += kBoundsTolerance;
179 };
180 auto roundHigh = [aa](float v) {
181 v -= kBoundsTolerance;
184 };
185
186 if (bounds.isEmpty()) {
187 return SkIRect::MakeEmpty();
188 }
189
190 if (mode == BoundsType::kExterior) {
191 return SkIRect::MakeLTRB(roundLow(bounds.fLeft), roundLow(bounds.fTop),
192 roundHigh(bounds.fRight), roundHigh(bounds.fBottom));
193 } else {
194 return SkIRect::MakeLTRB(roundHigh(bounds.fLeft), roundHigh(bounds.fTop),
195 roundLow(bounds.fRight), roundLow(bounds.fBottom));
196 }
197 }
#define SkScalarRoundToInt(x)
Definition SkScalar.h:37
#define SkScalarCeilToInt(x)
Definition SkScalar.h:36
#define SkScalarFloorToInt(x)
Definition SkScalar.h:35
static constexpr SkScalar kBoundsTolerance
Definition GrClip.h:110
static constexpr SkScalar kHalfPixelRoundingTolerance
Definition GrClip.h:120
Optional< SkRect > bounds
Definition SkRecords.h:189
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition SkRect.h:91
static constexpr SkIRect MakeEmpty()
Definition SkRect.h:45

◆ IsInsideClip()

static bool GrClip::IsInsideClip ( const SkIRect innerClipBounds,
const SkRect drawBounds,
GrAA  aa 
)
inlinestatic

Returns true if the given draw bounds count as entirely inside the clip.

Parameters
innerClipBoundsdevice-space rect fully contained by the clip
drawBoundsdevice-space bounds of the query region.

Definition at line 128 of file GrClip.h.

128 {
129 return innerClipBounds.contains(GetPixelIBounds(drawBounds, aa));
130 }
static SkIRect GetPixelIBounds(const SkRect &bounds, GrAA aa, BoundsType mode=BoundsType::kExterior)
Definition GrClip.h:173
bool contains(int32_t x, int32_t y) const
Definition SkRect.h:463

◆ IsOutsideClip()

static bool GrClip::IsOutsideClip ( const SkIRect outerClipBounds,
const SkRect drawBounds,
GrAA  aa 
)
inlinestatic

Returns true if the given draw bounds count as entirely outside the clip.

Parameters
outerClipBoundsdevice-space rect that contains the clip
drawBoundsdevice-space bounds of the query region.
aawhether or not the draw will use anti-aliasing

Definition at line 139 of file GrClip.h.

139 {
140 return !SkIRect::Intersects(outerClipBounds, GetPixelIBounds(drawBounds, aa));
141 }
static bool Intersects(const SkIRect &a, const SkIRect &b)
Definition SkRect.h:535

◆ IsPixelAligned()

static bool GrClip::IsPixelAligned ( const SkRect rect)
inlinestatic

Returns true if the given rect counts as aligned with pixel boundaries.

Definition at line 202 of file GrClip.h.

202 {
203 return SkScalarAbs(SkScalarRoundToScalar(rect.fLeft) - rect.fLeft) <= kBoundsTolerance &&
207 }
#define SkScalarRoundToScalar(x)
Definition SkScalar.h:32
#define SkScalarAbs(x)
Definition SkScalar.h:39
sk_sp< SkBlender > blender SkRect rect
Definition SkRecords.h:350

◆ preApply()

virtual PreClipResult GrClip::preApply ( const SkRect drawBounds,
GrAA  aa 
) const
inlinevirtual

Perform preliminary, conservative analysis on the draw bounds as if it were provided to apply(). The results of this are returned the PreClipResults struct, where 'result.fEffect' corresponds to what 'apply' would return. If this value is kUnclipped or kNoDraw, then it can be assumed that apply() would also always result in the same Effect.

If kClipped is returned, apply() may further refine the effect to kUnclipped or kNoDraw, with one exception. When 'result.fIsRRect' is true, preApply() reports the single round rect and anti-aliased state that would act as an intersection on the draw geometry. If no further action is taken to modify the draw, apply() will represent this round rect in the applied clip.

When set, 'result.fRRect' will intersect with the render target bounds but may extend beyond it. If the render target bounds are the only clip effect on the draw, this is reported as kUnclipped and not as a degenerate rrect that matches the bounds.

Reimplemented in GrFixedClip, skgpu::ganesh::StencilClip, and skgpu::ganesh::ClipStack.

Definition at line 97 of file GrClip.h.

97 {
98 SkIRect pixelBounds = GetPixelIBounds(drawBounds, aa);
99 bool outside = !SkIRect::Intersects(pixelBounds, this->getConservativeBounds());
100 return outside ? Effect::kClippedOut : Effect::kClipped;
101 }
virtual SkIRect getConservativeBounds() const =0

Member Data Documentation

◆ kBoundsTolerance

constexpr SkScalar GrClip::kBoundsTolerance = 1e-3f
staticconstexpr

This is the maximum distance that a draw may extend beyond a clip's boundary and still count count as "on the other side". We leave some slack because floating point rounding error is likely to blame. The rationale for 1e-3 is that in the coverage case (and barring unexpected rounding), as long as coverage stays within 0.5 * 1/256 of its intended value it shouldn't have any effect on the final pixel values.

Definition at line 110 of file GrClip.h.

◆ kHalfPixelRoundingTolerance

constexpr SkScalar GrClip::kHalfPixelRoundingTolerance = 5e-2f
staticconstexpr

This is the slack around a half-pixel vertex coordinate where we don't trust the GPU's rasterizer to round consistently. The rounding method is not defined in GPU specs, and rasterizer precision frequently introduces errors where a fraction < 1/2 still rounds up.

For non-AA bounds edges, an edge value between 0.45 and 0.55 will round in or round out depending on what side its on. Outside of this range, the non-AA edge will snap using round()

Definition at line 120 of file GrClip.h.


The documentation for this class was generated from the following file: