From 6ba55aaf8699d3df2a6a3f92f2946ff9733aa728 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Tue, 25 Jun 2019 10:45:46 -0700 Subject: [PATCH] Revert "IOS Platform view transform/clipping (#9075)" This reverts commit ebb5b909fbb10dad2275acd4fc8ec1d9744a0bf6. Seeing the following breakage on host build: ``` ../../flutter/flow/scene_update_context.cc:205:36: error: non-const lvalue reference to type 'flutter::MutatorsStack' cannot bind to a value of unrelated type 'const flutter::Stopwatch' frame.context().raster_time(), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../flutter/flow/scene_update_context.cc:207:36: error: no viable conversion from 'flutter::TextureRegistry' to 'const flutter::Stopwatch' frame.context().texture_registry(), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../flutter/flow/instrumentation.h:55:32: note: candidate constructor not viable: no known conversion from 'flutter::TextureRegistry' to 'const flutter::Stopwatch &' for 1st argument FML_DISALLOW_COPY_AND_ASSIGN(Stopwatch); ^ ../../flutter/fml/macros.h:28:3: note: expanded from macro 'FML_DISALLOW_COPY_AND_ASSIGN' TypeName(const TypeName&) = delete; \ ^ ../../flutter/flow/scene_update_context.cc:208:36: error: non-const lvalue reference to type 'flutter::TextureRegistry' cannot bind to a temporary of type 'flutter::RasterCache *' &frame.context().raster_cache(), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../flutter/flow/scene_update_context.cc:209:36: error: cannot initialize a member subobject of type 'const flutter::RasterCache *' with an rvalue of type 'bool' false}; ^~~~~ ``` --- ci/licenses_golden/licenses_flutter | 1 - flow/BUILD.gn | 1 - flow/embedded_views.cc | 30 --- flow/embedded_views.h | 158 +-------------- flow/layers/clip_rect_layer.cc | 3 - flow/layers/clip_rrect_layer.cc | 3 - flow/layers/layer.h | 1 - flow/layers/layer_tree.cc | 4 - .../performance_overlay_layer_unittests.cc | 9 +- flow/layers/platform_view_layer.cc | 1 - flow/layers/transform_layer.cc | 3 - flow/mutators_stack_unittests.cc | 180 ------------------ flow/raster_cache.cc | 2 - .../framework/Source/FlutterPlatformViews.mm | 151 ++------------- .../Source/FlutterPlatformViews_Internal.h | 64 ------- .../Source/FlutterPlatformViews_Internal.mm | 140 -------------- 16 files changed, 23 insertions(+), 728 deletions(-) delete mode 100644 flow/mutators_stack_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 053832d1bd1cd..d877f2acf507a 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -71,7 +71,6 @@ FILE: ../../../flutter/flow/layers/transform_layer.h FILE: ../../../flutter/flow/matrix_decomposition.cc FILE: ../../../flutter/flow/matrix_decomposition.h FILE: ../../../flutter/flow/matrix_decomposition_unittests.cc -FILE: ../../../flutter/flow/mutators_stack_unittests.cc FILE: ../../../flutter/flow/paint_utils.cc FILE: ../../../flutter/flow/paint_utils.h FILE: ../../../flutter/flow/raster_cache.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 133cddca4fcd7..c578a95bd6a18 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -114,7 +114,6 @@ executable("flow_unittests") { "layers/performance_overlay_layer_unittests.cc", "layers/physical_shape_layer_unittests.cc", "matrix_decomposition_unittests.cc", - "mutators_stack_unittests.cc", "raster_cache_unittests.cc", ] diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index 9bbd913748079..e37a837deec0e 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -9,34 +9,4 @@ namespace flutter { bool ExternalViewEmbedder::SubmitFrame(GrContext* context) { return false; }; - -void MutatorsStack::pushClipRect(const SkRect& rect) { - std::shared_ptr element = std::make_shared(rect); - vector_.push_back(element); -}; - -void MutatorsStack::pushClipRRect(const SkRRect& rrect) { - std::shared_ptr element = std::make_shared(rrect); - vector_.push_back(element); -}; - -void MutatorsStack::pushTransform(const SkMatrix& matrix) { - std::shared_ptr element = std::make_shared(matrix); - vector_.push_back(element); -}; - -void MutatorsStack::pop() { - vector_.pop_back(); -}; - -const std::vector>::const_reverse_iterator -MutatorsStack::top() const { - return vector_.rend(); -}; - -const std::vector>::const_reverse_iterator -MutatorsStack::bottom() const { - return vector_.rbegin(); -}; - } // namespace flutter diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 88cfac45d28b2..d37c18f383221 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -9,169 +9,18 @@ #include "flutter/fml/memory/ref_counted.h" #include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPoint.h" -#include "third_party/skia/include/core/SkRRect.h" -#include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { -enum MutatorType { clip_rect, clip_rrect, clip_path, transform }; - -// Stores mutation information like clipping or transform. -// -// The `type` indicates the type of the mutation: clip_rect, transform 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 -// 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: - rect_ = other.rect_; - break; - case clip_rrect: - rrect_ = other.rrect_; - break; - case clip_path: - path_ = new SkPath(*other.path_); - break; - case transform: - matrix_ = other.matrix_; - 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 SkPath& path) - : type_(clip_path), path_(new SkPath(path)) {} - explicit Mutator(const SkMatrix& matrix) - : type_(transform), matrix_(matrix) {} - - const MutatorType& type() const { return type_; } - const SkRect& rect() const { return rect_; } - const SkRRect& rrect() const { return rrect_; } - const SkPath& path() const { return *path_; } - const SkMatrix& matrix() const { return matrix_; } - - bool operator==(const Mutator& other) const { - if (type_ != other.type_) { - return false; - } - if (type_ == clip_rect && rect_ == other.rect_) { - return true; - } - if (type_ == clip_rrect && rrect_ == other.rrect_) { - return true; - } - if (type_ == clip_path && *path_ == *other.path_) { - return true; - } - if (type_ == transform && matrix_ == other.matrix_) { - return true; - } - - return false; - } - - bool operator!=(const Mutator& other) const { return !operator==(other); } - - bool isClipType() { - return type_ == clip_rect || type_ == clip_rrect || type_ == clip_path; - } - - ~Mutator() { - if (type_ == clip_path) { - delete path_; - } - }; - - private: - MutatorType type_; - - union { - SkRect rect_; - SkRRect rrect_; - SkMatrix matrix_; - SkPath* path_; - }; - -}; // Mutator - -// A stack of mutators that can be applied to an embedded platform view. -// -// The stack may include mutators like transforms and clips, each mutator -// applies to all the mutators that are below it in the stack and to the -// embedded view. -// -// For example consider the following stack: [T1, T2, T3], where T1 is the top -// of the stack and T3 is the bottom of the stack. Applying this mutators stack -// to a platform view P1 will result in T1(T2(T2(P1))). -class MutatorsStack { - public: - MutatorsStack() = default; - - void pushClipRect(const SkRect& rect); - void pushClipRRect(const SkRRect& rrect); - void pushClipPath(const SkPath& path); - - void pushTransform(const SkMatrix& matrix); - - // Removes the `Mutator` on the top of the stack - // and destroys it. - void pop(); - - // Returns an iterator pointing to the top of the stack. - const std::vector>::const_reverse_iterator top() - const; - // Returns an iterator pointing to the bottom of the stack. - const std::vector>::const_reverse_iterator bottom() - const; - - bool operator==(const MutatorsStack& other) const { - if (vector_.size() != other.vector_.size()) { - return false; - } - for (size_t i = 0; i < vector_.size(); i++) { - if (*vector_[i] != *other.vector_[i]) { - return false; - } - } - return true; - } - - bool operator!=(const MutatorsStack& other) const { - return !operator==(other); - } - - private: - std::vector> vector_; -}; // MutatorsStack - class EmbeddedViewParams { public: - EmbeddedViewParams() = default; - - EmbeddedViewParams(const EmbeddedViewParams& other) { - offsetPixels = other.offsetPixels; - sizePoints = other.sizePoints; - mutatorsStack = other.mutatorsStack; - }; - SkPoint offsetPixels; SkSize sizePoints; - MutatorsStack mutatorsStack; bool operator==(const EmbeddedViewParams& other) const { - return offsetPixels == other.offsetPixels && - sizePoints == other.sizePoints && - mutatorsStack == other.mutatorsStack; + return offsetPixels == other.offsetPixels && sizePoints == other.sizePoints; } }; @@ -179,8 +28,6 @@ class EmbeddedViewParams { // in this case ExternalViewEmbedder is a reference to the // FlutterPlatformViewsController which is owned by FlutterViewController. class ExternalViewEmbedder { - // TODO(cyanglaz): Make embedder own the `EmbeddedViewParams`. - public: ExternalViewEmbedder() = default; @@ -199,8 +46,7 @@ class ExternalViewEmbedder { virtual ~ExternalViewEmbedder() = default; FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder); - -}; // ExternalViewEmbedder +}; } // namespace flutter diff --git a/flow/layers/clip_rect_layer.cc b/flow/layers/clip_rect_layer.cc index 31562649e1829..103e2e021a92e 100644 --- a/flow/layers/clip_rect_layer.cc +++ b/flow/layers/clip_rect_layer.cc @@ -50,8 +50,6 @@ void ClipRectLayer::Paint(PaintContext& context) const { SkAutoCanvasRestore save(context.internal_nodes_canvas, true); context.internal_nodes_canvas->clipRect(clip_rect_, clip_behavior_ != Clip::hardEdge); - context.mutators_stack.pushClipRect(clip_rect_); - if (clip_behavior_ == Clip::antiAliasWithSaveLayer) { context.internal_nodes_canvas->saveLayer(clip_rect_, nullptr); } @@ -59,7 +57,6 @@ void ClipRectLayer::Paint(PaintContext& context) const { if (clip_behavior_ == Clip::antiAliasWithSaveLayer) { context.internal_nodes_canvas->restore(); } - context.mutators_stack.pop(); } } // namespace flutter diff --git a/flow/layers/clip_rrect_layer.cc b/flow/layers/clip_rrect_layer.cc index 5308b806a1e88..cf866089b84b0 100644 --- a/flow/layers/clip_rrect_layer.cc +++ b/flow/layers/clip_rrect_layer.cc @@ -58,8 +58,6 @@ void ClipRRectLayer::Paint(PaintContext& context) const { SkAutoCanvasRestore save(context.internal_nodes_canvas, true); context.internal_nodes_canvas->clipRRect(clip_rrect_, clip_behavior_ != Clip::hardEdge); - context.mutators_stack.pushClipRRect(clip_rrect_); - if (clip_behavior_ == Clip::antiAliasWithSaveLayer) { context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr); } @@ -67,7 +65,6 @@ void ClipRRectLayer::Paint(PaintContext& context) const { if (clip_behavior_ == Clip::antiAliasWithSaveLayer) { context.internal_nodes_canvas->restore(); } - context.mutators_stack.pop(); } } // namespace flutter diff --git a/flow/layers/layer.h b/flow/layers/layer.h index 5e30a50c907f9..7400af5468214 100644 --- a/flow/layers/layer.h +++ b/flow/layers/layer.h @@ -83,7 +83,6 @@ class Layer { SkCanvas* leaf_nodes_canvas; GrContext* gr_context; ExternalViewEmbedder* view_embedder; - MutatorsStack& mutators_stack; const Stopwatch& raster_time; const Stopwatch& ui_time; TextureRegistry& texture_registry; diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index 57bc87838980b..5de5f9a48fba9 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -83,13 +83,11 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame, } } - MutatorsStack stack; Layer::PaintContext context = { (SkCanvas*)&internal_nodes_canvas, frame.canvas(), frame.gr_context(), frame.view_embedder(), - stack, frame.context().raster_time(), frame.context().ui_time(), frame.context().texture_registry(), @@ -110,7 +108,6 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { return nullptr; } - MutatorsStack unused_stack; const Stopwatch unused_stopwatch; TextureRegistry unused_texture_registry; SkMatrix root_surface_transformation; @@ -138,7 +135,6 @@ sk_sp LayerTree::Flatten(const SkRect& bounds) { canvas, // canvas nullptr, nullptr, - unused_stack, unused_stopwatch, // frame time (dont care) unused_stopwatch, // engine time (dont care) unused_texture_registry, // texture registry (not supported) diff --git a/flow/layers/performance_overlay_layer_unittests.cc b/flow/layers/performance_overlay_layer_unittests.cc index f82b0e2963869..0de07c9a70878 100644 --- a/flow/layers/performance_overlay_layer_unittests.cc +++ b/flow/layers/performance_overlay_layer_unittests.cc @@ -47,13 +47,10 @@ TEST(PerformanceOverlayLayer, Gold) { ASSERT_TRUE(surface != nullptr); flutter::TextureRegistry unused_texture_registry; - flutter::MutatorsStack unused_stack; + flutter::Layer::PaintContext paintContext = { - nullptr, surface->getCanvas(), - nullptr, nullptr, - unused_stack, mock_stopwatch, - mock_stopwatch, unused_texture_registry, - nullptr, false}; + nullptr, surface->getCanvas(), nullptr, nullptr, mock_stopwatch, + mock_stopwatch, unused_texture_registry, nullptr, false}; // Specify font file to ensure the same font across different operation // systems. diff --git a/flow/layers/platform_view_layer.cc b/flow/layers/platform_view_layer.cc index c7845a867de61..9fde621a6a22c 100644 --- a/flow/layers/platform_view_layer.cc +++ b/flow/layers/platform_view_layer.cc @@ -37,7 +37,6 @@ void PlatformViewLayer::Paint(PaintContext& context) const { params.offsetPixels = SkPoint::Make(transform.getTranslateX(), transform.getTranslateY()); params.sizePoints = size_; - params.mutatorsStack = context.mutators_stack; SkCanvas* canvas = context.view_embedder->CompositeEmbeddedView(view_id_, params); diff --git a/flow/layers/transform_layer.cc b/flow/layers/transform_layer.cc index 1a63ff8a48431..f0a925dcd2f50 100644 --- a/flow/layers/transform_layer.cc +++ b/flow/layers/transform_layer.cc @@ -66,10 +66,7 @@ void TransformLayer::Paint(PaintContext& context) const { SkAutoCanvasRestore save(context.internal_nodes_canvas, true); context.internal_nodes_canvas->concat(transform_); - context.mutators_stack.pushTransform(transform_); - PaintChildren(context); - context.mutators_stack.pop(); } } // namespace flutter diff --git a/flow/mutators_stack_unittests.cc b/flow/mutators_stack_unittests.cc deleted file mode 100644 index 16d4b3d5a8ba0..0000000000000 --- a/flow/mutators_stack_unittests.cc +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/flow/embedded_views.h" -#include "gtest/gtest.h" - -TEST(MutatorsStack, Initialization) { - flutter::MutatorsStack stack; - ASSERT_TRUE(true); -} - -TEST(MutatorsStack, CopyConstructor) { - flutter::MutatorsStack stack; - SkRRect rrect; - SkRect rect; - stack.pushClipRect(rect); - stack.pushClipRRect(rrect); - flutter::MutatorsStack copy = flutter::MutatorsStack(stack); - ASSERT_TRUE(copy == stack); -} - -TEST(MutatorsStack, PushClipRect) { - flutter::MutatorsStack stack; - SkRect rect; - stack.pushClipRect(rect); - auto iter = stack.bottom(); - ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::clip_rect); - ASSERT_TRUE(iter->get()->rect() == rect); -} - -TEST(MutatorsStack, PushClipRRect) { - flutter::MutatorsStack stack; - SkRRect rrect; - stack.pushClipRRect(rrect); - auto iter = stack.bottom(); - ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::clip_rrect); - ASSERT_TRUE(iter->get()->rrect() == rrect); -} - -TEST(MutatorsStack, PushTransform) { - flutter::MutatorsStack stack; - SkMatrix matrix; - stack.pushTransform(matrix); - auto iter = stack.bottom(); - ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::transform); - ASSERT_TRUE(iter->get()->matrix() == matrix); -} - -TEST(MutatorsStack, Pop) { - flutter::MutatorsStack stack; - SkMatrix matrix; - stack.pushTransform(matrix); - stack.pop(); - auto iter = stack.bottom(); - ASSERT_TRUE(iter == stack.top()); -} - -TEST(MutatorsStack, Traversal) { - flutter::MutatorsStack stack; - SkMatrix matrix; - stack.pushTransform(matrix); - SkRect rect; - stack.pushClipRect(rect); - SkRRect rrect; - stack.pushClipRRect(rrect); - auto iter = stack.bottom(); - int index = 0; - while (iter != stack.top()) { - switch (index) { - case 0: - ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::clip_rrect); - ASSERT_TRUE(iter->get()->rrect() == rrect); - break; - case 1: - ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::clip_rect); - ASSERT_TRUE(iter->get()->rect() == rect); - break; - case 2: - ASSERT_TRUE(iter->get()->type() == flutter::MutatorType::transform); - ASSERT_TRUE(iter->get()->matrix() == matrix); - break; - default: - break; - } - ++iter; - ++index; - } -} - -TEST(MutatorsStack, Equality) { - flutter::MutatorsStack stack; - SkMatrix matrix = SkMatrix::MakeScale(1, 1); - stack.pushTransform(matrix); - SkRect rect = SkRect::MakeEmpty(); - stack.pushClipRect(rect); - SkRRect rrect = SkRRect::MakeEmpty(); - stack.pushClipRRect(rrect); - - flutter::MutatorsStack stackOther; - SkMatrix matrixOther = SkMatrix::MakeScale(1, 1); - stackOther.pushTransform(matrixOther); - SkRect rectOther = SkRect::MakeEmpty(); - stackOther.pushClipRect(rectOther); - SkRRect rrectOther = SkRRect::MakeEmpty(); - stackOther.pushClipRRect(rrectOther); - - ASSERT_TRUE(stack == stackOther); -} - -TEST(Mutator, Initialization) { - SkRect rect = SkRect::MakeEmpty(); - flutter::Mutator mutator = flutter::Mutator(rect); - ASSERT_TRUE(mutator.type() == flutter::MutatorType::clip_rect); - ASSERT_TRUE(mutator.rect() == rect); - - SkRRect rrect; - flutter::Mutator mutator2 = flutter::Mutator(rrect); - ASSERT_TRUE(mutator2.type() == flutter::MutatorType::clip_rrect); - ASSERT_TRUE(mutator2.rrect() == rrect); - - SkPath path; - flutter::Mutator mutator3 = flutter::Mutator(path); - ASSERT_TRUE(mutator3.type() == flutter::MutatorType::clip_path); - ASSERT_TRUE(mutator3.path() == path); - - SkMatrix matrix; - flutter::Mutator mutator4 = flutter::Mutator(matrix); - ASSERT_TRUE(mutator4.type() == flutter::MutatorType::transform); - ASSERT_TRUE(mutator4.matrix() == matrix); -} - -TEST(Mutator, CopyConstructor) { - SkRect rect = SkRect::MakeEmpty(); - flutter::Mutator mutator = flutter::Mutator(rect); - flutter::Mutator copy = flutter::Mutator(mutator); - ASSERT_TRUE(mutator == copy); - - SkRRect rrect; - flutter::Mutator mutator2 = flutter::Mutator(rrect); - flutter::Mutator copy2 = flutter::Mutator(mutator2); - ASSERT_TRUE(mutator2 == copy2); - - SkPath path; - flutter::Mutator mutator3 = flutter::Mutator(path); - flutter::Mutator copy3 = flutter::Mutator(mutator3); - ASSERT_TRUE(mutator3 == copy3); - - SkMatrix matrix; - flutter::Mutator mutator4 = flutter::Mutator(matrix); - flutter::Mutator copy4 = flutter::Mutator(mutator4); - ASSERT_TRUE(mutator4 == copy4); -} - -TEST(Mutator, Equality) { - SkMatrix matrix; - flutter::Mutator mutator = flutter::Mutator(matrix); - flutter::Mutator otherMutator = flutter::Mutator(matrix); - ASSERT_TRUE(mutator == otherMutator); - - SkRect rect = SkRect::MakeEmpty(); - flutter::Mutator mutator2 = flutter::Mutator(rect); - flutter::Mutator otherMutator2 = flutter::Mutator(rect); - ASSERT_TRUE(mutator2 == otherMutator2); - - SkRRect rrect; - flutter::Mutator mutator3 = flutter::Mutator(rrect); - flutter::Mutator otherMutator3 = flutter::Mutator(rrect); - ASSERT_TRUE(mutator3 == otherMutator3); - - ASSERT_FALSE(mutator2 == mutator); -} - -TEST(Mutator, UnEquality) { - SkRect rect = SkRect::MakeEmpty(); - flutter::Mutator mutator = flutter::Mutator(rect); - SkMatrix matrix; - flutter::Mutator notEqualMutator = flutter::Mutator(matrix); - ASSERT_TRUE(notEqualMutator != mutator); -} diff --git a/flow/raster_cache.cc b/flow/raster_cache.cc index be0c88d5cc7e8..4ad18adf172e4 100644 --- a/flow/raster_cache.cc +++ b/flow/raster_cache.cc @@ -159,7 +159,6 @@ void RasterCache::Prepare(PrerollContext* context, entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space, checkerboard_images_, layer->paint_bounds(), [layer, context](SkCanvas* canvas) { - MutatorsStack stack; SkISize canvas_size = canvas->getBaseLayerSize(); SkNWayCanvas internal_nodes_canvas( canvas_size.width(), canvas_size.height()); @@ -169,7 +168,6 @@ void RasterCache::Prepare(PrerollContext* context, canvas, context->gr_context, nullptr, - stack, context->raster_time, context->ui_time, context->texture_registry, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index ea838e3817298..4a530922fa89e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -91,7 +91,6 @@ touch_interceptors_[viewId] = fml::scoped_nsobject([touch_interceptor retain]); - root_views_[viewId] = fml::scoped_nsobject([touch_interceptor retain]); result(nil); } @@ -183,117 +182,6 @@ return canvases; } -int FlutterPlatformViewsController::CountClips(const MutatorsStack& mutators_stack) { - std::vector>::const_reverse_iterator iter = mutators_stack.bottom(); - int clipCount = 0; - while (iter != mutators_stack.top()) { - if ((*iter)->isClipType()) { - clipCount++; - } - ++iter; - } - return clipCount; -} - -UIView* FlutterPlatformViewsController::ReconstructClipViewsChain(int number_of_clips, - UIView* platform_view, - UIView* head_clip_view) { - NSInteger indexInFlutterView = -1; - if (head_clip_view.superview) { - // TODO(cyanglaz): potentially cache the index of oldPlatformViewRoot to make this a O(1). - // https://github.com/flutter/flutter/issues/35023 - indexInFlutterView = [flutter_view_.get().subviews indexOfObject:head_clip_view]; - [head_clip_view removeFromSuperview]; - } - UIView* head = platform_view; - int clipIndex = 0; - // Re-use as much existing clip views as needed. - while (head != head_clip_view && clipIndex < number_of_clips) { - head = head.superview; - clipIndex++; - } - // If there were not enough existing clip views, add more. - while (clipIndex < number_of_clips) { - ChildClippingView* clippingView = [ChildClippingView new]; - [clippingView addSubview:head]; - head = clippingView; - clipIndex++; - } - [head removeFromSuperview]; - - if (indexInFlutterView > -1) { - // The chain was previously attached; attach it to the same position. - [flutter_view_.get() insertSubview:head atIndex:indexInFlutterView]; - } - return head; -} - -void FlutterPlatformViewsController::ApplyMutators(const MutatorsStack& mutators_stack, - UIView* embedded_view) { - UIView* head = embedded_view; - head.clipsToBounds = YES; - head.layer.transform = CATransform3DIdentity; - ResetAnchor(head.layer); - - std::vector>::const_reverse_iterator iter = mutators_stack.bottom(); - while (iter != mutators_stack.top()) { - switch ((*iter)->type()) { - case transform: { - CATransform3D transform = GetCATransform3DFromSkMatrix((*iter)->matrix()); - head.layer.transform = CATransform3DConcat(head.layer.transform, transform); - break; - } - case clip_rect: - case clip_rrect: - case clip_path: { - ChildClippingView* clipView = (ChildClippingView*)head.superview; - clipView.layer.transform = CATransform3DIdentity; - [clipView setClip:(*iter)->type() - rect:(*iter)->rect() - rrect:(*iter)->rrect() - path:(*iter)->path()]; - head.clipsToBounds = YES; - ResetAnchor(clipView.layer); - head = clipView; - break; - } - } - ++iter; - } - - // Reverse scale based on screen scale. - // - // The UIKit frame is set based on the logical resolution instead of physical. - // (https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/Displays/Displays.html). - // However, flow is based on the physical resolution. For eaxmple, 1000 pixels in flow equals - // 500 points in UIKit. And until this point, we did all the calculation based on the flow - // resolution. So we need to scale down to match UIKit's logical resolution. - CGFloat screenScale = [UIScreen mainScreen].scale; - head.layer.transform = CATransform3DConcat( - head.layer.transform, CATransform3DMakeScale(1 / screenScale, 1 / screenScale, 1)); -} - -void FlutterPlatformViewsController::CompositeWithParams( - int view_id, - const flutter::EmbeddedViewParams& params) { - CGRect frame = CGRectMake(0, 0, params.sizePoints.width(), params.sizePoints.height()); - UIView* touchInterceptor = touch_interceptors_[view_id].get(); - touchInterceptor.frame = frame; - - int currentClippingCount = CountClips(params.mutatorsStack); - int previousClippingCount = clip_count_[view_id]; - if (currentClippingCount != previousClippingCount) { - clip_count_[view_id] = currentClippingCount; - // If we have a different clipping count in this frame, we need to reconstruct the - // ClippingChildView chain to prepare for `ApplyMutators`. - UIView* oldPlatformViewRoot = root_views_[view_id].get(); - UIView* newPlatformViewRoot = - ReconstructClipViewsChain(currentClippingCount, touchInterceptor, oldPlatformViewRoot); - root_views_[view_id] = fml::scoped_nsobject([newPlatformViewRoot retain]); - } - ApplyMutators(params.mutatorsStack, touchInterceptor); -} - SkCanvas* FlutterPlatformViewsController::CompositeEmbeddedView( int view_id, const flutter::EmbeddedViewParams& params) { @@ -305,8 +193,15 @@ current_composition_params_[view_id] == params) { return picture_recorders_[view_id]->getRecordingCanvas(); } - current_composition_params_[view_id] = EmbeddedViewParams(params); - CompositeWithParams(view_id, params); + current_composition_params_[view_id] = params; + + CGFloat screenScale = [[UIScreen mainScreen] scale]; + CGRect rect = + CGRectMake(params.offsetPixels.x() / screenScale, params.offsetPixels.y() / screenScale, + params.sizePoints.width(), params.sizePoints.height()); + + UIView* touch_interceptor = touch_interceptors_[view_id].get(); + [touch_interceptor setFrame:rect]; return picture_recorders_[view_id]->getRecordingCanvas(); } @@ -322,7 +217,6 @@ active_composition_order_.clear(); picture_recorders_.clear(); current_composition_params_.clear(); - clip_count_.clear(); } bool FlutterPlatformViewsController::SubmitFrame(bool gl_rendering, @@ -355,18 +249,15 @@ for (size_t i = 0; i < composition_order_.size(); i++) { int view_id = composition_order_[i]; - // We added a chain of super views to the platform view to handle clipping. - // The `platform_view_root` is the view at the top of the chain which is a direct subview of the - // `FlutterView`. - UIView* platform_view_root = root_views_[view_id].get(); + UIView* intercepter = touch_interceptors_[view_id].get(); UIView* overlay = overlays_[view_id]->overlay_view; - FML_CHECK(platform_view_root.superview == overlay.superview); + FML_CHECK(intercepter.superview == overlay.superview); - if (platform_view_root.superview == flutter_view) { - [flutter_view bringSubviewToFront:platform_view_root]; + if (intercepter.superview == flutter_view) { + [flutter_view bringSubviewToFront:intercepter]; [flutter_view bringSubviewToFront:overlay]; } else { - [flutter_view addSubview:platform_view_root]; + [flutter_view addSubview:intercepter]; [flutter_view addSubview:overlay]; } @@ -385,14 +276,10 @@ for (int64_t view_id : active_composition_order_) { if (composition_order_set.find(view_id) == composition_order_set.end()) { - if (root_views_.find(view_id) == root_views_.end()) { + if (touch_interceptors_.find(view_id) == touch_interceptors_.end()) { continue; } - // We added a chain of super views to the platform view to handle clipping. - // The `platform_view_root` is the view at the top of the chain which is a direct subview of - // the `FlutterView`. - UIView* platform_view_root = root_views_[view_id].get(); - [platform_view_root removeFromSuperview]; + [touch_interceptors_[view_id].get() removeFromSuperview]; [overlays_[view_id]->overlay_view.get() removeFromSuperview]; } } @@ -404,14 +291,12 @@ } for (int64_t viewId : views_to_dispose_) { - UIView* root_view = root_views_[viewId].get(); - [root_view removeFromSuperview]; + UIView* touch_interceptor = touch_interceptors_[viewId].get(); + [touch_interceptor removeFromSuperview]; views_.erase(viewId); touch_interceptors_.erase(viewId); - root_views_.erase(viewId); overlays_.erase(viewId); current_composition_params_.erase(viewId); - clip_count_.erase(viewId); } views_to_dispose_.clear(); } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index dfa4816f48d38..8c76a45916b58 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -28,29 +28,8 @@ - (void)blockGesture; @end -// The parent view handles clipping to its subviews. -@interface ChildClippingView : UIView - -// Performs the clipping based on the type. -// -// The `type` must be one of the 3: clip_rect, clip_rrect, clip_path. -- (void)setClip:(flutter::MutatorType)type - rect:(const SkRect&)rect - rrect:(const SkRRect&)rrect - path:(const SkPath&)path; - -@end - namespace flutter { -// Converts a SkMatrix to CATransform3D. -// Certain fields are ignored in CATransform3D since SkMatrix is 3x3 and CATransform3D is 4x4. -CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix); - -// Reset the anchor of `layer` to match the tranform operation from flow. -// The position of the `layer` should be unchanged after resetting the anchor. -void ResetAnchor(CALayer* layer); - class IOSGLContext; class IOSSurface; @@ -109,17 +88,8 @@ class FlutterPlatformViewsController { std::map>> factories_; std::map>> views_; std::map> touch_interceptors_; - // Mapping a platform view ID to the top most parent view (root_view) who is a direct child to the - // `flutter_view_`. - // - // The platform view with the view ID is a child of the root view; If the platform view is not - // clipped, and no clipping view is added, the root view will be the intercepting view. - std::map> root_views_; // Mapping a platform view ID to its latest composition params. std::map current_composition_params_; - // Mapping a platform view ID to the count of the clipping operations that were applied to the - // platform view last time it was composited. - std::map clip_count_; std::map> overlays_; // The GrContext that is currently used by all of the overlay surfaces. // We track this to know when the GrContext for the Flutter app has changed @@ -152,40 +122,6 @@ class FlutterPlatformViewsController { void EnsureGLOverlayInitialized(int64_t overlay_id, std::shared_ptr gl_context, GrContext* gr_context); - // Traverse the `mutators_stack` and return the number of clip operations. - int CountClips(const MutatorsStack& mutators_stack); - - // Make sure that platform_view has exactly clip_count ChildClippingView ancestors. - // - // Existing ChildClippingViews are re-used. If there are currently more ChildClippingView - // ancestors than needed, the extra views are detached. If there are less ChildClippingView - // ancestors than needed, new ChildClippingViews will be added. - // - // If head_clip_view was attached as a subview to FlutterView, the head of the newly constructed - // ChildClippingViews chain is attached to FlutterView in the same position. - // - // Returns the new head of the clip views chain. - UIView* ReconstructClipViewsChain(int number_of_clips, - UIView* platform_view, - UIView* head_clip_view); - - // Applies the mutators in the mutators_stack to the UIView chain that was constructed by - // `ReconstructClipViewsChain` - // - // Clips are applied to the super view with a CALayer mask. Transforms are applied to the current - // view that's at the head of the chain. For example the following mutators stack [T_1, C_2, T_3, - // T_4, C_5, T_6] where T denotes a transform and C denotes a clip, will result in the following - // UIView tree: - // - // C_2 -> C_5 -> PLATFORM_VIEW - // (PLATFORM_VIEW is a subview of C_5 which is a subview of C_2) - // - // T_1 is applied to C_2, T_3 and T_4 are applied to C_5, and T_6 is applied to PLATFORM_VIEW. - // - // After each clip operation, we update the head to the super view of the current head. - void ApplyMutators(const MutatorsStack& mutators_stack, UIView* embedded_view); - - void CompositeWithParams(int view_id, const flutter::EmbeddedViewParams& params); FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewsController); }; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm index 7afb8c3314478..7c2fb3e6ca5a2 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm @@ -21,144 +21,4 @@ FlutterPlatformViewsController::~FlutterPlatformViewsController() = default; -CATransform3D GetCATransform3DFromSkMatrix(const SkMatrix& matrix) { - // Skia only supports 2D transform so we don't map z. - CATransform3D transform = CATransform3DIdentity; - transform.m11 = matrix.getScaleX(); - transform.m21 = matrix.getSkewX(); - transform.m41 = matrix.getTranslateX(); - transform.m14 = matrix.getPerspX(); - - transform.m12 = matrix.getSkewY(); - transform.m22 = matrix.getScaleY(); - transform.m42 = matrix.getTranslateY(); - transform.m24 = matrix.getPerspY(); - return transform; -} - -void ResetAnchor(CALayer* layer) { - // Flow uses (0, 0) to apply transform matrix so we need to match that in Quartz. - layer.anchorPoint = CGPointZero; - layer.position = CGPointZero; -} - } // namespace flutter - -@implementation ChildClippingView - -+ (CGRect)getCGRectFromSkRect:(const SkRect&)clipSkRect { - return CGRectMake(clipSkRect.fLeft, clipSkRect.fTop, clipSkRect.fRight - clipSkRect.fLeft, - clipSkRect.fBottom - clipSkRect.fTop); -} - -- (void)clipRect:(const SkRect&)clipSkRect { - CGRect clipRect = [ChildClippingView getCGRectFromSkRect:clipSkRect]; - CGPathRef pathRef = CGPathCreateWithRect(clipRect, nil); - CAShapeLayer* clip = [[CAShapeLayer alloc] init]; - clip.path = pathRef; - self.layer.mask = clip; - CGPathRelease(pathRef); -} - -- (void)clipRRect:(const SkRRect&)clipSkRRect { - CGPathRef pathRef = nullptr; - switch (clipSkRRect.getType()) { - case SkRRect::kEmpty_Type: { - break; - } - case SkRRect::kRect_Type: { - [self clipRect:clipSkRRect.rect()]; - return; - } - case SkRRect::kOval_Type: - case SkRRect::kSimple_Type: { - CGRect clipRect = [ChildClippingView getCGRectFromSkRect:clipSkRRect.rect()]; - pathRef = CGPathCreateWithRoundedRect(clipRect, clipSkRRect.getSimpleRadii().x(), - clipSkRRect.getSimpleRadii().y(), nil); - break; - } - case SkRRect::kNinePatch_Type: - case SkRRect::kComplex_Type: { - CGMutablePathRef mutablePathRef = CGPathCreateMutable(); - // Complex types, we manually add each corner. - SkRect clipSkRect = clipSkRRect.rect(); - SkVector topLeftRadii = clipSkRRect.radii(SkRRect::kUpperLeft_Corner); - SkVector topRightRadii = clipSkRRect.radii(SkRRect::kUpperRight_Corner); - SkVector bottomRightRadii = clipSkRRect.radii(SkRRect::kLowerRight_Corner); - SkVector bottomLeftRadii = clipSkRRect.radii(SkRRect::kLowerLeft_Corner); - - // Start drawing RRect - // Move point to the top left corner adding the top left radii's x. - CGPathMoveToPoint(mutablePathRef, nil, clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop); - // Move point horizontally right to the top right corner and add the top right curve. - CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight - topRightRadii.x(), - clipSkRect.fTop); - CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fTop, - clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y(), - clipSkRect.fRight, clipSkRect.fTop + topRightRadii.y()); - // Move point vertically down to the bottom right corner and add the bottom right curve. - CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fRight, - clipSkRect.fBottom - bottomRightRadii.y()); - CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fRight, clipSkRect.fBottom, - clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom, - clipSkRect.fRight - bottomRightRadii.x(), clipSkRect.fBottom); - // Move point horizontally left to the bottom left corner and add the bottom left curve. - CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft + bottomLeftRadii.x(), - clipSkRect.fBottom); - CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fBottom, - clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y(), - clipSkRect.fLeft, clipSkRect.fBottom - bottomLeftRadii.y()); - // Move point vertically up to the top left corner and add the top left curve. - CGPathAddLineToPoint(mutablePathRef, nil, clipSkRect.fLeft, - clipSkRect.fTop + topLeftRadii.y()); - CGPathAddCurveToPoint(mutablePathRef, nil, clipSkRect.fLeft, clipSkRect.fTop, - clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop, - clipSkRect.fLeft + topLeftRadii.x(), clipSkRect.fTop); - CGPathCloseSubpath(mutablePathRef); - - pathRef = mutablePathRef; - break; - } - } - // TODO(cyanglaz): iOS does not seem to support hard edge on CAShapeLayer. It clearly stated that - // the CAShaperLayer will be drawn antialiased. Need to figure out a way to do the hard edge - // clipping on iOS. - CAShapeLayer* clip = [[CAShapeLayer alloc] init]; - clip.path = pathRef; - self.layer.mask = clip; - CGPathRelease(pathRef); -} - -- (void)setClip:(flutter::MutatorType)type - rect:(const SkRect&)rect - rrect:(const SkRRect&)rrect - path:(const SkPath&)path { - FML_CHECK(type == flutter::clip_rect || type == flutter::clip_rrect || - type == flutter::clip_path); - switch (type) { - case flutter::clip_rect: - [self clipRect:rect]; - break; - case flutter::clip_rrect: - [self clipRRect:rrect]; - break; - case flutter::clip_path: - // TODO(cyanglaz): Add clip path - break; - default: - break; - } -} - -// The ChildClippingView is as big as the FlutterView, we only want touches to be hit tested and -// consumed by this view if they are inside the smaller child view. -- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event { - for (UIView* view in self.subviews) { - if ([view pointInside:[self convertPoint:point toView:view] withEvent:event]) { - return YES; - } - } - return NO; -} - -@end