diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index 5234bf1e50c8c..c660f4691318b 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -6,13 +6,10 @@ namespace flutter { -bool ExternalViewEmbedder::SubmitFrame(GrContext* context, - SkCanvas* background_canvas) { +bool ExternalViewEmbedder::SubmitFrame(GrContext* context) { return false; }; -void ExternalViewEmbedder::FinishFrame(){}; - void MutatorsStack::PushClipRect(const SkRect& rect) { std::shared_ptr element = std::make_shared(rect); vector_.push_back(element); diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 7a491a8a152ef..030eb88c8a06d 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -248,10 +248,7 @@ class ExternalViewEmbedder { // Must be called on the UI thread. virtual SkCanvas* CompositeEmbeddedView(int view_id) = 0; - virtual bool SubmitFrame(GrContext* context, SkCanvas* background_canvas); - - // This is called after submitting the embedder frame and the surface frame. - virtual void FinishFrame(); + virtual bool SubmitFrame(GrContext* context); FML_DISALLOW_COPY_AND_ASSIGN(ExternalViewEmbedder); diff --git a/flow/layers/picture_layer.cc b/flow/layers/picture_layer.cc index 08c09cc9e833b..3bc7e394c1033 100644 --- a/flow/layers/picture_layer.cc +++ b/flow/layers/picture_layer.cc @@ -59,7 +59,7 @@ void PictureLayer::Paint(PaintContext& context) const { return; } } - picture()->playback(context.leaf_nodes_canvas); + context.leaf_nodes_canvas->drawPicture(picture()); } } // namespace flutter diff --git a/flow/layers/picture_layer_unittests.cc b/flow/layers/picture_layer_unittests.cc index 4f565cf500ecc..687c870eeac66 100644 --- a/flow/layers/picture_layer_unittests.cc +++ b/flow/layers/picture_layer_unittests.cc @@ -94,6 +94,9 @@ TEST_F(PictureLayerTest, SimplePicture) { 1, MockCanvas::SetMatrixData{RasterCache::GetIntegralTransCTM( layer_offset_matrix)}}, #endif + MockCanvas::DrawCall{ + 1, MockCanvas::DrawPictureData{mock_picture->serialize(), SkPaint(), + SkMatrix()}}, MockCanvas::DrawCall{1, MockCanvas::RestoreData{0}}}); EXPECT_EQ(mock_canvas().draw_calls(), expected_draw_calls); } diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index f7e4350fe9c97..811898b5a42d2 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -342,17 +342,9 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { if (raster_status == RasterStatus::kFailed) { return raster_status; } + frame->Submit(); if (external_view_embedder != nullptr) { - external_view_embedder->SubmitFrame(surface_->GetContext(), - root_surface_canvas); - // The external view embedder may mutate the root surface canvas while - // submitting the frame. - // Therefore, submit the final frame after asking the external view - // embedder to submit the frame. - frame->Submit(); - external_view_embedder->FinishFrame(); - } else { - frame->Submit(); + external_view_embedder->SubmitFrame(surface_->GetContext()); } FireNextFrameCallbackIfPresent(); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index b96fcbbbaa76a..b86c4623fa7a7 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -8,77 +8,16 @@ #import "flutter/shell/platform/darwin/ios/ios_surface.h" #import "flutter/shell/platform/darwin/ios/ios_surface_gl.h" -#include #include #include #include #include "FlutterPlatformViews_Internal.h" -#include "flutter/flow/rtree.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" -#include "flutter/shell/common/persistent_cache.h" #include "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" namespace flutter { -std::shared_ptr FlutterPlatformViewLayerPool::GetLayer( - GrContext* gr_context, - std::shared_ptr ios_context) { - if (available_layer_index_ >= layers_.size()) { - std::shared_ptr layer; - - if (!gr_context) { - fml::scoped_nsobject overlay_view([[FlutterOverlayView alloc] init]); - overlay_view.get().autoresizingMask = - (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); - std::unique_ptr ios_surface = - [overlay_view.get() createSurface:std::move(ios_context)]; - std::unique_ptr surface = ios_surface->CreateGPUSurface(); - - layer = std::make_shared( - std::move(overlay_view), std::move(ios_surface), std::move(surface)); - } else { - CGFloat screenScale = [UIScreen mainScreen].scale; - fml::scoped_nsobject overlay_view( - [[FlutterOverlayView alloc] initWithContentsScale:screenScale]); - overlay_view.get().autoresizingMask = - (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); - std::unique_ptr ios_surface = - [overlay_view.get() createSurface:std::move(ios_context)]; - std::unique_ptr surface = ios_surface->CreateGPUSurface(gr_context); - - layer = std::make_shared( - std::move(overlay_view), std::move(ios_surface), std::move(surface)); - layer->gr_context = gr_context; - } - layers_.push_back(layer); - } - auto layer = layers_[available_layer_index_]; - if (gr_context != layer->gr_context) { - layer->gr_context = gr_context; - // The overlay already exists, but the GrContext was changed so we need to recreate - // the rendering surface with the new GrContext. - IOSSurface* ios_surface = layer->ios_surface.get(); - std::unique_ptr surface = ios_surface->CreateGPUSurface(gr_context); - layer->surface = std::move(surface); - } - available_layer_index_++; - return layer; -} - -void FlutterPlatformViewLayerPool::RecycleLayers() { - available_layer_index_ = 0; -} - -std::vector> -FlutterPlatformViewLayerPool::GetUnusedLayers() { - std::vector> results; - for (size_t i = available_layer_index_; i < layers_.size(); i++) { - results.push_back(layers_[i]); - } - return results; -} - void FlutterPlatformViewsController::SetFlutterView(UIView* flutter_view) { flutter_view_.reset([flutter_view retain]); } @@ -144,9 +83,6 @@ NSObject* embedded_view = [factory createWithFrame:CGRectZero viewIdentifier:viewId arguments:params]; - // Set a unique view identifier, so the platform view can be identified in unit tests. - [embedded_view view].accessibilityIdentifier = - [NSString stringWithFormat:@"platform_view[%ld]", viewId]; views_[viewId] = fml::scoped_nsobject>([embedded_view retain]); FlutterTouchInterceptingView* touch_interceptor = [[[FlutterTouchInterceptingView alloc] @@ -260,11 +196,8 @@ int view_id, std::unique_ptr params) { picture_recorders_[view_id] = std::make_unique(); - - auto rtree_factory = RTreeFactory(); - platform_view_rtrees_[view_id] = rtree_factory.getInstance(); - picture_recorders_[view_id]->beginRecording(SkRect::Make(frame_size_), &rtree_factory); - + picture_recorders_[view_id]->beginRecording(SkRect::Make(frame_size_)); + picture_recorders_[view_id]->getRecordingCanvas()->clear(SK_ColorTRANSPARENT); composition_order_.push_back(view_id); if (current_composition_params_.count(view_id) == 1 && @@ -428,182 +361,77 @@ composition_order_.clear(); active_composition_order_.clear(); picture_recorders_.clear(); - platform_view_rtrees_.clear(); current_composition_params_.clear(); clip_count_.clear(); views_to_recomposite_.clear(); - layer_pool_->RecycleLayers(); -} - -SkRect FlutterPlatformViewsController::GetPlatformViewRect(int view_id) { - UIView* platform_view = [views_[view_id].get() view]; - UIScreen* screen = [UIScreen mainScreen]; - CGRect platform_view_cgrect = [platform_view convertRect:platform_view.bounds - toView:flutter_view_]; - return SkRect::MakeXYWH(platform_view_cgrect.origin.x * screen.scale, // - platform_view_cgrect.origin.y * screen.scale, // - platform_view_cgrect.size.width * screen.scale, // - platform_view_cgrect.size.height * screen.scale // - ); } bool FlutterPlatformViewsController::SubmitFrame(GrContext* gr_context, - std::shared_ptr ios_context, - SkCanvas* background_canvas) { + std::shared_ptr ios_context) { DisposeViews(); - // Clipping the background canvas before drawing the picture recorders requires to - // save and restore the clip context. - SkAutoCanvasRestore save(background_canvas, /*doSave=*/true); - // Maps a platform view id to a vector of `FlutterPlatformViewLayer`. - LayersMap platform_view_layers; - - auto did_submit = true; - auto num_platform_views = composition_order_.size(); - - for (size_t i = 0; i < num_platform_views; i++) { - int64_t platform_view_id = composition_order_[i]; - sk_sp rtree = platform_view_rtrees_[platform_view_id]; - sk_sp picture = picture_recorders_[platform_view_id]->finishRecordingAsPicture(); - - // Check if the current picture contains overlays that intersect with the - // current platform view or any of the previous platform views. - for (size_t j = i + 1; j > 0; j--) { - int64_t current_platform_view_id = composition_order_[j - 1]; - SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id); - std::list intersection_rects = - rtree->searchNonOverlappingDrawnRects(platform_view_rect); - auto allocation_size = intersection_rects.size(); - - // For testing purposes, the overlay id is used to find the overlay view. - // This is the index of the layer for the current platform view. - auto overlay_id = platform_view_layers[current_platform_view_id].size(); - - // If the max number of allocations per platform view is exceeded, - // then join all the rects into a single one. - // - // TODO(egarciad): Consider making this configurable. - // https://github.com/flutter/flutter/issues/52510 - if (allocation_size > kMaxLayerAllocations) { - SkRect joined_rect; - for (const SkRect& rect : intersection_rects) { - joined_rect.join(rect); - } - // Replace the rects in the intersection rects list for a single rect that is - // the union of all the rects in the list. - intersection_rects.clear(); - intersection_rects.push_back(joined_rect); - } - for (SkRect& joined_rect : intersection_rects) { - // Get the intersection rect between the current rect - // and the platform view rect. - joined_rect.intersect(platform_view_rect); - // Clip the background canvas, so it doesn't contain any of the pixels drawn - // on the overlay layer. - background_canvas->clipRect(joined_rect, SkClipOp::kDifference); - // Get a new host layer. - auto layer = GetLayer(gr_context, // - ios_context, // - picture, // - joined_rect, // - current_platform_view_id, // - overlay_id // - ); - did_submit &= layer->did_submit_last_frame; - platform_view_layers[current_platform_view_id].push_back(layer); - overlay_id++; - } - } - background_canvas->drawPicture(picture); - } - // If a layer was allocated in the previous frame, but it's not used in the current frame, - // then it can be removed from the scene. - RemoveUnusedLayers(); - // Organize the layers by their z indexes. - BringLayersIntoView(platform_view_layers); - // Mark all layers as available, so they can be used in the next frame. - layer_pool_->RecycleLayers(); - // Reset the composition order, so next frame starts empty. - composition_order_.clear(); - return did_submit; -} - -void FlutterPlatformViewsController::BringLayersIntoView(LayersMap layer_map) { + bool did_submit = true; + for (int64_t view_id : composition_order_) { + EnsureOverlayInitialized(view_id, ios_context, gr_context); + auto frame = overlays_[view_id]->surface->AcquireFrame(frame_size_); + // If frame is null, AcquireFrame already printed out an error message. + if (frame) { + SkCanvas* canvas = frame->SkiaCanvas(); + canvas->drawPicture(picture_recorders_[view_id]->finishRecordingAsPicture()); + canvas->flush(); + did_submit &= frame->Submit(); + } + } + picture_recorders_.clear(); + if (composition_order_ == active_composition_order_) { + composition_order_.clear(); + return did_submit; + } + DetachUnusedLayers(); + active_composition_order_.clear(); UIView* flutter_view = flutter_view_.get(); - auto zIndex = 0; - for (size_t i = 0; i < composition_order_.size(); i++) { - int64_t platform_view_id = composition_order_[i]; - std::vector> layers = layer_map[platform_view_id]; - UIView* platform_view_root = root_views_[platform_view_id].get(); - if (platform_view_root.superview != flutter_view) { - [flutter_view addSubview:platform_view_root]; + 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* overlay = overlays_[view_id]->overlay_view; + FML_CHECK(platform_view_root.superview == overlay.superview); + if (platform_view_root.superview == flutter_view) { + [flutter_view bringSubviewToFront:platform_view_root]; + [flutter_view bringSubviewToFront:overlay]; } else { - platform_view_root.layer.zPosition = zIndex++; - } - for (const std::shared_ptr& layer : layers) { - if ([layer->overlay_view superview] != flutter_view) { - [flutter_view addSubview:layer->overlay_view]; - } else { - layer->overlay_view.get().layer.zPosition = zIndex++; - } + [flutter_view addSubview:platform_view_root]; + [flutter_view addSubview:overlay]; + overlay.frame = flutter_view.bounds; } - active_composition_order_.push_back(platform_view_id); - } -} -std::shared_ptr FlutterPlatformViewsController::GetLayer( - GrContext* gr_context, - std::shared_ptr ios_context, - sk_sp picture, - SkRect rect, - int64_t view_id, - int64_t overlay_id) { - auto layer = layer_pool_->GetLayer(gr_context, ios_context); - auto screenScale = [UIScreen mainScreen].scale; - // Set the size of the overlay UIView. - layer->overlay_view.get().frame = CGRectMake(rect.x() / screenScale, // - rect.y() / screenScale, // - rect.width() / screenScale, // - rect.height() / screenScale // - ); - // Set a unique view identifier, so the overlay can be identified in unit tests. - layer->overlay_view.get().accessibilityIdentifier = - [NSString stringWithFormat:@"platform_view[%lld].overlay[%lld]", view_id, overlay_id]; - - std::unique_ptr frame = - layer->surface->AcquireFrame(SkISize::Make(rect.width(), rect.height())); - // If frame is null, AcquireFrame already printed out an error message. - if (!frame) { - return layer; - } - auto overlay_canvas = frame->SkiaCanvas(); - overlay_canvas->clear(SK_ColorTRANSPARENT); - // Offset the picture since its absolute position on the scene is determined - // by the position of the overlay view. - overlay_canvas->translate(-rect.x(), -rect.y()); - overlay_canvas->drawPicture(picture); - - layer->did_submit_last_frame = frame->Submit(); - return layer; -} - -void FlutterPlatformViewsController::RemoveUnusedLayers() { - auto layers = layer_pool_->GetUnusedLayers(); - for (const std::shared_ptr& layer : layers) { - [layer->overlay_view removeFromSuperview]; + active_composition_order_.push_back(view_id); } + composition_order_.clear(); + return did_submit; +} +void FlutterPlatformViewsController::DetachUnusedLayers() { std::unordered_set composition_order_set; for (int64_t view_id : composition_order_) { composition_order_set.insert(view_id); } - // Remove unused platform views. + 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()) { + 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]; + [overlays_[view_id]->overlay_view.get() removeFromSuperview]; } } } @@ -630,6 +458,56 @@ views_to_dispose_.clear(); } +void FlutterPlatformViewsController::EnsureOverlayInitialized( + int64_t overlay_id, + std::shared_ptr ios_context, + GrContext* gr_context) { + FML_DCHECK(flutter_view_); + + auto overlay_it = overlays_.find(overlay_id); + + if (!gr_context) { + if (overlays_.count(overlay_id) != 0) { + return; + } + fml::scoped_nsobject overlay_view([[FlutterOverlayView alloc] init]); + overlay_view.get().frame = flutter_view_.get().bounds; + overlay_view.get().autoresizingMask = + (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); + std::unique_ptr ios_surface = + [overlay_view.get() createSurface:std::move(ios_context)]; + std::unique_ptr surface = ios_surface->CreateGPUSurface(); + overlays_[overlay_id] = std::make_unique( + std::move(overlay_view), std::move(ios_surface), std::move(surface)); + return; + } + + if (overlay_it != overlays_.end()) { + FlutterPlatformViewLayer* overlay = overlay_it->second.get(); + if (gr_context != overlay->gr_context) { + overlay->gr_context = gr_context; + // The overlay already exists, but the GrContext was changed so we need to recreate + // the rendering surface with the new GrContext. + IOSSurface* ios_surface = overlay_it->second->ios_surface.get(); + std::unique_ptr surface = ios_surface->CreateGPUSurface(gr_context); + overlay_it->second->surface = std::move(surface); + } + return; + } + auto contentsScale = flutter_view_.get().layer.contentsScale; + fml::scoped_nsobject overlay_view( + [[FlutterOverlayView alloc] initWithContentsScale:contentsScale]); + overlay_view.get().frame = flutter_view_.get().bounds; + overlay_view.get().autoresizingMask = + (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight); + std::unique_ptr ios_surface = + [overlay_view.get() createSurface:std::move(ios_context)]; + std::unique_ptr surface = ios_surface->CreateGPUSurface(gr_context); + overlays_[overlay_id] = std::make_unique( + std::move(overlay_view), std::move(ios_surface), std::move(surface)); + overlays_[overlay_id]->gr_context = gr_context; +} + } // namespace flutter // This recognizers delays touch events from being dispatched to the responder chain until it failed diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 59dc940c4d126..d135d7d2ac290 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -6,7 +6,6 @@ #define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_FRAMEWORK_SOURCE_FLUTTERPLATFORMVIEWS_INTERNAL_H_ #include "flutter/flow/embedded_views.h" -#include "flutter/flow/rtree.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/platform/darwin/common/framework/Headers/FlutterBinaryMessenger.h" @@ -69,52 +68,12 @@ struct FlutterPlatformViewLayer { std::unique_ptr ios_surface; std::unique_ptr surface; - // Whether a frame for this layer was submitted. - bool did_submit_last_frame; - // The GrContext that is currently used by the overlay surfaces. // We track this to know when the GrContext for the Flutter app has changed // so we can update the overlay with the new context. GrContext* gr_context; }; -// This class isn't thread safe. -class FlutterPlatformViewLayerPool { - public: - FlutterPlatformViewLayerPool() = default; - ~FlutterPlatformViewLayerPool() = default; - - // Gets a layer from the pool if available, or allocates a new one. - // Finally, it marks the layer as used. That is, it increments `available_layer_index_`. - std::shared_ptr GetLayer(GrContext* gr_context, - std::shared_ptr ios_context); - - // Gets the layers in the pool that aren't currently used. - // This method doesn't mark the layers as unused. - std::vector> GetUnusedLayers(); - - // Marks the layers in the pool as available for reuse. - void RecycleLayers(); - - private: - // The index of the entry in the layers_ vector that determines the beginning of the unused - // layers. For example, consider the following vector: - // _____ - // | 0 | - /// |---| - /// | 1 | <-- available_layer_index_ - /// |---| - /// | 2 | - /// |---| - /// - /// This indicates that entries starting from 1 can be reused meanwhile the entry at position 0 - /// cannot be reused. - size_t available_layer_index_ = 0; - std::vector> layers_; - - FML_DISALLOW_COPY_AND_ASSIGN(FlutterPlatformViewLayerPool); -}; - class FlutterPlatformViewsController { public: FlutterPlatformViewsController(); @@ -150,37 +109,14 @@ class FlutterPlatformViewsController { SkCanvas* CompositeEmbeddedView(int view_id); - // The rect of the platform view at index view_id. This rect has been translated into the - // host view coordinate system. Units are device screen pixels. - SkRect GetPlatformViewRect(int view_id); - // Discards all platform views instances and auxiliary resources. void Reset(); - bool SubmitFrame(GrContext* gr_context, - std::shared_ptr ios_context, - SkCanvas* background_canvas); + bool SubmitFrame(GrContext* gr_context, std::shared_ptr ios_context); void OnMethodCall(FlutterMethodCall* call, FlutterResult& result); private: - static const size_t kMaxLayerAllocations = 2; - - using LayersMap = std::map>>; - - // The pool of reusable view layers. The pool allows to recycle layer in each frame. - std::unique_ptr layer_pool_; - - // The platform view's R-tree keyed off the view id, which contains any subsequent - // draw operation until the next platform view or the last leaf node in the layer tree. - // - // The R-trees are deleted by the FlutterPlatformViewsController.reset(). - std::map> platform_view_rtrees_; - - // The platform view's picture recorder keyed off the view id, which contains any subsequent - // operation until the next platform view or the end of the last leaf node in the layer tree. - std::map> picture_recorders_; - fml::scoped_nsobject channel_; fml::scoped_nsobject flutter_view_; fml::scoped_nsobject flutter_view_controller_; @@ -227,12 +163,19 @@ class FlutterPlatformViewsController { std::map gesture_recognizers_blocking_policies; + std::map> picture_recorders_; + void OnCreate(FlutterMethodCall* call, FlutterResult& result); void OnDispose(FlutterMethodCall* call, FlutterResult& result); void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result); void OnRejectGesture(FlutterMethodCall* call, FlutterResult& result); + + void DetachUnusedLayers(); // Dispose the views in `views_to_dispose_`. void DisposeViews(); + void EnsureOverlayInitialized(int64_t overlay_id, + std::shared_ptr ios_context, + GrContext* gr_context); // This will return true after pre-roll if any of the embedded views // have mutated for last layer tree. @@ -272,20 +215,6 @@ class FlutterPlatformViewsController { void ApplyMutators(const MutatorsStack& mutators_stack, UIView* embedded_view); void CompositeWithParams(int view_id, const EmbeddedViewParams& params); - // Allocates a new FlutterPlatformViewLayer if needed, draws the pixels within the rect from - // the picture on the layer's canvas. - std::shared_ptr GetLayer(GrContext* gr_context, - std::shared_ptr ios_context, - sk_sp picture, - SkRect rect, - int64_t view_id, - int64_t overlay_id); - // Removes overlay views and platform views that aren't needed in the current frame. - void RemoveUnusedLayers(); - // Appends the overlay views and platform view and sets their z index based on the composition - // order. - void BringLayersIntoView(LayersMap layer_map); - 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 21db9530fe0bb..9310fa1803f11 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.mm @@ -20,8 +20,7 @@ FlutterPlatformViewLayer::~FlutterPlatformViewLayer() = default; -FlutterPlatformViewsController::FlutterPlatformViewsController() - : layer_pool_(std::make_unique()){}; +FlutterPlatformViewsController::FlutterPlatformViewsController() = default; FlutterPlatformViewsController::~FlutterPlatformViewsController() = default; diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h index 8cba9285cfb02..58233d8a2f656 100644 --- a/shell/platform/darwin/ios/ios_surface.h +++ b/shell/platform/darwin/ios/ios_surface.h @@ -77,10 +77,7 @@ class IOSSurface : public ExternalViewEmbedder { SkCanvas* CompositeEmbeddedView(int view_id) override; // |ExternalViewEmbedder| - bool SubmitFrame(GrContext* context, SkCanvas* background_canvas) override; - - // |ExternalViewEmbedder| - void FinishFrame() override; + bool SubmitFrame(GrContext* context) override; public: FML_DISALLOW_COPY_AND_ASSIGN(IOSSurface); diff --git a/shell/platform/darwin/ios/ios_surface.mm b/shell/platform/darwin/ios/ios_surface.mm index f51160e94e471..fe85c77f12c2d 100644 --- a/shell/platform/darwin/ios/ios_surface.mm +++ b/shell/platform/darwin/ios/ios_surface.mm @@ -132,18 +132,12 @@ bool IsIosEmbeddedViewsPreviewEnabled() { } // |ExternalViewEmbedder| -bool IOSSurface::SubmitFrame(GrContext* context, SkCanvas* background_canvas) { +bool IOSSurface::SubmitFrame(GrContext* context) { TRACE_EVENT0("flutter", "IOSSurface::SubmitFrame"); FML_CHECK(platform_views_controller_ != nullptr); - bool submitted = - platform_views_controller_->SubmitFrame(std::move(context), ios_context_, background_canvas); - return submitted; -} - -// |ExternalViewEmbedder| -void IOSSurface::FinishFrame() { - TRACE_EVENT0("flutter", "IOSSurface::DidSubmitFrame"); + bool submitted = platform_views_controller_->SubmitFrame(std::move(context), ios_context_); [CATransaction commit]; + return submitted; } } // namespace flutter diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index 23658888f7caa..5e77073e7ff47 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -129,8 +129,7 @@ static FlutterBackingStoreConfig MakeBackingStoreConfig( } // |ExternalViewEmbedder| -bool EmbedderExternalViewEmbedder::SubmitFrame(GrContext* context, - SkCanvas* background_canvas) { +bool EmbedderExternalViewEmbedder::SubmitFrame(GrContext* context) { auto [matched_render_targets, pending_keys] = render_target_cache_.GetExistingTargetsInCache(pending_views_); @@ -266,7 +265,4 @@ bool EmbedderExternalViewEmbedder::SubmitFrame(GrContext* context, return true; } -// |ExternalViewEmbedder| -void EmbedderExternalViewEmbedder::FinishFrame() {} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index 63c944a88d7ef..7000d2cde04cd 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -89,10 +89,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { SkCanvas* CompositeEmbeddedView(int view_id) override; // |ExternalViewEmbedder| - bool SubmitFrame(GrContext* context, SkCanvas* background_canvas) override; - - // |ExternalViewEmbedder| - void FinishFrame() override; + bool SubmitFrame(GrContext* context) override; // |ExternalViewEmbedder| SkCanvas* GetRootCanvas() override; diff --git a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj index 818d902b3e2e9..c24333a3a8a7f 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj +++ b/testing/scenario_app/ios/Scenarios/Scenarios.xcodeproj/project.pbxproj @@ -43,7 +43,6 @@ 3DEF491A23C3BE6500184216 /* golden_platform_view_transform_iPhone 8_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 3DE09E9123C010BD006C9851 /* golden_platform_view_transform_iPhone 8_simulator.png */; }; 59A97FD8236A49D300B4C066 /* golden_platform_view_multiple_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 59A97FD7236A49D300B4C066 /* golden_platform_view_multiple_iPhone SE_simulator.png */; }; 59A97FDA236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png in Resources */ = {isa = PBXBuildFile; fileRef = 59A97FD9236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png */; }; - 6402EBD124147BDA00987DCB /* UnobstructedPlatformViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */; }; 6816DB9E231750ED00A51400 /* GoldenPlatformViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DB9D231750ED00A51400 /* GoldenPlatformViewTests.m */; }; 6816DBA12317573300A51400 /* GoldenImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA02317573300A51400 /* GoldenImage.m */; }; 6816DBA42318358200A51400 /* PlatformViewGoldenTestManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6816DBA32318358200A51400 /* PlatformViewGoldenTestManager.m */; }; @@ -150,7 +149,6 @@ 3DE09E9223C010BD006C9851 /* golden_platform_view_cliprect_iPhone 8_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_cliprect_iPhone 8_simulator.png"; sourceTree = ""; }; 59A97FD7236A49D300B4C066 /* golden_platform_view_multiple_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_multiple_iPhone SE_simulator.png"; sourceTree = ""; }; 59A97FD9236B984300B4C066 /* golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "golden_platform_view_multiple_background_foreground_iPhone SE_simulator.png"; sourceTree = ""; }; - 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = UnobstructedPlatformViewTests.m; sourceTree = ""; }; 6816DB9C231750ED00A51400 /* GoldenPlatformViewTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoldenPlatformViewTests.h; sourceTree = ""; }; 6816DB9D231750ED00A51400 /* GoldenPlatformViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GoldenPlatformViewTests.m; sourceTree = ""; }; 6816DB9F2317573300A51400 /* GoldenImage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GoldenImage.h; sourceTree = ""; }; @@ -247,7 +245,6 @@ 248D76ED22E388380012F0C1 /* ScenariosUITests */ = { isa = PBXGroup; children = ( - 6402EBD024147BDA00987DCB /* UnobstructedPlatformViewTests.m */, 0D14A3FD239743190013D873 /* golden_platform_view_rotate_iPhone SE_simulator.png */, 3DE09E8B23C010BC006C9851 /* golden_platform_view_clippath_iPhone 8_simulator.png */, 3DE09E9223C010BD006C9851 /* golden_platform_view_cliprect_iPhone 8_simulator.png */, @@ -491,7 +488,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6402EBD124147BDA00987DCB /* UnobstructedPlatformViewTests.m in Sources */, 68A5B63423EB71D300BDBCDB /* PlatformViewGestureRecognizerTests.m in Sources */, 6816DBA12317573300A51400 /* GoldenImage.m in Sources */, 6816DB9E231750ED00A51400 /* GoldenPlatformViewTests.m in Sources */, diff --git a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m index 9bd732f647039..348889b19b856 100644 --- a/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m +++ b/testing/scenario_app/ios/Scenarios/Scenarios/AppDelegate.m @@ -29,13 +29,6 @@ - (BOOL)application:(UIApplication*)application // the launchArgsMap should match the one in the `PlatformVieGoldenTestManager`. NSDictionary* launchArgsMap = @{ @"--platform-view" : @"platform_view", - @"--platform-view-no-overlay-intersection" : @"platform_view_no_overlay_intersection", - @"--platform-view-two-intersecting-overlays" : @"platform_view_two_intersecting_overlays", - @"--platform-view-partial-intersection" : @"platform_view_partial_intersection", - @"--platform-view-one-overlay-two-intersecting-overlays" : - @"platform_view_one_overlay_two_intersecting_overlays", - @"--platform-view-multiple-without-overlays" : @"platform_view_multiple_without_overlays", - @"--platform-view-max-overlays" : @"platform_view_max_overlays", @"--platform-view-multiple" : @"platform_view_multiple", @"--platform-view-multiple-background-foreground" : @"platform_view_multiple_background_foreground", diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/UnobstructedPlatformViewTests.m b/testing/scenario_app/ios/Scenarios/ScenariosUITests/UnobstructedPlatformViewTests.m deleted file mode 100644 index 02e7eee35f098..0000000000000 --- a/testing/scenario_app/ios/Scenarios/ScenariosUITests/UnobstructedPlatformViewTests.m +++ /dev/null @@ -1,254 +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. - -#import - -@interface UnobstructedPlatformViewTests : XCTestCase - -@end - -@implementation UnobstructedPlatformViewTests - -- (void)setUp { - self.continueAfterFailure = NO; -} - -// A is the layer, which z index is higher than the platform view. -// +--------+ -// | PV | +---+ -// +--------+ | A | -// +---+ -- (void)testNoOverlay { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-no-overlay-intersection" ]; - [app launch]; - - XCUIElement* platform_view = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view.exists); - XCTAssertEqual(platform_view.frame.origin.x, 25); - XCTAssertEqual(platform_view.frame.origin.y, 25); - XCTAssertEqual(platform_view.frame.size.width, 250); - XCTAssertEqual(platform_view.frame.size.height, 250); - - XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"]; - XCTAssertFalse(overlay.exists); -} - -// A is the layer above the platform view. -// +-----------------+ -// | PV +---+ | -// | | A | | -// | +---+ | -// +-----------------+ -- (void)testOneOverlay { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view" ]; - [app launch]; - - XCUIElement* platform_view = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view.exists); - XCTAssertEqual(platform_view.frame.origin.x, 25); - XCTAssertEqual(platform_view.frame.origin.y, 25); - XCTAssertEqual(platform_view.frame.size.width, 250); - XCTAssertEqual(platform_view.frame.size.height, 250); - - XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"]; - XCTAssertTrue(overlay.exists); - XCTAssertEqual(overlay.frame.origin.x, 150); - XCTAssertEqual(overlay.frame.origin.y, 150); - XCTAssertEqual(overlay.frame.size.width, 50); - XCTAssertEqual(overlay.frame.size.height, 50); -} - -// A is the layer above the platform view. -// +-----------------+ -// | PV +---+ | -// +-----------| A |-+ -// +---+ -- (void)testOneOverlayPartialIntersection { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-partial-intersection" ]; - [app launch]; - - XCUIElement* platform_view = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view.exists); - XCTAssertEqual(platform_view.frame.origin.x, 25); - XCTAssertEqual(platform_view.frame.origin.y, 25); - XCTAssertEqual(platform_view.frame.size.width, 250); - XCTAssertEqual(platform_view.frame.size.height, 250); - - XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"]; - XCTAssertTrue(overlay.exists); - XCTAssertEqual(overlay.frame.origin.x, 200); - XCTAssertEqual(overlay.frame.origin.y, 250); - XCTAssertEqual(overlay.frame.size.width, 50); - // Half the height of the overlay. - XCTAssertEqual(overlay.frame.size.height, 25); -} - -// A and B are the layers above the platform view. -// +--------------------+ -// | PV +------------+ | -// | | B +-----+ | | -// | +---| A |-+ | -// +----------| |---+ -// +-----+ -- (void)testTwoIntersectingOverlays { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-two-intersecting-overlays" ]; - [app launch]; - - XCUIElement* platform_view = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view.exists); - XCTAssertEqual(platform_view.frame.origin.x, 25); - XCTAssertEqual(platform_view.frame.origin.y, 25); - XCTAssertEqual(platform_view.frame.size.width, 250); - XCTAssertEqual(platform_view.frame.size.height, 250); - - XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"]; - XCTAssertTrue(overlay.exists); - XCTAssertEqual(overlay.frame.origin.x, 150); - XCTAssertEqual(overlay.frame.origin.y, 150); - XCTAssertEqual(overlay.frame.size.width, 75); - XCTAssertEqual(overlay.frame.size.height, 75); - - XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[1]"].exists); -} - -// A, B, and C are the layers above the platform view. -// +-------------------------+ -// | PV +-----------+ | -// | +---+ | B +-----+ | | -// | | C | +---| A |-+ | -// | +---+ +-----+ | -// +-------------------------+ -- (void)testOneOverlayAndTwoIntersectingOverlays { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-one-overlay-two-intersecting-overlays" ]; - [app launch]; - - XCUIElement* platform_view = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view.exists); - XCTAssertEqual(platform_view.frame.origin.x, 25); - XCTAssertEqual(platform_view.frame.origin.y, 25); - XCTAssertEqual(platform_view.frame.size.width, 250); - XCTAssertEqual(platform_view.frame.size.height, 250); - - XCUIElement* overlay1 = app.otherElements[@"platform_view[0].overlay[0]"]; - XCTAssertTrue(overlay1.exists); - XCTAssertEqual(overlay1.frame.origin.x, 150); - XCTAssertEqual(overlay1.frame.origin.y, 150); - XCTAssertEqual(overlay1.frame.size.width, 75); - XCTAssertEqual(overlay1.frame.size.height, 75); - - XCUIElement* overlay2 = app.otherElements[@"platform_view[0].overlay[1]"]; - XCTAssertTrue(overlay2.exists); - XCTAssertEqual(overlay2.frame.origin.x, 75); - XCTAssertEqual(overlay2.frame.origin.y, 225); - XCTAssertEqual(overlay2.frame.size.width, 50); - XCTAssertEqual(overlay2.frame.size.height, 50); -} - -// A is the layer, which z index is higher than the platform view. -// +--------+ -// | PV | +---+ -// +--------+ | A | -// +--------+ +---+ -// | PV | -// +--------+ -- (void)testMultiplePlatformViewsWithoutOverlays { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-multiple-without-overlays" ]; - [app launch]; - - XCUIElement* platform_view1 = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view1.exists); - XCTAssertEqual(platform_view1.frame.origin.x, 25); - XCTAssertEqual(platform_view1.frame.origin.y, 325); - XCTAssertEqual(platform_view1.frame.size.width, 250); - XCTAssertEqual(platform_view1.frame.size.height, 250); - - XCUIElement* platform_view2 = app.textViews[@"platform_view[1]"]; - XCTAssertTrue(platform_view2.exists); - XCTAssertEqual(platform_view2.frame.origin.x, 25); - XCTAssertEqual(platform_view2.frame.origin.y, 25); - XCTAssertEqual(platform_view2.frame.size.width, 250); - XCTAssertEqual(platform_view2.frame.size.height, 250); - - XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[0]"].exists); - XCTAssertFalse(app.otherElements[@"platform_view[1].overlay[0]"].exists); -} - -// A is the layer above both platform view. -// +------------+ -// | PV +----+ | -// +-----| A |-+ -// +-----| |-+ -// | PV +----+ | -// +------------+ -- (void)testMultiplePlatformViewsWithOverlays { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-multiple-background-foreground" ]; - [app launch]; - - XCUIElement* platform_view1 = app.textViews[@"platform_view[8]"]; - XCTAssertTrue(platform_view1.exists); - XCTAssertEqual(platform_view1.frame.origin.x, 25); - XCTAssertEqual(platform_view1.frame.origin.y, 325); - XCTAssertEqual(platform_view1.frame.size.width, 250); - XCTAssertEqual(platform_view1.frame.size.height, 250); - - XCUIElement* platform_view2 = app.textViews[@"platform_view[9]"]; - XCTAssertTrue(platform_view2.exists); - XCTAssertEqual(platform_view2.frame.origin.x, 25); - XCTAssertEqual(platform_view2.frame.origin.y, 25); - XCTAssertEqual(platform_view2.frame.size.width, 250); - XCTAssertEqual(platform_view2.frame.size.height, 250); - - XCUIElement* overlay1 = app.otherElements[@"platform_view[8].overlay[0]"]; - XCTAssertTrue(overlay1.exists); - XCTAssertEqual(overlay1.frame.origin.x, 25); - XCTAssertEqual(overlay1.frame.origin.y, 325); - XCTAssertEqual(overlay1.frame.size.width, 225); - XCTAssertEqual(overlay1.frame.size.height, 175); - - XCUIElement* overlay2 = app.otherElements[@"platform_view[9].overlay[0]"]; - XCTAssertTrue(overlay2.exists); - XCTAssertEqual(overlay2.frame.origin.x, 25); - XCTAssertEqual(overlay2.frame.origin.y, 25); - XCTAssertEqual(overlay2.frame.size.width, 225); - XCTAssertEqual(overlay2.frame.size.height, 250); -} - -// More then two overlays are merged into a single layer. -// +---------------------+ -// | +---+ +---+ +---+ | -// | | A | | B | | C | | -// | +---+ +---+ +---+ | -// | +-------+ | -// +-| D |-----------+ -// +-------+ -- (void)testPlatformViewsMaxOverlays { - XCUIApplication* app = [[XCUIApplication alloc] init]; - app.launchArguments = @[ @"--platform-view-max-overlays" ]; - [app launch]; - - XCUIElement* platform_view = app.textViews[@"platform_view[0]"]; - XCTAssertTrue(platform_view.exists); - XCTAssertEqual(platform_view.frame.origin.x, 25); - XCTAssertEqual(platform_view.frame.origin.y, 25); - XCTAssertEqual(platform_view.frame.size.width, 250); - XCTAssertEqual(platform_view.frame.size.height, 250); - - XCUIElement* overlay = app.otherElements[@"platform_view[0].overlay[0]"]; - XCTAssertTrue(overlay.exists); - XCTAssertEqual(overlay.frame.origin.x, 75); - XCTAssertEqual(overlay.frame.origin.y, 85); - XCTAssertEqual(overlay.frame.size.width, 150); - XCTAssertEqual(overlay.frame.size.height, 190); - - XCTAssertFalse(app.otherElements[@"platform_view[0].overlay[1]"].exists); -} - -@end diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone 8_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone 8_simulator.png index 9ec19ab474f03..a193faeb04022 100644 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone 8_simulator.png and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_clippath_iPhone 8_simulator.png differ diff --git a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone 8_simulator.png b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone 8_simulator.png index a2e9351d385e0..793082f8f0f7c 100644 Binary files a/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone 8_simulator.png and b/testing/scenario_app/ios/Scenarios/ScenariosUITests/golden_platform_view_transform_iPhone 8_simulator.png differ diff --git a/testing/scenario_app/lib/main.dart b/testing/scenario_app/lib/main.dart index 0ab3f7c5352f1..494d6585aa7fe 100644 --- a/testing/scenario_app/lib/main.dart +++ b/testing/scenario_app/lib/main.dart @@ -19,12 +19,6 @@ import 'src/touches_scenario.dart'; Map _scenarios = { 'animated_color_square': AnimatedColorSquareScenario(window), 'platform_view': PlatformViewScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_no_overlay_intersection': PlatformViewNoOverlayIntersectionScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_partial_intersection': PlatformViewPartialIntersectionScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_two_intersecting_overlays': PlatformViewTwoIntersectingOverlaysScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_one_overlay_two_intersecting_overlays': PlatformViewOneOverlayTwoIntersectingOverlaysScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_multiple_without_overlays': MultiPlatformViewWithoutOverlaysScenario(window, 'Hello from Scenarios (Platform View)', id: 0), - 'platform_view_max_overlays': PlatformViewMaxOverlaysScenario(window, 'Hello from Scenarios (Platform View)', id: 0), 'platform_view_cliprect': PlatformViewClipRectScenario(window, 'PlatformViewClipRect', id: 1), 'platform_view_cliprrect': PlatformViewClipRRectScenario(window, 'PlatformViewClipRRect', id: 2), 'platform_view_clippath': PlatformViewClipPathScenario(window, 'PlatformViewClipPath', id: 3), diff --git a/testing/scenario_app/lib/src/platform_view.dart b/testing/scenario_app/lib/src/platform_view.dart index fcea41a65f7d5..0dde98fd9eebb 100644 --- a/testing/scenario_app/lib/src/platform_view.dart +++ b/testing/scenario_app/lib/src/platform_view.dart @@ -48,224 +48,6 @@ class PlatformViewScenario extends Scenario with _BasePlatformViewScenarioMixin } } -/// A simple platform view with overlay that doesn't intersect with the platform view. -class PlatformViewNoOverlayIntersectionScenario extends Scenario with _BasePlatformViewScenarioMixin { - /// Creates the PlatformView scenario. - /// - /// The [window] parameter must not be null. - PlatformViewNoOverlayIntersectionScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - createPlatformView(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - finishBuilderByAddingPlatformViewAndPicture( - builder, - 0, - overlayOffset: const Offset(150, 350), - ); - } -} - -/// A simple platform view with an overlay that partially intersects with the platform view. -class PlatformViewPartialIntersectionScenario extends Scenario with _BasePlatformViewScenarioMixin { - /// Creates the PlatformView scenario. - /// - /// The [window] parameter must not be null. - PlatformViewPartialIntersectionScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - createPlatformView(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - finishBuilderByAddingPlatformViewAndPicture( - builder, - 0, - overlayOffset: const Offset(150, 250), - ); - } -} - -/// A simple platform view with two overlays that intersect with each other and the platform view. -class PlatformViewTwoIntersectingOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin { - /// Creates the PlatformView scenario. - /// - /// The [window] parameter must not be null. - PlatformViewTwoIntersectingOverlaysScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - createPlatformView(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - _addPlatformViewtoScene(builder, 0, 500, 500); - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawCircle( - const Offset(50, 50), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - canvas.drawCircle( - const Offset(100, 100), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - final Picture picture = recorder.endRecording(); - builder.addPicture(const Offset(300, 300), picture); - final Scene scene = builder.build(); - window.render(scene); - scene.dispose(); - } -} - -/// A simple platform view with one overlay and two overlays that intersect with each other and the platform view. -class PlatformViewOneOverlayTwoIntersectingOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin { - /// Creates the PlatformView scenario. - /// - /// The [window] parameter must not be null. - PlatformViewOneOverlayTwoIntersectingOverlaysScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - createPlatformView(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - _addPlatformViewtoScene(builder, 0, 500, 500); - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawCircle( - const Offset(50, 50), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - canvas.drawCircle( - const Offset(100, 100), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - canvas.drawCircle( - const Offset(-100, 200), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - final Picture picture = recorder.endRecording(); - builder.addPicture(const Offset(300, 300), picture); - final Scene scene = builder.build(); - window.render(scene); - scene.dispose(); - } -} - -/// Two platform views without an overlay intersecting either platform view. -class MultiPlatformViewWithoutOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin { - /// Creates the PlatformView scenario. - /// - /// The [window] parameter must not be null. - MultiPlatformViewWithoutOverlaysScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - createPlatformView(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - builder.pushOffset(0, 600); - _addPlatformViewtoScene(builder, 0, 500, 500); - builder.pop(); - - _addPlatformViewtoScene(builder, 1, 500, 500); - - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawRect( - const Rect.fromLTRB(0, 0, 100, 1000), - Paint()..color = const Color(0xFFFF0000), - ); - final Picture picture = recorder.endRecording(); - builder.addPicture(const Offset(580, 0), picture); - - builder.pop(); - final Scene scene = builder.build(); - window.render(scene); - scene.dispose(); - } -} - -/// A simple platform view with too many overlays result in a single native view. -class PlatformViewMaxOverlaysScenario extends Scenario with _BasePlatformViewScenarioMixin { - /// Creates the PlatformView scenario. - /// - /// The [window] parameter must not be null. - PlatformViewMaxOverlaysScenario(Window window, String text, {int id = 0}) - : assert(window != null), - super(window) { - createPlatformView(window, text, id); - } - - @override - void onBeginFrame(Duration duration) { - final SceneBuilder builder = SceneBuilder(); - - builder.pushOffset(0, 0); - - _addPlatformViewtoScene(builder, 0, 500, 500); - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawCircle( - const Offset(50, 50), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - canvas.drawCircle( - const Offset(100, 100), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - canvas.drawCircle( - const Offset(-100, 200), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - canvas.drawCircle( - const Offset(-100, -80), - 50, - Paint()..color = const Color(0xFFABCDEF), - ); - final Picture picture = recorder.endRecording(); - builder.addPicture(const Offset(300, 300), picture); - final Scene scene = builder.build(); - window.render(scene); - scene.dispose(); - } -} - /// Builds a scene with 2 platform views. class MultiPlatformViewScenario extends Scenario with _BasePlatformViewScenarioMixin { /// Creates the PlatformView scenario. @@ -642,17 +424,12 @@ mixin _BasePlatformViewScenarioMixin on Scenario { } // Add a platform view and a picture to the scene, then finish the `sceneBuilder`. - void finishBuilderByAddingPlatformViewAndPicture( - SceneBuilder sceneBuilder, - int viewId, { - Offset overlayOffset, - }) { - overlayOffset ??= const Offset(50, 50); + void finishBuilderByAddingPlatformViewAndPicture(SceneBuilder sceneBuilder, int viewId) { _addPlatformViewtoScene(sceneBuilder, viewId, 500, 500); final PictureRecorder recorder = PictureRecorder(); final Canvas canvas = Canvas(recorder); canvas.drawCircle( - overlayOffset, + const Offset(50, 50), 50, Paint()..color = const Color(0xFFABCDEF), );