Port Flutter to Mozart. (#3094)

Example: $ mojo:launcher mojo:spinning_square
This commit is contained in:
Jeff Brown
2016-10-04 12:54:54 -07:00
committed by GitHub
parent 1af7a6fe30
commit e13412bd24
31 changed files with 362 additions and 336 deletions
+4 -2
View File
@@ -12,16 +12,18 @@ executable("content_handler") {
"application_impl.h",
"content_handler_impl.cc",
"content_handler_impl.h",
"framebuffer_skia.cc",
"framebuffer_skia.h",
"main.cc",
"rasterizer.cc",
"rasterizer.h",
"runtime_holder.cc",
"runtime_holder.h",
"skia_surface_holder.cc",
"skia_surface_holder.h",
]
deps = [
"//apps/mozart/services/composition/interfaces",
"//apps/mozart/services/views/interfaces",
"//dart/runtime:libdart",
"//dart/runtime/vm:libdart_platform",
"//flutter/assets",
+19 -10
View File
@@ -27,9 +27,6 @@ ApplicationImpl::ApplicationImpl(
FTL_LOG(ERROR) << "Failed to receive bundle.";
return;
}
// TODO(abarth): In principle, we should call StartRuntimeIfReady() here but
// because we're draining the data pipe synchronously, we know that we can't
// possibly be ready yet because we haven't received the Initialize() message.
}
ApplicationImpl::~ApplicationImpl() {}
@@ -42,24 +39,36 @@ void ApplicationImpl::Initialize(mojo::InterfaceHandle<mojo::Shell> shell,
mojo::ApplicationConnectorPtr connector;
shell_->CreateApplicationConnector(mojo::GetProxy(&connector));
runtime_holder_.reset(new RuntimeHolder());
runtime_holder_->Init(std::move(connector));
StartRuntimeIfReady();
runtime_holder_->Init(std::move(connector), std::move(bundle_));
}
void ApplicationImpl::AcceptConnection(
const mojo::String& requestor_url,
const mojo::String& resolved_url,
mojo::InterfaceRequest<mojo::ServiceProvider> services) {}
mojo::InterfaceRequest<mojo::ServiceProvider> services) {
service_provider_bindings_.AddBinding(this, std::move(services));
}
void ApplicationImpl::RequestQuit() {
binding_.Close();
delete this;
}
void ApplicationImpl::StartRuntimeIfReady() {
if (!runtime_holder_ || bundle_.empty())
return;
runtime_holder_->Run(url_, std::move(bundle_));
void ApplicationImpl::ConnectToService(
const mojo::String& service_name,
mojo::ScopedMessagePipeHandle client_handle) {
if (service_name == mozart::ViewProvider::Name_) {
view_provider_bindings_.AddBinding(
this,
mojo::InterfaceRequest<mozart::ViewProvider>(std::move(client_handle)));
}
}
void ApplicationImpl::CreateView(
mojo::InterfaceRequest<mozart::ViewOwner> view_owner_request,
mojo::InterfaceRequest<mojo::ServiceProvider> services) {
runtime_holder_->CreateView(url_, std::move(view_owner_request),
std::move(services));
}
} // namespace flutter_content_handler
+18 -1
View File
@@ -7,17 +7,22 @@
#include <memory>
#include "apps/mozart/services/views/interfaces/view_provider.mojom.h"
#include "flutter/glue/drain_data_pipe_job.h"
#include "lib/ftl/macros.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "mojo/public/interfaces/application/application.mojom.h"
#include "mojo/public/interfaces/application/service_provider.mojom.h"
#include "mojo/public/interfaces/application/shell.mojom.h"
#include "mojo/services/content_handler/interfaces/content_handler.mojom.h"
namespace flutter_content_handler {
class RuntimeHolder;
class ApplicationImpl : public mojo::Application {
class ApplicationImpl : public mojo::Application,
public mojo::ServiceProvider,
public mozart::ViewProvider {
public:
ApplicationImpl(mojo::InterfaceRequest<mojo::Application> application,
mojo::URLResponsePtr response);
@@ -34,11 +39,23 @@ class ApplicationImpl : public mojo::Application {
mojo::InterfaceRequest<mojo::ServiceProvider> services) override;
void RequestQuit() override;
// mojo::ServiceProvider
void ConnectToService(const mojo::String& service_name,
mojo::ScopedMessagePipeHandle client_handle) override;
// mozart::ViewProvider
void CreateView(
mojo::InterfaceRequest<mozart::ViewOwner> view_owner_request,
mojo::InterfaceRequest<mojo::ServiceProvider> services) override;
void StartRuntimeIfReady();
mojo::StrongBinding<mojo::Application> binding_;
std::unique_ptr<glue::DrainDataPipeJob> drainer_;
mojo::BindingSet<mojo::ServiceProvider> service_provider_bindings_;
mojo::BindingSet<mozart::ViewProvider> view_provider_bindings_;
std::vector<char> bundle_;
mojo::ShellPtr shell_;
std::string url_;
-98
View File
@@ -1,98 +0,0 @@
// 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/framebuffer_skia.h"
#include <magenta/process.h>
#include <magenta/syscalls.h>
#include <utility>
#include "lib/ftl/logging.h"
namespace flutter_content_handler {
namespace {
struct BackingStoreInfo {
mx_handle_t vmo;
uintptr_t buffer;
size_t size;
};
void DidReleaseSurface(void* pixels, void* context) {
BackingStoreInfo* info = static_cast<BackingStoreInfo*>(context);
mx_process_unmap_vm(mx_process_self(), info->buffer, info->size);
mx_handle_close(info->vmo);
delete info;
}
} // namespace
FramebufferSkia::FramebufferSkia() {}
FramebufferSkia::~FramebufferSkia() {}
void FramebufferSkia::Bind(mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info) {
if (!framebuffer) {
FTL_LOG(ERROR) << "Failed to bind framebuffer";
surface_ = nullptr;
return;
}
framebuffer_.Bind(std::move(framebuffer));
info_ = std::move(info);
uintptr_t buffer = 0;
size_t row_bytes = info_->row_bytes;
size_t size = row_bytes * info_->size->height;
mx_status_t status =
mx_process_map_vm(mx_process_self(), info_->vmo.get().value(), 0, size,
&buffer, MX_VM_FLAG_PERM_READ | MX_VM_FLAG_PERM_WRITE);
if (status < 0) {
FTL_LOG(ERROR) << "Cannot map framebuffer (status=" << status << ")";
return;
}
SkColorType sk_color_type;
SkAlphaType sk_alpha_type;
switch (info_->format) {
case mojo::FramebufferFormat::RGB_565:
sk_color_type = kRGB_565_SkColorType;
sk_alpha_type = kOpaque_SkAlphaType;
break;
case mojo::FramebufferFormat::ARGB_8888:
sk_color_type = kBGRA_8888_SkColorType;
sk_alpha_type = kPremul_SkAlphaType;
break;
case mojo::FramebufferFormat::RGB_x888:
sk_color_type = kBGRA_8888_SkColorType;
sk_alpha_type = kOpaque_SkAlphaType;
break;
default:
FTL_LOG(ERROR) << "Unknown color type " << info_->format;
return;
}
SkImageInfo image_info = SkImageInfo::Make(
info_->size->width, info_->size->height, sk_color_type, sk_alpha_type);
BackingStoreInfo* backing_store_info = new BackingStoreInfo();
backing_store_info->vmo = info_->vmo.release().value();
backing_store_info->buffer = buffer;
backing_store_info->size = size;
surface_ = SkSurface::MakeRasterDirectReleaseProc(
image_info, reinterpret_cast<void*>(buffer), row_bytes, DidReleaseSurface,
backing_store_info);
}
void FramebufferSkia::Finish() {
framebuffer_->Flush([] {});
framebuffer_.WaitForIncomingResponse();
}
} // namespace flutter_content_handler
-35
View File
@@ -1,35 +0,0 @@
// 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_FRAMEBUFFER_SKIA_H_
#define FLUTTER_CONTENT_HANDLER_FRAMEBUFFER_SKIA_H_
#include "lib/ftl/macros.h"
#include "mojo/services/framebuffer/interfaces/framebuffer.mojom.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter_content_handler {
class FramebufferSkia {
public:
FramebufferSkia();
~FramebufferSkia();
void Bind(mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info);
void Finish();
const sk_sp<SkSurface>& surface() { return surface_; }
private:
mojo::FramebufferPtr framebuffer_;
mojo::FramebufferInfoPtr info_;
sk_sp<SkSurface> surface_;
FTL_DISALLOW_COPY_AND_ASSIGN(FramebufferSkia);
};
} // namespace flutter_content_handler
#endif // FLUTTER_CONTENT_HANDLER_FRAMEBUFFER_SKIA_H_
+53 -13
View File
@@ -6,36 +6,76 @@
#include <utility>
#include "lib/ftl/functional/make_runnable.h"
#include "apps/mozart/services/composition/interfaces/image.mojom.h"
#include "flutter/content_handler/skia_surface_holder.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace flutter_content_handler {
namespace {
constexpr uint32_t kContentImageResourceId = 1;
constexpr uint32_t kRootNodeId = mozart::kSceneRootNodeId;
} // namespace
Rasterizer::Rasterizer() {}
Rasterizer::~Rasterizer() {}
void Rasterizer::SetFramebuffer(
mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info) {
framebuffer_.Bind(std::move(framebuffer), std::move(info));
void Rasterizer::SetScene(mojo::InterfaceHandle<mozart::Scene> scene) {
scene_.Bind(std::move(scene));
}
void Rasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
ftl::Closure callback) {
if (!framebuffer_.surface()) {
FTL_DCHECK(layer_tree);
if (!scene_) {
callback();
return;
}
SkCanvas* canvas = framebuffer_.surface()->getCanvas();
flow::CompositorContext::ScopedFrame frame =
compositor_context_.AcquireFrame(nullptr, *canvas);
canvas->clear(SK_ColorBLACK);
layer_tree->Raster(frame);
canvas->flush();
const SkISize& frame_size = layer_tree->frame_size();
auto update = mozart::SceneUpdate::New();
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();
mojo::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();
update->resources.insert(kContentImageResourceId, content_resource.Pass());
auto root_node = mozart::Node::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;
update->nodes.insert(kRootNodeId, root_node.Pass());
layer_tree->UpdateScene(update.get(), root_node.get());
} else {
auto root_node = mozart::Node::New();
update->nodes.insert(kRootNodeId, root_node.Pass());
}
scene_->Update(std::move(update));
auto metadata = mozart::SceneMetadata::New();
metadata->version = layer_tree->scene_version();
scene_->Publish(std::move(metadata));
framebuffer_.Finish();
callback();
}
+3 -7
View File
@@ -5,13 +5,11 @@
#ifndef FLUTTER_CONTENT_HANDLER_RASTERIZER_H_
#define FLUTTER_CONTENT_HANDLER_RASTERIZER_H_
#include "flutter/content_handler/framebuffer_skia.h"
#include "apps/mozart/services/composition/interfaces/scenes.mojom.h"
#include "flutter/flow/compositor_context.h"
#include "flutter/flow/layers/layer_tree.h"
#include "lib/ftl/functional/closure.h"
#include "lib/ftl/macros.h"
#include "mojo/services/framebuffer/interfaces/framebuffer.mojom.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter_content_handler {
@@ -20,14 +18,12 @@ class Rasterizer {
Rasterizer();
~Rasterizer();
void SetFramebuffer(mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info);
void SetScene(mojo::InterfaceHandle<mozart::Scene> scene);
void Draw(std::unique_ptr<flow::LayerTree> layer_tree, ftl::Closure callback);
private:
FramebufferSkia framebuffer_;
sk_sp<SkSurface> surface_;
mozart::ScenePtr scene_;
flow::CompositorContext compositor_context_;
FTL_DISALLOW_COPY_AND_ASSIGN(Rasterizer);
+90 -58
View File
@@ -24,14 +24,20 @@ namespace flutter_content_handler {
namespace {
constexpr char kSnapshotKey[] = "snapshot_blob.bin";
constexpr int kPipelineDepth = 3;
constexpr ftl::TimeDelta kTargetFrameInterval =
ftl::TimeDelta::FromMilliseconds(16);
// Maximum number of frames in flight.
constexpr int kMaxPipelineDepth = 3;
// When the max pipeline depth is exceeded, drain to this number of frames
// to recover before acknowleding the invalidation and scheduling more frames.
constexpr int kRecoveryPipelineDepth = 1;
} // namespace
RuntimeHolder::RuntimeHolder()
: viewport_metrics_(sky::ViewportMetrics::New()), weak_factory_(this) {}
: viewport_metrics_(sky::ViewportMetrics::New()),
view_listener_binding_(this),
weak_factory_(this) {}
RuntimeHolder::~RuntimeHolder() {
blink::Threads::Gpu()->PostTask(
@@ -40,22 +46,26 @@ RuntimeHolder::~RuntimeHolder() {
}));
}
void RuntimeHolder::Init(mojo::ApplicationConnectorPtr connector) {
void RuntimeHolder::Init(mojo::ApplicationConnectorPtr connector,
std::vector<char> bundle) {
FTL_DCHECK(!rasterizer_);
rasterizer_.reset(new Rasterizer());
mojo::ConnectToService(connector.get(), "mojo:framebuffer",
mojo::GetProxy(&framebuffer_provider_));
framebuffer_provider_->Create(ftl::MakeRunnable([self = GetWeakPtr()](
mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info) {
if (self)
self->DidCreateFramebuffer(std::move(framebuffer), std::move(info));
}));
InitRootBundle(std::move(bundle));
mojo::ConnectToService(connector.get(), "mojo:view_manager_service",
mojo::GetProxy(&view_manager_));
}
void RuntimeHolder::Run(const std::string& script_uri,
std::vector<char> bundle) {
InitRootBundle(std::move(bundle));
void RuntimeHolder::CreateView(
const std::string& script_uri,
mojo::InterfaceRequest<mozart::ViewOwner> view_owner_request,
mojo::InterfaceRequest<mojo::ServiceProvider> services) {
if (view_listener_binding_.is_bound()) {
// TODO(jeffbrown): Refactor this to support multiple view instances
// sharing the same underlying root bundle (but with different runtimes).
FTL_LOG(ERROR) << "The view has already been created.";
return;
}
std::vector<uint8_t> snapshot;
if (!asset_store_->GetAsBuffer(kSnapshotKey, &snapshot)) {
@@ -63,6 +73,18 @@ void RuntimeHolder::Run(const std::string& script_uri,
return;
}
mozart::ViewListenerPtr view_listener;
view_listener_binding_.Bind(mojo::GetProxy(&view_listener));
view_manager_->CreateView(mojo::GetProxy(&view_),
std::move(view_owner_request),
std::move(view_listener), script_uri);
mozart::ScenePtr scene;
view_->CreateScene(mojo::GetProxy(&scene));
blink::Threads::Gpu()->PostTask(ftl::MakeCopyable([
rasterizer = rasterizer_.get(), scene = std::move(scene)
]() mutable { rasterizer->SetScene(std::move(scene)); }));
runtime_ = blink::RuntimeController::Create(this);
runtime_->CreateDartController(script_uri);
runtime_->SetViewportMetrics(viewport_metrics_);
@@ -71,19 +93,10 @@ void RuntimeHolder::Run(const std::string& script_uri,
}
void RuntimeHolder::ScheduleFrame() {
if (runtime_requested_frame_)
if (pending_invalidation_ || !deferred_invalidation_callback_.is_null())
return;
runtime_requested_frame_ = true;
FTL_DCHECK(!did_defer_frame_request_);
++outstanding_requests_;
if (outstanding_requests_ >= kPipelineDepth) {
did_defer_frame_request_ = true;
return;
}
ScheduleDelayedFrame();
pending_invalidation_ = true;
view_->Invalidate();
}
void RuntimeHolder::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
@@ -91,6 +104,10 @@ void RuntimeHolder::Render(std::unique_ptr<flow::LayerTree> layer_tree) {
return; // Only draw once per frame.
is_ready_to_draw_ = false;
layer_tree->set_frame_size(SkISize::Make(viewport_metrics_->physical_width,
viewport_metrics_->physical_height));
layer_tree->set_scene_version(scene_version_);
blink::Threads::Gpu()->PostTask(ftl::MakeCopyable([
rasterizer = rasterizer_.get(), layer_tree = std::move(layer_tree),
self = GetWeakPtr()
@@ -129,42 +146,51 @@ blink::UnzipperProvider RuntimeHolder::GetUnzipperProviderForRootBundle() {
};
}
void RuntimeHolder::DidCreateFramebuffer(
mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info) {
viewport_metrics_->physical_width = info->size->width;
viewport_metrics_->physical_height = info->size->height;
if (runtime_)
runtime_->SetViewportMetrics(viewport_metrics_);
void RuntimeHolder::OnInvalidation(mozart::ViewInvalidationPtr invalidation,
const OnInvalidationCallback& callback) {
FTL_DCHECK(invalidation);
pending_invalidation_ = false;
blink::Threads::Gpu()->PostTask(ftl::MakeCopyable([
rasterizer = rasterizer_.get(), framebuffer = std::move(framebuffer),
info = std::move(info)
]() mutable {
rasterizer->SetFramebuffer(std::move(framebuffer), std::move(info));
}));
// Apply view property changes.
if (invalidation->properties) {
view_properties_ = std::move(invalidation->properties);
viewport_metrics_->physical_width =
view_properties_->view_layout->size->width;
viewport_metrics_->physical_height =
view_properties_->view_layout->size->height;
viewport_metrics_->device_pixel_ratio =
view_properties_->display_metrics->device_pixel_ratio;
runtime_->SetViewportMetrics(viewport_metrics_);
}
// Remember the scene version for rendering.
scene_version_ = invalidation->scene_version;
// TODO(jeffbrown): Flow the frame time through the rendering pipeline.
if (outstanding_requests_ >= kMaxPipelineDepth) {
FTL_DCHECK(deferred_invalidation_callback_.is_null());
deferred_invalidation_callback_ = callback;
return;
}
++outstanding_requests_;
BeginFrame();
// TODO(jeffbrown): Consider running the callback earlier.
// Note that this may result in the view processing stale view properties
// (such as size) if it prematurely acks the frame but takes too long
// to handle it.
callback.Run();
}
ftl::WeakPtr<RuntimeHolder> RuntimeHolder::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
void RuntimeHolder::ScheduleDelayedFrame() {
// TODO(abarth): We should align with vsync or with our own timer pulse.
blink::Threads::UI()->PostDelayedTask(
[self = GetWeakPtr()]() {
if (self)
self->BeginFrame();
},
kTargetFrameInterval);
}
void RuntimeHolder::BeginFrame() {
FTL_DCHECK(outstanding_requests_ > 0);
FTL_DCHECK(outstanding_requests_ <= kPipelineDepth) << outstanding_requests_;
FTL_DCHECK(runtime_requested_frame_);
runtime_requested_frame_ = false;
FTL_DCHECK(outstanding_requests_ <= kMaxPipelineDepth)
<< outstanding_requests_;
FTL_DCHECK(!is_ready_to_draw_);
is_ready_to_draw_ = true;
@@ -183,9 +209,15 @@ void RuntimeHolder::OnFrameComplete() {
FTL_DCHECK(outstanding_requests_ > 0);
--outstanding_requests_;
if (did_defer_frame_request_) {
did_defer_frame_request_ = false;
ScheduleDelayedFrame();
if (!deferred_invalidation_callback_.is_null() &&
outstanding_requests_ <= kRecoveryPipelineDepth) {
// Schedule frame first to avoid potentially generating a second
// invalidation in case the view manager already has one pending
// awaiting acknowledgement of the deferred invalidation.
OnInvalidationCallback callback = deferred_invalidation_callback_;
deferred_invalidation_callback_.reset();
ScheduleFrame();
callback.Run();
}
}
+20 -12
View File
@@ -5,6 +5,7 @@
#ifndef FLUTTER_CONTENT_HANDLER_RUNTIME_HOLDER_H_
#define FLUTTER_CONTENT_HANDLER_RUNTIME_HOLDER_H_
#include "apps/mozart/services/views/interfaces/view_manager.mojom.h"
#include "flutter/assets/unzipper_provider.h"
#include "flutter/assets/zip_asset_store.h"
#include "flutter/flow/layers/layer_tree.h"
@@ -14,20 +15,22 @@
#include "lib/ftl/functional/closure.h"
#include "lib/ftl/macros.h"
#include "lib/ftl/memory/weak_ptr.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/interfaces/application/application_connector.mojom.h"
#include "mojo/services/asset_bundle/interfaces/asset_bundle.mojom.h"
#include "mojo/services/framebuffer/interfaces/framebuffer.mojom.h"
namespace flutter_content_handler {
class Rasterizer;
class RuntimeHolder : public blink::RuntimeDelegate {
class RuntimeHolder : public blink::RuntimeDelegate, mozart::ViewListener {
public:
RuntimeHolder();
~RuntimeHolder();
void Init(mojo::ApplicationConnectorPtr connector);
void Run(const std::string& script_uri, std::vector<char> bundle);
void Init(mojo::ApplicationConnectorPtr connector, std::vector<char> bundle);
void CreateView(const std::string& script_uri,
mojo::InterfaceRequest<mozart::ViewOwner> view_owner_request,
mojo::InterfaceRequest<mojo::ServiceProvider> services);
private:
// |blink::RuntimeDelegate| implementation:
@@ -35,30 +38,35 @@ class RuntimeHolder : public blink::RuntimeDelegate {
void Render(std::unique_ptr<flow::LayerTree> layer_tree) override;
void DidCreateMainIsolate(Dart_Isolate isolate) override;
// |mozart::ViewListener| implementation:
void OnInvalidation(mozart::ViewInvalidationPtr invalidation,
const OnInvalidationCallback& callback) override;
ftl::WeakPtr<RuntimeHolder> GetWeakPtr();
void InitRootBundle(std::vector<char> bundle);
blink::UnzipperProvider GetUnzipperProviderForRootBundle();
void DidCreateFramebuffer(
mojo::InterfaceHandle<mojo::Framebuffer> framebuffer,
mojo::FramebufferInfoPtr info);
void ScheduleDelayedFrame();
void BeginFrame();
void OnFrameComplete();
void Invalidate();
std::vector<char> root_bundle_data_;
ftl::RefPtr<blink::ZipAssetStore> asset_store_;
mojo::asset_bundle::AssetBundlePtr root_bundle_;
mojo::FramebufferProviderPtr framebuffer_provider_;
std::unique_ptr<Rasterizer> rasterizer_;
std::unique_ptr<blink::RuntimeController> runtime_;
sky::ViewportMetricsPtr viewport_metrics_;
bool runtime_requested_frame_ = false;
bool did_defer_frame_request_ = false;
mozart::ViewManagerPtr view_manager_;
mojo::Binding<mozart::ViewListener> view_listener_binding_;
mozart::ViewPtr view_;
mozart::ViewPropertiesPtr view_properties_;
uint32_t scene_version_ = mozart::kSceneVersionNone;
bool pending_invalidation_ = false;
OnInvalidationCallback deferred_invalidation_callback_;
bool is_ready_to_draw_ = false;
int outstanding_requests_ = 0;
+48
View File
@@ -0,0 +1,48 @@
// 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 "lib/ftl/logging.h"
#include "mojo/public/cpp/system/buffer.h"
#include "third_party/skia/include/core/SkCanvas.h"
namespace flutter_content_handler {
SkiaSurfaceHolder::SkiaSurfaceHolder(const SkISize& size) {
size_t row_bytes = size.width() * sizeof(uint32_t);
size_t total_bytes = size.height() * row_bytes;
FTL_CHECK(MOJO_RESULT_OK ==
mojo::CreateSharedBuffer(nullptr, total_bytes, &buffer_handle_));
FTL_CHECK(MOJO_RESULT_OK == mojo::MapBuffer(buffer_handle_.get(), 0u,
total_bytes, &buffer_,
MOJO_MAP_BUFFER_FLAG_NONE));
surface_ = SkSurface::MakeRasterDirect(
SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType,
kPremul_SkAlphaType),
buffer_, row_bytes);
FTL_CHECK(surface_);
}
SkiaSurfaceHolder::~SkiaSurfaceHolder() {
FTL_CHECK(MOJO_RESULT_OK == mojo::UnmapBuffer(buffer_));
}
mozart::ImagePtr SkiaSurfaceHolder::TakeImage() {
FTL_DCHECK(buffer_handle_.get().value());
auto image = mozart::Image::New();
image->size = mojo::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(buffer_handle_);
return image;
}
} // namespace flutter_content_handler
+47
View File
@@ -0,0 +1,47 @@
// 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 "apps/mozart/services/composition/interfaces/image.mojom.h"
#include "lib/ftl/macros.h"
#include "mojo/services/geometry/interfaces/geometry.mojom.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter_content_handler {
// 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:
mojo::ScopedSharedBufferHandle buffer_handle_;
void* buffer_;
sk_sp<SkSurface> surface_;
FTL_DISALLOW_COPY_AND_ASSIGN(SkiaSurfaceHolder);
};
} // namespace flutter_content_handler
#endif // FLUTTER_CONTENT_HANDLER_SKIA_SURFACE_HOLDER_H_
+5 -3
View File
@@ -10,8 +10,6 @@ source_set("flow") {
"instrumentation.h",
"layers/backdrop_filter_layer.cc",
"layers/backdrop_filter_layer.h",
"layers/child_scene_layer.cc",
"layers/child_scene_layer.h",
"layers/clip_path_layer.cc",
"layers/clip_path_layer.h",
"layers/clip_rect_layer.cc",
@@ -48,13 +46,17 @@ source_set("flow") {
"//flutter/skia",
"//flutter/synchronization",
"//lib/ftl",
"//mojo/services/gfx/composition/interfaces",
]
if (is_fuchsia) {
sources += [
"layers/child_scene_layer.cc",
"layers/child_scene_layer.h",
"texture_image_none.cc",
]
deps += [
"//apps/mozart/services/composition/interfaces",
]
} else {
sources += [
"gl_connection.cc",
+9 -8
View File
@@ -50,18 +50,19 @@ void ChildSceneLayer::Paint(PaintContext& context) {
TRACE_EVENT0("flutter", "ChildSceneLayer::Paint");
}
void ChildSceneLayer::UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container) {
void ChildSceneLayer::UpdateScene(mozart::SceneUpdate* update,
mozart::Node* container) {
uint32_t id = next_id++;
auto child_resource = mojo::gfx::composition::Resource::New();
child_resource->set_scene(mojo::gfx::composition::SceneResource::New());
child_resource->get_scene()->scene_token = scene_token_.Clone();
auto child_resource = mozart::Resource::New();
child_resource->set_scene(mozart::SceneResource::New());
child_resource->get_scene()->scene_token = mozart::SceneToken::New();
child_resource->get_scene()->scene_token->value = scene_token_;
update->resources.insert(id, child_resource.Pass());
auto child_node = mojo::gfx::composition::Node::New();
child_node->op = mojo::gfx::composition::NodeOp::New();
child_node->op->set_scene(mojo::gfx::composition::SceneNodeOp::New());
auto child_node = mozart::Node::New();
child_node->op = mozart::NodeOp::New();
child_node->op->set_scene(mozart::SceneNodeOp::New());
child_node->op->get_scene()->scene_resource_id = id;
child_node->content_clip = mojo::RectF::New();
child_node->content_clip->width = physical_size_.width();
+5 -7
View File
@@ -6,7 +6,7 @@
#define FLUTTER_FLOW_LAYERS_CHILD_SCENE_LAYER_H_
#include "flutter/flow/layers/layer.h"
#include "mojo/services/gfx/composition/interfaces/scenes.mojom.h"
#include "apps/mozart/services/composition/interfaces/scenes.mojom.h"
namespace flow {
@@ -25,20 +25,18 @@ class ChildSceneLayer : public Layer {
physical_size_ = physical_size;
}
void set_scene_token(mojo::gfx::composition::SceneTokenPtr scene_token) {
scene_token_ = scene_token.Pass();
}
void set_scene_token(uint32_t scene_token) { scene_token_ = scene_token; }
void Preroll(PrerollContext* context, const SkMatrix& matrix) override;
void Paint(PaintContext& context) override;
void UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container) override;
void UpdateScene(mozart::SceneUpdate* update,
mozart::Node* container) override;
private:
SkPoint offset_;
float device_pixel_ratio_;
SkISize physical_size_;
mojo::gfx::composition::SceneTokenPtr scene_token_;
uint32_t scene_token_;
SkMatrix transform_;
FTL_DISALLOW_COPY_AND_ASSIGN(ChildSceneLayer);
+4 -2
View File
@@ -39,10 +39,12 @@ void ContainerLayer::PaintChildren(PaintContext& context) const {
layer->Paint(context);
}
void ContainerLayer::UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container) {
#if defined(OS_FUCHSIA)
void ContainerLayer::UpdateScene(mozart::SceneUpdate* update,
mozart::Node* container) {
for (auto& layer : layers_)
layer->UpdateScene(update, container);
}
#endif
} // namespace flow
+4 -2
View File
@@ -22,8 +22,10 @@ class ContainerLayer : public Layer {
void PaintChildren(PaintContext& context) const;
void UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container) override;
#if defined(OS_FUCHSIA)
void UpdateScene(mozart::SceneUpdate* update,
mozart::Node* container) override;
#endif
const std::vector<std::unique_ptr<Layer>>& layers() const { return layers_; }
+3 -2
View File
@@ -14,7 +14,8 @@ Layer::~Layer() {}
void Layer::Preroll(PrerollContext* context, const SkMatrix& matrix) {}
void Layer::UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container) {}
#if defined(OS_FUCHSIA)
void Layer::UpdateScene(mozart::SceneUpdate* update, mozart::Node* container) {}
#endif
} // namespace flow
+10 -8
View File
@@ -11,6 +11,7 @@
#include "flutter/flow/instrumentation.h"
#include "flutter/flow/raster_cache.h"
#include "flutter/glue/trace_event.h"
#include "lib/ftl/build_config.h"
#include "lib/ftl/logging.h"
#include "lib/ftl/macros.h"
#include "third_party/skia/include/core/SkCanvas.h"
@@ -23,14 +24,12 @@
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkXfermode.h"
namespace mojo {
namespace gfx {
namespace composition {
#if defined(OS_FUCHSIA)
namespace mozart {
class SceneUpdate;
class Node;
} // composition
} // namespace gfx
} // namespace mojo
} // namespace mozart
#endif
namespace flow {
@@ -55,8 +54,11 @@ class Layer {
};
virtual void Paint(PaintContext& context) = 0;
virtual void UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container);
#if defined(OS_FUCHSIA)
virtual void UpdateScene(mozart::SceneUpdate* update,
mozart::Node* container);
#endif
ContainerLayer* parent() const { return parent_; }
+6 -3
View File
@@ -9,7 +9,8 @@
namespace flow {
LayerTree::LayerTree() : scene_version_(0), rasterizer_tracing_threshold_(0) {}
LayerTree::LayerTree()
: frame_size_{}, scene_version_(0), rasterizer_tracing_threshold_(0) {}
LayerTree::~LayerTree() {}
@@ -32,10 +33,12 @@ void LayerTree::Raster(CompositorContext::ScopedFrame& frame,
}
}
void LayerTree::UpdateScene(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container) {
#if defined(OS_FUCHSIA)
void LayerTree::UpdateScene(mozart::SceneUpdate* update,
mozart::Node* container) {
TRACE_EVENT0("flutter", "LayerTree::UpdateScene");
root_layer_->UpdateScene(update, container);
}
#endif
} // namespace flow
+3 -2
View File
@@ -26,11 +26,12 @@ class LayerTree {
void Raster(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(mojo::gfx::composition::SceneUpdate* update,
mojo::gfx::composition::Node* container);
void UpdateScene(mozart::SceneUpdate* update, mozart::Node* container);
#endif
Layer* root_layer() const { return root_layer_.get(); }

Some files were not shown because too many files have changed in this diff Show More