Flutter Engine
The Flutter Engine
Public Member Functions | List of all members
skgpu::ganesh::StencilMaskHelper Class Reference

#include <StencilMaskHelper.h>

Inheritance diagram for skgpu::ganesh::StencilMaskHelper:
SkNoncopyable

Public Member Functions

 StencilMaskHelper (GrRecordingContext *, SurfaceDrawContext *)
 
bool init (const SkIRect &maskBounds, uint32_t genID, const GrWindowRectangles &windowRects, int numFPs)
 
void drawRect (const SkRect &rect, const SkMatrix &matrix, SkRegion::Op, GrAA)
 
bool drawPath (const SkPath &path, const SkMatrix &matrix, SkRegion::Op, GrAA)
 
bool drawShape (const GrShape &shape, const SkMatrix &matrix, SkRegion::Op, GrAA)
 
void clear (bool insideStencil)
 
void finish ()
 

Detailed Description

The StencilMaskHelper helps generate clip masks using the stencil buffer. It is intended to be used as:

StencilMaskHelper helper; helper.init(...);

draw one or more paths/rects specifying the required boolean ops

helper.finish();

The result of this process will be the mask stored in the clip bits of the stencil buffer.

Definition at line 37 of file StencilMaskHelper.h.

Constructor & Destructor Documentation

◆ StencilMaskHelper()

skgpu::ganesh::StencilMaskHelper::StencilMaskHelper ( GrRecordingContext rContext,
SurfaceDrawContext sdc 
)

Definition at line 346 of file StencilMaskHelper.cpp.

348 : fContext(rContext)
349 , fSDC(sdc)
350 , fClip(sdc->dimensions()) {
351}

Member Function Documentation

◆ clear()

void skgpu::ganesh::StencilMaskHelper::clear ( bool  insideStencil)

Definition at line 488 of file StencilMaskHelper.cpp.

