Skip to content

Commit d117ac9

Browse files
authored
Wire up Opacity on Fuchsia, round 2 (flutter#14024)
* Remove erroneous ChildView opacity * Wire frame metrics through contexts * Maintain layer stack inside of SceneBuilder * Remove EnsureSingleChild * Centralize system-composite and elevation logic * Wire up OpacityLayer to Scenic
1 parent 1bf04ad commit d117ac9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+668
-481
lines changed

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",

flow/layers/child_scene_layer.cc

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,25 @@ ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id,
2020
void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
2121
TRACE_EVENT0("flutter", "ChildSceneLayer::Preroll");
2222
set_needs_system_composite(true);
23+
24+
// An alpha "hole punch" is required if the frame behind us is not opaque.
25+
if (!context->is_opaque) {
26+
set_paint_bounds(
27+
SkRect::MakeXYWH(offset_.fX, offset_.fY, size_.fWidth, size_.fHeight));
28+
}
2329
}
2430

2531
void ChildSceneLayer::Paint(PaintContext& context) const {
26-
FML_NOTREACHED() << "This layer never needs painting.";
32+
TRACE_EVENT0("flutter", "ChildSceneLayer::Paint");
33+
FML_DCHECK(needs_painting());
34+
35+
// If we are being rendered into our own frame using the system compositor,
36+
// then it is neccesary to "punch a hole" in the canvas/frame behind us so
37+
// that group opacity looks correct.
38+
SkPaint paint;
39+
paint.setColor(SK_ColorTRANSPARENT);
40+
paint.setBlendMode(SkBlendMode::kSrc);
41+
context.leaf_nodes_canvas->drawRect(paint_bounds(), paint);
2742
}
2843

2944
void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) {

flow/layers/container_layer.cc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ namespace flutter {
99
ContainerLayer::ContainerLayer() {}
1010

1111
void ContainerLayer::Add(std::shared_ptr<Layer> layer) {
12-
layer->set_parent(this);
13-
layers_.push_back(std::move(layer));
12+
layers_.emplace_back(std::move(layer));
1413
}
1514

1615
void ContainerLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {

flow/layers/container_layer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ContainerLayer : public Layer {
1414
public:
1515
ContainerLayer();
1616

17-
void Add(std::shared_ptr<Layer> layer);
17+
virtual void Add(std::shared_ptr<Layer> layer);
1818

1919
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
2020
void Paint(PaintContext& context) const override;
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: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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+
SkAlpha opacity,
11+
float elevation)
12+
: ElevatedContainerLayer(elevation), color_(color), opacity_(opacity) {}
13+
14+
void FuchsiaSystemCompositedLayer::Preroll(PrerollContext* context,
15+
const SkMatrix& matrix) {
16+
TRACE_EVENT0("flutter", "FuchsiaSystemCompositedLayer::Preroll");
17+
18+
const float parent_is_opaque = context->is_opaque;
19+
context->mutators_stack.PushOpacity(opacity_);
20+
context->is_opaque = parent_is_opaque && (opacity_ == SK_AlphaOPAQUE);
21+
ElevatedContainerLayer::Preroll(context, matrix);
22+
context->is_opaque = parent_is_opaque;
23+
context->mutators_stack.Pop();
24+
}
25+
26+
void FuchsiaSystemCompositedLayer::UpdateScene(SceneUpdateContext& context) {
27+
FML_DCHECK(needs_system_composite());
28+
29+
// Retained rendering: speedup by reusing a retained entity node if
30+
// possible. When an entity node is reused, no paint layer is added to the
31+
// frame so we won't call Paint.
32+
LayerRasterCacheKey key(unique_id(), context.Matrix());
33+
if (context.HasRetainedNode(key)) {
34+
TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit");
35+
const scenic::EntityNode& retained_node = context.GetRetainedNode(key);
36+
FML_DCHECK(context.top_entity());
37+
FML_DCHECK(retained_node.session() == context.session());
38+
context.top_entity()->embedder_node().AddChild(retained_node);
39+
return;
40+
}
41+
42+
TRACE_EVENT_INSTANT0("flutter", "retained cache miss, creating");
43+
// If we can't find an existing retained surface, create one.
44+
SceneUpdateContext::Frame frame(context, rrect_, color_, opacity_ / 255.0f,
45+
elevation(), this);
46+
for (auto& layer : layers()) {
47+
if (layer->needs_painting()) {
48+
frame.AddPaintLayer(layer.get());
49+
}
50+
}
51+
52+
ElevatedContainerLayer::UpdateScene(context);
53+
}
54+
55+
} // namespace flutter
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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, SkAlpha opacity, float elevation);
18+
19+
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
20+
void UpdateScene(SceneUpdateContext& context) override;
21+
22+
void set_dimensions(SkRRect rrect) { rrect_ = rrect; }
23+
24+
SkColor color() const { return color_; }
25+
SkAlpha opacity() const { return opacity_; }
26+
27+
private:
28+
SkRRect rrect_ = SkRRect::MakeEmpty();
29+
SkColor color_ = SK_ColorTRANSPARENT;
30+
SkAlpha opacity_ = SK_AlphaOPAQUE;
31+
32+
FML_DISALLOW_COPY_AND_ASSIGN(FuchsiaSystemCompositedLayer);
33+
};
34+
35+
} // namespace flutter
36+
37+
#endif // FLUTTER_FLOW_LAYERS_FUCHSIA_SYSTEM_COMPOSITED_LAYER_H_

