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

Retained rendering in Fuchsia PhysicalShapeLayer#6558

Merged
liyuqian merged 3 commits intoflutter:masterfrom
liyuqian:fuchsia
Feb 4, 2019
Merged

Retained rendering in Fuchsia PhysicalShapeLayer#6558
liyuqian merged 3 commits intoflutter:masterfrom
liyuqian:fuchsia

Conversation

@liyuqian
Copy link
Contributor

@liyuqian liyuqian commented Oct 16, 2018

For flutter/flutter#23535

When this lands/rolls into Fuchsia, a manual roll with https://fuchsia-review.googlesource.com/c/topaz/+/241557 is needed.

@liyuqian liyuqian changed the title [wip] Retained rendering in Fuchsia PhysicalShapeLayer Retained rendering in Fuchsia PhysicalShapeLayer Oct 16, 2018
@liyuqian liyuqian requested a review from chinmaygarde October 16, 2018 19:16
FML_DCHECK(needs_system_composite());

if (entity_node_ != nullptr) {
if (entity_node_->session() && context.top_entity()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Just add an assertion for this condition and add the child node as normal.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@chinmaygarde
Copy link
Contributor

Can you land this please?

@liyuqian
Copy link
Contributor Author

Oops, I was waiting for the framework change to land first. Mark this as wip.

@liyuqian liyuqian changed the title Retained rendering in Fuchsia PhysicalShapeLayer [wip] Retained rendering in Fuchsia PhysicalShapeLayer Oct 24, 2018
@liyuqian liyuqian changed the title [wip] Retained rendering in Fuchsia PhysicalShapeLayer Retained rendering in Fuchsia PhysicalShapeLayer Nov 13, 2018
@liyuqian liyuqian requested a review from mikejurka November 13, 2018 16:44
@liyuqian
Copy link
Contributor Author

@chinmaygarde @mikejurka : Please have a look at this PR again as I now changed EntityNode to be stored as unique_ptr according to https://fuchsia-review.googlesource.com/c/garnet/+/224197

See also FL-53 about the performance difference with or without this retained rendering. Here's a short summary:

Before retained rendering,
the RenderFrame in Scenic Compositor takes 22.9ms on average, the GPURasterizer::Draw in flutter takes 23.5ms on average.

After retained rendering,
the RenderFrame in Scenic Compositor takes 15.7ms on average, the GPURasterizer::Draw in flutter takes 7.9ms on average.


#if defined(OS_FUCHSIA)
std::unique_ptr<scenic::EntityNode> entity_node_ptr_;
mutable bool fuchsia_painted_ = false;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand this variable, could you add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

FML_DCHECK(needs_painting());

#if defined(OS_FUCHSIA)
if (fuchsia_painted_) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the difference between fuchsia_painted_ and needs_painting() ? When/why do their values diverge?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needs_painting check whether the paint_bounds is empty and it applies to all Flutter platforms.

fuchsia_painted is for Fuchsia only because Fuchsia always allocates a buffer for a PhysicalShapeLayer. Even if the paint_bounds is not empty, we can still use this to optimize performance by only paint the same PhysicalShapeLayer once within Fuchsia.

std::unique_ptr<scenic::EntityNode> entity_node_ptr_;

// Whether the Fuchsia scenic::EntityNode of this exact same layer has already
// been painted in previous frames. If so, we can skip the Paint phase and
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has been painted in a previous frame. This means that the content below the EntityNode has already been rasterized.

"and let Scenic re-use the same Entity nodes."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@liyuqian liyuqian force-pushed the fuchsia branch 2 times, most recently from eaf2663 to dc90dc0 Compare January 15, 2019 20:41
@liyuqian liyuqian changed the title Retained rendering in Fuchsia PhysicalShapeLayer [wip] Retained rendering in Fuchsia PhysicalShapeLayer Jan 15, 2019
@liyuqian liyuqian changed the title [wip] Retained rendering in Fuchsia PhysicalShapeLayer Retained rendering in Fuchsia PhysicalShapeLayer Jan 16, 2019
@liyuqian
Copy link
Contributor Author

@chinmaygarde @mikejurka : please check the updated PR that (I think) correctly manages the scenic resources: (1) only SubmitSurface when the surface is no longer used in retained rendering; (2) let the SurfaceProducer own surfaces and entity nodes so they'll get destructed in the right thread.

frame.AddPaintedLayer(root_layer_.get());
}
container.AddChild(transform.entity_node());
frame.Finalize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this happen in the frame's destructor?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nm

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually found a way to remove Finalize() and do everything in the destructor :)

Copy link
Contributor

@mikejurka mikejurka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we keep using unique_ptrs, but have them be moved onto a "used" list somehow?

Alternatively, could we use shared_ptrs and have the SurfaceProducer use custom deleters to take further action when something is no longer referenced?


