Skip to content

Commit

Permalink
[Impeller] libImpeller: Add support for Metal and Vulkan rendering.
Browse files Browse the repository at this point in the history
The tests were already parameterized. This enables the remaining backends.

Fixes flutter/flutter#159512
  • Loading branch information
chinmaygarde committed Dec 2, 2024
1 parent 05fdaa6 commit 43ea25f
Show file tree
Hide file tree
Showing 27 changed files with 618 additions and 126 deletions.
10 changes: 9 additions & 1 deletion impeller/playground/backend/vulkan/playground_impl_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ PlaygroundImplVK::PlaygroundImplVK(PlaygroundSwitches switches)
context_settings.enable_validation = switches_.enable_vulkan_validation;
context_settings.fatal_missing_validations =
switches_.enable_vulkan_validation;
;

auto context_vk = ContextVK::Create(std::move(context_settings));
if (!context_vk || !context_vk->IsValid()) {
Expand Down Expand Up @@ -233,4 +232,13 @@ bool PlaygroundImplVK::IsVulkanDriverPresent() {
return false;
}

// |PlaygroundImpl|
Playground::VKProcAddressResolver
PlaygroundImplVK::CreateVKProcAddressResolver() const {
return [](void* instance, const char* proc_name) -> void* {
return reinterpret_cast<void*>(::glfwGetInstanceProcAddress(
reinterpret_cast<VkInstance>(instance), proc_name));
};
}

} // namespace impeller
4 changes: 4 additions & 0 deletions impeller/playground/backend/vulkan/playground_impl_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ class PlaygroundImplVK final : public PlaygroundImpl {
std::unique_ptr<Surface> AcquireSurfaceFrame(
std::shared_ptr<Context> context) override;

// |PlaygroundImpl|
Playground::VKProcAddressResolver CreateVKProcAddressResolver()
const override;

PlaygroundImplVK(const PlaygroundImplVK&) = delete;

PlaygroundImplVK& operator=(const PlaygroundImplVK&) = delete;
Expand Down
5 changes: 5 additions & 0 deletions impeller/playground/playground.cc
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,9 @@ Playground::GLProcAddressResolver Playground::CreateGLProcAddressResolver()
return impl_->CreateGLProcAddressResolver();
}

Playground::VKProcAddressResolver Playground::CreateVKProcAddressResolver()
const {
return impl_->CreateVKProcAddressResolver();
}

} // namespace impeller
4 changes: 4 additions & 0 deletions impeller/playground/playground.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class Playground {
using GLProcAddressResolver = std::function<void*(const char* proc_name)>;
GLProcAddressResolver CreateGLProcAddressResolver() const;

using VKProcAddressResolver =
std::function<void*(void* instance, const char* proc_name)>;
VKProcAddressResolver CreateVKProcAddressResolver() const;

protected:
const PlaygroundSwitches switches_;

Expand Down
5 changes: 5 additions & 0 deletions impeller/playground/playground_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,9 @@ Playground::GLProcAddressResolver PlaygroundImpl::CreateGLProcAddressResolver()
return nullptr;
}

