提交 5b972a46 编写于 作者: J Jeff Brown 提交者: GitHub

Use new image buffer mechanism. (#3221)

上级 21c98464
......@@ -17,15 +17,16 @@ executable("content_handler") {
"rasterizer.h",
"runtime_holder.cc",
"runtime_holder.h",
"skia_surface_holder.cc",
"skia_surface_holder.h",
]
deps = [
"//apps/modular/lib/app",
"//apps/mozart/services/buffers",
"//apps/mozart/services/buffers/cpp",
"//apps/mozart/services/composition",
"//apps/mozart/services/input",
"//apps/mozart/services/views",
"//apps/mozart/lib/skia:vmo",
"//dart/runtime/vm:libdart_platform",
"//dart/runtime:libdart",
"//flutter/assets",
......
......@@ -6,8 +6,7 @@
#include <utility>
#include "apps/mozart/services/composition/image.fidl.h"
#include "flutter/content_handler/skia_surface_holder.h"
#include "apps/mozart/lib/skia/skia_vmo_surface.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
......@@ -24,6 +23,7 @@ Rasterizer::~Rasterizer() {}
void Rasterizer::SetScene(fidl::InterfaceHandle<mozart::Scene> scene) {
scene_.Bind(std::move(scene));
buffer_producer_.reset(new mozart::BufferProducer());
}
void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
......@@ -37,24 +37,21 @@ 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()) {
// TODO(jeffbrown): Maintain a pool of images and recycle them.
SkiaSurfaceHolder surface_holder(frame_size);
SkCanvas* canvas = surface_holder.surface()->getCanvas();
flow::CompositorContext::ScopedFrame frame =
compositor_context_.AcquireFrame(nullptr, *canvas);
canvas->clear(SK_ColorBLACK);
layer_tree->Raster(frame);
canvas->flush();
// 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 = surface_holder.TakeImage();
content_resource->get_image()->image = std::move(image);
update->resources.insert(kContentImageResourceId,
std::move(content_resource));
......@@ -72,12 +69,26 @@ void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
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));
// Draw the contents of the scene to a surface.
// 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();
}
callback();
}
......
......@@ -5,6 +5,9 @@
#ifndef FLUTTER_CONTENT_HANDLER_RASTERIZER_H_
#define FLUTTER_CONTENT_HANDLER_RASTERIZER_H_
#include <memory>
#include "apps/mozart/services/buffers/cpp/buffer_producer.h"
#include "apps/mozart/services/composition/scenes.fidl.h"
#include "flutter/flow/compositor_context.h"
#include "flutter/flow/layers/layer_tree.h"
......@@ -24,6 +27,7 @@ class Rasterizer {
private:
mozart::ScenePtr scene_;
std::unique_ptr<mozart::BufferProducer> buffer_producer_;
flow::CompositorContext compositor_context_;
FTL_DISALLOW_COPY_AND_ASSIGN(Rasterizer);
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "flutter/content_handler/skia_surface_holder.h"
#include <mx/process.h>
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace flutter_runner {
SkiaSurfaceHolder::SkiaSurfaceHolder(const SkISize& size) {
size_t row_bytes = size.width() * sizeof(uint32_t);
size_t total_bytes = size.height() * row_bytes;
mx_status_t rv = mx::vmo::create(total_bytes, 0, &vmo_);
FTL_CHECK(rv == NO_ERROR);
uintptr_t address = 0;
rv = mx::process::self().map_vm(vmo_, 0, total_bytes, &address,
MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE);
FTL_CHECK(rv == NO_ERROR);
buffer_ = reinterpret_cast<void*>(address);
surface_ = SkSurface::MakeRasterDirect(
SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType,
kPremul_SkAlphaType),
buffer_, row_bytes);
FTL_CHECK(surface_);
}
SkiaSurfaceHolder::~SkiaSurfaceHolder() {
mx_status_t rv =
mx::process::self().unmap_vm(reinterpret_cast<uintptr_t>(buffer_), 0);
FTL_CHECK(rv == NO_ERROR);
}
mozart::ImagePtr SkiaSurfaceHolder::TakeImage() {
FTL_DCHECK(vmo_);
auto image = mozart::Image::New();
image->size = mozart::Size::New();
image->size->width = surface_->width();
image->size->height = surface_->height();
image->stride = image->size->width * sizeof(uint32_t);
image->pixel_format = mozart::Image::PixelFormat::B8G8R8A8;
image->alpha_format = mozart::Image::AlphaFormat::PREMULTIPLIED;
image->buffer = std::move(vmo_);
return image;
}
} // namespace flutter_runner
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FLUTTER_CONTENT_HANDLER_SKIA_SURFACE_HOLDER_H_
#define FLUTTER_CONTENT_HANDLER_SKIA_SURFACE_HOLDER_H_
#include <mx/vmo.h>
#include "apps/mozart/services/composition/image.fidl.h"
#include "apps/mozart/services/geometry/geometry.fidl.h"
#include "lib/ftl/macros.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter_runner {
// Provides an |SkSurface| backed by a shared memory buffer for software
// rendering which can then be passed to the Mozart compositor in the form
// of an |Image|.
class SkiaSurfaceHolder {
public:
SkiaSurfaceHolder(const SkISize& size);
~SkiaSurfaceHolder();
// Gets the |SkSurface| backed by this buffer.
const sk_sp<SkSurface>& surface() const { return surface_; }
// Gets an |Image| backed by this buffer, transferring ownership of the
// underlying shared memory buffer to the image. The image can then be
// sent to the Mozart compositor as an |ImageResource|.
// This method must be called at most once.
//
// Note: The underlying shared memory buffer remains mapped in this process
// (and the |SkSurface| remains usable) until the |SkiaSurfaceHolder|
// itself is destroyed.
mozart::ImagePtr TakeImage();
private:
mx::vmo vmo_;
void* buffer_;
sk_sp<SkSurface> surface_;
FTL_DISALLOW_COPY_AND_ASSIGN(SkiaSurfaceHolder);
};
} // namespace flutter_runner
#endif // FLUTTER_CONTENT_HANDLER_SKIA_SURFACE_HOLDER_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册