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

Commit 2a13567

Browse files
authored
Fix Mozart child views (#3232)
When we pipelined the drawing commands we caused UpdateScene to be called before Preroll, which isn't allowed. Now we call Preroll, UpdateScene, and Paint separately.
1 parent 52bbe39 commit 2a13567

File tree

3 files changed

+74
-54
lines changed

3 files changed

+74
-54
lines changed

content_handler/rasterizer.cc

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,38 +37,52 @@ void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
3737
const SkISize& frame_size = layer_tree->frame_size();
3838
auto update = mozart::SceneUpdate::New();
3939

40-
sk_sp<SkSurface> surface;
41-
if (!frame_size.isEmpty()) {
42-
// Get a surface to draw the contents.
43-
mozart::ImagePtr image;
44-
surface = mozart::MakeSkSurface(frame_size, buffer_producer_.get(), &image);
45-
FTL_CHECK(surface);
46-
47-
// Update the scene contents.
48-
mozart::RectF bounds;
49-
bounds.width = frame_size.width();
50-
bounds.height = frame_size.height();
51-
52-
auto content_resource = mozart::Resource::New();
53-
content_resource->set_image(mozart::ImageResource::New());
54-
content_resource->get_image()->image = std::move(image);
55-
update->resources.insert(kContentImageResourceId,
56-
std::move(content_resource));
57-
58-
auto root_node = mozart::Node::New();
59-
root_node->hit_test_behavior = mozart::HitTestBehavior::New();
60-
root_node->op = mozart::NodeOp::New();
61-
root_node->op->set_image(mozart::ImageNodeOp::New());
62-
root_node->op->get_image()->content_rect = bounds.Clone();
63-
root_node->op->get_image()->image_resource_id = kContentImageResourceId;
64-
65-
layer_tree->UpdateScene(update.get(), root_node.get());
66-
67-
update->nodes.insert(kRootNodeId, std::move(root_node));
68-
} else {
40+
if (frame_size.isEmpty()) {
6941
update->nodes.insert(kRootNodeId, mozart::Node::New());
42+
// Publish the updated scene contents.
43+
// TODO(jeffbrown): We should set the metadata's presentation_time here too.
44+
scene_->Update(std::move(update));
45+
auto metadata = mozart::SceneMetadata::New();
46+
metadata->version = layer_tree->scene_version();
47+
scene_->Publish(std::move(metadata));
48+
callback();
49+
return;
7050
}
7151

52+
// Get a surface to draw the contents.
53+
mozart::ImagePtr image;
54+
sk_sp<SkSurface> surface =
55+
mozart::MakeSkSurface(frame_size, buffer_producer_.get(), &image);
56+
57+
FTL_CHECK(surface);
58+
59+
flow::CompositorContext::ScopedFrame frame =
60+
compositor_context_.AcquireFrame(nullptr, *surface->getCanvas());
61+
62+
layer_tree->Preroll(frame);
63+
64+
// Update the scene contents.
65+
mozart::RectF bounds;
66+
bounds.width = frame_size.width();
67+
bounds.height = frame_size.height();
68+
69+
auto content_resource = mozart::Resource::New();
70+
content_resource->set_image(mozart::ImageResource::New());
71+
content_resource->get_image()->image = std::move(image);
72+
update->resources.insert(kContentImageResourceId,
73+
std::move(content_resource));
74+
75+
auto root_node = mozart::Node::New();
76+
root_node->hit_test_behavior = mozart::HitTestBehavior::New();
77+
root_node->op = mozart::NodeOp::New();
78+
root_node->op->set_image(mozart::ImageNodeOp::New());
79+
root_node->op->get_image()->content_rect = bounds.Clone();
80+
root_node->op->get_image()->image_resource_id = kContentImageResourceId;
81+
82+
layer_tree->UpdateScene(update.get(), root_node.get());
83+
84+
update->nodes.insert(kRootNodeId, std::move(root_node));
85+
7286
// Publish the updated scene contents.
7387
// TODO(jeffbrown): We should set the metadata's presentation_time here too.
7488
scene_->Update(std::move(update));
@@ -80,14 +94,10 @@ void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
8094
// We do this after publishing to take advantage of pipelining.
8195
// The image buffer's fence is signalled automatically when the surface
8296
// goes out of scope.
83-
if (surface) {
84-
SkCanvas* canvas = surface->getCanvas();
85-
flow::CompositorContext::ScopedFrame frame =
86-
compositor_context_.AcquireFrame(nullptr, *canvas);
87-
canvas->clear(SK_ColorBLACK);
88-
layer_tree->Raster(frame);
89-
canvas->flush();
90-
}
97+
SkCanvas* canvas = surface->getCanvas();
98+
canvas->clear(SK_ColorBLACK);
99+
layer_tree->Paint(frame);
100+
canvas->flush();
91101

92102
callback();
93103
}

flow/layers/layer_tree.cc

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,20 @@ LayerTree::~LayerTree() {}
1919

2020
void LayerTree::Raster(CompositorContext::ScopedFrame& frame,
2121
bool ignore_raster_cache) {
22-
{
23-
TRACE_EVENT0("flutter", "LayerTree::Preroll");
24-
frame.context().raster_cache().SetCheckboardCacheImages(
25-
checkerboard_raster_cache_images_);
26-
Layer::PrerollContext context = {
27-
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
28-
frame.gr_context(), SkRect::MakeEmpty(),
29-
};
30-
root_layer_->Preroll(&context, SkMatrix());
31-
}
32-
33-
{
34-
Layer::PaintContext context = {frame.canvas(), frame.context().frame_time(),
35-
frame.context().engine_time()};
36-
TRACE_EVENT0("flutter", "LayerTree::Paint");
37-
root_layer_->Paint(context);
38-
}
22+
Preroll(frame, ignore_raster_cache);
23+
Paint(frame);
24+
}
25+
26+
void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
27+
bool ignore_raster_cache) {
28+
TRACE_EVENT0("flutter", "LayerTree::Preroll");
29+
frame.context().raster_cache().SetCheckboardCacheImages(
30+
checkerboard_raster_cache_images_);
31+
Layer::PrerollContext context = {
32+
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
33+
frame.gr_context(), SkRect::MakeEmpty(),
34+
};
35+
root_layer_->Preroll(&context, SkMatrix());
3936
}
4037

