Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSGMaskEffect.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2018 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
9
18
19class SkMatrix;
20struct SkPoint;
21
22namespace sksg {
23
25 return static_cast<uint32_t>(mode) & 1;
26}
27
29 return static_cast<uint32_t>(mode) & 2;
30}
31
33 : INHERITED(std::move(child))
34 , fMaskNode(std::move(mask))
35 , fMaskMode(mode) {
36 this->observeInval(fMaskNode);
37}
38
40 this->unobserveInval(fMaskNode);
41}
42
43void MaskEffect::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
44 SkAutoCanvasRestore acr(canvas, false);
45
46 // The mask mode covers two independent bits.
47 //
48 // - mask source controls how the mask coverage is generated:
49 // * alpha => coverage = mask_alpha
50 // * luma => coverage = luma(mask_rgb)
51 //
52 // - mask type controls how the mask coverage is interpreted:
53 // * normal => coverage' = coverage
54 // * inverted => coverage' = 1 - coverage
55
56 {
57 // Outer layer: mask coverage stored in the alpha channel.
58 SkPaint mask_layer_paint;
59 if (ctx) {
60 // Apply all optional context overrides upfront.
61 ctx->modulatePaint(canvas->getTotalMatrix(), &mask_layer_paint);
62 }
63
64 RenderContext mask_render_context;
65 if (is_luma(fMaskMode)) {
66 mask_render_context.fColorFilter = SkLumaColorFilter::Make();
67 }
68
69 // TODO: could be an A8 layer?
70 canvas->saveLayer(this->bounds(), &mask_layer_paint);
71 fMaskNode->render(canvas, &mask_render_context);
72
73 {
74 // Inner layer: masked content.
75 SkPaint content_layer_paint;
76 content_layer_paint.setBlendMode(is_inverted(fMaskMode) ? SkBlendMode::kSrcOut
78 canvas->saveLayer(this->bounds(), &content_layer_paint);
79
80 this->INHERITED::onRender(canvas, nullptr);
81 }
82 }
83}
84
85const RenderNode* MaskEffect::onNodeAt(const SkPoint& p) const {
86 const auto mask_hit = (SkToBool(fMaskNode->nodeAt(p)) == !is_inverted(fMaskMode));
87
88 if (!mask_hit) {
89 return nullptr;
90 }
91
92 return this->INHERITED::onNodeAt(p);
93}
94
96 SkASSERT(this->hasInval());
97
98 const auto maskBounds = fMaskNode->revalidate(ic, ctm);
99 auto childBounds = this->INHERITED::onRevalidate(ic, ctm);
100
101 return (is_inverted(fMaskMode) || childBounds.intersect(maskBounds))
102 ? childBounds
104}
105
106} // namespace sksg
#define SkASSERT(cond)
Definition SkAssert.h:116
@ kSrcOut
r = s * (1-da)
@ kSrcIn
r = s * da
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition SkCanvas.cpp:500
SkMatrix getTotalMatrix() const
void setBlendMode(SkBlendMode mode)
Definition SkPaint.cpp:151
const RenderNode * onNodeAt(const SkPoint &) const override
void onRender(SkCanvas *, const RenderContext *) const override
SkRect onRevalidate(InvalidationController *, const SkMatrix &) override
const RenderNode * onNodeAt(const SkPoint &) const override
MaskEffect(sk_sp< RenderNode >, sk_sp< RenderNode > mask, Mode)
SkRect onRevalidate(InvalidationController *, const SkMatrix &) override
void onRender(SkCanvas *, const RenderContext *) const override
void observeInval(const sk_sp< Node > &)
Definition SkSGNode.cpp:61
void unobserveInval(const sk_sp< Node > &)
Definition SkSGNode.cpp:84
const SkRect & bounds() const
Definition SkSGNode.h:55
bool hasInval() const
Definition SkSGNode.h:60
Definition Skottie.h:32
static bool is_inverted(sksg::MaskEffect::Mode mode)
static bool is_luma(sksg::MaskEffect::Mode mode)
Definition ref_ptr.h:256
static sk_sp< SkColorFilter > Make()
static constexpr SkRect MakeEmpty()
Definition SkRect.h:595
sk_sp< SkColorFilter > fColorFilter
void modulatePaint(const SkMatrix &ctm, SkPaint *, bool is_layer_paint=false) const