Embedder: Refactor EmbedderConfigBuilder by backend (flutter/engine#56598)

Extracts backend-specific code in EmbedderConfigBuilder to separate translation units. In particular, this allows for less conditional header includes, and more specifically, for code relating to the Metal backend to include headers that include Objective-C types -- today we cast these all to void* to avoid declaring them in headers, which requires special handling for ARC.

An alternative approach would have been to extract backend-specific subclasses, but there are test suites such as EmbedderTestMultiBackend that are executed against multiple backends, which currently make that approach impractical, though that should likely be the long-term goal.

Issue: https://github.com/flutter/flutter/issues/137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
Chris Bracken 2024-11-14 15:24:22 -08:00 committed by GitHub
parent c74f169f93
commit dfb631ffed
8 changed files with 285 additions and 222 deletions

View File

@ -313,6 +313,7 @@ if (enable_unittests) {
if (test_enable_gl) { if (test_enable_gl) {
sources += [ sources += [
"tests/embedder_config_builder_gl.cc",
"tests/embedder_test_compositor_gl.cc", "tests/embedder_test_compositor_gl.cc",
"tests/embedder_test_compositor_gl.h", "tests/embedder_test_compositor_gl.h",
"tests/embedder_test_context_gl.cc", "tests/embedder_test_context_gl.cc",
@ -328,6 +329,7 @@ if (enable_unittests) {
if (test_enable_metal) { if (test_enable_metal) {
sources += [ sources += [
"tests/embedder_config_builder_metal.mm",
"tests/embedder_test_compositor_metal.h", "tests/embedder_test_compositor_metal.h",
"tests/embedder_test_compositor_metal.mm", "tests/embedder_test_compositor_metal.mm",
"tests/embedder_test_context_metal.h", "tests/embedder_test_context_metal.h",
@ -340,6 +342,7 @@ if (enable_unittests) {
if (test_enable_vulkan) { if (test_enable_vulkan) {
sources += [ sources += [
"tests/embedder_config_builder_vulkan.cc",
"tests/embedder_test_compositor_vulkan.cc", "tests/embedder_test_compositor_vulkan.cc",
"tests/embedder_test_compositor_vulkan.h", "tests/embedder_test_compositor_vulkan.h",
"tests/embedder_test_context_vulkan.cc", "tests/embedder_test_context_vulkan.cc",

View File

@ -11,23 +11,7 @@
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/core/SkImage.h"
#ifdef SHELL_ENABLE_GL namespace flutter::testing {
#include "flutter/shell/platform/embedder/tests/embedder_test_compositor_gl.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h"
#endif
#ifdef SHELL_ENABLE_VULKAN
#include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h"
#include "flutter/vulkan/vulkan_device.h" // nogncheck
#include "vulkan/vulkan_core.h" // nogncheck
#endif
#ifdef SHELL_ENABLE_METAL
#include "flutter/shell/platform/embedder/tests/embedder_test_context_metal.h"
#endif
namespace flutter {
namespace testing {
EmbedderConfigBuilder::EmbedderConfigBuilder( EmbedderConfigBuilder::EmbedderConfigBuilder(
EmbedderTestContext& context, EmbedderTestContext& context,
@ -43,49 +27,9 @@ EmbedderConfigBuilder::EmbedderConfigBuilder(
custom_task_runners_.struct_size = sizeof(FlutterCustomTaskRunners); custom_task_runners_.struct_size = sizeof(FlutterCustomTaskRunners);
#ifdef SHELL_ENABLE_GL InitializeGLRendererConfig();
opengl_renderer_config_.struct_size = sizeof(FlutterOpenGLRendererConfig);
opengl_renderer_config_.make_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLMakeCurrent();
};
opengl_renderer_config_.clear_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLClearCurrent();
};
opengl_renderer_config_.present_with_info =
[](void* context, const FlutterPresentInfo* present_info) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLPresent(
*present_info);
};
opengl_renderer_config_.fbo_with_frame_info_callback =
[](void* context, const FlutterFrameInfo* frame_info) -> uint32_t {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetFramebuffer(
*frame_info);
};
opengl_renderer_config_.populate_existing_damage = nullptr;
opengl_renderer_config_.make_resource_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)
->GLMakeResourceCurrent();
};
opengl_renderer_config_.gl_proc_resolver = [](void* context,
const char* name) -> void* {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetProcAddress(
name);
};
opengl_renderer_config_.fbo_reset_after_present = true;
opengl_renderer_config_.surface_transformation =
[](void* context) -> FlutterTransformation {
return reinterpret_cast<EmbedderTestContext*>(context)
->GetRootSurfaceTransformation();
};
#endif
#ifdef SHELL_ENABLE_METAL
InitializeMetalRendererConfig(); InitializeMetalRendererConfig();
#endif
#ifdef SHELL_ENABLE_VULKAN
InitializeVulkanRendererConfig(); InitializeVulkanRendererConfig();
#endif
software_renderer_config_.struct_size = sizeof(FlutterSoftwareRendererConfig); software_renderer_config_.struct_size = sizeof(FlutterSoftwareRendererConfig);
software_renderer_config_.surface_present_callback = software_renderer_config_.surface_present_callback =
@ -141,37 +85,6 @@ void EmbedderConfigBuilder::SetSoftwareRendererConfig(SkISize surface_size) {
context_.SetupSurface(surface_size); context_.SetupSurface(surface_size);
} }
void EmbedderConfigBuilder::SetOpenGLFBOCallBack() {
#ifdef SHELL_ENABLE_GL
// SetOpenGLRendererConfig must be called before this.
FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
renderer_config_.open_gl.fbo_callback = [](void* context) -> uint32_t {
FlutterFrameInfo frame_info = {};
// fbo_callback doesn't use the frame size information, only
// fbo_callback_with_frame_info does.
frame_info.struct_size = sizeof(FlutterFrameInfo);
frame_info.size.width = 0;
frame_info.size.height = 0;
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetFramebuffer(
frame_info);
};
#endif
}
void EmbedderConfigBuilder::SetOpenGLPresentCallBack() {
#ifdef SHELL_ENABLE_GL
// SetOpenGLRendererConfig must be called before this.
FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
renderer_config_.open_gl.present = [](void* context) -> bool {
// passing a placeholder fbo_id.
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLPresent(
FlutterPresentInfo{
.fbo_id = 0,
});
};
#endif
}
void EmbedderConfigBuilder::SetRendererConfig(EmbedderTestContextType type, void EmbedderConfigBuilder::SetRendererConfig(EmbedderTestContextType type,
SkISize surface_size) { SkISize surface_size) {
switch (type) { switch (type) {
@ -190,38 +103,6 @@ void EmbedderConfigBuilder::SetRendererConfig(EmbedderTestContextType type,
} }
} }
void EmbedderConfigBuilder::SetOpenGLRendererConfig(SkISize surface_size) {
#ifdef SHELL_ENABLE_GL
renderer_config_.type = FlutterRendererType::kOpenGL;
renderer_config_.open_gl = opengl_renderer_config_;
context_.SetupSurface(surface_size);
#endif
}
void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) {
#ifdef SHELL_ENABLE_METAL
renderer_config_.type = FlutterRendererType::kMetal;
renderer_config_.metal = metal_renderer_config_;
context_.SetupSurface(surface_size);
#endif
}
void EmbedderConfigBuilder::SetVulkanRendererConfig(
SkISize surface_size,
std::optional<FlutterVulkanInstanceProcAddressCallback>
instance_proc_address_callback) {
#ifdef SHELL_ENABLE_VULKAN
renderer_config_.type = FlutterRendererType::kVulkan;
FlutterVulkanRendererConfig vulkan_renderer_config = vulkan_renderer_config_;
if (instance_proc_address_callback.has_value()) {
vulkan_renderer_config.get_instance_proc_address_callback =
instance_proc_address_callback.value();
}
renderer_config_.vulkan = vulkan_renderer_config;
context_.SetupSurface(surface_size);
#endif
}
void EmbedderConfigBuilder::SetAssetsPath() { void EmbedderConfigBuilder::SetAssetsPath() {
project_args_.assets_path = context_.GetAssetsPath().c_str(); project_args_.assets_path = context_.GetAssetsPath().c_str();
} }
@ -406,18 +287,7 @@ FlutterCompositor& EmbedderConfigBuilder::GetCompositor() {
void EmbedderConfigBuilder::SetRenderTargetType( void EmbedderConfigBuilder::SetRenderTargetType(
EmbedderTestBackingStoreProducer::RenderTargetType type, EmbedderTestBackingStoreProducer::RenderTargetType type,
FlutterSoftwarePixelFormat software_pixfmt) { FlutterSoftwarePixelFormat software_pixfmt) {
auto& compositor = context_.GetCompositor(); context_.SetRenderTargetType(type, software_pixfmt);
auto producer = std::make_unique<EmbedderTestBackingStoreProducer>(
compositor.GetGrContext(), type, software_pixfmt);
#ifdef SHELL_ENABLE_GL
producer->SetEGLContext(context_.egl_context_);
#endif
// TODO(wrightgeorge): figure out a better way of plumbing through the
// GrDirectContext
compositor.SetBackingStoreProducer(std::move(producer));
} }
UniqueEngine EmbedderConfigBuilder::LaunchEngine() const { UniqueEngine EmbedderConfigBuilder::LaunchEngine() const {
@ -479,93 +349,52 @@ UniqueEngine EmbedderConfigBuilder::SetupEngine(bool run) const {
return UniqueEngine{engine}; return UniqueEngine{engine};
} }
#ifdef SHELL_ENABLE_METAL #ifndef SHELL_ENABLE_GL
// OpenGL fallback implementations.
// See: flutter/shell/platform/embedder/tests/embedder_config_builder_gl.cc.
void EmbedderConfigBuilder::InitializeGLRendererConfig() {
// no-op.
}
void EmbedderConfigBuilder::SetOpenGLFBOCallBack() {
FML_LOG(FATAL) << "OpenGL is not enabled in this build.";
}
void EmbedderConfigBuilder::SetOpenGLPresentCallBack() {
FML_LOG(FATAL) << "OpenGL is not enabled in this build.";
}
void EmbedderConfigBuilder::SetOpenGLRendererConfig(SkISize surface_size) {
FML_LOG(FATAL) << "OpenGL is not enabled in this build.";
}
#endif
#ifndef SHELL_ENABLE_METAL
// Metal fallback implementations.
// See: flutter/shell/platform/embedder/tests/embedder_config_builder_metal.mm.
void EmbedderConfigBuilder::InitializeMetalRendererConfig() { void EmbedderConfigBuilder::InitializeMetalRendererConfig() {
if (context_.GetContextType() != EmbedderTestContextType::kMetalContext) { // no-op.
return;
} }
metal_renderer_config_.struct_size = sizeof(metal_renderer_config_); void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) {
EmbedderTestContextMetal& metal_context = FML_LOG(FATAL) << "Metal is not enabled in this build.";
reinterpret_cast<EmbedderTestContextMetal&>(context_);
metal_renderer_config_.device =
metal_context.GetTestMetalContext()->GetMetalDevice();
metal_renderer_config_.present_command_queue =
metal_context.GetTestMetalContext()->GetMetalCommandQueue();
metal_renderer_config_.get_next_drawable_callback =
[](void* user_data, const FlutterFrameInfo* frame_info) {
return reinterpret_cast<EmbedderTestContextMetal*>(user_data)
->GetNextDrawable(frame_info);
};
metal_renderer_config_.present_drawable_callback =
[](void* user_data, const FlutterMetalTexture* texture) -> bool {
EmbedderTestContextMetal* metal_context =
reinterpret_cast<EmbedderTestContextMetal*>(user_data);
return metal_context->Present(texture->texture_id);
};
metal_renderer_config_.external_texture_frame_callback =
[](void* user_data, int64_t texture_id, size_t width, size_t height,
FlutterMetalExternalTexture* texture_out) -> bool {
EmbedderTestContextMetal* metal_context =
reinterpret_cast<EmbedderTestContextMetal*>(user_data);
return metal_context->PopulateExternalTexture(texture_id, width, height,
texture_out);
};
} }
#endif
#endif // SHELL_ENABLE_METAL #ifndef SHELL_ENABLE_VULKAN
// Vulkan fallback implementations.
#ifdef SHELL_ENABLE_VULKAN // See: flutter/shell/platform/embedder/tests/embedder_config_builder_vulkan.cc.
void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { void EmbedderConfigBuilder::InitializeVulkanRendererConfig() {
if (context_.GetContextType() != EmbedderTestContextType::kVulkanContext) { // no-op.
return;
} }
vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); void EmbedderConfigBuilder::SetVulkanRendererConfig(
vulkan_renderer_config_.version = SkISize surface_size,
static_cast<EmbedderTestContextVulkan&>(context_) std::optional<FlutterVulkanInstanceProcAddressCallback>
.vulkan_context_->application_->GetAPIVersion(); instance_proc_address_callback) {
vulkan_renderer_config_.instance = FML_LOG(FATAL) << "Vulkan is not enabled in this build.";
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->application_->GetInstance();
vulkan_renderer_config_.physical_device =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetPhysicalDeviceHandle();
vulkan_renderer_config_.device =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetHandle();
vulkan_renderer_config_.queue_family_index =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetGraphicsQueueIndex();
vulkan_renderer_config_.queue =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetQueueHandle();
vulkan_renderer_config_.get_instance_proc_address_callback =
EmbedderTestContextVulkan::InstanceProcAddr;
vulkan_renderer_config_.get_next_image_callback =
[](void* context,
const FlutterFrameInfo* frame_info) -> FlutterVulkanImage {
VkImage image =
reinterpret_cast<EmbedderTestContextVulkan*>(context)->GetNextImage(
{static_cast<int>(frame_info->size.width),
static_cast<int>(frame_info->size.height)});
return {
.struct_size = sizeof(FlutterVulkanImage),
.image = reinterpret_cast<uint64_t>(image),
.format = VK_FORMAT_R8G8B8A8_UNORM,
};
};
vulkan_renderer_config_.present_image_callback =
[](void* context, const FlutterVulkanImage* image) -> bool {
return reinterpret_cast<EmbedderTestContextVulkan*>(context)->PresentImage(
reinterpret_cast<VkImage>(image->image));
};
} }
#endif #endif
} // namespace testing } // namespace flutter::testing
} // namespace flutter

View File

@ -11,8 +11,7 @@
#include "flutter/shell/platform/embedder/tests/embedder_test.h" #include "flutter/shell/platform/embedder/tests/embedder_test.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_context_software.h" #include "flutter/shell/platform/embedder/tests/embedder_test_context_software.h"
namespace flutter { namespace flutter::testing {
namespace testing {
struct UniqueEngineTraits { struct UniqueEngineTraits {
static FlutterEngine InvalidValue() { return nullptr; } static FlutterEngine InvalidValue() { return nullptr; }
@ -126,6 +125,10 @@ class EmbedderConfigBuilder {
void SetupVsyncCallback(); void SetupVsyncCallback();
private: private:
void InitializeGLRendererConfig();
void InitializeVulkanRendererConfig();
void InitializeMetalRendererConfig();
EmbedderTestContext& context_; EmbedderTestContext& context_;
FlutterProjectArgs project_args_ = {}; FlutterProjectArgs project_args_ = {};
FlutterRendererConfig renderer_config_ = {}; FlutterRendererConfig renderer_config_ = {};
@ -133,13 +136,11 @@ class EmbedderConfigBuilder {
#ifdef SHELL_ENABLE_GL #ifdef SHELL_ENABLE_GL
FlutterOpenGLRendererConfig opengl_renderer_config_ = {}; FlutterOpenGLRendererConfig opengl_renderer_config_ = {};
#endif #endif
#ifdef SHELL_ENABLE_VULKAN
void InitializeVulkanRendererConfig();
FlutterVulkanRendererConfig vulkan_renderer_config_ = {};
#endif
#ifdef SHELL_ENABLE_METAL #ifdef SHELL_ENABLE_METAL
void InitializeMetalRendererConfig();
FlutterMetalRendererConfig metal_renderer_config_ = {}; FlutterMetalRendererConfig metal_renderer_config_ = {};
#endif
#ifdef SHELL_ENABLE_VULKAN
FlutterVulkanRendererConfig vulkan_renderer_config_ = {};
#endif #endif
std::string dart_entrypoint_; std::string dart_entrypoint_;
FlutterCustomTaskRunners custom_task_runners_ = {}; FlutterCustomTaskRunners custom_task_runners_ = {};
@ -153,7 +154,6 @@ class EmbedderConfigBuilder {
FML_DISALLOW_COPY_AND_ASSIGN(EmbedderConfigBuilder); FML_DISALLOW_COPY_AND_ASSIGN(EmbedderConfigBuilder);
}; };
} // namespace testing } // namespace flutter::testing
} // namespace flutter
#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONFIG_BUILDER_H_ #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONFIG_BUILDER_H_

View File

@ -0,0 +1,81 @@
// 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 "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_compositor_gl.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_context_gl.h"
namespace flutter::testing {
void EmbedderConfigBuilder::InitializeGLRendererConfig() {
opengl_renderer_config_.struct_size = sizeof(FlutterOpenGLRendererConfig);
opengl_renderer_config_.make_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLMakeCurrent();
};
opengl_renderer_config_.clear_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLClearCurrent();
};
opengl_renderer_config_.present_with_info =
[](void* context, const FlutterPresentInfo* present_info) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLPresent(
*present_info);
};
opengl_renderer_config_.fbo_with_frame_info_callback =
[](void* context, const FlutterFrameInfo* frame_info) -> uint32_t {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetFramebuffer(
*frame_info);
};
opengl_renderer_config_.populate_existing_damage = nullptr;
opengl_renderer_config_.make_resource_current = [](void* context) -> bool {
return reinterpret_cast<EmbedderTestContextGL*>(context)
->GLMakeResourceCurrent();
};
opengl_renderer_config_.gl_proc_resolver = [](void* context,
const char* name) -> void* {
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetProcAddress(
name);
};
opengl_renderer_config_.fbo_reset_after_present = true;
opengl_renderer_config_.surface_transformation =
[](void* context) -> FlutterTransformation {
return reinterpret_cast<EmbedderTestContext*>(context)
->GetRootSurfaceTransformation();
};
}
void EmbedderConfigBuilder::SetOpenGLFBOCallBack() {
// SetOpenGLRendererConfig must be called before this.
FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
renderer_config_.open_gl.fbo_callback = [](void* context) -> uint32_t {
FlutterFrameInfo frame_info = {};
// fbo_callback doesn't use the frame size information, only
// fbo_callback_with_frame_info does.
frame_info.struct_size = sizeof(FlutterFrameInfo);
frame_info.size.width = 0;
frame_info.size.height = 0;
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLGetFramebuffer(
frame_info);
};
}
void EmbedderConfigBuilder::SetOpenGLPresentCallBack() {
// SetOpenGLRendererConfig must be called before this.
FML_CHECK(renderer_config_.type == FlutterRendererType::kOpenGL);
renderer_config_.open_gl.present = [](void* context) -> bool {
// passing a placeholder fbo_id.
return reinterpret_cast<EmbedderTestContextGL*>(context)->GLPresent(
FlutterPresentInfo{
.fbo_id = 0,
});
};
}
void EmbedderConfigBuilder::SetOpenGLRendererConfig(SkISize surface_size) {
renderer_config_.type = FlutterRendererType::kOpenGL;
renderer_config_.open_gl = opengl_renderer_config_;
context_.SetupSurface(surface_size);
}
} // namespace flutter::testing

View File

@ -0,0 +1,47 @@
// 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 "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_context_metal.h"
namespace flutter::testing {
void EmbedderConfigBuilder::InitializeMetalRendererConfig() {
if (context_.GetContextType() != EmbedderTestContextType::kMetalContext) {
return;
}
metal_renderer_config_.struct_size = sizeof(metal_renderer_config_);
EmbedderTestContextMetal& metal_context = reinterpret_cast<EmbedderTestContextMetal&>(context_);
metal_renderer_config_.device = metal_context.GetTestMetalContext()->GetMetalDevice();
metal_renderer_config_.present_command_queue =
metal_context.GetTestMetalContext()->GetMetalCommandQueue();
metal_renderer_config_.get_next_drawable_callback = [](void* user_data,
const FlutterFrameInfo* frame_info) {
return reinterpret_cast<EmbedderTestContextMetal*>(user_data)->GetNextDrawable(frame_info);
};
metal_renderer_config_.present_drawable_callback =
[](void* user_data, const FlutterMetalTexture* texture) -> bool {
EmbedderTestContextMetal* metal_context =
reinterpret_cast<EmbedderTestContextMetal*>(user_data);
return metal_context->Present(texture->texture_id);
};
metal_renderer_config_.external_texture_frame_callback =
[](void* user_data, int64_t texture_id, size_t width, size_t height,
FlutterMetalExternalTexture* texture_out) -> bool {
EmbedderTestContextMetal* metal_context =
reinterpret_cast<EmbedderTestContextMetal*>(user_data);
return metal_context->PopulateExternalTexture(texture_id, width, height, texture_out);
};
}
void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) {
renderer_config_.type = FlutterRendererType::kMetal;
renderer_config_.metal = metal_renderer_config_;
context_.SetupSurface(surface_size);
}
} // namespace flutter::testing

View File

@ -0,0 +1,73 @@
// 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 "flutter/shell/platform/embedder/tests/embedder_config_builder.h"
#include "flutter/shell/platform/embedder/tests/embedder_test_context_vulkan.h"
#include "flutter/vulkan/vulkan_device.h" // nogncheck
#include "vulkan/vulkan_core.h" // nogncheck
namespace flutter::testing {
void EmbedderConfigBuilder::InitializeVulkanRendererConfig() {
if (context_.GetContextType() != EmbedderTestContextType::kVulkanContext) {
return;
}
vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig);
vulkan_renderer_config_.version =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->application_->GetAPIVersion();
vulkan_renderer_config_.instance =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->application_->GetInstance();
vulkan_renderer_config_.physical_device =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetPhysicalDeviceHandle();
vulkan_renderer_config_.device =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetHandle();
vulkan_renderer_config_.queue_family_index =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetGraphicsQueueIndex();
vulkan_renderer_config_.queue =
static_cast<EmbedderTestContextVulkan&>(context_)
.vulkan_context_->device_->GetQueueHandle();
vulkan_renderer_config_.get_instance_proc_address_callback =
EmbedderTestContextVulkan::InstanceProcAddr;
vulkan_renderer_config_.get_next_image_callback =
[](void* context,
const FlutterFrameInfo* frame_info) -> FlutterVulkanImage {
VkImage image =
reinterpret_cast<EmbedderTestContextVulkan*>(context)->GetNextImage(
{static_cast<int>(frame_info->size.width),
static_cast<int>(frame_info->size.height)});
return {
.struct_size = sizeof(FlutterVulkanImage),
.image = reinterpret_cast<uint64_t>(image),
.format = VK_FORMAT_R8G8B8A8_UNORM,
};
};
vulkan_renderer_config_.present_image_callback =
[](void* context, const FlutterVulkanImage* image) -> bool {
return reinterpret_cast<EmbedderTestContextVulkan*>(context)->PresentImage(
reinterpret_cast<VkImage>(image->image));
};
}
void EmbedderConfigBuilder::SetVulkanRendererConfig(
SkISize surface_size,
std::optional<FlutterVulkanInstanceProcAddressCallback>
instance_proc_address_callback) {
renderer_config_.type = FlutterRendererType::kVulkan;
FlutterVulkanRendererConfig vulkan_renderer_config = vulkan_renderer_config_;
if (instance_proc_address_callback.has_value()) {
vulkan_renderer_config.get_instance_proc_address_callback =
instance_proc_address_callback.value();
}
renderer_config_.vulkan = vulkan_renderer_config;
context_.SetupSurface(surface_size);
}
} // namespace flutter::testing

View File

@ -96,6 +96,32 @@ void EmbedderTestContext::SetRootSurfaceTransformation(SkMatrix matrix) {
root_surface_transformation_ = matrix; root_surface_transformation_ = matrix;
} }
void EmbedderTestContext::SetRenderTargetType(
EmbedderTestBackingStoreProducer::RenderTargetType type,
FlutterSoftwarePixelFormat software_pixfmt) {
// TODO(wrightgeorge): figure out a better way of plumbing through the
// GrDirectContext
auto& compositor = GetCompositor();
auto producer = std::make_unique<EmbedderTestBackingStoreProducer>(
compositor.GetGrContext(), type, software_pixfmt);
#ifdef SHELL_ENABLE_GL
switch (type) {
case EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLFramebuffer:
case EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLTexture:
case EmbedderTestBackingStoreProducer::RenderTargetType::kOpenGLSurface:
producer->SetEGLContext(egl_context_);
break;
case EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer:
case EmbedderTestBackingStoreProducer::RenderTargetType::kSoftwareBuffer2:
case EmbedderTestBackingStoreProducer::RenderTargetType::kMetalTexture:
case EmbedderTestBackingStoreProducer::RenderTargetType::kVulkanImage:
// no-op.
break;
}
#endif // SHELL_ENABLE_GL
compositor.SetBackingStoreProducer(std::move(producer));
}
void EmbedderTestContext::AddIsolateCreateCallback( void EmbedderTestContext::AddIsolateCreateCallback(
const fml::closure& closure) { const fml::closure& closure) {
if (closure) { if (closure) {

View File

@ -72,6 +72,10 @@ class EmbedderTestContext {
void SetRootSurfaceTransformation(SkMatrix matrix); void SetRootSurfaceTransformation(SkMatrix matrix);
void SetRenderTargetType(
EmbedderTestBackingStoreProducer::RenderTargetType type,
FlutterSoftwarePixelFormat software_pixfmt);
void AddIsolateCreateCallback(const fml::closure& closure); void AddIsolateCreateCallback(const fml::closure& closure);
void SetSemanticsUpdateCallback2(SemanticsUpdateCallback2 update_semantics); void SetSemanticsUpdateCallback2(SemanticsUpdateCallback2 update_semantics);