Skip to content

Commit

Permalink
Add a Vulkan backend for Fuchsia and Android. (flutter#3282)
Browse files Browse the repository at this point in the history
  • Loading branch information
chinmaygarde authored Jan 20, 2017
1 parent dd106ae commit 94306f4
Show file tree
Hide file tree
Showing 70 changed files with 4,035 additions and 1,085 deletions.
30 changes: 26 additions & 4 deletions content_handler/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@

assert(is_fuchsia)

declare_args() {
flutter_enable_vulkan = false
}

executable("content_handler") {
output_name = "flutter_runner"

defines = []

sources = [
"app.cc",
"app.h",
Expand All @@ -17,6 +23,8 @@ executable("content_handler") {
"rasterizer.h",
"runtime_holder.cc",
"runtime_holder.h",
"software_rasterizer.cc",
"software_rasterizer.h",
]

deps = [
Expand All @@ -29,6 +37,10 @@ executable("content_handler") {
"//apps/mozart/services/views",
"//apps/tracing/lib/trace:provider",
"//dart/runtime:libdart",

# TODO(abarth): We shouldn't need to depend on libdart_builtin but we fail
# to link otherwise.
"//dart/runtime/bin:libdart_builtin",
"//dart/runtime/vm:libdart_platform",
"//flutter/assets",
"//flutter/common",
Expand All @@ -44,9 +56,19 @@ executable("content_handler") {
"//lib/zip",
"//third_party/rapidjson",
"//third_party/skia",

# TODO(abarth): We shouldn't need to depend on libdart_builtin but we fail
# to link otherwise.
"//dart/runtime/bin:libdart_builtin",
]

if (flutter_enable_vulkan) {
defines += [ "FLUTTER_ENABLE_VULKAN" ]

sources += [
"vulkan_rasterizer.cc",
"vulkan_rasterizer.h",
]

deps += [
"//flutter/vulkan",
"//magma:vulkan",
]
}
}
78 changes: 17 additions & 61 deletions content_handler/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,76 +4,32 @@

#include "flutter/content_handler/rasterizer.h"

#include <utility>
#include "flutter/content_handler/software_rasterizer.h"

#include "apps/mozart/lib/skia/skia_vmo_surface.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
#if FLUTTER_ENABLE_VULKAN
#include "flutter/content_handler/vulkan_rasterizer.h"
#endif // FLUTTER_ENABLE_VULKAN

namespace flutter_runner {

Rasterizer::Rasterizer() : compositor_context_(nullptr) {}
Rasterizer::~Rasterizer() = default;

Rasterizer::~Rasterizer() {}
std::unique_ptr<Rasterizer> Rasterizer::Create() {
#if FLUTTER_ENABLE_VULKAN
auto vulkan_rasterizer = std::make_unique<VulkanRasterizer>();

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,
ftl::Closure callback) {
FTL_DCHECK(layer_tree);
if (!scene_) {
callback();
return;
}

const SkISize& frame_size = layer_tree->frame_size();

auto update = mozart::SceneUpdate::New();
// TODO(abarth): Support incremental updates.
update->clear_resources = true;
update->clear_nodes = true;

if (frame_size.isEmpty()) {
update->nodes.insert(mozart::kSceneRootNodeId, 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;
if (!vulkan_rasterizer->IsValid()) {
FTL_DLOG(INFO) << "Could not initialize a valid vulkan rasterizer. "
"Attempting to fallback to the software rasterizer.";
return std::make_unique<SoftwareRasterizer>();
}

flow::CompositorContext::ScopedFrame frame =
compositor_context_.AcquireFrame(nullptr, nullptr);

layer_tree->Preroll(frame);

flow::SceneUpdateContext context(update.get(), buffer_producer_.get());
auto root_node = mozart::Node::New();
root_node->hit_test_behavior = mozart::HitTestBehavior::New();
layer_tree->UpdateScene(context, root_node.get());
update->nodes.insert(mozart::kSceneRootNodeId, 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));
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.
context.ExecutePaintTasks(frame);
buffer_producer_->Tick();
FTL_DLOG(INFO) << "Successfully initialized a valid vulkan rasterizer.";

callback();
return vulkan_rasterizer;
#else // FLUTTER_ENABLE_VULKAN
return std::make_unique<SoftwareRasterizer>();
#endif // FLUTTER_ENABLE_VULKAN
}

} // namespace flutter_runner
17 changes: 5 additions & 12 deletions content_handler/rasterizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@

#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"
#include "lib/ftl/functional/closure.h"
#include "lib/ftl/macros.h"
Expand All @@ -18,19 +16,14 @@ namespace flutter_runner {

class Rasterizer {
public:
Rasterizer();
~Rasterizer();
virtual ~Rasterizer();

void SetScene(fidl::InterfaceHandle<mozart::Scene> scene);
static std::unique_ptr<Rasterizer> Create();

void Draw(std::unique_ptr<flow::LayerTree> layer_tree, ftl::Closure callback);
virtual void SetScene(fidl::InterfaceHandle<mozart::Scene> scene) = 0;

private:
mozart::ScenePtr scene_;
std::unique_ptr<mozart::BufferProducer> buffer_producer_;
flow::CompositorContext compositor_context_;

FTL_DISALLOW_COPY_AND_ASSIGN(Rasterizer);
virtual void Draw(std::unique_ptr<flow::LayerTree> layer_tree,
ftl::Closure callback) = 0;
};

} // namespace flutter_runner
Expand Down
3 changes: 2 additions & 1 deletion content_handler/runtime_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ void RuntimeHolder::Init(
fidl::InterfaceRequest<modular::ServiceProvider> outgoing_services,
std::vector<char> bundle) {
FTL_DCHECK(!rasterizer_);
rasterizer_.reset(new Rasterizer());
rasterizer_ = Rasterizer::Create();
FTL_DCHECK(rasterizer_);

environment_.Bind(std::move(environment));
environment_->GetServices(fidl::GetProxy(&environment_services_));
Expand Down
80 changes: 80 additions & 0 deletions content_handler/software_rasterizer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright 2017 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/software_rasterizer.h"

#include <memory>
#include <utility>

#include "apps/mozart/lib/skia/skia_vmo_surface.h"
#include "lib/ftl/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"

namespace flutter_runner {

SoftwareRasterizer::SoftwareRasterizer() : compositor_context_(nullptr) {}

SoftwareRasterizer::~SoftwareRasterizer() = default;

void SoftwareRasterizer::SetScene(fidl::InterfaceHandle<mozart::Scene> scene) {
scene_.Bind(std::move(scene));
buffer_producer_.reset(new mozart::BufferProducer());
}

void SoftwareRasterizer::Draw(std::unique_ptr<flow::LayerTree> layer_tree,
ftl::Closure callback) {
FTL_DCHECK(layer_tree);
if (!scene_) {
callback();
return;
}

const SkISize& frame_size = layer_tree->frame_size();

auto update = mozart::SceneUpdate::New();
// TODO(abarth): Support incremental updates.
update->clear_resources = true;
update->clear_nodes = true;

if (frame_size.isEmpty()) {
update->nodes.insert(mozart::kSceneRootNodeId, 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;
}

flow::CompositorContext::ScopedFrame frame =
compositor_context_.AcquireFrame(nullptr, nullptr);

layer_tree->Preroll(frame);

flow::SceneUpdateContext context(update.get(), buffer_producer_.get());
auto root_node = mozart::Node::New();
root_node->hit_test_behavior = mozart::HitTestBehavior::New();
layer_tree->UpdateScene(context, root_node.get());
update->nodes.insert(mozart::kSceneRootNodeId, 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));
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.
context.ExecutePaintTasks(frame);
buffer_producer_->Tick();

callback();
}

} // namespace flutter_runner
38 changes: 38 additions & 0 deletions content_handler/software_rasterizer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2017 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_SOFTWARE_RASTERIZER_H_
#define FLUTTER_CONTENT_HANDLER_SOFTWARE_RASTERIZER_H_

#include <memory>

#include "apps/mozart/services/buffers/cpp/buffer_producer.h"
#include "flutter/content_handler/rasterizer.h"
#include "flutter/flow/compositor_context.h"
#include "lib/ftl/macros.h"

namespace flutter_runner {

class SoftwareRasterizer : public Rasterizer {
public:
SoftwareRasterizer();

~SoftwareRasterizer() override;

void SetScene(fidl::InterfaceHandle<mozart::Scene> scene) override;

void Draw(std::unique_ptr<flow::LayerTree> layer_tree,
ftl::Closure callback) override;

private:
mozart::ScenePtr scene_;
std::unique_ptr<mozart::BufferProducer> buffer_producer_;
flow::CompositorContext compositor_context_;

FTL_DISALLOW_COPY_AND_ASSIGN(SoftwareRasterizer);
};

} // namespace flutter_runner

#endif // FLUTTER_CONTENT_HANDLER_SOFTWARE_RASTERIZER_H_
Loading

0 comments on commit 94306f4

Please sign in to comment.