Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions flow/layers/child_scene_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ ChildSceneLayer::ChildSceneLayer(zx_koid_t layer_id,
void ChildSceneLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
TRACE_EVENT0("flutter", "ChildSceneLayer::Preroll");
set_needs_system_composite(true);

CheckForChildLayerBelow(context);

context->child_scene_layer_exists_below = true;

// An alpha "hole punch" is required if the frame behind us is not opaque.
Expand Down Expand Up @@ -47,6 +50,8 @@ void ChildSceneLayer::UpdateScene(SceneUpdateContext& context) {
TRACE_EVENT0("flutter", "ChildSceneLayer::UpdateScene");
FML_DCHECK(needs_system_composite());

Layer::UpdateScene(context);

auto* view_holder = ViewHolder::FromId(layer_id_);
FML_DCHECK(view_holder);

Expand Down
76 changes: 71 additions & 5 deletions flow/layers/container_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ void ContainerLayer::Paint(PaintContext& context) const {
void ContainerLayer::PrerollChildren(PrerollContext* context,
const SkMatrix& child_matrix,
SkRect* child_paint_bounds) {
#if defined(OS_FUCHSIA)
child_layer_exists_below_ = context->child_scene_layer_exists_below;
context->child_scene_layer_exists_below = false;
#endif

// Platform views have no children, so context->has_platform_view should
// always be false.
FML_DCHECK(!context->has_platform_view);
Expand All @@ -51,6 +56,14 @@ void ContainerLayer::PrerollChildren(PrerollContext* context,
}

context->has_platform_view = child_has_platform_view;

#if defined(OS_FUCHSIA)
if (child_layer_exists_below_) {
set_needs_system_composite(true);
}
context->child_scene_layer_exists_below =
context->child_scene_layer_exists_below || child_layer_exists_below_;
#endif
}

void ContainerLayer::PaintChildren(PaintContext& context) const {
Expand All @@ -67,19 +80,72 @@ void ContainerLayer::PaintChildren(PaintContext& context) const {

#if defined(OS_FUCHSIA)

void ContainerLayer::CheckForChildLayerBelow(PrerollContext* context) {
// All ContainerLayers make the check in PrerollChildren.
}

void ContainerLayer::UpdateScene(SceneUpdateContext& context) {
UpdateSceneChildren(context);
}

void ContainerLayer::UpdateSceneChildren(SceneUpdateContext& context) {
auto update_scene_layers = [&] {
// Paint all of the layers which need to be drawn into the container.
// These may be flattened down to a containing Scenic Frame.
for (auto& layer : layers_) {
if (layer->needs_system_composite()) {
layer->UpdateScene(context);
}
}
};

FML_DCHECK(needs_system_composite());

// Paint all of the layers which need to be drawn into the container.
// These may be flattened down to a containing
for (auto& layer : layers_) {
if (layer->needs_system_composite()) {
layer->UpdateScene(context);
// If there is embedded Fuchsia content in the scene (a ChildSceneLayer),
// PhysicalShapeLayers that appear above the embedded content will be turned
// into their own Scenic layers.
if (child_layer_exists_below_) {
float global_scenic_elevation =
context.GetGlobalElevationForNextScenicLayer();
float local_scenic_elevation =
global_scenic_elevation - context.scenic_elevation();
float z_translation = -local_scenic_elevation;

// Retained rendering: speedup by reusing a retained entity node if
// possible. When an entity node is reused, no paint layer is added to the
// frame so we won't call PhysicalShapeLayer::Paint.
LayerRasterCacheKey key(unique_id(), context.Matrix());
if (context.HasRetainedNode(key)) {
TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit");
scenic::EntityNode* retained_node = context.GetRetainedNode(key);
FML_DCHECK(context.top_entity());
FML_DCHECK(retained_node->session() == context.session());

// Re-adjust the elevation.
retained_node->SetTranslation(0.f, 0.f, z_translation);

context.top_entity()->entity_node().AddChild(*retained_node);
return;
}

TRACE_EVENT_INSTANT0("flutter", "cache miss, creating");
// If we can't find an existing retained surface, create one.
SceneUpdateContext::Frame frame(
context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT,
SkScalarRoundToInt(context.alphaf() * 255),
"flutter::PhysicalShapeLayer", z_translation, this);

frame.AddPaintLayer(this);

// Node: UpdateSceneChildren needs to be called here so that |frame| is
// still in scope (and therefore alive) while UpdateSceneChildren is being
// called.
float scenic_elevation = context.scenic_elevation();
context.set_scenic_elevation(scenic_elevation + local_scenic_elevation);
update_scene_layers();
context.set_scenic_elevation(scenic_elevation);
} else {
update_scene_layers();
}
}

Expand Down
1 change: 1 addition & 0 deletions flow/layers/container_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ContainerLayer : public Layer {
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext& context) const override;
#if defined(OS_FUCHSIA)
void CheckForChildLayerBelow(PrerollContext* context) override;
void UpdateScene(SceneUpdateContext& context) override;
#endif // defined(OS_FUCHSIA)

Expand Down
48 changes: 47 additions & 1 deletion flow/layers/layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,53 @@ Layer::AutoPrerollSaveLayerState::~AutoPrerollSaveLayerState() {
}

#if defined(OS_FUCHSIA)
void Layer::UpdateScene(SceneUpdateContext& context) {}

void Layer::CheckForChildLayerBelow(PrerollContext* context) {
child_layer_exists_below_ = context->child_scene_layer_exists_below;
if (child_layer_exists_below_) {
set_needs_system_composite(true);
}
}

void Layer::UpdateScene(SceneUpdateContext& context) {
// If there is embedded Fuchsia content in the scene (a ChildSceneLayer),
// PhysicalShapeLayers that appear above the embedded content will be turned
// into their own Scenic layers.
if (child_layer_exists_below_) {
float global_scenic_elevation =
context.GetGlobalElevationForNextScenicLayer();
float local_scenic_elevation =
global_scenic_elevation - context.scenic_elevation();
float z_translation = -local_scenic_elevation;

// Retained rendering: speedup by reusing a retained entity node if
// possible. When an entity node is reused, no paint layer is added to the
// frame so we won't call PhysicalShapeLayer::Paint.
LayerRasterCacheKey key(unique_id(), context.Matrix());
if (context.HasRetainedNode(key)) {
TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit");
scenic::EntityNode* retained_node = context.GetRetainedNode(key);
FML_DCHECK(context.top_entity());
FML_DCHECK(retained_node->session() == context.session());

// Re-adjust the elevation.
retained_node->SetTranslation(0.f, 0.f, z_translation);

context.top_entity()->entity_node().AddChild(*retained_node);
return;
}

TRACE_EVENT_INSTANT0("flutter", "cache miss, creating");
// If we can't find an existing retained surface, create one.
SceneUpdateContext::Frame frame(
context, SkRRect::MakeRect(paint_bounds()), SK_ColorTRANSPARENT,
SkScalarRoundToInt(context.alphaf() * 255),
"flutter::PhysicalShapeLayer", z_translation, this);

frame.AddPaintLayer(this);
}
}

#endif // defined(OS_FUCHSIA)

Layer::AutoSaveLayer::AutoSaveLayer(const PaintContext& paint_context,
Expand Down
6 changes: 6 additions & 0 deletions flow/layers/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ class Layer {
#if defined(OS_FUCHSIA)
// Updates the system composited scene.
virtual void UpdateScene(SceneUpdateContext& context);
virtual void CheckForChildLayerBelow(PrerollContext* context);
#endif

bool needs_system_composite() const { return needs_system_composite_; }
Expand All @@ -184,6 +185,11 @@ class Layer {

uint64_t unique_id() const { return unique_id_; }

protected:
#if defined(OS_FUCHSIA)
bool child_layer_exists_below_ = false;
#endif

private:
SkRect paint_bounds_;
uint64_t unique_id_;
Expand Down
67 changes: 0 additions & 67 deletions flow/layers/physical_shape_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,10 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context,

context->total_elevation += elevation_;
total_elevation_ = context->total_elevation;
#if defined(OS_FUCHSIA)
child_layer_exists_below_ = context->child_scene_layer_exists_below;
context->child_scene_layer_exists_below = false;
#endif

SkRect child_paint_bounds;
PrerollChildren(context, matrix, &child_paint_bounds);

#if defined(OS_FUCHSIA)
if (child_layer_exists_below_) {
set_needs_system_composite(true);
}
context->child_scene_layer_exists_below =
context->child_scene_layer_exists_below || child_layer_exists_below_;
#endif
context->total_elevation -= elevation_;

if (elevation_ == 0) {
Expand All @@ -80,62 +69,6 @@ void PhysicalShapeLayer::Preroll(PrerollContext* context,
}
}

#if defined(OS_FUCHSIA)

void PhysicalShapeLayer::UpdateScene(SceneUpdateContext& context) {
FML_DCHECK(needs_system_composite());
TRACE_EVENT0("flutter", "PhysicalShapeLayer::UpdateScene");

// If there is embedded Fuchsia content in the scene (a ChildSceneLayer),
// PhysicalShapeLayers that appear above the embedded content will be turned
// into their own Scenic layers.
if (child_layer_exists_below_) {
float global_scenic_elevation =
context.GetGlobalElevationForNextScenicLayer();
float local_scenic_elevation =
global_scenic_elevation - context.scenic_elevation();
float z_translation = -local_scenic_elevation;

// Retained rendering: speedup by reusing a retained entity node if
// possible. When an entity node is reused, no paint layer is added to the
// frame so we won't call PhysicalShapeLayer::Paint.
LayerRasterCacheKey key(unique_id(), context.Matrix());
if (context.HasRetainedNode(key)) {
TRACE_EVENT_INSTANT0("flutter", "retained layer cache hit");
scenic::EntityNode* retained_node = context.GetRetainedNode(key);
FML_DCHECK(context.top_entity());
FML_DCHECK(retained_node->session() == context.session());

// Re-adjust the elevation.
retained_node->SetTranslation(0.f, 0.f, z_translation);

context.top_entity()->entity_node().AddChild(*retained_node);
return;
}

TRACE_EVENT_INSTANT0("flutter", "cache miss, creating");
// If we can't find an existing retained surface, create one.
SceneUpdateContext::Frame frame(context, frameRRect_, SK_ColorTRANSPARENT,
SkScalarRoundToInt(context.alphaf() * 255),
"flutter::PhysicalShapeLayer",
z_translation, this);

frame.AddPaintLayer(this);

// Node: UpdateSceneChildren needs to be called here so that |frame| is
// still in scope (and therefore alive) while UpdateSceneChildren is being
// called.
float scenic_elevation = context.scenic_elevation();
context.set_scenic_elevation(scenic_elevation + local_scenic_elevation);
ContainerLayer::UpdateSceneChildren(context);
context.set_scenic_elevation(scenic_elevation);
} else {
ContainerLayer::UpdateSceneChildren(context);
}
}

#endif // defined(OS_FUCHSIA)

void PhysicalShapeLayer::Paint(PaintContext& context) const {
TRACE_EVENT0("flutter", "PhysicalShapeLayer::Paint");
FML_DCHECK(needs_painting());
Expand Down
7 changes: 0 additions & 7 deletions flow/layers/physical_shape_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,9 @@ class PhysicalShapeLayer : public ContainerLayer {
return clip_behavior_ == Clip::antiAliasWithSaveLayer;
}

#if defined(OS_FUCHSIA)
void UpdateScene(SceneUpdateContext& context) override;
#endif // defined(OS_FUCHSIA)

float total_elevation() const { return total_elevation_; }

private:
#if defined(OS_FUCHSIA)
bool child_layer_exists_below_ = false;
#endif
SkColor color_;
SkColor shadow_color_;
float elevation_ = 0.0f;
Expand Down
5 changes: 5 additions & 0 deletions flow/layers/picture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ PictureLayer::PictureLayer(const SkPoint& offset,

void PictureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
TRACE_EVENT0("flutter", "PictureLayer::Preroll");

#if defined(OS_FUCHSIA)
CheckForChildLayerBelow(context);
#endif

SkPicture* sk_picture = picture();

if (auto* cache = context->raster_cache) {
Expand Down
4 changes: 4 additions & 0 deletions flow/layers/platform_view_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ PlatformViewLayer::PlatformViewLayer(const SkPoint& offset,

void PlatformViewLayer::Preroll(PrerollContext* context,
const SkMatrix& matrix) {
#if defined(OS_FUCHSIA)
CheckForChildLayerBelow(context);
#endif

set_paint_bounds(SkRect::MakeXYWH(offset_.x(), offset_.y(), size_.width(),
size_.height()));

Expand Down
4 changes: 4 additions & 0 deletions flow/layers/shader_mask_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ ShaderMaskLayer::ShaderMaskLayer(sk_sp<SkShader> shader,
: shader_(shader), mask_rect_(mask_rect), blend_mode_(blend_mode) {}

void ShaderMaskLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
#if defined(OS_FUCHSIA)
CheckForChildLayerBelow(context);
#endif

Layer::AutoPrerollSaveLayerState save =
Layer::AutoPrerollSaveLayerState::Create(context);
ContainerLayer::Preroll(context, matrix);
Expand Down
4 changes: 4 additions & 0 deletions flow/layers/texture_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ TextureLayer::TextureLayer(const SkPoint& offset,
void TextureLayer::Preroll(PrerollContext* context, const SkMatrix& matrix) {
TRACE_EVENT0("flutter", "TextureLayer::Preroll");

#if defined(OS_FUCHSIA)
CheckForChildLayerBelow(context);
#endif

set_paint_bounds(SkRect::MakeXYWH(offset_.x(), offset_.y(), size_.width(),
size_.height()));
}
Expand Down