From dfb631ffed08a92ab1e744eac8d1915b72ab8b36 Mon Sep 17 00:00:00 2001 From: Chris Bracken Date: Thu, 14 Nov 2024 15:24:22 -0800 Subject: [PATCH] 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 --- .../flutter/shell/platform/embedder/BUILD.gn | 3 + .../embedder/tests/embedder_config_builder.cc | 255 +++--------------- .../embedder/tests/embedder_config_builder.h | 18 +- .../tests/embedder_config_builder_gl.cc | 81 ++++++ .../tests/embedder_config_builder_metal.mm | 47 ++++ .../tests/embedder_config_builder_vulkan.cc | 73 +++++ .../embedder/tests/embedder_test_context.cc | 26 ++ .../embedder/tests/embedder_test_context.h | 4 + 8 files changed, 285 insertions(+), 222 deletions(-) create mode 100644 engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_gl.cc create mode 100644 engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_metal.mm create mode 100644 engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_vulkan.cc diff --git a/engine/src/flutter/shell/platform/embedder/BUILD.gn b/engine/src/flutter/shell/platform/embedder/BUILD.gn index 31e0f191a4..2dbe8eb990 100644 --- a/engine/src/flutter/shell/platform/embedder/BUILD.gn +++ b/engine/src/flutter/shell/platform/embedder/BUILD.gn @@ -313,6 +313,7 @@ if (enable_unittests) { if (test_enable_gl) { sources += [ + "tests/embedder_config_builder_gl.cc", "tests/embedder_test_compositor_gl.cc", "tests/embedder_test_compositor_gl.h", "tests/embedder_test_context_gl.cc", @@ -328,6 +329,7 @@ if (enable_unittests) { if (test_enable_metal) { sources += [ + "tests/embedder_config_builder_metal.mm", "tests/embedder_test_compositor_metal.h", "tests/embedder_test_compositor_metal.mm", "tests/embedder_test_context_metal.h", @@ -340,6 +342,7 @@ if (enable_unittests) { if (test_enable_vulkan) { sources += [ + "tests/embedder_config_builder_vulkan.cc", "tests/embedder_test_compositor_vulkan.cc", "tests/embedder_test_compositor_vulkan.h", "tests/embedder_test_context_vulkan.cc", diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.cc b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.cc index 3d39cca7ed..ef1a59f31d 100644 --- a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.cc @@ -11,23 +11,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkImage.h" -#ifdef SHELL_ENABLE_GL -#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 { +namespace flutter::testing { EmbedderConfigBuilder::EmbedderConfigBuilder( EmbedderTestContext& context, @@ -43,49 +27,9 @@ EmbedderConfigBuilder::EmbedderConfigBuilder( custom_task_runners_.struct_size = sizeof(FlutterCustomTaskRunners); -#ifdef SHELL_ENABLE_GL - opengl_renderer_config_.struct_size = sizeof(FlutterOpenGLRendererConfig); - opengl_renderer_config_.make_current = [](void* context) -> bool { - return reinterpret_cast(context)->GLMakeCurrent(); - }; - opengl_renderer_config_.clear_current = [](void* context) -> bool { - return reinterpret_cast(context)->GLClearCurrent(); - }; - opengl_renderer_config_.present_with_info = - [](void* context, const FlutterPresentInfo* present_info) -> bool { - return reinterpret_cast(context)->GLPresent( - *present_info); - }; - opengl_renderer_config_.fbo_with_frame_info_callback = - [](void* context, const FlutterFrameInfo* frame_info) -> uint32_t { - return reinterpret_cast(context)->GLGetFramebuffer( - *frame_info); - }; - opengl_renderer_config_.populate_existing_damage = nullptr; - opengl_renderer_config_.make_resource_current = [](void* context) -> bool { - return reinterpret_cast(context) - ->GLMakeResourceCurrent(); - }; - opengl_renderer_config_.gl_proc_resolver = [](void* context, - const char* name) -> void* { - return reinterpret_cast(context)->GLGetProcAddress( - name); - }; - opengl_renderer_config_.fbo_reset_after_present = true; - opengl_renderer_config_.surface_transformation = - [](void* context) -> FlutterTransformation { - return reinterpret_cast(context) - ->GetRootSurfaceTransformation(); - }; -#endif - -#ifdef SHELL_ENABLE_METAL + InitializeGLRendererConfig(); InitializeMetalRendererConfig(); -#endif - -#ifdef SHELL_ENABLE_VULKAN InitializeVulkanRendererConfig(); -#endif software_renderer_config_.struct_size = sizeof(FlutterSoftwareRendererConfig); software_renderer_config_.surface_present_callback = @@ -141,37 +85,6 @@ void EmbedderConfigBuilder::SetSoftwareRendererConfig(SkISize 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(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(context)->GLPresent( - FlutterPresentInfo{ - .fbo_id = 0, - }); - }; -#endif -} - void EmbedderConfigBuilder::SetRendererConfig(EmbedderTestContextType type, SkISize surface_size) { 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 - 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() { project_args_.assets_path = context_.GetAssetsPath().c_str(); } @@ -406,18 +287,7 @@ FlutterCompositor& EmbedderConfigBuilder::GetCompositor() { void EmbedderConfigBuilder::SetRenderTargetType( EmbedderTestBackingStoreProducer::RenderTargetType type, FlutterSoftwarePixelFormat software_pixfmt) { - auto& compositor = context_.GetCompositor(); - - auto producer = std::make_unique( - 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)); + context_.SetRenderTargetType(type, software_pixfmt); } UniqueEngine EmbedderConfigBuilder::LaunchEngine() const { @@ -479,93 +349,52 @@ UniqueEngine EmbedderConfigBuilder::SetupEngine(bool run) const { 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() { - if (context_.GetContextType() != EmbedderTestContextType::kMetalContext) { - return; - } - - metal_renderer_config_.struct_size = sizeof(metal_renderer_config_); - EmbedderTestContextMetal& metal_context = - reinterpret_cast(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(user_data) - ->GetNextDrawable(frame_info); - }; - metal_renderer_config_.present_drawable_callback = - [](void* user_data, const FlutterMetalTexture* texture) -> bool { - EmbedderTestContextMetal* metal_context = - reinterpret_cast(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(user_data); - return metal_context->PopulateExternalTexture(texture_id, width, height, - texture_out); - }; + // no-op. } -#endif // SHELL_ENABLE_METAL - -#ifdef SHELL_ENABLE_VULKAN +void EmbedderConfigBuilder::SetMetalRendererConfig(SkISize surface_size) { + FML_LOG(FATAL) << "Metal is not enabled in this build."; +} +#endif +#ifndef SHELL_ENABLE_VULKAN +// Vulkan fallback implementations. +// See: flutter/shell/platform/embedder/tests/embedder_config_builder_vulkan.cc. void EmbedderConfigBuilder::InitializeVulkanRendererConfig() { - if (context_.GetContextType() != EmbedderTestContextType::kVulkanContext) { - return; - } - - vulkan_renderer_config_.struct_size = sizeof(FlutterVulkanRendererConfig); - vulkan_renderer_config_.version = - static_cast(context_) - .vulkan_context_->application_->GetAPIVersion(); - vulkan_renderer_config_.instance = - static_cast(context_) - .vulkan_context_->application_->GetInstance(); - vulkan_renderer_config_.physical_device = - static_cast(context_) - .vulkan_context_->device_->GetPhysicalDeviceHandle(); - vulkan_renderer_config_.device = - static_cast(context_) - .vulkan_context_->device_->GetHandle(); - vulkan_renderer_config_.queue_family_index = - static_cast(context_) - .vulkan_context_->device_->GetGraphicsQueueIndex(); - vulkan_renderer_config_.queue = - static_cast(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(context)->GetNextImage( - {static_cast(frame_info->size.width), - static_cast(frame_info->size.height)}); - return { - .struct_size = sizeof(FlutterVulkanImage), - .image = reinterpret_cast(image), - .format = VK_FORMAT_R8G8B8A8_UNORM, - }; - }; - vulkan_renderer_config_.present_image_callback = - [](void* context, const FlutterVulkanImage* image) -> bool { - return reinterpret_cast(context)->PresentImage( - reinterpret_cast(image->image)); - }; + // no-op. } +void EmbedderConfigBuilder::SetVulkanRendererConfig( + SkISize surface_size, + std::optional + instance_proc_address_callback) { + FML_LOG(FATAL) << "Vulkan is not enabled in this build."; +} #endif -} // namespace testing -} // namespace flutter +} // namespace flutter::testing diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.h b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.h index 82498ac06b..3ed9a8940e 100644 --- a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.h +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder.h @@ -11,8 +11,7 @@ #include "flutter/shell/platform/embedder/tests/embedder_test.h" #include "flutter/shell/platform/embedder/tests/embedder_test_context_software.h" -namespace flutter { -namespace testing { +namespace flutter::testing { struct UniqueEngineTraits { static FlutterEngine InvalidValue() { return nullptr; } @@ -126,6 +125,10 @@ class EmbedderConfigBuilder { void SetupVsyncCallback(); private: + void InitializeGLRendererConfig(); + void InitializeVulkanRendererConfig(); + void InitializeMetalRendererConfig(); + EmbedderTestContext& context_; FlutterProjectArgs project_args_ = {}; FlutterRendererConfig renderer_config_ = {}; @@ -133,13 +136,11 @@ class EmbedderConfigBuilder { #ifdef SHELL_ENABLE_GL FlutterOpenGLRendererConfig opengl_renderer_config_ = {}; #endif -#ifdef SHELL_ENABLE_VULKAN - void InitializeVulkanRendererConfig(); - FlutterVulkanRendererConfig vulkan_renderer_config_ = {}; -#endif #ifdef SHELL_ENABLE_METAL - void InitializeMetalRendererConfig(); FlutterMetalRendererConfig metal_renderer_config_ = {}; +#endif +#ifdef SHELL_ENABLE_VULKAN + FlutterVulkanRendererConfig vulkan_renderer_config_ = {}; #endif std::string dart_entrypoint_; FlutterCustomTaskRunners custom_task_runners_ = {}; @@ -153,7 +154,6 @@ class EmbedderConfigBuilder { FML_DISALLOW_COPY_AND_ASSIGN(EmbedderConfigBuilder); }; -} // namespace testing -} // namespace flutter +} // namespace flutter::testing #endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_TESTS_EMBEDDER_CONFIG_BUILDER_H_ diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_gl.cc b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_gl.cc new file mode 100644 index 0000000000..2defa53fea --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_gl.cc @@ -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(context)->GLMakeCurrent(); + }; + opengl_renderer_config_.clear_current = [](void* context) -> bool { + return reinterpret_cast(context)->GLClearCurrent(); + }; + opengl_renderer_config_.present_with_info = + [](void* context, const FlutterPresentInfo* present_info) -> bool { + return reinterpret_cast(context)->GLPresent( + *present_info); + }; + opengl_renderer_config_.fbo_with_frame_info_callback = + [](void* context, const FlutterFrameInfo* frame_info) -> uint32_t { + return reinterpret_cast(context)->GLGetFramebuffer( + *frame_info); + }; + opengl_renderer_config_.populate_existing_damage = nullptr; + opengl_renderer_config_.make_resource_current = [](void* context) -> bool { + return reinterpret_cast(context) + ->GLMakeResourceCurrent(); + }; + opengl_renderer_config_.gl_proc_resolver = [](void* context, + const char* name) -> void* { + return reinterpret_cast(context)->GLGetProcAddress( + name); + }; + opengl_renderer_config_.fbo_reset_after_present = true; + opengl_renderer_config_.surface_transformation = + [](void* context) -> FlutterTransformation { + return reinterpret_cast(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(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(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 diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_metal.mm b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_metal.mm new file mode 100644 index 0000000000..c76b311865 --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_metal.mm @@ -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(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(user_data)->GetNextDrawable(frame_info); + }; + metal_renderer_config_.present_drawable_callback = + [](void* user_data, const FlutterMetalTexture* texture) -> bool { + EmbedderTestContextMetal* metal_context = + reinterpret_cast(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(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 diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_vulkan.cc b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_vulkan.cc new file mode 100644 index 0000000000..3f6558104c --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_config_builder_vulkan.cc @@ -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(context_) + .vulkan_context_->application_->GetAPIVersion(); + vulkan_renderer_config_.instance = + static_cast(context_) + .vulkan_context_->application_->GetInstance(); + vulkan_renderer_config_.physical_device = + static_cast(context_) + .vulkan_context_->device_->GetPhysicalDeviceHandle(); + vulkan_renderer_config_.device = + static_cast(context_) + .vulkan_context_->device_->GetHandle(); + vulkan_renderer_config_.queue_family_index = + static_cast(context_) + .vulkan_context_->device_->GetGraphicsQueueIndex(); + vulkan_renderer_config_.queue = + static_cast(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(context)->GetNextImage( + {static_cast(frame_info->size.width), + static_cast(frame_info->size.height)}); + return { + .struct_size = sizeof(FlutterVulkanImage), + .image = reinterpret_cast(image), + .format = VK_FORMAT_R8G8B8A8_UNORM, + }; + }; + vulkan_renderer_config_.present_image_callback = + [](void* context, const FlutterVulkanImage* image) -> bool { + return reinterpret_cast(context)->PresentImage( + reinterpret_cast(image->image)); + }; +} + +void EmbedderConfigBuilder::SetVulkanRendererConfig( + SkISize surface_size, + std::optional + 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 diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.cc b/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.cc index 0f5e3dcf9a..d53491ee29 100644 --- a/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.cc +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.cc @@ -96,6 +96,32 @@ void EmbedderTestContext::SetRootSurfaceTransformation(SkMatrix 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( + 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( const fml::closure& closure) { if (closure) { diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.h b/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.h index eb0deb4b76..4ea8de4cc9 100644 --- a/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.h +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_test_context.h @@ -72,6 +72,10 @@ class EmbedderTestContext { void SetRootSurfaceTransformation(SkMatrix matrix); + void SetRenderTargetType( + EmbedderTestBackingStoreProducer::RenderTargetType type, + FlutterSoftwarePixelFormat software_pixfmt); + void AddIsolateCreateCallback(const fml::closure& closure); void SetSemanticsUpdateCallback2(SemanticsUpdateCallback2 update_semantics);