Playground::VKProcAddressResolver PlaygroundImpl::CreateVKProcAddressResolver()
const {
return nullptr;
}

} // namespace impeller
2 changes: 2 additions & 0 deletions impeller/playground/playground_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ class PlaygroundImpl {

virtual Playground::GLProcAddressResolver CreateGLProcAddressResolver() const;

virtual Playground::VKProcAddressResolver CreateVKProcAddressResolver() const;

protected:
const PlaygroundSwitches switches_;

Expand Down
3 changes: 2 additions & 1 deletion impeller/renderer/backend/vulkan/context_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ void ContextVK::Setup(Settings settings) {
TRACE_EVENT0("impeller", "ContextVK::Setup");

if (!settings.proc_address_callback) {
VALIDATION_LOG << "Missing proc address callback.";
return;
}

Expand All @@ -152,7 +153,7 @@ void ContextVK::Setup(Settings settings) {
fml::RequestAffinity(fml::CpuAffinity::kNotPerformance);
#ifdef FML_OS_ANDROID
if (::setpriority(PRIO_PROCESS, gettid(), -5) != 0) {
FML_LOG(ERROR) << "Failed to set Workers task runner priority";
VALIDATION_LOG << "Failed to set Workers task runner priority";
}
#endif // FML_OS_ANDROID
});
Expand Down
30 changes: 23 additions & 7 deletions impeller/toolkit/interop/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,21 @@ embed_blob("embedded_icu_data") {
deps = []
}

impeller_component("interop") {
# The public C/C++ Impeller API.
impeller_component("interop_api") {
public = [
"impeller.h",
"impeller.hpp",
]

sources = [
"impeller_c.c",
"impeller_cc.cc",
]
}

# The common base used by all interop backends.
impeller_component("interop_base") {
sources = [
"color_filter.cc",
"color_filter.h",
Expand All @@ -29,11 +43,6 @@ impeller_component("interop") {
"formats.h",
"image_filter.cc",
"image_filter.h",
"impeller.cc",
"impeller.h",
"impeller.hpp",
"impeller_c.c",
"impeller_cc.cc",
"mask_filter.cc",
"mask_filter.h",
"object.cc",
Expand All @@ -59,6 +68,8 @@ impeller_component("interop") {
]

public_deps = [
":embedded_icu_data",
":interop_api",
"../../base",
"../../display_list",
"../../entity",
Expand All @@ -67,8 +78,13 @@ impeller_component("interop") {
"//flutter/fml",
"//flutter/third_party/txt",
]
}

deps = [ ":embedded_icu_data" ]
# Wires up the public API entrypoints to the appropriate backends.
impeller_component("interop") {
sources = [ "impeller.cc" ]
public_deps = [ ":interop_base" ]
deps = [ "backend" ]
}

impeller_component("library") {
Expand Down
21 changes: 21 additions & 0 deletions impeller/toolkit/interop/backend/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//flutter/impeller/tools/impeller.gni")

group("backend") {
public_deps = []

if (impeller_enable_metal) {
public_deps += [ "metal" ]
}

if (impeller_enable_opengles) {
public_deps += [ "gles" ]
}

if (impeller_enable_vulkan) {
public_deps += [ "vulkan" ]
}
}
15 changes: 15 additions & 0 deletions impeller/toolkit/interop/backend/gles/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//flutter/impeller/tools/impeller.gni")

impeller_component("gles") {
public_deps = [ "../../:interop_base" ]
sources = [
"context_gles.cc",
"context_gles.h",
"reactor_worker_gles.cc",
"reactor_worker_gles.h",
]
}
61 changes: 61 additions & 0 deletions impeller/toolkit/interop/backend/gles/context_gles.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2013 The Flutter 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 "impeller/toolkit/interop/backend/gles/context_gles.h"

#include "impeller/base/validation.h"
#include "impeller/entity/gles/entity_shaders_gles.h"
#include "impeller/entity/gles/framebuffer_blend_shaders_gles.h"
#include "impeller/renderer/backend/gles/context_gles.h"

namespace impeller::interop {

ScopedObject<Context> ContextGLES::Create(
std::function<void*(const char* gl_proc_name)> proc_address_callback) {
auto proc_table = std::make_unique<ProcTableGLES>(
impeller::ProcTableGLES(std::move(proc_address_callback)));
if (!proc_table || !proc_table->IsValid()) {
VALIDATION_LOG << "Could not create valid OpenGL ES proc. table.";
return {};
}
std::vector<std::shared_ptr<fml::Mapping>> shader_mappings = {
std::make_shared<fml::NonOwnedMapping>(
impeller_entity_shaders_gles_data,
impeller_entity_shaders_gles_length),
std::make_shared<fml::NonOwnedMapping>(
impeller_framebuffer_blend_shaders_gles_data,
impeller_framebuffer_blend_shaders_gles_length),
};
auto impeller_context = impeller::ContextGLES::Create(std::move(proc_table),
shader_mappings, false);
if (!impeller_context) {
VALIDATION_LOG << "Could not create Impeller context.";
return {};
}
auto reactor_worker = std::make_shared<ReactorWorkerGLES>();
auto worker_id = impeller_context->AddReactorWorker(reactor_worker);
if (!worker_id.has_value()) {
VALIDATION_LOG << "Could not add reactor worker.";
return {};
}

// Can't call Create because of private constructor. Adopt the raw pointer
// instead.
auto context = Adopt<Context>(
new ContextGLES(std::move(impeller_context), std::move(reactor_worker)));

if (!context->IsValid()) {
VALIDATION_LOG << "Could not create valid context.";
return {};
}
return context;
}

ContextGLES::ContextGLES(std::shared_ptr<impeller::Context> context,
std::shared_ptr<ReactorWorkerGLES> worker)
: Context(std::move(context)), worker_(std::move(worker)) {}

ContextGLES::~ContextGLES() = default;

} // namespace impeller::interop
39 changes: 39 additions & 0 deletions impeller/toolkit/interop/backend/gles/context_gles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2013 The Flutter 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_IMPELLER_TOOLKIT_INTEROP_BACKEND_GLES_CONTEXT_GLES_H_
#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_BACKEND_GLES_CONTEXT_GLES_H_

#include <functional>
#include <memory>

#include "impeller/toolkit/interop/backend/gles/reactor_worker_gles.h"
#include "impeller/toolkit/interop/context.h"

namespace impeller::interop {

class ContextGLES final : public Context {
public:
static ScopedObject<Context> Create(
std::function<void*(const char* gl_proc_name)> proc_address_callback);

ContextGLES();

// |Context|
~ContextGLES() override;

ContextGLES(const ContextGLES&) = delete;

ContextGLES& operator=(const ContextGLES&) = delete;

private:
std::shared_ptr<ReactorWorkerGLES> worker_;

ContextGLES(std::shared_ptr<impeller::Context> context,
std::shared_ptr<ReactorWorkerGLES> worker);
};

} // namespace impeller::interop

#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_BACKEND_GLES_CONTEXT_GLES_H_
19 changes: 19 additions & 0 deletions impeller/toolkit/interop/backend/gles/reactor_worker_gles.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2013 The Flutter 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 "impeller/toolkit/interop/backend/gles/reactor_worker_gles.h"

namespace impeller::interop {

ReactorWorkerGLES::ReactorWorkerGLES()
: thread_id_(std::this_thread::get_id()) {}

ReactorWorkerGLES::~ReactorWorkerGLES() = default;

bool ReactorWorkerGLES::CanReactorReactOnCurrentThreadNow(
const ReactorGLES& reactor) const {
return thread_id_ == std::this_thread::get_id();
}

} // namespace impeller::interop
33 changes: 33 additions & 0 deletions impeller/toolkit/interop/backend/gles/reactor_worker_gles.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2013 The Flutter 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_IMPELLER_TOOLKIT_INTEROP_BACKEND_GLES_REACTOR_WORKER_GLES_H_
#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_BACKEND_GLES_REACTOR_WORKER_GLES_H_

#include "impeller/renderer/backend/gles/reactor_gles.h"

namespace impeller::interop {

class ReactorWorkerGLES final : public ReactorGLES::Worker {
public:
ReactorWorkerGLES();

// |ReactorGLES::Worker|
~ReactorWorkerGLES() override;

// |ReactorGLES::Worker|
bool CanReactorReactOnCurrentThreadNow(
const ReactorGLES& reactor) const override;

private:
std::thread::id thread_id_;

ReactorWorkerGLES(const ReactorWorkerGLES&) = delete;

ReactorWorkerGLES& operator=(const ReactorWorkerGLES&) = delete;
};

} // namespace impeller::interop

#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_BACKEND_GLES_REACTOR_WORKER_GLES_H_
13 changes: 13 additions & 0 deletions impeller/toolkit/interop/backend/metal/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2013 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import("//flutter/impeller/tools/impeller.gni")

impeller_component("metal") {
public_deps = [ "../../:interop_base" ]
sources = [
"context_mtl.h",
"context_mtl.mm",
]
}
29 changes: 29 additions & 0 deletions impeller/toolkit/interop/backend/metal/context_mtl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2013 The Flutter 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_IMPELLER_TOOLKIT_INTEROP_BACKEND_METAL_CONTEXT_MTL_H_
#define FLUTTER_IMPELLER_TOOLKIT_INTEROP_BACKEND_METAL_CONTEXT_MTL_H_

#include "impeller/toolkit/interop/context.h"

namespace impeller::interop {

class ContextMTL final : public Context {
public:
static ScopedObject<Context> Create();

// |Context|
~ContextMTL() override;

ContextMTL(const ContextMTL&) = delete;

ContextMTL& operator=(const ContextMTL&) = delete;

private:
explicit ContextMTL(std::shared_ptr<impeller::Context> context);
};

} // namespace impeller::interop

#endif // FLUTTER_IMPELLER_TOOLKIT_INTEROP_BACKEND_METAL_CONTEXT_MTL_H_
Loading

0 comments on commit 43ea25f

Please sign in to comment.