UpdateSceneChildren(context);

context.SetRetainedSurface(key, frame.Finalize());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I see why you had to create a Finalize()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I found a way to remove Finalize()

SceneUpdateContext::Frame::~Frame() {
context().CreateFrame(entity_node(), rrect_, color_, paint_bounds_,
std::move(paint_layers_));
SceneUpdateContext::SurfaceProducerSurface*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep the destructor, and have it call Finalize if Finalize() was not already called?
Also, can we add a boolean to make sure we're finalized only once?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just removed Finalize() and restored the destructor.

// won't call PhysicalShapeLayer::Paint.
LayerRasterCacheKey key(
this, SkMatrix::MakeScale(context.ScaleX(), context.ScaleY()));
SceneUpdateContext::SurfaceProducerSurface* retained_surface =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we keep unique_ptrs to surfaces, and then just place them in a Used struct somewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I just removed all raw pointers and restore the unique_ptr everywhere.

return;
}

SceneUpdateContext::Frame frame(context, frameRRect_, color_, elevation_);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment: "If we can't find an existing retained surface, create one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

FML_DCHECK(needs_system_composite());

// 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"When a entity node is resued, no paint layer is added to the frame"
I guess I'm still confused as to how the Layers work here, but: Does this mean that the contents of it haven't changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, all engine layers (flow::Layer descendents) are currently immutable once constructed from the SceneBuilder. Unfortunately, the fields of those layers don't seem to be immutable due to set field methods. But we only call those set field methods in SceneBuilder. I'll change those fields to "const" in the future and update the SceneBuilder accordingly to reduce the confusion.

frame.AddPaintedLayer(root_layer_.get());
}
container.AddChild(transform.entity_node());
frame.Finalize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nm

Copy link
Contributor Author

@liyuqian liyuqian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mikejurka for your helpful comments! Now I found a way to preserve all the std::unique_ptrs and ~Frame. I hope that this makes the change safer and easier to understand.

FML_DCHECK(needs_system_composite());

// 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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, all engine layers (flow::Layer descendents) are currently immutable once constructed from the SceneBuilder. Unfortunately, the fields of those layers don't seem to be immutable due to set field methods. But we only call those set field methods in SceneBuilder. I'll change those fields to "const" in the future and update the SceneBuilder accordingly to reduce the confusion.

frame.AddPaintedLayer(root_layer_.get());
}
container.AddChild(transform.entity_node());
frame.Finalize();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually found a way to remove Finalize() and do everything in the destructor :)

// won't call PhysicalShapeLayer::Paint.
LayerRasterCacheKey key(
this, SkMatrix::MakeScale(context.ScaleX(), context.ScaleY()));
SceneUpdateContext::SurfaceProducerSurface* retained_surface =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I just removed all raw pointers and restore the unique_ptr everywhere.

return;
}

SceneUpdateContext::Frame frame(context, frameRRect_, color_, elevation_);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


UpdateSceneChildren(context);

context.SetRetainedSurface(key, frame.Finalize());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, I found a way to remove Finalize()

SceneUpdateContext::Frame::~Frame() {
context().CreateFrame(entity_node(), rrect_, color_, paint_bounds_,
std::move(paint_layers_));
SceneUpdateContext::SurfaceProducerSurface*
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just removed Finalize() and restored the destructor.

@mikejurka
Copy link
Contributor

LGTM

@liyuqian liyuqian merged commit eaae8a6 into flutter:master Feb 4, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Feb 5, 2019
engine-flutter-autoroll added a commit to flutter/flutter that referenced this pull request Feb 5, 2019
flutter/engine@85492c3...4812a2a

git log 85492c3..4812a2a --no-merges --oneline
4812a2a DCHECK that clip layer&#39;s behavior isn&#39;t none (flutter/engine#7659)
eaae8a6 Retained rendering in Fuchsia PhysicalShapeLayer (flutter/engine#6558)
1946082 Move Brightness definition to dart:ui (#27479) (flutter/engine#7678)

The AutoRoll server is located here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md

If the roll is causing failures, please contact the current sheriff ([email protected]), and stop
the roller if necessary.
kangwang1988 pushed a commit to XianyuTech/flutter that referenced this pull request Feb 12, 2019
flutter/engine@85492c3...4812a2a

git log 85492c3..4812a2a --no-merges --oneline
4812a2a DCHECK that clip layer&flutter#39;s behavior isn&flutter#39;t none (flutter/engine#7659)
eaae8a6 Retained rendering in Fuchsia PhysicalShapeLayer (flutter/engine#6558)
1946082 Move Brightness definition to dart:ui (flutter#27479) (flutter/engine#7678)

The AutoRoll server is located here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md

If the roll is causing failures, please contact the current sheriff ([email protected]), and stop
the roller if necessary.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants