Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit c4df6df

Browse files
committed
Centralize system-composite and elevation logic
1 parent 2277d7d commit c4df6df

10 files changed

Lines changed: 219 additions & 52 deletions

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ FILE: ../../../flutter/flow/layers/color_filter_layer_unittests.cc
4848
FILE: ../../../flutter/flow/layers/container_layer.cc
4949
FILE: ../../../flutter/flow/layers/container_layer.h
5050
FILE: ../../../flutter/flow/layers/container_layer_unittests.cc
51+
FILE: ../../../flutter/flow/layers/elevated_container_layer.cc
52+
FILE: ../../../flutter/flow/layers/elevated_container_layer.h
53+
FILE: ../../../flutter/flow/layers/fuchsia_system_composited_layer.cc
54+
FILE: ../../../flutter/flow/layers/fuchsia_system_composited_layer.h
5155
FILE: ../../../flutter/flow/layers/layer.cc
5256
FILE: ../../../flutter/flow/layers/layer.h
5357
FILE: ../../../flutter/flow/layers/layer_tree.cc

flow/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ source_set("flow") {
2828
"layers/color_filter_layer.h",
2929
"layers/container_layer.cc",
3030
"layers/container_layer.h",
31+
"layers/elevated_container_layer.cc",
32+
"layers/elevated_container_layer.h",
3133
"layers/layer.cc",
3234
"layers/layer.h",
3335
"layers/layer_tree.cc",
@@ -76,6 +78,8 @@ source_set("flow") {
7678
sources += [
7779
"layers/child_scene_layer.cc",
7880
"layers/child_scene_layer.h",
81+
"layers/fuchsia_system_composited_layer.cc",
82+
"layers/fuchsia_system_composited_layer.h",
7983
"scene_update_context.cc",
8084
"scene_update_context.h",
8185
"view_holder.cc",
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/flow/layers/elevated_container_layer.h"
6+
7+
namespace flutter {
8+
namespace {
9+
10+
float ClampElevation(float elevation,
11+
float parent_elevation,
12+
float max_elevation) {
13+
// TODO(mklim): Deal with bounds overflow more elegantly. We'd like to be
14+
// able to have developers specify the behavior here to alternatives besides
15+
// clamping, like normalization on some arbitrary curve.
16+
float clamped_elevation = elevation;
17+
if (max_elevation > -1 && (parent_elevation + elevation) > max_elevation) {
18+
// Clamp the local z coordinate at our max bound. Take into account the
19+
// parent z position here to fix clamping in cases where the child is
20+
// overflowing because of its parents.
21+
clamped_elevation = max_elevation - parent_elevation;
22+
}
23+
24+
return clamped_elevation;
25+
}
26+
27+
} // namespace
28+
29+
ElevatedContainerLayer::ElevatedContainerLayer(float elevation)
30+
: elevation_(elevation), clamped_elevation_(elevation) {}
31+
32+
void ElevatedContainerLayer::Preroll(PrerollContext* context,
33+
const SkMatrix& matrix) {
34+
TRACE_EVENT0("flutter", "ElevatedContainerLayer::Preroll");
35+
36+
// Track total elevation as we walk the tree, in order to deal with bounds
37+
// overflow in z.
38+
parent_elevation_ = context->total_elevation;
39+
clamped_elevation_ = ClampElevation(elevation_, parent_elevation_,
40+
context->frame_physical_depth);
41+
context->total_elevation += clamped_elevation_;
42+
43+
ContainerLayer::Preroll(context, matrix);
44+
45+
// Restore the elevation for our parent.
46+
context->total_elevation = parent_elevation_;
47+
}
48+
49+
} // namespace flutter
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_FLOW_LAYERS_ELEVATED_CONTAINER_LAYER_H_
6+
#define FLUTTER_FLOW_LAYERS_ELEVATED_CONTAINER_LAYER_H_
7+
8+
#include "flutter/flow/layers/container_layer.h"
9+
10+
namespace flutter {
11+
12+
class ElevatedContainerLayer : public ContainerLayer {
13+
public:
14+
ElevatedContainerLayer(float elevation);
15+
~ElevatedContainerLayer() override = default;
16+
17+
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
18+
19+
float elevation() const { return clamped_elevation_; }
20+
float total_elevation() const {
21+
return parent_elevation_ + clamped_elevation_;
22+
}
23+
24+
private:
25+
float parent_elevation_ = 0.0f;
26+
float elevation_ = 0.0f;
27+
float clamped_elevation_ = 0.0f;
28+
29+
FML_DISALLOW_COPY_AND_ASSIGN(ElevatedContainerLayer);
30+
};
31+
32+
} // namespace flutter
33+
34+
#endif // FLUTTER_FLOW_LAYERS_ELEVATED_CONTAINER_LAYER_H_
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "flutter/flow/layers/fuchsia_system_composited_layer.h"
6+
7+
namespace flutter {
8+
9+
FuchsiaSystemCompositedLayer::FuchsiaSystemCompositedLayer(SkColor color,
10+
float elevation)
11+
: ElevatedContainerLayer(elevation), color_(color) {}
12+
13+
void FuchsiaSystemCompositedLayer::UpdateScene(SceneUpdateContext& context) {
14+
FML_DCHECK(needs_system_composite());
15+
16+
// Retained rendering: speedup by reusing a retained entity node if
17+
// possible. When an entity node is reused, no paint layer is added to the
18+
// frame so we won't call Paint.
19+
LayerRasterCacheKey key(unique_id(), context.Matrix());
20+
if (context.HasRetainedNode(key)) {
21+
TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit");
22+
const scenic::EntityNode& retained_node = context.GetRetainedNode(key);
23+
FML_DCHECK(context.top_entity());
24+
FML_DCHECK(retained_node.session() == context.session());
25+
context.top_entity()->embedder_node().AddChild(retained_node);
26+
return;
27+
}
28+
29+
TRACE_EVENT_INSTANT0("flutter", "retained cache miss, creating");
30+
// If we can't find an existing retained surface, create one.
31+
SceneUpdateContext::Frame frame(context, rrect_, color_, elevation(), this);
32+
for (auto& layer : layers()) {
33+
if (layer->needs_painting()) {
34+
frame.AddPaintLayer(layer.get());
35+
}
36+
}
37+
38+
ContainerLayer::UpdateScene(context);
39+
}
40+
41+
} // namespace flutter
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_FLOW_LAYERS_FUCHSIA_SYSTEM_COMPOSITED_LAYER_H_
6+
#define FLUTTER_FLOW_LAYERS_FUCHSIA_SYSTEM_COMPOSITED_LAYER_H_
7+
8+
#include "flutter/flow/layers/elevated_container_layer.h"
9+
#include "flutter/flow/scene_update_context.h"
10+
11+
namespace flutter {
12+
13+
class FuchsiaSystemCompositedLayer : public ElevatedContainerLayer {
14+
public:
15+
static bool can_system_composite() { return true; }
16+
17+
FuchsiaSystemCompositedLayer(SkColor color, float elevation);
18+
19+
void UpdateScene(SceneUpdateContext& context) override;
20+
21+
void set_dimensions(SkRRect rrect) { rrect_ = rrect; }
22+
23+
SkColor color() const { return color_; }
24+
25+
private:
26+
SkRRect rrect_ = SkRRect::MakeEmpty();
27+
SkColor color_ = SK_ColorTRANSPARENT;
28+
29+
FML_DISALLOW_COPY_AND_ASSIGN(FuchsiaSystemCompositedLayer);
30+
};
31+
32+
} // namespace flutter
33+
34+
#endif // FLUTTER_FLOW_LAYERS_FUCHSIA_SYSTEM_COMPOSITED_LAYER_H_

flow/layers/physical_shape_layer.cc

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color,
1717
float elevation,
1818
const SkPath& path,
1919
Clip clip_behavior)
20-
: color_(color),
20+
: PhysicalShapeLayerBase(color, elevation),
2121
shadow_color_(shadow_color),
22-
elevation_(elevation),
2322
path_(path),
2423
isRect_(false),
2524
clip_behavior_(clip_behavior) {
@@ -42,30 +41,33 @@ PhysicalShapeLayer::PhysicalShapeLayer(SkColor color,
4241
// an SkPath.
4342
frameRRect_ = SkRRect::MakeRect(path.getBounds());
4443
}
44+
45+
set_dimensions(frameRRect_);
4546
}
4647

4748
void PhysicalShapeLayer::Preroll(PrerollContext* context,
4849
const SkMatrix& matrix) {
4950
TRACE_EVENT0("flutter", "PhysicalShapeLayer::Preroll");
50-
context->total_elevation += elevation_;
51-
total_elevation_ = context->total_elevation;
52-
SkRect child_paint_bounds;
53-
PrerollChildren(context, matrix, &child_paint_bounds);
54-
context->total_elevation -= elevation_;
5551

56-
if (elevation_ == 0) {
52+
PhysicalShapeLayerBase::Preroll(context, matrix);
53+
54+
if (elevation() == 0) {
5755
set_paint_bounds(path_.getBounds());
5856
} else {
59-
#if defined(OS_FUCHSIA)
60-
// Let the system compositor draw all shadows for us.
61-
set_needs_system_composite(true);
62-
#else
57+
if (PhysicalShapeLayerBase::can_system_composite()) {
58+
set_needs_system_composite(true);
59+
return;
60+
}
61+
//#if defined(OS_FUCHSIA)
62+
// // Let the system compositor draw all shadows for us.
63+
// set_needs_system_composite(true);
64+
//#else
6365
// We will draw the shadow in Paint(), so add some margin to the paint
6466
// bounds to leave space for the shadow. We fill this whole region and clip
6567
// children to it so we don't need to join the child paint bounds.
66-
set_paint_bounds(ComputeShadowBounds(path_.getBounds(), elevation_,
68+
set_paint_bounds(ComputeShadowBounds(path_.getBounds(), elevation(),
6769
context->frame_device_pixel_ratio));
68-
#endif // defined(OS_FUCHSIA)
70+
//#endif // defined(OS_FUCHSIA)
6971
}
7072
}
7173

@@ -90,8 +92,8 @@ void PhysicalShapeLayer::UpdateScene(SceneUpdateContext& context) {
9092

9193
TRACE_EVENT_INSTANT0("flutter", "cache miss, creating");
9294
// If we can't find an existing retained surface, create one.
93-
SceneUpdateContext::Frame frame(context, frameRRect_, color_, elevation_,
94-
total_elevation_, this);
95+
SceneUpdateContext::Frame frame(context, frameRRect_, color(), elevation(),
96+
this);
9597
for (auto& layer : layers()) {
9698
if (layer->needs_painting()) {
9799
frame.AddPaintLayer(layer.get());
@@ -107,14 +109,14 @@ void PhysicalShapeLayer::Paint(PaintContext& context) const {
107109
TRACE_EVENT0("flutter", "PhysicalShapeLayer::Paint");
108110
FML_DCHECK(needs_painting());
109111

110-
if (elevation_ != 0) {
111-
DrawShadow(context.leaf_nodes_canvas, path_, shadow_color_, elevation_,
112-
SkColorGetA(color_) != 0xff, context.frame_device_pixel_ratio);
112+
if (elevation() != 0) {
113+
DrawShadow(context.leaf_nodes_canvas, path_, shadow_color_, elevation(),
114+
SkColorGetA(color()) != 0xff, context.frame_device_pixel_ratio);
113115
}
114116

115117
// Call drawPath without clip if possible for better performance.
116118
SkPaint paint;
117-
paint.setColor(color_);
119+
paint.setColor(color());
118120
paint.setAntiAlias(true);
119121
if (clip_behavior_ != Clip::antiAliasWithSaveLayer) {
120122
context.leaf_nodes_canvas->drawPath(path_, paint);

flow/layers/physical_shape_layer.h

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,33 @@
55
#ifndef FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_
66
#define FLUTTER_FLOW_LAYERS_PHYSICAL_SHAPE_LAYER_H_
77

8-
#include "flutter/flow/layers/container_layer.h"
8+
#include "flutter/flow/layers/elevated_container_layer.h"
9+
#if defined(OS_FUCHSIA)
10+
#include "flutter/flow/layers/fuchsia_system_composited_layer.h"
11+
#endif
912

1013
namespace flutter {
1114

12-
class PhysicalShapeLayer : public ContainerLayer {
15+
#if !defined(OS_FUCHSIA)
16+
class PhysicalShapeLayerBase : public ElevatedContainerLayer {
1317
public:
14-
PhysicalShapeLayer(SkColor color,
15-
SkColor shadow_color,
16-
float elevation,
17-
const SkPath& path,
18-
Clip clip_behavior);
18+
static bool can_system_composite() { return false; }
19+
20+
PhysicalShapeLayerBase(SkColor color, float elevation)
21+
: ElevatedContainerLayer(elevation), color_(color) {}
22+
23+
void set_dimensions(SkRRect rrect) { }
24+
SkColor color() const { return color_; }
25+
26+
private:
27+
SkColor color_;
28+
};
29+
#else
30+
using PhysicalShapeLayerBase = FuchsiaSystemCompositedLayer;
31+
#endif
1932

33+
class PhysicalShapeLayer : public PhysicalShapeLayerBase {
34+
public:
2035
static SkRect ComputeShadowBounds(const SkRect& bounds,
2136
float elevation,
2237
float pixel_ratio);
@@ -27,21 +42,21 @@ class PhysicalShapeLayer : public ContainerLayer {
2742
bool transparentOccluder,
2843
SkScalar dpr);
2944

30-
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
45+
PhysicalShapeLayer(SkColor color,
46+
SkColor shadow_color,
47+
float elevation,
48+
const SkPath& path,
49+
Clip clip_behavior);
3150

51+
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
3252
void Paint(PaintContext& context) const override;
3353

3454
#if defined(OS_FUCHSIA)
3555
void UpdateScene(SceneUpdateContext& context) override;
3656
#endif // defined(OS_FUCHSIA)
3757

38-
float total_elevation() const { return total_elevation_; }
39-
4058
private:
41-
SkColor color_;
4259
SkColor shadow_color_;
43-
float elevation_ = 0.0f;
44-
float total_elevation_ = 0.0f;
4560
SkPath path_;
4661
bool isRect_;
4762
SkRRect frameRRect_;

flow/scene_update_context.cc

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -301,29 +301,14 @@ SceneUpdateContext::Shape::Shape(SceneUpdateContext& context)
301301
SceneUpdateContext::Frame::Frame(SceneUpdateContext& context,
302302
const SkRRect& rrect,
303303
SkColor color,
304-
float local_elevation,
305-
float world_elevation,
304+
float elevation,
306305
Layer* layer)
307306
: Shape(context),
308307
rrect_(rrect),
309308
color_(color),
310309
paint_bounds_(SkRect::MakeEmpty()),
311310
layer_(layer) {
312-
const float depth = context.frame_physical_depth();
313-
if (depth > -1 && world_elevation > depth) {
314-
// TODO(mklim): Deal with bounds overflow more elegantly. We'd like to be
315-
// able to have developers specify the behavior here to alternatives besides
316-
// clamping, like normalization on some arbitrary curve.
317-
318-
// Clamp the local z coordinate at our max bound. Take into account the
319-
// parent z position here to fix clamping in cases where the child is
320-
// overflowing because of its parents.
321-
const float parent_elevation = world_elevation - local_elevation;
322-
local_elevation = depth - parent_elevation;
323-
}
324-
if (local_elevation != 0.0) {
325-
entity_node().SetTranslation(0.f, 0.f, -local_elevation);
326-
}
311+
entity_node().SetTranslation(0.f, 0.f, -elevation);
327312
}
328313

329314
SceneUpdateContext::Frame::~Frame() {

flow/scene_update_context.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ class SceneUpdateContext {
115115
Frame(SceneUpdateContext& context,
116116
const SkRRect& rrect,
117117
SkColor color,
118-
float local_elevation = 0.0f,
119-
float parent_elevation = 0.0f,
118+
float elevation = 0.0f,
120119
Layer* layer = nullptr);
121120
virtual ~Frame();
122121

0 commit comments

Comments
 (0)