4138
#if defined(OS_FUCHSIA)
@@ -46,4 +43,11 @@ void LayerTree::UpdateScene(mozart::SceneUpdate* update,
4643
}
4744
#endif
4845

46+
void LayerTree::Paint(CompositorContext::ScopedFrame& frame) {
47+
Layer::PaintContext context = {frame.canvas(), frame.context().frame_time(),
48+
frame.context().engine_time()};
49+
TRACE_EVENT0("flutter", "LayerTree::Paint");
50+
root_layer_->Paint(context);
51+
}
52+
4953
} // namespace flow

flow/layers/layer_tree.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,22 @@ class LayerTree {
2323

2424
~LayerTree();
2525

26+
// Raster includes both Preroll and Paint.
2627
void Raster(CompositorContext::ScopedFrame& frame,
2728
bool ignore_raster_cache = false);
2829

30+
void Preroll(CompositorContext::ScopedFrame& frame,
31+
bool ignore_raster_cache = false);
32+
2933
#if defined(OS_FUCHSIA)
3034
// TODO(abarth): Integrate scene updates with the rasterization pass so that
3135
// we can draw on top of child scenes (and so that we can apply clips and
3236
// blending operations to child scene).
3337
void UpdateScene(mozart::SceneUpdate* update, mozart::Node* container);
3438
#endif
3539

40+
void Paint(CompositorContext::ScopedFrame& frame);
41+
3642
Layer* root_layer() const { return root_layer_.get(); }
3743

3844
void set_root_layer(std::unique_ptr<Layer> root_layer) {

0 commit comments

Comments
 (0)