flow/layers/layer.cc

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@
1010
namespace flutter {
1111

1212
Layer::Layer()
13-
: parent_(nullptr),
14-
needs_system_composite_(false),
15-
paint_bounds_(SkRect::MakeEmpty()),
16-
unique_id_(NextUniqueID()) {}
13+
: paint_bounds_(SkRect::MakeEmpty()),
14+
unique_id_(NextUniqueID()),
15+
needs_system_composite_(false) {}
1716

1817
Layer::~Layer() = default;
1918

flow/layers/layer.h

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ static constexpr SkRect kGiantRect = SkRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F);
4242
// This should be an exact copy of the Clip enum in painting.dart.
4343
enum Clip { none, hardEdge, antiAlias, antiAliasWithSaveLayer };
4444

45-
class ContainerLayer;
46-
4745
struct PrerollContext {
4846
RasterCache* raster_cache;
4947
GrContext* gr_context;
@@ -52,13 +50,21 @@ struct PrerollContext {
5250
SkColorSpace* dst_color_space;
5351
SkRect cull_rect;
5452

55-
// The following allows us to paint in the end of subtree preroll
53+
// These allow us to paint in the end of subtree Preroll.
5654
const Stopwatch& raster_time;
5755
const Stopwatch& ui_time;
5856
TextureRegistry& texture_registry;
5957
const bool checkerboard_offscreen_layers;
58+
59+
// These allow us to make use of the scene metrics during Preroll.
60+
float frame_physical_depth;
61+
float frame_device_pixel_ratio;
62+
63+
// These allow us to track properties like elevation, opacity, and the
64+
// prescence of a platform view during Preroll.
6065
float total_elevation = 0.0f;
6166
bool has_platform_view = false;
67+
bool is_opaque = true;
6268
};
6369

6470
// Represents a single composited layer. Created on the UI thread but then
@@ -90,6 +96,10 @@ class Layer {
9096
TextureRegistry& texture_registry;
9197
const RasterCache* raster_cache;
9298
const bool checkerboard_offscreen_layers;
99+
100+
// These allow us to make use of the scene metrics during Paint.
101+
float frame_physical_depth;
102+
float frame_device_pixel_ratio;
93103
};
94104

95105
// Calls SkCanvas::saveLayer and restores the layer upon destruction. Also
@@ -126,10 +136,6 @@ class Layer {
126136
virtual void UpdateScene(SceneUpdateContext& context);
127137
#endif
128138

129-
ContainerLayer* parent() const { return parent_; }
130-
131-
void set_parent(ContainerLayer* parent) { parent_ = parent; }
132-
133139
bool needs_system_composite() const { return needs_system_composite_; }
134140
void set_needs_system_composite(bool value) {
135141
needs_system_composite_ = value;
@@ -148,10 +154,9 @@ class Layer {
148154
uint64_t unique_id() const { return unique_id_; }
149155

150156
private:
151-
ContainerLayer* parent_;
152-
bool needs_system_composite_;
153157
SkRect paint_bounds_;
154158
uint64_t unique_id_;
159+
bool needs_system_composite_;
155160

156161
static uint64_t NextUniqueID();
157162

0 commit comments

Comments
 (0)