diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index c85ad66f8dc75..32acb94fc2296 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -36,6 +36,11 @@ void MutatorsStack::PushOpacity(const int& alpha) { vector_.push_back(element); }; +void MutatorsStack::PushBackdropFilter(const DlImageFilter& filter) { + std::shared_ptr element = std::make_shared(filter); + vector_.push_back(element); +}; + void MutatorsStack::Pop() { vector_.pop_back(); }; diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 7a5a34f33069b..5e801dea40846 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -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_; }; }; // 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. diff --git a/flow/mutators_stack_unittests.cc b/flow/mutators_stack_unittests.cc index b165f68efc221..cfc642dff1f1c 100644 --- a/flow/mutators_stack_unittests.cc +++ b/flow/mutators_stack_unittests.cc @@ -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) { + 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) { diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 79bea738b6a68..a123d152f6ec7 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -1412,7 +1412,7 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView( mutators_stack.Begin(); while (iter != mutators_stack.End()) { switch ((*iter)->GetType()) { - case transform: { + case kTransform: { const SkMatrix& matrix = (*iter)->GetMatrix(); SkScalar matrix_array[9]; matrix.get9(matrix_array); @@ -1425,7 +1425,7 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView( transformMatrix.obj()); break; } - case clip_rect: { + case kClipRect: { const SkRect& rect = (*iter)->GetRect(); env->CallVoidMethod( mutatorsStack, g_mutators_stack_push_cliprect_method, @@ -1433,7 +1433,7 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView( static_cast(rect.right()), static_cast(rect.bottom())); break; } - case clip_rrect: { + case kClipRRect: { const SkRRect& rrect = (*iter)->GetRRect(); const SkRect& rect = rrect.rect(); const SkVector& upper_left = rrect.radii(SkRRect::kUpperLeft_Corner); @@ -1455,8 +1455,9 @@ void PlatformViewAndroidJNIImpl::FlutterViewOnDisplayPlatformView( } // TODO(cyanglaz): Implement other mutators. // https://github.com/flutter/flutter/issues/58426 - case clip_path: - case opacity: + case kClipPath: + case kOpacity: + case kBackdropFilter: break; } ++iter; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index e5325aee855b6..16ae589c32185 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -405,23 +405,25 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree { auto iter = mutators_stack.Begin(); while (iter != mutators_stack.End()) { switch ((*iter)->GetType()) { - case transform: { + case kTransform: { CATransform3D transform = GetCATransform3DFromSkMatrix((*iter)->GetMatrix()); finalTransform = CATransform3DConcat(transform, finalTransform); break; } - case clip_rect: + case kClipRect: [maskView clipRect:(*iter)->GetRect() matrix:finalTransform]; break; - case clip_rrect: + case kClipRRect: [maskView clipRRect:(*iter)->GetRRect() matrix:finalTransform]; break; - case clip_path: + case kClipPath: [maskView clipPath:(*iter)->GetPath() matrix:finalTransform]; break; - case opacity: + case kOpacity: embedded_view.alpha = (*iter)->GetAlphaFloat() * embedded_view.alpha; break; + case kBackdropFilter: + break; } ++iter; } diff --git a/shell/platform/embedder/embedder_layers.cc b/shell/platform/embedder/embedder_layers.cc index 4716ea15683dd..7d9a4bc9a8892 100644 --- a/shell/platform/embedder/embedder_layers.cc +++ b/shell/platform/embedder/embedder_layers.cc @@ -115,22 +115,22 @@ void EmbedderLayers::PushPlatformViewLayer( for (auto i = mutators.Bottom(); i != mutators.Top(); ++i) { const auto& mutator = *i; switch (mutator->GetType()) { - case MutatorType::clip_rect: { + case MutatorType::kClipRect: { mutations_array.push_back( mutations_referenced_ .emplace_back(ConvertMutation(mutator->GetRect())) .get()); } break; - case MutatorType::clip_rrect: { + case MutatorType::kClipRRect: { mutations_array.push_back( mutations_referenced_ .emplace_back(ConvertMutation(mutator->GetRRect())) .get()); } break; - case MutatorType::clip_path: { + case MutatorType::kClipPath: { // Unsupported mutation. } break; - case MutatorType::transform: { + case MutatorType::kTransform: { const auto& matrix = mutator->GetMatrix(); if (!matrix.isIdentity()) { mutations_array.push_back( @@ -138,7 +138,7 @@ void EmbedderLayers::PushPlatformViewLayer( .get()); } } break; - case MutatorType::opacity: { + case MutatorType::kOpacity: { const double opacity = std::clamp(mutator->GetAlphaFloat(), 0.0f, 1.0f); if (opacity < 1.0) { @@ -147,6 +147,8 @@ void EmbedderLayers::PushPlatformViewLayer( .get()); } } break; + case MutatorType::kBackdropFilter: + break; } } diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc index fb81886c1f000..03924fcdda5d0 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc @@ -442,28 +442,28 @@ FlatlandExternalViewEmbedder::ParseMutatorStack( for (auto i = mutators_stack.Begin(); i != mutators_stack.End(); ++i) { const auto& mutator = *i; switch (mutator->GetType()) { - case flutter::MutatorType::opacity: { + case flutter::MutatorType::kOpacity: { mutators.opacity *= std::clamp(mutator->GetAlphaFloat(), 0.f, 1.f); } break; - case flutter::MutatorType::transform: { + case flutter::MutatorType::kTransform: { total_transform.preConcat(mutator->GetMatrix()); transform_accumulator.preConcat(mutator->GetMatrix()); } break; - case flutter::MutatorType::clip_rect: { + case flutter::MutatorType::kClipRect: { mutators.clips.emplace_back(TransformedClip{ .transform = transform_accumulator, .rect = mutator->GetRect(), }); transform_accumulator = SkMatrix::I(); } break; - case flutter::MutatorType::clip_rrect: { + case flutter::MutatorType::kClipRRect: { mutators.clips.emplace_back(TransformedClip{ .transform = transform_accumulator, .rect = mutator->GetRRect().getBounds(), }); transform_accumulator = SkMatrix::I(); } break; - case flutter::MutatorType::clip_path: { + case flutter::MutatorType::kClipPath: { mutators.clips.emplace_back(TransformedClip{ .transform = transform_accumulator, .rect = mutator->GetPath().getBounds(), diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc index 225cf31b0c3c0..388671808f001 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc @@ -26,28 +26,28 @@ ViewMutators ParseMutatorStack(const flutter::MutatorsStack& mutators_stack) { for (auto i = mutators_stack.Begin(); i != mutators_stack.End(); ++i) { const auto& mutator = *i; switch (mutator->GetType()) { - case flutter::MutatorType::opacity: { + case flutter::MutatorType::kOpacity: { mutators.opacity *= std::clamp(mutator->GetAlphaFloat(), 0.f, 1.f); } break; - case flutter::MutatorType::transform: { + case flutter::MutatorType::kTransform: { total_transform.preConcat(mutator->GetMatrix()); transform_accumulator.preConcat(mutator->GetMatrix()); } break; - case flutter::MutatorType::clip_rect: { + case flutter::MutatorType::kClipRect: { mutators.clips.emplace_back(TransformedClip{ .transform = transform_accumulator, .rect = mutator->GetRect(), }); transform_accumulator = SkMatrix::I(); } break; - case flutter::MutatorType::clip_rrect: { + case flutter::MutatorType::kClipRRect: { mutators.clips.emplace_back(TransformedClip{ .transform = transform_accumulator, .rect = mutator->GetRRect().getBounds(), }); transform_accumulator = SkMatrix::I(); } break; - case flutter::MutatorType::clip_path: { + case flutter::MutatorType::kClipPath: { mutators.clips.emplace_back(TransformedClip{ .transform = transform_accumulator, .rect = mutator->GetPath().getBounds(),