488 {
489 if (fClip.fixedClip().hasWindowRectangles()) {
490 // Use a draw to benefit from window rectangles when resetting the stencil buffer; for
491 // large buffers with MSAA this can be significant.
492 draw_stencil_rect(fSDC, fClip.fixedClip(),
495 } else {
496 fSDC->clearStencilClip(fClip.fixedClip().scissorRect(), insideStencil);
497 }
498}
const SkIRect & scissorRect() const
Definition: GrFixedClip.h:29
bool hasWindowRectangles() const
Definition: GrFixedClip.h:41
static const GrUserStencilSettings * SetClipBitSettings(bool setToInside)
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
const GrFixedClip & fixedClip() const
Definition: StencilClip.h:31
void clearStencilClip(const SkIRect &scissor, bool insideStencilMask)
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669

◆ drawPath()

bool skgpu::ganesh::StencilMaskHelper::drawPath ( const SkPath path,
const SkMatrix matrix,
SkRegion::Op  op,
GrAA  aa 
)

Definition at line 400 of file StencilMaskHelper.cpp.

403 {
404 if (path.isEmpty()) {
405 return true;
406 }
407
408 // drawPath follows a similar approach to drawRect(), where we either draw directly to the clip
409 // bit or first draw to client bits and then apply a cover pass. The complicating factor is that
410 // we rely on path rendering and how the chosen path renderer uses the stencil buffer.
411 aa = supported_aa(fSDC, aa);
412
413 GrAAType pathAAType = aa == GrAA::kYes ? GrAAType::kMSAA : GrAAType::kNone;
414
415 // This will be used to determine whether the clip shape can be rendered into the
416 // stencil with arbitrary stencil settings.
417 PathRenderer::StencilSupport stencilSupport;
418
419 // Make path canonical with regards to fill type (inverse handled by stencil settings).
420 bool fillInverted = path.isInverseFillType();
422 if (fillInverted) {
423 clipPath.writable()->toggleInverseFillType();
424 }
425
427 SkASSERT(!shape.inverseFilled());
428
429 PathRenderer::CanDrawPathArgs canDrawArgs;
430 canDrawArgs.fCaps = fContext->priv().caps();
431 canDrawArgs.fProxy = fSDC->asRenderTargetProxy();
432 canDrawArgs.fClipConservativeBounds = &fClip.fixedClip().scissorRect();
433 canDrawArgs.fViewMatrix = &matrix;
434 canDrawArgs.fShape = &shape;
435 canDrawArgs.fPaint = nullptr;
436 canDrawArgs.fSurfaceProps = &fSDC->surfaceProps();
437 canDrawArgs.fAAType = pathAAType;
438 canDrawArgs.fHasUserStencilSettings = false;
439
440 auto pr = fContext->priv().drawingManager()->getPathRenderer(
441 canDrawArgs, false, PathRendererChain::DrawType::kStencil, &stencilSupport);
442 if (!pr) {
443 return false;
444 }
445
446 bool drawDirectToClip;
447 auto passes = get_stencil_passes(op, stencilSupport, fillInverted, &drawDirectToClip);
448
449 // Write to client bits if necessary
450 if (!drawDirectToClip) {
451 if (stencilSupport == PathRenderer::kNoRestriction_StencilSupport) {
452 draw_path(fContext, fSDC, pr, fClip.fixedClip(), fClip.fixedClip().scissorRect(),
453 &gDrawToStencil, matrix, shape, aa);
454 } else {
455 stencil_path(fContext, fSDC, pr, fClip.fixedClip(), matrix, shape, aa);
456 }
457 }
458
459 // Now modify the clip bit (either by rendering directly), or by covering the bounding box
460 // of the clip
461 for (GrUserStencilSettings const* const* pass = passes; *pass; ++pass) {
462 if (drawDirectToClip) {
463 draw_path(fContext, fSDC, pr, fClip, fClip.fixedClip().scissorRect(),
464 *pass, matrix, shape, aa);
465 } else {
466 draw_stencil_rect(fSDC, fClip, *pass, SkMatrix::I(),
467 SkRect::Make(fClip.fixedClip().scissorRect()), aa);
468 }
469 }
470
471 return true;
472}
GrAAType
Definition: GrTypesPriv.h:200
#define SkASSERT(cond)
Definition: SkAssert.h:116
const GrCaps * caps() const
PathRenderer * getPathRenderer(const PathRenderer::CanDrawPathArgs &, bool allowSW, PathRendererChain::DrawType, PathRenderer::StencilSupport *=nullptr)
GrDrawingManager * drawingManager()
GrRecordingContextPriv priv()
static const GrStyle & SimpleFill()
Definition: GrStyle.h:30
GrRenderTargetProxy * asRenderTargetProxy()
const SkSurfaceProps & surfaceProps() const
static void draw_path(SkCanvas *canvas, const SkRect &r, sk_sp< SkImageFilter > imf)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
clipPath(r.path, r.opAA.op(), r.opAA.aa())) DRAW(ClipRRect
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57

◆ drawRect()

void skgpu::ganesh::StencilMaskHelper::drawRect ( const SkRect rect,
const SkMatrix matrix,
SkRegion::Op  op,
GrAA  aa 
)

Definition at line 370 of file StencilMaskHelper.cpp.

373 {
374 if (rect.isEmpty()) {
375 return;
376 }
377
378 bool drawDirectToClip;
379 auto passes = get_stencil_passes(op, PathRenderer::kNoRestriction_StencilSupport,
380 false, &drawDirectToClip);
381 aa = supported_aa(fSDC, aa);
382
383 if (!drawDirectToClip) {
384 // Draw to client stencil bits first
385 draw_stencil_rect(fSDC, fClip.fixedClip(), &gDrawToStencil, matrix, rect, aa);
386 }
387
388 // Now modify the clip bit (either by rendering directly), or by covering the bounding box
389 // of the clip
390 for (GrUserStencilSettings const* const* pass = passes; *pass; ++pass) {
391 if (drawDirectToClip) {
392 draw_stencil_rect(fSDC, fClip, *pass, matrix, rect, aa);
393 } else {
394 draw_stencil_rect(fSDC, fClip, *pass, SkMatrix::I(),
395 SkRect::Make(fClip.fixedClip().scissorRect()), aa);
396 }
397 }
398}
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350

◆ drawShape()

bool skgpu::ganesh::StencilMaskHelper::drawShape ( const GrShape shape,
const SkMatrix matrix,
SkRegion::Op  op,
GrAA  aa 
)

Definition at line 474 of file StencilMaskHelper.cpp.

477 {
478 if (shape.isRect() && !shape.inverted()) {
479 this->drawRect(shape.rect(), matrix, op, aa);
480 return true;
481 } else {
482 SkPath p;
483 shape.asPath(&p);
484 return this->drawPath(p, matrix, op, aa);
485 }
486}
SkRect & rect()
Definition: GrShape.h:134
bool isRect() const
Definition: GrShape.h:86
bool inverted() const
Definition: GrShape.h:99
void asPath(SkPath *out, bool simpleFill=true) const
Definition: GrShape.cpp:423
Definition: SkPath.h:59
void drawRect(const SkRect &rect, const SkMatrix &matrix, SkRegion::Op, GrAA)
bool drawPath(const SkPath &path, const SkMatrix &matrix, SkRegion::Op, GrAA)

◆ finish()

void skgpu::ganesh::StencilMaskHelper::finish ( )

Definition at line 500 of file StencilMaskHelper.cpp.

500 {
501 fSDC->setLastClip(fClip.stencilStackID(), fClip.fixedClip().scissorRect(), fNumFPs);
502}
uint32_t stencilStackID() const
Definition: StencilClip.h:34
void setLastClip(uint32_t clipStackGenID, const SkIRect &devClipBounds, int numClipAnalyticElements)

◆ init()

bool skgpu::ganesh::StencilMaskHelper::init ( const SkIRect maskBounds,
uint32_t  genID,
const GrWindowRectangles windowRects,
int  numFPs 
)

Definition at line 353 of file StencilMaskHelper.cpp.

354 {
355 if (!fSDC->mustRenderClip(genID, bounds, numFPs)) {
356 return false;
357 }
358
359 fClip.setStencilClip(genID);
360 // Should have caught bounds not intersecting the render target much earlier in clip application
362 if (!windowRects.empty()) {
365 }
366 fNumFPs = numFPs;
367 return true;
368}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
void setWindowRectangles(const GrWindowRectangles &windows, GrWindowRectsState::Mode mode)
Definition: GrFixedClip.h:45
bool setScissor(const SkIRect &irect)
Definition: GrFixedClip.h:33
void setStencilClip(uint32_t stencilStackID)
Definition: StencilClip.h:36
bool mustRenderClip(uint32_t clipStackGenID, const SkIRect &devClipBounds, int numClipAnalyticElements)
Optional< SkRect > bounds
Definition: SkRecords.h:189

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