-
Notifications
You must be signed in to change notification settings - Fork 6k
Create blanket backdrop filter mutator #34408
Changes from all commits
afbb37a
5103d9d
825fbc8
4b5c705
24c077f
e1a817d
d06155c
452a0b7
6b74e7d
455b87f
bc1d19b
4c0f2a5
55d328c
d080e8e
93accab
a9cd101
abc3a0e
7ad4a02
5d9657a
a741bb9
5712cdb
097740e
e0466c2
2525dde
2e1731c
964c43a
c6ef165
e8fd78f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,53 +20,65 @@ | |
|
|
||
| namespace flutter { | ||
|
|
||
| // TODO(chinmaygarde): Make these enum names match the style guide. | ||
| enum MutatorType { clip_rect, clip_rrect, clip_path, transform, opacity }; | ||
| enum MutatorType { | ||
| kClipRect, | ||
| kClipRRect, | ||
| kClipPath, | ||
| kTransform, | ||
| kOpacity, | ||
| kBackdropFilter | ||
| }; | ||
|
|
||
| // Stores mutation information like clipping or transform. | ||
| // Stores mutation information like clipping or kTransform. | ||
| // | ||
| // The `type` indicates the type of the mutation: clip_rect, transform and etc. | ||
| // The `type` indicates the type of the mutation: kClipRect, kTransform and etc. | ||
| // Each `type` is paired with an object that supports the mutation. For example, | ||
| // if the `type` is clip_rect, `rect()` is used the represent the rect to be | ||
| // if the `type` is kClipRect, `rect()` is used the represent the rect to be | ||
| // clipped. One mutation object must only contain one type of mutation. | ||
| class Mutator { | ||
| public: | ||
| Mutator(const Mutator& other) { | ||
| type_ = other.type_; | ||
| switch (other.type_) { | ||
| case clip_rect: | ||
| case kClipRect: | ||
| rect_ = other.rect_; | ||
| break; | ||
| case clip_rrect: | ||
| case kClipRRect: | ||
| rrect_ = other.rrect_; | ||
| break; | ||
| case clip_path: | ||
| case kClipPath: | ||
| path_ = new SkPath(*other.path_); | ||
| break; | ||
| case transform: | ||
| case kTransform: | ||
| matrix_ = other.matrix_; | ||
| break; | ||
| case opacity: | ||
| case kOpacity: | ||
| alpha_ = other.alpha_; | ||
| break; | ||
| case kBackdropFilter: | ||
| filter_ = other.filter_; | ||
| break; | ||
| default: | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| explicit Mutator(const SkRect& rect) : type_(clip_rect), rect_(rect) {} | ||
| explicit Mutator(const SkRRect& rrect) : type_(clip_rrect), rrect_(rrect) {} | ||
| explicit Mutator(const SkRect& rect) : type_(kClipRect), rect_(rect) {} | ||
| explicit Mutator(const SkRRect& rrect) : type_(kClipRRect), rrect_(rrect) {} | ||
| explicit Mutator(const SkPath& path) | ||
| : type_(clip_path), path_(new SkPath(path)) {} | ||
| : type_(kClipPath), path_(new SkPath(path)) {} | ||
| explicit Mutator(const SkMatrix& matrix) | ||
| : type_(transform), matrix_(matrix) {} | ||
| explicit Mutator(const int& alpha) : type_(opacity), alpha_(alpha) {} | ||
| : type_(kTransform), matrix_(matrix) {} | ||
| explicit Mutator(const int& alpha) : type_(kOpacity), alpha_(alpha) {} | ||
| explicit Mutator(const DlImageFilter& filter) | ||
| : type_(kBackdropFilter), filter_(&filter) {} | ||
|
|
||
| const MutatorType& GetType() const { return type_; } | ||
| const SkRect& GetRect() const { return rect_; } | ||
| const SkRRect& GetRRect() const { return rrect_; } | ||
| const SkPath& GetPath() const { return *path_; } | ||
| const SkMatrix& GetMatrix() const { return matrix_; } | ||
| const DlImageFilter& GetFilter() const { return *filter_; } | ||
| const int& GetAlpha() const { return alpha_; } | ||
| float GetAlphaFloat() const { return (alpha_ / 255.0); } | ||
|
|
||
|
|
@@ -75,16 +87,18 @@ class Mutator { | |
| return false; | ||
| } | ||
| switch (type_) { | ||
| case clip_rect: | ||
| case kClipRect: | ||
| return rect_ == other.rect_; | ||
| case clip_rrect: | ||
| case kClipRRect: | ||
| return rrect_ == other.rrect_; | ||
| case clip_path: | ||
| case kClipPath: | ||
| return *path_ == *other.path_; | ||
| case transform: | ||
| case kTransform: | ||
| return matrix_ == other.matrix_; | ||
| case opacity: | ||
| case kOpacity: | ||
| return alpha_ == other.alpha_; | ||
| case kBackdropFilter: | ||
| return *filter_ == *other.filter_; | ||
| } | ||
|
|
||
| return false; | ||
|
|
@@ -93,11 +107,11 @@ class Mutator { | |
| bool operator!=(const Mutator& other) const { return !operator==(other); } | ||
|
|
||
| bool IsClipType() { | ||
| return type_ == clip_rect || type_ == clip_rrect || type_ == clip_path; | ||
| return type_ == kClipRect || type_ == kClipRRect || type_ == kClipPath; | ||
| } | ||
|
|
||
| ~Mutator() { | ||
| if (type_ == clip_path) { | ||
| if (type_ == kClipPath) { | ||
| delete path_; | ||
| } | ||
| }; | ||
|
|
@@ -111,6 +125,7 @@ class Mutator { | |
| SkMatrix matrix_; | ||
| SkPath* path_; | ||
| int alpha_; | ||
| const DlImageFilter* filter_; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These should be stored as std::shared_ptr. The lifecycle is probably not going to fail with the current architecture, but we should be safe. Also the SkPath object is supposed to be fast-copy in that it shares the underlying storage and marks the origin object as copy-on-write. Given that our paths never change, we could probably store an SkPath rather than a pointer.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good, I will make that change for the next PR. Thanks! |
||
| }; | ||
|
|
||
| }; // Mutator | ||
|
|
@@ -133,6 +148,7 @@ class MutatorsStack { | |
| void PushClipPath(const SkPath& path); | ||
| void PushTransform(const SkMatrix& matrix); | ||
| void PushOpacity(const int& alpha); | ||
| void PushBackdropFilter(const DlImageFilter& filter); | ||
|
|
||
| // Removes the `Mutator` on the top of the stack | ||
| // and destroys it. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,10 +36,10 @@ TEST(MutatorsStack, CopyAndUpdateTheCopy) { | |
| ASSERT_TRUE(copy.is_empty()); | ||
| ASSERT_TRUE(!stack.is_empty()); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::clip_rrect); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRRect); | ||
| ASSERT_TRUE(iter->get()->GetRRect() == rrect); | ||
| ++iter; | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::clip_rect); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRect); | ||
| ASSERT_TRUE(iter->get()->GetRect() == rect); | ||
| } | ||
|
|
||
|
|
@@ -48,7 +48,7 @@ TEST(MutatorsStack, PushClipRect) { | |
| auto rect = SkRect::MakeEmpty(); | ||
| stack.PushClipRect(rect); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::clip_rect); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRect); | ||
| ASSERT_TRUE(iter->get()->GetRect() == rect); | ||
| } | ||
|
|
||
|
|
@@ -57,7 +57,7 @@ TEST(MutatorsStack, PushClipRRect) { | |
| auto rrect = SkRRect::MakeEmpty(); | ||
| stack.PushClipRRect(rrect); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::clip_rrect); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRRect); | ||
| ASSERT_TRUE(iter->get()->GetRRect() == rrect); | ||
| } | ||
|
|
||
|
|
@@ -66,7 +66,7 @@ TEST(MutatorsStack, PushClipPath) { | |
| SkPath path; | ||
| stack.PushClipPath(path); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == flutter::MutatorType::clip_path); | ||
| ASSERT_TRUE(iter->get()->GetType() == flutter::MutatorType::kClipPath); | ||
| ASSERT_TRUE(iter->get()->GetPath() == path); | ||
| } | ||
|
|
||
|
|
@@ -76,7 +76,7 @@ TEST(MutatorsStack, PushTransform) { | |
| matrix.setIdentity(); | ||
| stack.PushTransform(matrix); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::transform); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kTransform); | ||
| ASSERT_TRUE(iter->get()->GetMatrix() == matrix); | ||
| } | ||
|
|
||
|
|
@@ -85,10 +85,19 @@ TEST(MutatorsStack, PushOpacity) { | |
| int alpha = 240; | ||
| stack.PushOpacity(alpha); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::opacity); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kOpacity); | ||
| ASSERT_TRUE(iter->get()->GetAlpha() == 240); | ||
| } | ||
|
|
||
| TEST(MutatorsStack, PushBackdropFilter) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It couldn't hurt to add a test to confirm that the == method on the mutators works for all types, including if they are fed copies of the original data (i.e. they compare by content rather than reference). |
||
| MutatorsStack stack; | ||
| auto filter = DlBlurImageFilter(5, 5, DlTileMode::kClamp); | ||
| stack.PushBackdropFilter(filter); | ||
| auto iter = stack.Bottom(); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kBackdropFilter); | ||
| ASSERT_TRUE(iter->get()->GetFilter() == filter); | ||
| } | ||
|
|
||
| TEST(MutatorsStack, Pop) { | ||
| MutatorsStack stack; | ||
| SkMatrix matrix; | ||
|
|
@@ -113,15 +122,15 @@ TEST(MutatorsStack, Traversal) { | |
| while (iter != stack.Top()) { | ||
| switch (index) { | ||
| case 0: | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::clip_rrect); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRRect); | ||
| ASSERT_TRUE(iter->get()->GetRRect() == rrect); | ||
| break; | ||
| case 1: | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::clip_rect); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kClipRect); | ||
| ASSERT_TRUE(iter->get()->GetRect() == rect); | ||
| break; | ||
| case 2: | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::transform); | ||
| ASSERT_TRUE(iter->get()->GetType() == MutatorType::kTransform); | ||
| ASSERT_TRUE(iter->get()->GetMatrix() == matrix); | ||
| break; | ||
| default: | ||
|
|
@@ -163,28 +172,28 @@ TEST(MutatorsStack, Equality) { | |
| TEST(Mutator, Initialization) { | ||
| SkRect rect = SkRect::MakeEmpty(); | ||
| Mutator mutator = Mutator(rect); | ||
| ASSERT_TRUE(mutator.GetType() == MutatorType::clip_rect); | ||
| ASSERT_TRUE(mutator.GetType() == MutatorType::kClipRect); | ||
| ASSERT_TRUE(mutator.GetRect() == rect); | ||
|
|
||
| SkRRect rrect = SkRRect::MakeEmpty(); | ||
| Mutator mutator2 = Mutator(rrect); | ||
| ASSERT_TRUE(mutator2.GetType() == MutatorType::clip_rrect); | ||
| ASSERT_TRUE(mutator2.GetType() == MutatorType::kClipRRect); | ||
| ASSERT_TRUE(mutator2.GetRRect() == rrect); | ||
|
|
||
| SkPath path; | ||
| Mutator mutator3 = Mutator(path); | ||
| ASSERT_TRUE(mutator3.GetType() == MutatorType::clip_path); | ||
| ASSERT_TRUE(mutator3.GetType() == MutatorType::kClipPath); | ||
| ASSERT_TRUE(mutator3.GetPath() == path); | ||
|
|
||
| SkMatrix matrix; | ||
| matrix.setIdentity(); | ||
| Mutator mutator4 = Mutator(matrix); | ||
| ASSERT_TRUE(mutator4.GetType() == MutatorType::transform); | ||
| ASSERT_TRUE(mutator4.GetType() == MutatorType::kTransform); | ||
| ASSERT_TRUE(mutator4.GetMatrix() == matrix); | ||
|
|
||
| int alpha = 240; | ||
| Mutator mutator5 = Mutator(alpha); | ||
| ASSERT_TRUE(mutator5.GetType() == MutatorType::opacity); | ||
| ASSERT_TRUE(mutator5.GetType() == MutatorType::kOpacity); | ||
| } | ||
|
|
||
| TEST(Mutator, CopyConstructor) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.