提交 2a13567a 编写于 作者: A Adam Barth 提交者: GitHub

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.
上级 52bbe398
......@@ -37,38 +37,52 @@ void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
const SkISize& frame_size = layer_tree->frame_size();
auto update = mozart::SceneUpdate::New();
sk_sp<SkSurface> surface;
if (!frame_size.isEmpty()) {
// Get a surface to draw the contents.
mozart::ImagePtr image;
surface = mozart::MakeSkSurface(frame_size, buffer_producer_.get(), &image);
FTL_CHECK(surface);
// Update the scene contents.
mozart::RectF bounds;
bounds.width = frame_size.width();
bounds.height = frame_size.height();
auto content_resource = mozart::Resource::New();
content_resource->set_image(mozart::ImageResource::New());
content_resource->get_image()->image = std::move(image);
update->resources.insert(kContentImageResourceId,
std::move(content_resource));
auto root_node = mozart::Node::New();
root_node->hit_test_behavior = mozart::HitTestBehavior::New();
root_node->op = mozart::NodeOp::New();
root_node->op->set_image(mozart::ImageNodeOp::New());
root_node->op->get_image()->content_rect = bounds.Clone();
root_node->op->get_image()->image_resource_id = kContentImageResourceId;
layer_tree->UpdateScene(update.get(), root_node.get());
update->nodes.insert(kRootNodeId, std::move(root_node));
} else {
if (frame_size.isEmpty()) {
update->nodes.insert(kRootNodeId, mozart::Node::New());
// Publish the updated scene contents.
// TODO(jeffbrown): We should set the metadata's presentation_time here too.
scene_->Update(std::move(update));
auto metadata = mozart::SceneMetadata::New();
metadata->version = layer_tree->scene_version();
scene_->Publish(std::move(metadata));
callback();
return;
}
// Get a surface to draw the contents.
mozart::ImagePtr image;
sk_sp<SkSurface> surface =
mozart::MakeSkSurface(frame_size, buffer_producer_.get(), &image);
FTL_CHECK(surface);
flow::CompositorContext::ScopedFrame frame =
compositor_context_.AcquireFrame(nullptr, *surface->getCanvas());
layer_tree->Preroll(frame);
// Update the scene contents.
mozart::RectF bounds;
bounds.width = frame_size.width();
bounds.height = frame_size.height();
auto content_resource = mozart::Resource::New();
content_resource->set_image(mozart::ImageResource::New());
content_resource->get_image()->image = std::move(image);
update->resources.insert(kContentImageResourceId,
std::move(content_resource));
auto root_node = mozart::Node::New();
root_node->hit_test_behavior = mozart::HitTestBehavior::New();
root_node->op = mozart::NodeOp::New();
root_node->op->set_image(mozart::ImageNodeOp::New());
root_node->op->get_image()->content_rect = bounds.Clone();
root_node->op->get_image()->image_resource_id = kContentImageResourceId;
layer_tree->UpdateScene(update.get(), root_node.get());
update->nodes.insert(kRootNodeId, std::move(root_node));
// Publish the updated scene contents.
// TODO(jeffbrown): We should set the metadata's presentation_time here too.
scene_->Update(std::move(update));
......@@ -80,14 +94,10 @@ void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
// We do this after publishing to take advantage of pipelining.
// The image buffer's fence is signalled automatically when the surface
// goes out of scope.
if (surface) {
SkCanvas* canvas = surface->getCanvas();
flow::CompositorContext::ScopedFrame frame =
compositor_context_.AcquireFrame(nullptr, *canvas);
canvas->clear(SK_ColorBLACK);
layer_tree->Raster(frame);
canvas->flush();
}
SkCanvas* canvas = surface->getCanvas();
canvas->clear(SK_ColorBLACK);
layer_tree->Paint(frame);
canvas->flush();
callback();
}
......
......@@ -19,23 +19,20 @@ LayerTree::~LayerTree() {}
void LayerTree::Raster(CompositorContext::ScopedFrame& frame,
bool ignore_raster_cache) {
{
TRACE_EVENT0("flutter", "LayerTree::Preroll");
frame.context().raster_cache().SetCheckboardCacheImages(
checkerboard_raster_cache_images_);
Layer::PrerollContext context = {
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
frame.gr_context(), SkRect::MakeEmpty(),
};
root_layer_->Preroll(&context, SkMatrix());
}
{
Layer::PaintContext context = {frame.canvas(), frame.context().frame_time(),
frame.context().engine_time()};
TRACE_EVENT0("flutter", "LayerTree::Paint");
root_layer_->Paint(context);
}
Preroll(frame, ignore_raster_cache);
Paint(frame);
}
void LayerTree::Preroll(CompositorContext::ScopedFrame& frame,
bool ignore_raster_cache) {
TRACE_EVENT0("flutter", "LayerTree::Preroll");
frame.context().raster_cache().SetCheckboardCacheImages(
checkerboard_raster_cache_images_);
Layer::PrerollContext context = {
ignore_raster_cache ? nullptr : &frame.context().raster_cache(),
frame.gr_context(), SkRect::MakeEmpty(),
};
root_layer_->Preroll(&context, SkMatrix());
}
#if defined(OS_FUCHSIA)
......@@ -46,4 +43,11 @@ void LayerTree::UpdateScene(mozart::SceneUpdate* update,
}
#endif
void LayerTree::Paint(CompositorContext::ScopedFrame& frame) {
Layer::PaintContext context = {frame.canvas(), frame.context().frame_time(),
frame.context().engine_time()};
TRACE_EVENT0("flutter", "LayerTree::Paint");
root_layer_->Paint(context);
}
} // namespace flow
......@@ -23,9 +23,13 @@ class LayerTree {
~LayerTree();
// Raster includes both Preroll and Paint.
void Raster(CompositorContext::ScopedFrame& frame,
bool ignore_raster_cache = false);
void Preroll(CompositorContext::ScopedFrame& frame,
bool ignore_raster_cache = false);
#if defined(OS_FUCHSIA)
// TODO(abarth): Integrate scene updates with the rasterization pass so that
// we can draw on top of child scenes (and so that we can apply clips and
......@@ -33,6 +37,8 @@ class LayerTree {
void UpdateScene(mozart::SceneUpdate* update, mozart::Node* container);
#endif
void Paint(CompositorContext::ScopedFrame& frame);
Layer* root_layer() const { return root_layer_.get(); }
void set_root_layer(std::unique_ptr<Layer> root_layer) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册