Skip to content

Commit

Permalink
Fix Mozart child views (#3232)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
abarth authored Nov 16, 2016
1 parent 52bbe39 commit 2a13567
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 54 deletions.
84 changes: 47 additions & 37 deletions content_handler/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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();
}
Expand Down
38 changes: 21 additions & 17 deletions flow/layers/layer_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
6 changes: 6 additions & 0 deletions flow/layers/layer_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,22 @@ 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
// blending operations to child scene).
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) {
Expand Down

0 comments on commit 2a13567

Please sign in to comment.