From b7d99da3e21ad174b26b562bc226e4da579da214 Mon Sep 17 00:00:00 2001 From: amirh Date: Mon, 8 Jan 2018 19:25:56 -0800 Subject: [PATCH] Revert "Delete the SkPath/SkRRect code duplication in for physical model layers. (#4519)" (#4527) This reverts commit d8740c70a58ada74aff5b773e2bec9d622c42a97. --- flow/BUILD.gn | 4 +- flow/layers/default_layer_builder.cc | 24 +++- flow/layers/default_layer_builder.h | 8 +- flow/layers/layer_builder.h | 7 +- ...shape_layer.cc => physical_model_layer.cc} | 45 +++--- flow/layers/physical_model_layer.h | 131 ++++++++++++++++++ flow/layers/physical_shape_layer.h | 56 -------- lib/ui/compositing.dart | 15 +- lib/ui/compositing/scene_builder.cc | 13 +- lib/ui/compositing/scene_builder.h | 1 + lib/ui/painting/canvas.cc | 4 +- travis/licenses_golden/licenses_flutter | 4 +- 12 files changed, 224 insertions(+), 88 deletions(-) rename flow/layers/{physical_shape_layer.cc => physical_model_layer.cc} (67%) create mode 100644 flow/layers/physical_model_layer.h delete mode 100644 flow/layers/physical_shape_layer.h diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 95f7ec3f60..8496d2b13d 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -34,8 +34,8 @@ source_set("flow") { "layers/opacity_layer.h", "layers/performance_overlay_layer.cc", "layers/performance_overlay_layer.h", - "layers/physical_shape_layer.cc", - "layers/physical_shape_layer.h", + "layers/physical_model_layer.cc", + "layers/physical_model_layer.h", "layers/picture_layer.cc", "layers/picture_layer.h", "layers/shader_mask_layer.cc", diff --git a/flow/layers/default_layer_builder.cc b/flow/layers/default_layer_builder.cc index 3f59943f77..310c12882f 100644 --- a/flow/layers/default_layer_builder.cc +++ b/flow/layers/default_layer_builder.cc @@ -14,7 +14,7 @@ #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_shape_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/texture_layer.h" @@ -106,7 +106,23 @@ void DefaultLayerBuilder::PushShaderMask(sk_sp shader, PushLayer(std::move(layer), cull_rects_.top()); } -void DefaultLayerBuilder::PushPhysicalShape(const SkPath& sk_path, +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_shape(std::make_unique(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::PushPhysicalModel(const SkPath& sk_path, double elevation, SkColor color, SkScalar device_pixel_ratio) { @@ -114,8 +130,8 @@ void DefaultLayerBuilder::PushPhysicalShape(const SkPath& sk_path, if (!cullRect.intersect(sk_path.getBounds(), cull_rects_.top())) { cullRect = SkRect::MakeEmpty(); } - auto layer = std::make_unique(); - layer->set_path(sk_path); + auto layer = std::make_unique(); + layer->set_shape(std::make_unique(sk_path)); layer->set_elevation(elevation); layer->set_color(color); layer->set_device_pixel_ratio(device_pixel_ratio); diff --git a/flow/layers/default_layer_builder.h b/flow/layers/default_layer_builder.h index 034769355c..fdafd5fea5 100644 --- a/flow/layers/default_layer_builder.h +++ b/flow/layers/default_layer_builder.h @@ -47,7 +47,13 @@ class DefaultLayerBuilder final : public LayerBuilder { SkBlendMode blend_mode) override; // |flow::LayerBuilder| - void PushPhysicalShape(const SkPath& path, + void PushPhysicalModel(const SkRRect& rect, + double elevation, + SkColor color, + SkScalar device_pixel_ratio) override; + + // |flow::LayerBuilder| + void PushPhysicalModel(const SkPath& path, double elevation, SkColor color, SkScalar device_pixel_ratio) override; diff --git a/flow/layers/layer_builder.h b/flow/layers/layer_builder.h index ee181a9682..05a5add480 100644 --- a/flow/layers/layer_builder.h +++ b/flow/layers/layer_builder.h @@ -47,7 +47,12 @@ class LayerBuilder { const SkRect& rect, SkBlendMode blend_mode) = 0; - virtual void PushPhysicalShape(const SkPath& path, + virtual void PushPhysicalModel(const SkRRect& rect, + double elevation, + SkColor color, + SkScalar device_pixel_ratio) = 0; + + virtual void PushPhysicalModel(const SkPath& path, double elevation, SkColor color, SkScalar device_pixel_ratio) = 0; diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_model_layer.cc similarity index 67% rename from flow/layers/physical_shape_layer.cc rename to flow/layers/physical_model_layer.cc index d4bc69d56f..4104d24eab 100644 --- a/flow/layers/physical_shape_layer.cc +++ b/flow/layers/physical_model_layer.cc @@ -2,24 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/flow/layers/physical_shape_layer.h" +#include "flutter/flow/layers/physical_model_layer.h" #include "flutter/flow/paint_utils.h" #include "third_party/skia/include/utils/SkShadowUtils.h" namespace flow { -PhysicalShapeLayer::PhysicalShapeLayer() : isRect_(false) {} +PhysicalModelLayer::PhysicalModelLayer() = default; -PhysicalShapeLayer::~PhysicalShapeLayer() = default; +PhysicalModelLayer::~PhysicalModelLayer() = default; -void PhysicalShapeLayer::Preroll(PrerollContext* context, +void PhysicalModelLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) { SkRect child_paint_bounds; PrerollChildren(context, matrix, &child_paint_bounds); if (elevation_ == 0) { - set_paint_bounds(path_.getBounds()); + set_paint_bounds(shape_->getBounds()); } else { #if defined(OS_FUCHSIA) // Let the system compositor draw all shadows for us. @@ -29,7 +29,7 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, // The margin is hardcoded to an arbitrary maximum for now because Skia // doesn't provide a way to calculate it. We fill this whole region // and clip children to it so we don't need to join the child paint bounds. - SkRect bounds(path_.getBounds()); + SkRect bounds(shape_->getBounds()); bounds.outset(20.0, 20.0); set_paint_bounds(bounds); #endif // defined(OS_FUCHSIA) @@ -38,10 +38,11 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context, #if defined(OS_FUCHSIA) -void PhysicalShapeLayer::UpdateScene(SceneUpdateContext& context) { +void PhysicalModelLayer::UpdateScene(SceneUpdateContext& context) { FXL_DCHECK(needs_system_composite()); - SceneUpdateContext::Frame frame(context, frameRRect_, color_, elevation_); + SceneUpdateContext::Frame frame(context, shape_->getFrameRRect(), color_, + elevation_); for (auto& layer : layers()) { if (layer->needs_painting()) { frame.AddPaintedLayer(layer.get()); @@ -53,32 +54,34 @@ void PhysicalShapeLayer::UpdateScene(SceneUpdateContext& context) { #endif // defined(OS_FUCHSIA) -void PhysicalShapeLayer::Paint(PaintContext& context) const { - TRACE_EVENT0("flutter", "PhysicalShapeLayer::Paint"); +void PhysicalModelLayer::Paint(PaintContext& context) const { + TRACE_EVENT0("flutter", "PhysicalModelLayer::Paint"); FXL_DCHECK(needs_painting()); + SkPath path = shape_->getPath(); + if (elevation_ != 0) { - DrawShadow(&context.canvas, path_, SK_ColorBLACK, elevation_, + DrawShadow(&context.canvas, path, SK_ColorBLACK, elevation_, SkColorGetA(color_) != 0xff, device_pixel_ratio_); } SkPaint paint; paint.setColor(color_); - context.canvas.drawPath(path_, paint); + context.canvas.drawPath(path, paint); SkAutoCanvasRestore save(&context.canvas, false); - if (isRect_) { + if (shape_->isRect()) { context.canvas.save(); } else { - context.canvas.saveLayer(path_.getBounds(), nullptr); + context.canvas.saveLayer(&shape_->getBounds(), nullptr); } - context.canvas.clipPath(path_, true); + shape_->clipCanvas(context.canvas); PaintChildren(context); - if (context.checkerboard_offscreen_layers && !isRect_) - DrawCheckerboard(&context.canvas, path_.getBounds()); + if (context.checkerboard_offscreen_layers && !shape_->isRect()) + DrawCheckerboard(&context.canvas, shape_->getBounds()); } -void PhysicalShapeLayer::DrawShadow(SkCanvas* canvas, +void PhysicalModelLayer::DrawShadow(SkCanvas* canvas, const SkPath& path, SkColor color, float elevation, @@ -95,4 +98,10 @@ void PhysicalShapeLayer::DrawShadow(SkCanvas* canvas, dpr * 800.0f, 0.039f, 0.25f, color, flags); } +SkPath PhysicalLayerRRect::getPath() const { + SkPath path; + path.addRRect(rrect_); + return path; +} + } // namespace flow diff --git a/flow/layers/physical_model_layer.h b/flow/layers/physical_model_layer.h new file mode 100644 index 0000000000..27072ca365 --- /dev/null +++ b/flow/layers/physical_model_layer.h @@ -0,0 +1,131 @@ +// Copyright 2017 The Chromium 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_PHYSICAL_MODEL_LAYER_H_ +#define FLUTTER_FLOW_LAYERS_PHYSICAL_MODEL_LAYER_H_ + +#include "flutter/flow/layers/container_layer.h" + +namespace flow { + +class PhysicalLayerShape; + +class PhysicalModelLayer : public ContainerLayer { + public: + PhysicalModelLayer(); + ~PhysicalModelLayer() override; + + void set_shape(std::unique_ptr shape) { + shape_ = std::move(shape); + } + void set_elevation(float elevation) { elevation_ = elevation; } + void set_color(SkColor color) { color_ = color; } + void set_device_pixel_ratio(SkScalar dpr) { device_pixel_ratio_ = dpr; } + + static void DrawShadow(SkCanvas* canvas, + const SkPath& path, + SkColor color, + float elevation, + bool transparentOccluder, + SkScalar dpr); + + void Preroll(PrerollContext* context, const SkMatrix& matrix) override; + + void Paint(PaintContext& context) const override; + +#if defined(OS_FUCHSIA) + void UpdateScene(SceneUpdateContext& context) override; +#endif // defined(OS_FUCHSIA) + + private: + std::unique_ptr shape_; + float elevation_; + SkColor color_; + SkScalar device_pixel_ratio_; +}; + +// Common interface for the shape operations needed by PhysicalModelLayer. +// +// Once Scenic supports specifying physical layers with paths we can get rid +// of this class and the subclasses, and have a single implementation of +// PhysicalModelLayer that holds an SkPath. +// TODO(amirh): remove this once Scenic supports arbitrary shaped layers. +class PhysicalLayerShape { + public: + virtual ~PhysicalLayerShape() = default; + virtual const SkRect& getBounds() const = 0; + virtual SkPath getPath() const = 0; + virtual void clipCanvas(SkCanvas& canvas) const = 0; + virtual bool isRect() const = 0; +#if defined(OS_FUCHSIA) + virtual const SkRRect& getFrameRRect() const = 0; +#endif // defined(OS_FUCHSIA) +}; + +class PhysicalLayerRRect final : public PhysicalLayerShape { + public: + PhysicalLayerRRect(const SkRRect& rrect) { rrect_ = rrect; } + + // |flow::PhysicalLayerShape| + const SkRect& getBounds() const override { return rrect_.getBounds(); } + + // |flow::PhysicalLayerShape| + SkPath getPath() const override; + + // |flow::PhysicalLayerShape| + void clipCanvas(SkCanvas& canvas) const override { + canvas.clipRRect(rrect_, true); + } + + // |flow::PhysicalLayerShape| + bool isRect() const override { return rrect_.isRect(); } + +#if defined(OS_FUCHSIA) + // |flow::PhysicalLayerShape| + const SkRRect& getFrameRRect() const override { return rrect_; } +#endif // defined(OS_FUCHSIA) + + private: + SkRRect rrect_; +}; + +class PhysicalLayerPath final : public PhysicalLayerShape { + public: + PhysicalLayerPath(const SkPath& path) { + path_ = path; +#if defined(OS_FUCHSIA) + frameRRect_ = SkRRect::MakeRect(path.getBounds()); +#endif // defined(OS_FUCHSIA) + } + + // |flow::PhysicalLayerShape| + const SkRect& getBounds() const override { return path_.getBounds(); } + + // |flow::PhysicalLayerShape| + SkPath getPath() const override { return path_; } + + // |flow::PhysicalLayerShape| + void clipCanvas(SkCanvas& canvas) const override { + canvas.clipPath(path_, true); + } + + // |flow::PhysicalLayerShape| + bool isRect() const override { return false; } + +#if defined(OS_FUCHSIA) + // Scenic does not currently support compositing arbitrary shaped layers, + // so we just use the path's bounding rectangle. + // |flow::PhysicalLayerShape| + const SkRRect& getFrameRRect() const override { return frameRRect_; } +#endif // defined(OS_FUCHSIA) + private: + SkPath path_; +#if defined(OS_FUCHSIA) + SkRRect frameRRect_; +#endif // defined(OS_FUCHSIA) +}; + +} // namespace flow + +#endif // FLUTTER_FLOW_LAYERS_PHYSICAL_MODEL_LAYER_H_ diff --git a/flow/layers/physical_shape_layer.h b/flow/layers/physical_shape_layer.h deleted file mode 100644 index bb46024748..0000000000 --- a/flow/layers/physical_shape_layer.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017 The Chromium 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_PHYSICAL_SHAPE_LAYER_H_ -#define FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_ - -#include "flutter/flow/layers/container_layer.h" - -namespace flow { - -class PhysicalShapeLayer : public ContainerLayer { - public: - PhysicalShapeLayer(); - ~PhysicalShapeLayer() override; - - void set_path(const SkPath& path) { - path_ = path; - if (path.isRRect(&frameRRect_)) { - isRect_ = frameRRect_.isRect(); - } else { - isRect_ = false; - } - } - - void set_elevation(float elevation) { elevation_ = elevation; } - void set_color(SkColor color) { color_ = color; } - void set_device_pixel_ratio(SkScalar dpr) { device_pixel_ratio_ = dpr; } - - static void DrawShadow(SkCanvas* canvas, - const SkPath& path, - SkColor color, - float elevation, - bool transparentOccluder, - SkScalar dpr); - - void Preroll(PrerollContext* context, const SkMatrix& matrix) override; - - void Paint(PaintContext& context) const override; - -#if defined(OS_FUCHSIA) - void UpdateScene(SceneUpdateContext& context) override; -#endif // defined(OS_FUCHSIA) - - private: - float elevation_; - SkColor color_; - SkScalar device_pixel_ratio_; - SkPath path_; - bool isRect_; - SkRRect frameRRect_; -}; - -} // namespace flow - -#endif // FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_ diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index c1cd49a5f2..4a9fd21bec 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -127,7 +127,20 @@ class SceneBuilder extends NativeFieldWrapperClass2 { double maskRectBottom, int blendMode) native "SceneBuilder_pushShaderMask"; - /// Pushes a physical layer operation for an arbitrary shape onto the + /// Pushes a physical model operation for a rounded rectangle onto the + /// operation stack. + /// + /// Rasterization will be clipped to the given shape. + /// + /// See [pop] for details about the operation stack. + void pushPhysicalModel({ RRect rrect, double elevation, Color color }) { + _pushPhysicalModel(rrect._value, elevation, color.value); + } + void _pushPhysicalModel(Float32List rrect, + double elevation, + int color) native "SceneBuilder_pushPhysicalModel"; + + /// Pushes a physical model operation for an arbitrary shape onto the /// operation stack. /// /// Rasterization will be clipped to the given shape. diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 44f6c62477..64c7a4315a 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -32,6 +32,7 @@ IMPLEMENT_WRAPPERTYPEINFO(ui, SceneBuilder); V(SceneBuilder, pushColorFilter) \ V(SceneBuilder, pushBackdropFilter) \ V(SceneBuilder, pushShaderMask) \ + V(SceneBuilder, pushPhysicalModel) \ V(SceneBuilder, pushPhysicalShape) \ V(SceneBuilder, pop) \ V(SceneBuilder, addPicture) \ @@ -100,10 +101,20 @@ void SceneBuilder::pushShaderMask(Shader* shader, static_cast(blendMode)); } +void SceneBuilder::pushPhysicalModel(const RRect& rrect, + double elevation, + int color) { + layer_builder_->PushPhysicalModel( + rrect.sk_rrect, // + elevation, // + static_cast(color), // + UIDartState::Current()->window()->viewport_metrics().device_pixel_ratio); +} + void SceneBuilder::pushPhysicalShape(const CanvasPath* path, double elevation, int color) { - layer_builder_->PushPhysicalShape( + layer_builder_->PushPhysicalModel( path->path(), // elevation, // static_cast(color), // diff --git a/lib/ui/compositing/scene_builder.h b/lib/ui/compositing/scene_builder.h index 873d91d964..894ebb0540 100644 --- a/lib/ui/compositing/scene_builder.h +++ b/lib/ui/compositing/scene_builder.h @@ -47,6 +47,7 @@ class SceneBuilder : public fxl::RefCountedThreadSafe, double maskRectTop, double maskRectBottom, int blendMode); + void pushPhysicalModel(const RRect& rrect, double elevation, int color); void pushPhysicalShape(const CanvasPath* path, double elevation, int color); void pop(); diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc index d09f4eebcf..34523f2048 100644 --- a/lib/ui/painting/canvas.cc +++ b/lib/ui/painting/canvas.cc @@ -6,7 +6,7 @@ #include -#include "flutter/flow/layers/physical_shape_layer.h" +#include "flutter/flow/layers/physical_model_layer.h" #include "flutter/lib/ui/painting/image.h" #include "flutter/lib/ui/painting/matrix.h" #include "flutter/lib/ui/ui_dart_state.h" @@ -416,7 +416,7 @@ void Canvas::drawShadow(const CanvasPath* path, ToDart("Canvas.drawShader called with non-genuine Path.")); SkScalar dpr = UIDartState::Current()->window()->viewport_metrics().device_pixel_ratio; - flow::PhysicalShapeLayer::DrawShadow(canvas_, path->path(), color, elevation, + flow::PhysicalModelLayer::DrawShadow(canvas_, path->path(), color, elevation, transparentOccluder, dpr); } diff --git a/travis/licenses_golden/licenses_flutter b/travis/licenses_golden/licenses_flutter index 855cff3724..0028b739dc 100644 --- a/travis/licenses_golden/licenses_flutter +++ b/travis/licenses_golden/licenses_flutter @@ -1072,8 +1072,8 @@ FILE: ../../../flutter/content_handler/vulkan_surface_producer.h FILE: ../../../flutter/flow/debug_print.cc FILE: ../../../flutter/flow/debug_print.h FILE: ../../../flutter/flow/export_node.h -FILE: ../../../flutter/flow/layers/physical_shape_layer.cc -FILE: ../../../flutter/flow/layers/physical_shape_layer.h +FILE: ../../../flutter/flow/layers/physical_model_layer.cc +FILE: ../../../flutter/flow/layers/physical_model_layer.h FILE: ../../../flutter/flow/layers/texture_layer.cc FILE: ../../../flutter/flow/layers/texture_layer.h FILE: ../../../flutter/flow/matrix_decomposition.cc -- GitLab