diff --git a/engine/src/flutter/flow/BUILD.gn b/engine/src/flutter/flow/BUILD.gn index bd1c6b739d..9b9530340d 100644 --- a/engine/src/flutter/flow/BUILD.gn +++ b/engine/src/flutter/flow/BUILD.gn @@ -22,6 +22,8 @@ source_set("flow") { "layers/color_filter_layer.h", "layers/container_layer.cc", "layers/container_layer.h", + "layers/default_layer_builder.cc", + "layers/default_layer_builder.h", "layers/layer.cc", "layers/layer.h", "layers/layer_builder.cc", diff --git a/engine/src/flutter/flow/debug_print.cc b/engine/src/flutter/flow/debug_print.cc index d1b7f25392..c30f7a44cc 100644 --- a/engine/src/flutter/flow/debug_print.cc +++ b/engine/src/flutter/flow/debug_print.cc @@ -59,6 +59,12 @@ std::ostream& operator<<(std::ostream& os, const SkRect& r) { return os; } +std::ostream& operator<<(std::ostream& os, const SkRRect& r) { + os << "LTRB: " << r.rect().fLeft << ", " << r.rect().fTop << ", " + << r.rect().fRight << ", " << r.rect().fBottom; + return os; +} + std::ostream& operator<<(std::ostream& os, const SkPoint& r) { os << "XY: " << r.fX << ", " << r.fY; return os; diff --git a/engine/src/flutter/flow/debug_print.h b/engine/src/flutter/flow/debug_print.h index 20612966d2..ca5973eeb0 100644 --- a/engine/src/flutter/flow/debug_print.h +++ b/engine/src/flutter/flow/debug_print.h @@ -11,6 +11,7 @@ #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkMatrix44.h" #include "third_party/skia/include/core/SkPoint3.h" +#include "third_party/skia/include/core/SkRRect.h" #define DEF_PRINTER(x) std::ostream& operator<<(std::ostream&, const x&); @@ -21,6 +22,7 @@ DEF_PRINTER(SkMatrix44); DEF_PRINTER(SkVector3); DEF_PRINTER(SkVector4); DEF_PRINTER(SkRect); +DEF_PRINTER(SkRRect); DEF_PRINTER(SkPoint); #endif // FLUTTER_FLOW_DEBUG_PRINT_H_ diff --git a/engine/src/flutter/flow/layers/default_layer_builder.cc b/engine/src/flutter/flow/layers/default_layer_builder.cc new file mode 100644 index 0000000000..50a33092c8 --- /dev/null +++ b/engine/src/flutter/flow/layers/default_layer_builder.cc @@ -0,0 +1,210 @@ +// Copyright 2017 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/layers/default_layer_builder.h" + +#include "flutter/flow/layers/backdrop_filter_layer.h" +#include "flutter/flow/layers/clip_path_layer.h" +#include "flutter/flow/layers/clip_rect_layer.h" +#include "flutter/flow/layers/clip_rrect_layer.h" +#include "flutter/flow/layers/color_filter_layer.h" +#include "flutter/flow/layers/container_layer.h" +#include "flutter/flow/layers/layer.h" +#include "flutter/flow/layers/layer_tree.h" +#include "flutter/flow/layers/opacity_layer.h" +#include "flutter/flow/layers/performance_overlay_layer.h" +#include "flutter/flow/layers/physical_model_layer.h" +#include "flutter/flow/layers/picture_layer.h" +#include "flutter/flow/layers/shader_mask_layer.h" +#include "flutter/flow/layers/transform_layer.h" + +#if defined(OS_FUCHSIA) +#include "flutter/flow/layers/child_scene_layer.h" +#endif // defined(OS_FUCHSIA) + +namespace flow { + +DefaultLayerBuilder::DefaultLayerBuilder() { + cull_rects_.push(SkRect::MakeLargest()); +} + +DefaultLayerBuilder::~DefaultLayerBuilder() = default; + +void DefaultLayerBuilder::PushTransform(const SkMatrix& sk_matrix) { + SkMatrix inverse_sk_matrix; + SkRect cullRect; + if (sk_matrix.invert(&inverse_sk_matrix)) { + inverse_sk_matrix.mapRect(&cullRect, cull_rects_.top()); + } else { + cullRect = SkRect::MakeLargest(); + } + + auto layer = std::make_unique(); + layer->set_transform(sk_matrix); + PushLayer(std::move(layer), cullRect); +} + +void DefaultLayerBuilder::PushClipRect(const SkRect& clipRect) { + SkRect cullRect; + if (!cullRect.intersect(clipRect, cull_rects_.top())) { + cullRect = SkRect::MakeEmpty(); + } + auto layer = std::make_unique(); + layer->set_clip_rect(clipRect); + PushLayer(std::move(layer), cullRect); +} + +void DefaultLayerBuilder::PushClipRoundedRect(const SkRRect& rrect) { + SkRect cullRect; + if (!cullRect.intersect(rrect.rect(), cull_rects_.top())) { + cullRect = SkRect::MakeEmpty(); + } + auto layer = std::make_unique(); + layer->set_clip_rrect(rrect); + PushLayer(std::move(layer), cullRect); +} + +void DefaultLayerBuilder::PushClipPath(const SkPath& path) { + SkRect cullRect; + if (!cullRect.intersect(path.getBounds(), cull_rects_.top())) { + cullRect = SkRect::MakeEmpty(); + } + auto layer = std::make_unique(); + layer->set_clip_path(path); + PushLayer(std::move(layer), cullRect); +} + +void DefaultLayerBuilder::PushOpacity(int alpha) { + auto layer = std::make_unique(); + layer->set_alpha(alpha); + PushLayer(std::move(layer), cull_rects_.top()); +} + +void DefaultLayerBuilder::PushColorFilter(SkColor color, + SkBlendMode blend_mode) { + auto layer = std::make_unique(); + layer->set_color(color); + layer->set_blend_mode(blend_mode); + PushLayer(std::move(layer), cull_rects_.top()); +} + +void DefaultLayerBuilder::PushBackdropFilter(sk_sp filter) { + auto layer = std::make_unique(); + layer->set_filter(filter); + PushLayer(std::move(layer), cull_rects_.top()); +} + +void DefaultLayerBuilder::PushShaderMask(sk_sp shader, + const SkRect& rect, + SkBlendMode blend_mode) { + auto layer = std::make_unique(); + layer->set_shader(shader); + layer->set_mask_rect(rect); + layer->set_blend_mode(blend_mode); + PushLayer(std::move(layer), cull_rects_.top()); +} + +void DefaultLayerBuilder::PushPhysicalModel(const SkRRect& sk_rrect, + double elevation, + SkColor color, + SkScalar device_pixel_ratio) { + SkRect cullRect; + if (!cullRect.intersect(sk_rrect.rect(), cull_rects_.top())) { + cullRect = SkRect::MakeEmpty(); + } + auto layer = std::make_unique(); + layer->set_rrect(sk_rrect); + layer->set_elevation(elevation); + layer->set_color(color); + layer->set_device_pixel_ratio(device_pixel_ratio); + PushLayer(std::move(layer), cullRect); +} + +void DefaultLayerBuilder::PushPerformanceOverlay(uint64_t enabled_options, + const SkRect& rect) { + if (!current_layer_) { + return; + } + auto layer = std::make_unique(enabled_options); + layer->set_paint_bounds(rect); + current_layer_->Add(std::move(layer)); +} + +void DefaultLayerBuilder::PushPicture(const SkPoint& offset, + sk_sp picture, + bool picture_is_complex, + bool picture_will_change) { + if (!current_layer_) { + return; + } + SkRect pictureRect = picture->cullRect(); + pictureRect.offset(offset.x(), offset.y()); + if (!SkRect::Intersects(pictureRect, cull_rects_.top())) { + return; + } + auto layer = std::make_unique(); + layer->set_offset(offset); + layer->set_picture(picture); + layer->set_is_complex(picture_is_complex); + layer->set_will_change(picture_will_change); + current_layer_->Add(std::move(layer)); +} + +#if defined(OS_FUCHSIA) +void DefaultLayerBuilder::PushChildScene( + const SkPoint& offset, + const SkSize& size, + fxl::RefPtr export_token_holder, + bool hit_testable) { + if (!current_layer_) { + return; + } + SkRect sceneRect = + SkRect::MakeXYWH(offset.x(), offset.y(), size.width(), size.height()); + if (!SkRect::Intersects(sceneRect, cull_rects_.top())) { + return; + } + auto layer = std::make_unique(); + layer->set_offset(offset); + layer->set_size(size); + layer->set_export_node_holder(std::move(export_token_holder)); + layer->set_hit_testable(hit_testable); + current_layer_->Add(std::move(layer)); +} +#endif // defined(OS_FUCHSIA) + +void DefaultLayerBuilder::Pop() { + if (!current_layer_) { + return; + } + cull_rects_.pop(); + current_layer_ = current_layer_->parent(); +} + +std::unique_ptr DefaultLayerBuilder::TakeLayer() { + return std::move(root_layer_); +} + +void DefaultLayerBuilder::PushLayer(std::unique_ptr layer, + const SkRect& cullRect) { + FXL_DCHECK(layer); + + cull_rects_.push(cullRect); + + if (!root_layer_) { + root_layer_ = std::move(layer); + current_layer_ = root_layer_.get(); + return; + } + + if (!current_layer_) { + return; + } + + flow::ContainerLayer* newLayer = layer.get(); + current_layer_->Add(std::move(layer)); + current_layer_ = newLayer; +} + +} // namespace flow diff --git a/engine/src/flutter/flow/layers/default_layer_builder.h b/engine/src/flutter/flow/layers/default_layer_builder.h new file mode 100644 index 0000000000..105758f3a6 --- /dev/null +++ b/engine/src/flutter/flow/layers/default_layer_builder.h @@ -0,0 +1,93 @@ +// Copyright 2017 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. + +#ifndef FLUTTER_FLOW_LAYERS_DEFAULT_LAYER_BUILDER_H_ +#define FLUTTER_FLOW_LAYERS_DEFAULT_LAYER_BUILDER_H_ + +#include + +#include "flutter/flow/layers/container_layer.h" +#include "flutter/flow/layers/layer_builder.h" +#include "garnet/public/lib/fxl/macros.h" + +namespace flow { + +class DefaultLayerBuilder final : public LayerBuilder { + public: + DefaultLayerBuilder(); + + // |flow::LayerBuilder| + ~DefaultLayerBuilder() override; + + // |flow::LayerBuilder| + void PushTransform(const SkMatrix& matrix) override; + + // |flow::LayerBuilder| + void PushClipRect(const SkRect& rect) override; + + // |flow::LayerBuilder| + void PushClipRoundedRect(const SkRRect& rect) override; + + // |flow::LayerBuilder| + void PushClipPath(const SkPath& path) override; + + // |flow::LayerBuilder| + void PushOpacity(int alpha) override; + + // |flow::LayerBuilder| + void PushColorFilter(SkColor color, SkBlendMode blend_mode) override; + + // |flow::LayerBuilder| + void PushBackdropFilter(sk_sp filter) override; + + // |flow::LayerBuilder| + void PushShaderMask(sk_sp shader, + const SkRect& rect, + SkBlendMode blend_mode) override; + + // |flow::LayerBuilder| + void PushPhysicalModel(const SkRRect& rect, + double elevation, + SkColor color, + SkScalar device_pixel_ratio) override; + + // |flow::LayerBuilder| + void PushPerformanceOverlay(uint64_t enabled_options, + const SkRect& rect) override; + + // |flow::LayerBuilder| + void PushPicture(const SkPoint& offset, + sk_sp picture, + bool picture_is_complex, + bool picture_will_change) override; + +#if defined(OS_FUCHSIA) + // |flow::LayerBuilder| + void PushChildScene(const SkPoint& offset, + const SkSize& size, + fxl::RefPtr export_token_holder, + bool hit_testable) override; +#endif // defined(OS_FUCHSIA) + + // |flow::LayerBuilder| + void Pop() override; + + // |flow::LayerBuilder| + std::unique_ptr TakeLayer() override; + + private: + std::unique_ptr root_layer_; + flow::ContainerLayer* current_layer_ = nullptr; + + std::stack cull_rects_; + + void PushLayer(std::unique_ptr layer, + const SkRect& cullRect); + + FXL_DISALLOW_COPY_AND_ASSIGN(DefaultLayerBuilder); +}; + +} // namespace flow + +#endif // FLUTTER_FLOW_LAYERS_DEFAULT_LAYER_BUILDER_H_ diff --git a/engine/src/flutter/flow/layers/layer_builder.cc b/engine/src/flutter/flow/layers/layer_builder.cc index caa9b70672..1d2243d5df 100644 --- a/engine/src/flutter/flow/layers/layer_builder.cc +++ b/engine/src/flutter/flow/layers/layer_builder.cc @@ -3,184 +3,18 @@ // found in the LICENSE file. #include "flutter/flow/layers/layer_builder.h" - -#include "flutter/flow/layers/backdrop_filter_layer.h" -#include "flutter/flow/layers/clip_path_layer.h" -#include "flutter/flow/layers/clip_rect_layer.h" -#include "flutter/flow/layers/clip_rrect_layer.h" -#include "flutter/flow/layers/color_filter_layer.h" -#include "flutter/flow/layers/container_layer.h" -#include "flutter/flow/layers/layer.h" -#include "flutter/flow/layers/layer_tree.h" -#include "flutter/flow/layers/opacity_layer.h" -#include "flutter/flow/layers/performance_overlay_layer.h" -#include "flutter/flow/layers/physical_model_layer.h" -#include "flutter/flow/layers/picture_layer.h" -#include "flutter/flow/layers/shader_mask_layer.h" -#include "flutter/flow/layers/transform_layer.h" - -#if defined(OS_FUCHSIA) -#include "flutter/flow/layers/child_scene_layer.h" -#endif // defined(OS_FUCHSIA) +#include "flutter/flow/layers/default_layer_builder.h" namespace flow { -LayerBuilder::LayerBuilder() { - cull_rects_.push(SkRect::MakeLargest()); +std::unique_ptr LayerBuilder::Create() { + return std::make_unique(); } +LayerBuilder::LayerBuilder() = default; + LayerBuilder::~LayerBuilder() = default; -void LayerBuilder::PushTransform(const SkMatrix& sk_matrix) { - SkMatrix inverse_sk_matrix; - SkRect cullRect; - if (sk_matrix.invert(&inverse_sk_matrix)) { - inverse_sk_matrix.mapRect(&cullRect, cull_rects_.top()); - } else { - cullRect = SkRect::MakeLargest(); - } - - auto layer = std::make_unique(); - layer->set_transform(sk_matrix); - PushLayer(std::move(layer), cullRect); -} - -void LayerBuilder::PushClipRect(const SkRect& clipRect) { - SkRect cullRect; - if (!cullRect.intersect(clipRect, cull_rects_.top())) { - cullRect = SkRect::MakeEmpty(); - } - auto layer = std::make_unique(); - layer->set_clip_rect(clipRect); - PushLayer(std::move(layer), cullRect); -} - -void LayerBuilder::PushClipRoundedRect(const SkRRect& rrect) { - SkRect cullRect; - if (!cullRect.intersect(rrect.rect(), cull_rects_.top())) { - cullRect = SkRect::MakeEmpty(); - } - auto layer = std::make_unique(); - layer->set_clip_rrect(rrect); - PushLayer(std::move(layer), cullRect); -} - -void LayerBuilder::PushClipPath(const SkPath& path) { - SkRect cullRect; - if (!cullRect.intersect(path.getBounds(), cull_rects_.top())) { - cullRect = SkRect::MakeEmpty(); - } - auto layer = std::make_unique(); - layer->set_clip_path(path); - PushLayer(std::move(layer), cullRect); -} - -void LayerBuilder::PushOpacity(int alpha) { - auto layer = std::make_unique(); - layer->set_alpha(alpha); - PushLayer(std::move(layer), cull_rects_.top()); -} - -void LayerBuilder::PushColorFilter(SkColor color, SkBlendMode blend_mode) { - auto layer = std::make_unique(); - layer->set_color(color); - layer->set_blend_mode(blend_mode); - PushLayer(std::move(layer), cull_rects_.top()); -} - -void LayerBuilder::PushBackdropFilter(sk_sp filter) { - auto layer = std::make_unique(); - layer->set_filter(filter); - PushLayer(std::move(layer), cull_rects_.top()); -} - -void LayerBuilder::PushShaderMask(sk_sp shader, - const SkRect& rect, - SkBlendMode blend_mode) { - auto layer = std::make_unique(); - layer->set_shader(shader); - layer->set_mask_rect(rect); - layer->set_blend_mode(blend_mode); - PushLayer(std::move(layer), cull_rects_.top()); -} - -void LayerBuilder::PushPhysicalModel(const SkRRect& sk_rrect, - double elevation, - SkColor color, - SkScalar device_pixel_ratio) { - SkRect cullRect; - if (!cullRect.intersect(sk_rrect.rect(), cull_rects_.top())) { - cullRect = SkRect::MakeEmpty(); - } - auto layer = std::make_unique(); - layer->set_rrect(sk_rrect); - layer->set_elevation(elevation); - layer->set_color(color); - layer->set_device_pixel_ratio(device_pixel_ratio); - PushLayer(std::move(layer), cullRect); -} - -void LayerBuilder::PushPerformanceOverlay(uint64_t enabled_options, - const SkRect& rect) { - if (!current_layer_) { - return; - } - auto layer = std::make_unique(enabled_options); - layer->set_paint_bounds(rect); - current_layer_->Add(std::move(layer)); -} - -void LayerBuilder::PushPicture(const SkPoint& offset, - sk_sp picture, - bool picture_is_complex, - bool picture_will_change) { - if (!current_layer_) { - return; - } - SkRect pictureRect = picture->cullRect(); - pictureRect.offset(offset.x(), offset.y()); - if (!SkRect::Intersects(pictureRect, cull_rects_.top())) { - return; - } - auto layer = std::make_unique(); - layer->set_offset(offset); - layer->set_picture(picture); - layer->set_is_complex(picture_is_complex); - layer->set_will_change(picture_will_change); - current_layer_->Add(std::move(layer)); -} - -#if defined(OS_FUCHSIA) -void LayerBuilder::PushChildScene( - const SkPoint& offset, - const SkSize& size, - fxl::RefPtr export_token_holder, - bool hit_testable) { - if (!current_layer_) { - return; - } - SkRect sceneRect = - SkRect::MakeXYWH(offset.x(), offset.y(), size.width(), size.height()); - if (!SkRect::Intersects(sceneRect, cull_rects_.top())) { - return; - } - auto layer = std::make_unique(); - layer->set_offset(offset); - layer->set_size(size); - layer->set_export_node_holder(std::move(export_token_holder)); - layer->set_hit_testable(hit_testable); - current_layer_->Add(std::move(layer)); -} -#endif // defined(OS_FUCHSIA) - -void LayerBuilder::Pop() { - if (!current_layer_) { - return; - } - cull_rects_.pop(); - current_layer_ = current_layer_->parent(); -} - int LayerBuilder::GetRasterizerTracingThreshold() const { return rasterizer_tracing_threshold_; } @@ -205,29 +39,4 @@ void LayerBuilder::SetCheckerboardOffscreenLayers(bool checkerboard) { checkerboard_offscreen_layers_ = checkerboard; } -std::unique_ptr LayerBuilder::TakeLayer() { - return std::move(root_layer_); -} - -void LayerBuilder::PushLayer(std::unique_ptr layer, - const SkRect& cullRect) { - FXL_DCHECK(layer); - - cull_rects_.push(cullRect); - - if (!root_layer_) { - root_layer_ = std::move(layer); - current_layer_ = root_layer_.get(); - return; - } - - if (!current_layer_) { - return; - } - - flow::ContainerLayer* newLayer = layer.get(); - current_layer_->Add(std::move(layer)); - current_layer_ = newLayer; -} - } // namespace flow diff --git a/engine/src/flutter/flow/layers/layer_builder.h b/engine/src/flutter/flow/layers/layer_builder.h index 39e8cf17f1..2c645b2c8c 100644 --- a/engine/src/flutter/flow/layers/layer_builder.h +++ b/engine/src/flutter/flow/layers/layer_builder.h @@ -6,9 +6,8 @@ #define FLUTTER_FLOW_LAYERS_LAYER_BUILDER_H_ #include -#include -#include "flutter/flow/layers/container_layer.h" +#include "flutter/flow/layers/layer.h" #include "garnet/public/lib/fxl/macros.h" #include "third_party/skia/include/core/SkBlendMode.h" #include "third_party/skia/include/core/SkColor.h" @@ -24,48 +23,54 @@ namespace flow { class LayerBuilder { public: + static std::unique_ptr Create(); + LayerBuilder(); - ~LayerBuilder(); + virtual ~LayerBuilder(); - void PushTransform(const SkMatrix& matrix); + virtual void PushTransform(const SkMatrix& matrix) = 0; - void PushClipRect(const SkRect& rect); + virtual void PushClipRect(const SkRect& rect) = 0; - void PushClipRoundedRect(const SkRRect& rect); + virtual void PushClipRoundedRect(const SkRRect& rect) = 0; - void PushClipPath(const SkPath& path); + virtual void PushClipPath(const SkPath& path) = 0; - void PushOpacity(int alpha); + virtual void PushOpacity(int alpha) = 0; - void PushColorFilter(SkColor color, SkBlendMode blend_mode); + virtual void PushColorFilter(SkColor color, SkBlendMode blend_mode) = 0; - void PushBackdropFilter(sk_sp filter); + virtual void PushBackdropFilter(sk_sp filter) = 0; - void PushShaderMask(sk_sp shader, - const SkRect& rect, - SkBlendMode blend_mode); + virtual void PushShaderMask(sk_sp shader, + const SkRect& rect, + SkBlendMode blend_mode) = 0; - void PushPhysicalModel(const SkRRect& rect, - double elevation, - SkColor color, - SkScalar device_pixel_ratio); + virtual void PushPhysicalModel(const SkRRect& rect, + double elevation, + SkColor color, + SkScalar device_pixel_ratio) = 0; - void PushPerformanceOverlay(uint64_t enabled_options, const SkRect& rect); + virtual void PushPerformanceOverlay(uint64_t enabled_options, + const SkRect& rect) = 0; - void PushPicture(const SkPoint& offset, - sk_sp picture, - bool picture_is_complex, - bool picture_will_change); + virtual void PushPicture(const SkPoint& offset, + sk_sp picture, + bool picture_is_complex, + bool picture_will_change) = 0; #if defined(OS_FUCHSIA) - void PushChildScene(const SkPoint& offset, - const SkSize& size, - fxl::RefPtr export_token_holder, - bool hit_testable); + virtual void PushChildScene( + const SkPoint& offset, + const SkSize& size, + fxl::RefPtr export_token_holder, + bool hit_testable) = 0; #endif // defined(OS_FUCHSIA) - void Pop(); + virtual void Pop() = 0; + + virtual std::unique_ptr TakeLayer() = 0; int GetRasterizerTracingThreshold() const; @@ -79,18 +84,10 @@ class LayerBuilder { void SetCheckerboardOffscreenLayers(bool checkerboard); - std::unique_ptr TakeLayer(); - private: - std::unique_ptr root_layer_; - flow::ContainerLayer* current_layer_ = nullptr; int rasterizer_tracing_threshold_ = 0; bool checkerboard_raster_cache_images_ = false; bool checkerboard_offscreen_layers_ = false; - std::stack cull_rects_; - - void PushLayer(std::unique_ptr layer, - const SkRect& cullRect); FXL_DISALLOW_COPY_AND_ASSIGN(LayerBuilder); }; diff --git a/engine/src/flutter/lib/ui/compositing/scene_builder.cc b/engine/src/flutter/lib/ui/compositing/scene_builder.cc index e1cc899136..9f21c0df1f 100644 --- a/engine/src/flutter/lib/ui/compositing/scene_builder.cc +++ b/engine/src/flutter/lib/ui/compositing/scene_builder.cc @@ -50,8 +50,7 @@ void SceneBuilder::RegisterNatives(tonic::DartLibraryNatives* natives) { FOR_EACH_BINDING(DART_REGISTER_NATIVE)}); } -SceneBuilder::SceneBuilder() - : layer_builder_(std::make_unique()){}; +SceneBuilder::SceneBuilder() : layer_builder_(flow::LayerBuilder::Create()) {} SceneBuilder::~SceneBuilder() = default;