From a356b2c9657d2100cfa6f9359d1f95c809f899c7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 29 May 2023 03:47:26 -0700 Subject: [PATCH 01/34] [Impeller] Support Impeller in the Metal embedder API --- impeller/renderer/backend/metal/context_mtl.h | 9 ++ .../renderer/backend/metal/context_mtl.mm | 63 +++++++++--- shell/gpu/gpu_surface_metal_impeller.h | 11 ++- shell/gpu/gpu_surface_metal_impeller.mm | 23 ++++- shell/platform/embedder/embedder.cc | 46 ++++++--- shell/platform/embedder/embedder_surface.cc | 9 ++ shell/platform/embedder/embedder_surface.h | 6 +- .../embedder_surface_metal_impeller.h | 67 +++++++++++++ .../embedder_surface_metal_impeller.mm | 99 +++++++++++++++++++ .../embedder/platform_view_embedder.cc | 7 +- .../embedder/platform_view_embedder.h | 5 +- 11 files changed, 305 insertions(+), 40 deletions(-) create mode 100644 shell/platform/embedder/embedder_surface_metal_impeller.h create mode 100644 shell/platform/embedder/embedder_surface_metal_impeller.mm diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index fe461601daf06..ef443b39aa40f 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -38,6 +38,14 @@ class ContextMTL final : public Context, std::shared_ptr is_gpu_disabled_sync_switch, const std::string& label); + static std::shared_ptr Create( + id device, + id command_queue, + const std::vector>& shader_libraries_data, + std::shared_ptr worker_task_runner, + std::shared_ptr is_gpu_disabled_sync_switch, + const std::string& label); + // |Context| ~ContextMTL() override; @@ -90,6 +98,7 @@ class ContextMTL final : public Context, ContextMTL( id device, + id command_queue, NSArray>* shader_libraries, std::shared_ptr worker_task_runner, std::shared_ptr is_gpu_disabled_sync_switch); diff --git a/impeller/renderer/backend/metal/context_mtl.mm b/impeller/renderer/backend/metal/context_mtl.mm index 20af3b87c7141..cc4ea365cab42 100644 --- a/impeller/renderer/backend/metal/context_mtl.mm +++ b/impeller/renderer/backend/metal/context_mtl.mm @@ -6,9 +6,11 @@ #include +#include "flutter/fml/concurrent_message_loop.h" #include "flutter/fml/file.h" #include "flutter/fml/logging.h" #include "flutter/fml/paths.h" +#include "flutter/fml/synchronization/sync_switch.h" #include "impeller/core/sampler_descriptor.h" #include "impeller/renderer/backend/metal/sampler_library_mtl.h" #include "impeller/renderer/capabilities.h" @@ -67,10 +69,12 @@ static bool DeviceSupportsComputeSubgroups(id device) { ContextMTL::ContextMTL( id device, + id command_queue, NSArray>* shader_libraries, std::shared_ptr worker_task_runner, std::shared_ptr is_gpu_disabled_sync_switch) : device_(device), + command_queue_(command_queue), worker_task_runner_(std::move(worker_task_runner)), is_gpu_disabled_sync_switch_(std::move(is_gpu_disabled_sync_switch)) { // Validate device. @@ -96,16 +100,6 @@ static bool DeviceSupportsComputeSubgroups(id device) { shader_library_ = std::move(library); } - // Setup command queue. - { - command_queue_ = device_.newCommandQueue; - if (!command_queue_) { - VALIDATION_LOG << "Could not setup the command queue."; - return; - } - command_queue_.label = @"Impeller Command Queue"; - } - // Setup the pipeline library. { pipeline_library_ = @@ -204,13 +198,28 @@ static bool DeviceSupportsComputeSubgroups(id device) { return ::MTLCreateSystemDefaultDevice(); } +static id CreateMetalCommandQueue(id device) { + auto command_queue = device.newCommandQueue; + if (!command_queue) { + VALIDATION_LOG << "Could not setup the command queue."; + return nullptr; + } + command_queue.label = @"Impeller Command Queue"; + return command_queue; +} + std::shared_ptr ContextMTL::Create( const std::vector& shader_library_paths, std::shared_ptr worker_task_runner, std::shared_ptr is_gpu_disabled_sync_switch) { auto device = CreateMetalDevice(); + auto command_queue = CreateMetalCommandQueue(device); + if (!command_queue) { + return nullptr; + } auto context = std::shared_ptr(new ContextMTL( - device, MTLShaderLibraryFromFilePaths(device, shader_library_paths), + device, command_queue, + MTLShaderLibraryFromFilePaths(device, shader_library_paths), std::move(worker_task_runner), std::move(is_gpu_disabled_sync_switch))); if (!context->IsValid()) { FML_LOG(ERROR) << "Could not create Metal context."; @@ -223,12 +232,36 @@ static bool DeviceSupportsComputeSubgroups(id device) { const std::vector>& shader_libraries_data, std::shared_ptr worker_task_runner, std::shared_ptr is_gpu_disabled_sync_switch, - const std::string& label) { + const std::string& library_label) { auto device = CreateMetalDevice(); + auto command_queue = CreateMetalCommandQueue(device); + if (!command_queue) { + return nullptr; + } auto context = std::shared_ptr(new ContextMTL( - device, - MTLShaderLibraryFromFileData(device, shader_libraries_data, label), - worker_task_runner, std::move(is_gpu_disabled_sync_switch))); + device, command_queue, + MTLShaderLibraryFromFileData(device, shader_libraries_data, + library_label), + std::move(worker_task_runner), std::move(is_gpu_disabled_sync_switch))); + if (!context->IsValid()) { + FML_LOG(ERROR) << "Could not create Metal context."; + return nullptr; + } + return context; +} + +std::shared_ptr ContextMTL::Create( + id device, + id command_queue, + const std::vector>& shader_libraries_data, + std::shared_ptr worker_task_runner, + std::shared_ptr is_gpu_disabled_sync_switch, + const std::string& library_label) { + auto context = std::shared_ptr(new ContextMTL( + device, command_queue, + MTLShaderLibraryFromFileData(device, shader_libraries_data, + library_label), + std::move(worker_task_runner), std::move(is_gpu_disabled_sync_switch))); if (!context->IsValid()) { FML_LOG(ERROR) << "Could not create Metal context."; return nullptr; diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 3b139c1890384..d99383dfed11d 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -20,7 +20,8 @@ namespace flutter { class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { public: GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, - const std::shared_ptr& context); + const std::shared_ptr& context, + bool render_to_surface = true); // |Surface| ~GPUSurfaceMetalImpeller(); @@ -35,13 +36,19 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { std::shared_ptr impeller_renderer_; std::shared_ptr aiks_context_; fml::scoped_nsprotocol> last_drawable_; + // TODO(38466): Refactor GPU surface APIs take into account the fact that an + // external view embedder may want to render to the root surface. This is a + // hack to make avoid allocating resources for the root surface when an + // external view embedder is present. + bool render_to_surface_ = true; bool disable_partial_repaint_ = false; // Accumulated damage for each framebuffer; Key is address of underlying // MTLTexture for each drawable std::map damage_; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame( + const SkISize& frame_size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 94f77a1ec192f..d8a7f9b232e24 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -29,11 +29,13 @@ } GPUSurfaceMetalImpeller::GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, - const std::shared_ptr& context) + const std::shared_ptr& context, + bool render_to_surface) : delegate_(delegate), impeller_renderer_(CreateImpellerRenderer(context)), aiks_context_( - std::make_shared(impeller_renderer_ ? context : nullptr)) { + std::make_shared(impeller_renderer_ ? context : nullptr)), + render_to_surface_(render_to_surface) { // If this preference is explicitly set, we allow for disabling partial repaint. NSNumber* disablePartialRepaint = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTDisablePartialRepaint"]; @@ -50,7 +52,7 @@ } // |Surface| -std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrame(const SkISize& frame_info) { +std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrame(const SkISize& frame_size) { TRACE_EVENT0("impeller", "GPUSurfaceMetalImpeller::AcquireFrame"); if (!IsValid()) { @@ -58,7 +60,18 @@ return nullptr; } - auto layer = delegate_->GetCAMetalLayer(frame_info); + if (frame_size.isEmpty()) { + FML_LOG(ERROR) << "Metal surface was asked for an empty frame."; + return nullptr; + } + + if (!render_to_surface_) { + return std::make_unique( + nullptr, SurfaceFrame::FramebufferInfo(), + [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, frame_size); + } + + auto layer = delegate_->GetCAMetalLayer(frame_size); if (!layer) { FML_LOG(ERROR) << "Invalid CAMetalLayer given by the embedder."; return nullptr; @@ -149,7 +162,7 @@ return std::make_unique(nullptr, // surface framebuffer_info, // framebuffer info submit_callback, // submit callback - frame_info, // frame size + frame_size, // frame size nullptr, // context result true // display list fallback ); diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 3090f58865f9a..d5c704703f70a 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -68,6 +68,7 @@ extern const intptr_t kPlatformStrongDillSize; #ifdef SHELL_ENABLE_METAL #include "flutter/shell/platform/embedder/embedder_surface_metal.h" +#include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" #endif const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; @@ -452,7 +453,8 @@ InferMetalPlatformViewCreationCallback( const flutter::PlatformViewEmbedder::PlatformDispatchTable& platform_dispatch_table, std::unique_ptr - external_view_embedder) { + external_view_embedder, + bool enable_impeller) { if (config->type != kMetal) { return nullptr; } @@ -486,20 +488,33 @@ InferMetalPlatformViewCreationCallback( return texture_info; }; - flutter::EmbedderSurfaceMetal::MetalDispatchTable metal_dispatch_table = { - .present = metal_present, - .get_texture = metal_get_texture, - }; - std::shared_ptr view_embedder = std::move(external_view_embedder); - std::unique_ptr embedder_surface = - std::make_unique( - const_cast(config->metal.device), - const_cast( - config->metal.present_command_queue), - metal_dispatch_table, view_embedder); + std::unique_ptr embedder_surface; + + if (enable_impeller) { + flutter::EmbedderSurfaceMetalImpeller::MetalDispatchTable + metal_dispatch_table = { + .present = metal_present, + .get_texture = metal_get_texture, + }; + embedder_surface = std::make_unique( + const_cast(config->metal.device), + const_cast( + config->metal.present_command_queue), + metal_dispatch_table, view_embedder); + } else { + flutter::EmbedderSurfaceMetal::MetalDispatchTable metal_dispatch_table = { + .present = metal_present, + .get_texture = metal_get_texture, + }; + embedder_surface = std::make_unique( + const_cast(config->metal.device), + const_cast( + config->metal.present_command_queue), + metal_dispatch_table, view_embedder); + } // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) @@ -650,7 +665,8 @@ InferPlatformViewCreationCallback( const flutter::PlatformViewEmbedder::PlatformDispatchTable& platform_dispatch_table, std::unique_ptr - external_view_embedder) { + external_view_embedder, + bool enable_impeller) { if (config == nullptr) { return nullptr; } @@ -667,7 +683,7 @@ InferPlatformViewCreationCallback( case kMetal: return InferMetalPlatformViewCreationCallback( config, user_data, platform_dispatch_table, - std::move(external_view_embedder)); + std::move(external_view_embedder), enable_impeller); case kVulkan: return InferVulkanPlatformViewCreationCallback( config, user_data, platform_dispatch_table, @@ -1830,7 +1846,7 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, auto on_create_platform_view = InferPlatformViewCreationCallback( config, user_data, platform_dispatch_table, - std::move(external_view_embedder_result.first)); + std::move(external_view_embedder_result.first), settings.enable_impeller); if (!on_create_platform_view) { return LOG_EMBEDDER_ERROR( diff --git a/shell/platform/embedder/embedder_surface.cc b/shell/platform/embedder/embedder_surface.cc index dbe619b8e0fa7..029833f7434ba 100644 --- a/shell/platform/embedder/embedder_surface.cc +++ b/shell/platform/embedder/embedder_surface.cc @@ -10,4 +10,13 @@ EmbedderSurface::EmbedderSurface() = default; EmbedderSurface::~EmbedderSurface() = default; +std::shared_ptr EmbedderSurface::CreateImpellerContext() + const { + return nullptr; +} + +sk_sp EmbedderSurface::CreateResourceContext() const { + return nullptr; +} + } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface.h b/shell/platform/embedder/embedder_surface.h index ed8dbff74b8d0..99b8de1342335 100644 --- a/shell/platform/embedder/embedder_surface.h +++ b/shell/platform/embedder/embedder_surface.h @@ -5,9 +5,11 @@ #ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_H_ +#include #include "flutter/flow/embedded_views.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" +#include "impeller/renderer/context.h" namespace flutter { @@ -21,7 +23,9 @@ class EmbedderSurface { virtual std::unique_ptr CreateGPUSurface() = 0; - virtual sk_sp CreateResourceContext() const = 0; + virtual std::shared_ptr CreateImpellerContext() const; + + virtual sk_sp CreateResourceContext() const; private: FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurface); diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.h b/shell/platform/embedder/embedder_surface_metal_impeller.h new file mode 100644 index 0000000000000..f723b838ed06b --- /dev/null +++ b/shell/platform/embedder/embedder_surface_metal_impeller.h @@ -0,0 +1,67 @@ +// 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_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_METAL_IMPELLER_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_METAL_IMPELLER_H_ + +#include +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "flutter/shell/gpu/gpu_surface_metal_skia.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_surface.h" +#include "fml/concurrent_message_loop.h" +#include "impeller/renderer/context.h" + +namespace flutter { + +class EmbedderSurfaceMetalImpeller final : public EmbedderSurface, + public GPUSurfaceMetalDelegate { + public: + struct MetalDispatchTable { + std::function present; // required + std::function + get_texture; // required + }; + + EmbedderSurfaceMetalImpeller( + GPUMTLDeviceHandle device, + GPUMTLCommandQueueHandle command_queue, + MetalDispatchTable dispatch_table, + std::shared_ptr external_view_embedder); + + ~EmbedderSurfaceMetalImpeller() override; + + private: + bool valid_ = false; + MetalDispatchTable metal_dispatch_table_; + std::shared_ptr external_view_embedder_; + std::shared_ptr context_; + std::shared_ptr concurrent_loop_; + + // |EmbedderSurface| + bool IsValid() const override; + + // |EmbedderSurface| + std::unique_ptr CreateGPUSurface() override; + + // |GPUSurfaceMetalDelegate| + GPUCAMetalLayerHandle GetCAMetalLayer( + const SkISize& frame_size) const override; + + // |GPUSurfaceMetalDelegate| + bool PresentDrawable(GrMTLHandle drawable) const override; + + // |GPUSurfaceMetalDelegate| + GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_size) const override; + + // |GPUSurfaceMetalDelegate| + bool PresentTexture(GPUMTLTextureInfo texture) const override; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceMetalImpeller); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SURFACE_METAL_IMPELLER_H_ diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm new file mode 100644 index 0000000000000..110d27221d871 --- /dev/null +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -0,0 +1,99 @@ +// 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 +#include + +#include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" + +#include "flutter/fml/logging.h" +#include "flutter/fml/synchronization/sync_switch.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "flutter/shell/gpu/gpu_surface_metal_impeller.h" +#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" +#include "impeller/entity/mtl/entity_shaders.h" +#include "impeller/entity/mtl/framebuffer_blend_shaders.h" +#include "impeller/entity/mtl/modern_shaders.h" +#include "impeller/renderer/backend/metal/context_mtl.h" +#include "impeller/scene/shaders/mtl/scene_shaders.h" + +FLUTTER_ASSERT_NOT_ARC + +namespace flutter { + +EmbedderSurfaceMetalImpeller::EmbedderSurfaceMetalImpeller( + GPUMTLDeviceHandle device, + GPUMTLCommandQueueHandle command_queue, + MetalDispatchTable metal_dispatch_table, + std::shared_ptr external_view_embedder) + : GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture), + metal_dispatch_table_(std::move(metal_dispatch_table)), + external_view_embedder_(std::move(external_view_embedder)), + concurrent_loop_(fml::ConcurrentMessageLoop::Create()) { + std::vector> shader_mappings = { + std::make_shared(impeller_entity_shaders_data, + impeller_entity_shaders_length), + std::make_shared(impeller_scene_shaders_data, + impeller_scene_shaders_length), + std::make_shared(impeller_modern_shaders_data, + impeller_modern_shaders_length), + std::make_shared(impeller_framebuffer_blend_shaders_data, + impeller_framebuffer_blend_shaders_length), + }; + context_ = impeller::ContextMTL::Create( + (id)device, // device + (id)command_queue, // command_queue + shader_mappings, // shader_libraries_data + concurrent_loop_->GetTaskRunner(), // worker_task_runner + std::make_shared(false), // is_gpu_disabled_sync_switch + "Impeller Library" // library_label + ); + + valid_ = !!context_; +} + +EmbedderSurfaceMetalImpeller::~EmbedderSurfaceMetalImpeller() = default; + +bool EmbedderSurfaceMetalImpeller::IsValid() const { + return valid_; +} + +std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() API_AVAILABLE(ios(13.0)) { + if (@available(iOS 13.0, *)) { + } else { + return nullptr; + } + if (!IsValid()) { + return nullptr; + } + + auto surface = std::make_unique(this, context_); + + if (!surface->IsValid()) { + return nullptr; + } + + return surface; +} + +GPUCAMetalLayerHandle EmbedderSurfaceMetalImpeller::GetCAMetalLayer( + const SkISize& frame_info) const { + FML_CHECK(false) << "Only rendering to MTLTexture is supported."; + return nullptr; +} + +bool EmbedderSurfaceMetalImpeller::PresentDrawable(GrMTLHandle drawable) const { + FML_CHECK(false) << "Only rendering to MTLTexture is supported."; + return false; +} + +GPUMTLTextureInfo EmbedderSurfaceMetalImpeller::GetMTLTexture(const SkISize& frame_info) const { + return metal_dispatch_table_.get_texture(frame_info); +} + +bool EmbedderSurfaceMetalImpeller::PresentTexture(GPUMTLTextureInfo texture) const { + return metal_dispatch_table_.present(texture); +} + +} // namespace flutter diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 1cedc22810a50..ccbe0fc01a524 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -86,7 +86,7 @@ PlatformViewEmbedder::PlatformViewEmbedder( PlatformViewEmbedder::PlatformViewEmbedder( PlatformView::Delegate& delegate, const flutter::TaskRunners& task_runners, - std::unique_ptr embedder_surface, + std::unique_ptr embedder_surface, PlatformDispatchTable platform_dispatch_table, std::shared_ptr external_view_embedder) : PlatformView(delegate, task_runners), @@ -157,6 +157,11 @@ PlatformViewEmbedder::CreateExternalViewEmbedder() { return external_view_embedder_; } +std::shared_ptr PlatformViewEmbedder::GetImpellerContext() + const { + return embedder_surface_->CreateImpellerContext(); +} + // |PlatformView| sk_sp PlatformViewEmbedder::CreateResourceContext() const { if (embedder_surface_ == nullptr) { diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index 20f4dc139875b..87378b5074672 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -76,7 +76,7 @@ class PlatformViewEmbedder final : public PlatformView { PlatformViewEmbedder( PlatformView::Delegate& delegate, const flutter::TaskRunners& task_runners, - std::unique_ptr embedder_surface, + std::unique_ptr embedder_surface, PlatformDispatchTable platform_dispatch_table, std::shared_ptr external_view_embedder); #endif @@ -118,6 +118,9 @@ class PlatformViewEmbedder final : public PlatformView { // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; + // |PlatformView| + std::shared_ptr GetImpellerContext() const override; + // |PlatformView| sk_sp CreateResourceContext() const override; From 3475eaffbea0c16b41f46e74860155f40b2134d0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Mon, 29 May 2023 14:25:31 -0700 Subject: [PATCH 02/34] Embedder platform view progress --- flow/embedded_views.h | 8 +- shell/common/rasterizer.cc | 7 +- shell/common/rasterizer_unittests.cc | 4 +- .../shell_test_external_view_embedder.cc | 1 + .../shell_test_external_view_embedder.h | 1 + .../external_view_embedder.cc | 1 + .../external_view_embedder.h | 1 + .../darwin/ios/ios_external_view_embedder.h | 1 + .../darwin/ios/ios_external_view_embedder.mm | 6 +- shell/platform/embedder/embedder.cc | 118 +++++++++++++++--- .../embedder_external_view_embedder.cc | 3 +- .../embedder_external_view_embedder.h | 4 + .../embedder/embedder_render_target.cc | 9 +- .../embedder/embedder_render_target.h | 3 + 14 files changed, 136 insertions(+), 31 deletions(-) diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 4162e79a15af6..71986a618caa2 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_FLOW_EMBEDDED_VIEWS_H_ #define FLUTTER_FLOW_EMBEDDED_VIEWS_H_ +#include #include #include "flutter/display_list/dl_builder.h" @@ -13,6 +14,7 @@ #include "flutter/flow/surface_frame.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/raster_thread_merger.h" +#include "impeller/renderer/context.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -414,8 +416,10 @@ class ExternalViewEmbedder { // This method can mutate the root Skia canvas before submitting the frame. // // It can also allocate frames for overlay surfaces to compose hybrid views. - virtual void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame); + virtual void SubmitFrame( + GrDirectContext* context, + const std::shared_ptr& impeller_context, + std::unique_ptr frame); // This method provides the embedder a way to do additional tasks after // |SubmitFrame|. For example, merge task runners if `should_resubmit_frame` diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 145ae60bb2833..0410dc87d54b5 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -635,8 +635,11 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( if (external_view_embedder_ && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - external_view_embedder_->SubmitFrame(surface_->GetContext(), - std::move(frame)); + auto aiks_context = surface_->GetAiksContext(); + external_view_embedder_->SubmitFrame( + surface_->GetContext(), + !!aiks_context ? aiks_context->GetContext() : nullptr, + std::move(frame)); } else { frame->Submit(); } diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 53de96c86bd4e..e81781cf18faf 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -14,6 +14,7 @@ #include "flutter/fml/time/time_point.h" #include "flutter/shell/common/thread_host.h" #include "flutter/testing/testing.h" +#include "impeller/renderer/context.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkSurface.h" @@ -74,8 +75,9 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { PostPrerollResult( fml::RefPtr raster_thread_merger)); MOCK_METHOD1(CompositeEmbeddedView, DlCanvas*(int64_t view_id)); - MOCK_METHOD2(SubmitFrame, + MOCK_METHOD3(SubmitFrame, void(GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame)); MOCK_METHOD2(EndFrame, void(bool should_resubmit_frame, diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc index 2536bb62ac6a2..55dde74369dc9 100644 --- a/shell/common/shell_test_external_view_embedder.cc +++ b/shell/common/shell_test_external_view_embedder.cc @@ -91,6 +91,7 @@ DlCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView( // |ExternalViewEmbedder| void ShellTestExternalViewEmbedder::SubmitFrame( GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) { if (!frame) { return; diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h index 204472d5bc050..0df8389db16ca 100644 --- a/shell/common/shell_test_external_view_embedder.h +++ b/shell/common/shell_test_external_view_embedder.h @@ -75,6 +75,7 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.cc b/shell/platform/android/external_view_embedder/external_view_embedder.cc index f1d8af9f6a710..79859cb9c0eac 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -64,6 +64,7 @@ SkRect AndroidExternalViewEmbedder::GetViewRect(int64_t view_id) const { // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::SubmitFrame( GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) { TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame"); diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.h b/shell/platform/android/external_view_embedder/external_view_embedder.h index 03bae5ecb8e1a..229c0301e91fd 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -46,6 +46,7 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.h b/shell/platform/darwin/ios/ios_external_view_embedder.h index 3893ccec0c1ab..a3f567e196e30 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -51,6 +51,7 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index 4e28b6cfcca82..da13b874092bf 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -66,8 +66,10 @@ } // |ExternalViewEmbedder| -void IOSExternalViewEmbedder::SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) { +void IOSExternalViewEmbedder::SubmitFrame( + GrDirectContext* context, + const std::shared_ptr& impeller_context, + std::unique_ptr frame) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); FML_CHECK(platform_views_controller_); platform_views_controller_->SubmitFrame(context, ios_context_, std::move(frame)); diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index d5c704703f70a..00ea711e80312 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "impeller/core/formats.h" +#include "impeller/core/texture_descriptor.h" +#include "impeller/renderer/backend/metal/texture_mtl.h" #define FML_USED_ON_EMBEDDER #define RAPIDJSON_HAS_STDSTRING 1 @@ -913,6 +916,66 @@ static sk_sp MakeSkSurfaceFromBackingStore( #endif } +static std::shared_ptr MakeImpellerSurfaceFromBackingStore( + std::shared_ptr impeller_context, + const FlutterBackingStoreConfig& config, + const FlutterMetalBackingStore* metal) { +#ifdef SHELL_ENABLE_METAL + if (!metal->texture.texture) { + FML_LOG(ERROR) << "Embedder supplied null Metal texture."; + return nullptr; + } + + impeller::TextureDescriptor desc; + desc.size = ISize(config.size.width, config.size.height); + desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + desc.mip_count = 0; + desc.sample_count = impeller::SampleCount::kCount1; + desc.usage = static_cast(TextureUsage::kRenderTarget) | + static_cast(TextureUsage::kShaderRead); + auto texture = impeller::TextureMTL::Wrapper(desc, metal->texture.texture); // WRAP THE DESTRUCTION CALLBACK HERE + + + + + + + + GrMtlTextureInfo texture_info; + GrBackendTexture backend_texture(config.size.width, // + config.size.height, // + GrMipMapped::kNo, // + texture_info // + ); + + SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); + + auto surface = SkSurfaces::WrapBackendTexture( + context, // context + backend_texture, // back-end texture + kTopLeft_GrSurfaceOrigin, // surface origin + // TODO(dnfield): Update this when embedders support MSAA, see + // https://github.com/flutter/flutter/issues/100392 + 1, // sample count + kBGRA_8888_SkColorType, // color type + nullptr, // color space + &surface_properties, // surface properties + static_cast( + metal->texture.destruction_callback), // release proc + metal->texture.user_data // release context + ); + + if (!surface) { + FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture."; + return nullptr; + } + + return surface; +#else + return nullptr; +#endif +} + static sk_sp MakeSkSurfaceFromBackingStore( GrDirectContext* context, const FlutterBackingStoreConfig& config, @@ -967,9 +1030,12 @@ static sk_sp MakeSkSurfaceFromBackingStore( } static std::unique_ptr -CreateEmbedderRenderTarget(const FlutterCompositor* compositor, - const FlutterBackingStoreConfig& config, - GrDirectContext* context) { +CreateEmbedderRenderTarget( + const FlutterCompositor* compositor, + const FlutterBackingStoreConfig& config, + GrDirectContext* context, + const std::shared_ptr& impeller_context, + bool enable_impeller) { FlutterBackingStore backing_store = {}; backing_store.struct_size = sizeof(backing_store); @@ -1004,53 +1070,61 @@ CreateEmbedderRenderTarget(const FlutterCompositor* compositor, // No safe access checks on the renderer are necessary since we allocated // the struct. - sk_sp render_surface; + sk_sp skia_surface; + std::shared_ptr impeller_surface; switch (backing_store.type) { case kFlutterBackingStoreTypeOpenGL: switch (backing_store.open_gl.type) { case kFlutterOpenGLTargetTypeTexture: - render_surface = MakeSkSurfaceFromBackingStore( + skia_surface = MakeSkSurfaceFromBackingStore( context, config, &backing_store.open_gl.texture); break; case kFlutterOpenGLTargetTypeFramebuffer: - render_surface = MakeSkSurfaceFromBackingStore( + skia_surface = MakeSkSurfaceFromBackingStore( context, config, &backing_store.open_gl.framebuffer); break; } break; case kFlutterBackingStoreTypeSoftware: - render_surface = MakeSkSurfaceFromBackingStore(context, config, - &backing_store.software); + skia_surface = MakeSkSurfaceFromBackingStore(context, config, + &backing_store.software); break; case kFlutterBackingStoreTypeSoftware2: - render_surface = MakeSkSurfaceFromBackingStore(context, config, - &backing_store.software2); + skia_surface = MakeSkSurfaceFromBackingStore(context, config, + &backing_store.software2); break; case kFlutterBackingStoreTypeMetal: - render_surface = - MakeSkSurfaceFromBackingStore(context, config, &backing_store.metal); + if (enable_impeller) { + impeller_surface = MakeImpellerSurfaceFromBackingStore( + impeller_context, config, &backing_store.metal); + } else { + skia_surface = MakeSkSurfaceFromBackingStore(context, config, + &backing_store.metal); + } break; case kFlutterBackingStoreTypeVulkan: - render_surface = + skia_surface = MakeSkSurfaceFromBackingStore(context, config, &backing_store.vulkan); break; }; - if (!render_surface) { + if (!(skia_surface || impeller_surface)) { FML_LOG(ERROR) << "Could not create a surface from an embedder provided " "render target."; return nullptr; } return std::make_unique( - backing_store, std::move(render_surface), collect_callback.Release()); + backing_store, std::move(skia_surface), std::move(impeller_surface), + collect_callback.Release()); } static std::pair, bool /* halt engine launch if true */> -InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) { +InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor, + bool enable_impeller) { if (compositor == nullptr) { return {nullptr, false}; } @@ -1074,9 +1148,13 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) { flutter::EmbedderExternalViewEmbedder::CreateRenderTargetCallback create_render_target_callback = - [captured_compositor](GrDirectContext* context, const auto& config) { + [captured_compositor, enable_impeller]( + GrDirectContext* context, + const std::shared_ptr& impeller_context, + const auto& config) { return CreateEmbedderRenderTarget(&captured_compositor, config, - context); + context, impeller_context, + enable_impeller); }; flutter::EmbedderExternalViewEmbedder::PresentCallback present_callback = @@ -1828,8 +1906,8 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, user_data]() { return ptr(user_data); }; } - auto external_view_embedder_result = - InferExternalViewEmbedderFromArgs(SAFE_ACCESS(args, compositor, nullptr)); + auto external_view_embedder_result = InferExternalViewEmbedderFromArgs( + SAFE_ACCESS(args, compositor, nullptr), settings.enable_impeller); if (external_view_embedder_result.second) { return LOG_EMBEDDER_ERROR(kInvalidArguments, "Compositor arguments were invalid."); diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index e4870090c6c9f..496fdc450e5d7 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -125,6 +125,7 @@ static FlutterBackingStoreConfig MakeBackingStoreConfig( // |ExternalViewEmbedder| void EmbedderExternalViewEmbedder::SubmitFrame( GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) { auto [matched_render_targets, pending_keys] = render_target_cache_.GetExistingTargetsInCache(pending_views_); @@ -173,7 +174,7 @@ void EmbedderExternalViewEmbedder::SubmitFrame( // // @warning: Embedder may trample on our OpenGL context here. auto render_target = - create_render_target_callback_(context, backing_store_config); + create_render_target_callback_(context, impeller_context, backing_store_config); if (!render_target) { FML_LOG(ERROR) << "Embedder did not return a valid render target."; diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index 55a08f0627a72..abffe0970516f 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -6,6 +6,7 @@ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_VIEW_EMBEDDER_H_ #include +#include #include #include "flutter/flow/embedded_views.h" @@ -13,6 +14,7 @@ #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder_external_view.h" #include "flutter/shell/platform/embedder/embedder_render_target_cache.h" +#include "impeller/renderer/context.h" namespace flutter { @@ -31,6 +33,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { using CreateRenderTargetCallback = std::function( GrDirectContext* context, + const std::shared_ptr& impeller_context, const FlutterBackingStoreConfig& config)>; using PresentCallback = std::function& layers)>; @@ -95,6 +98,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& impeller_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/embedder/embedder_render_target.cc b/shell/platform/embedder/embedder_render_target.cc index 5d6d22887c043..e7c15c6e77368 100644 --- a/shell/platform/embedder/embedder_render_target.cc +++ b/shell/platform/embedder/embedder_render_target.cc @@ -12,11 +12,14 @@ namespace flutter { -EmbedderRenderTarget::EmbedderRenderTarget(FlutterBackingStore backing_store, - sk_sp render_surface, - fml::closure on_release) +EmbedderRenderTarget::EmbedderRenderTarget( + FlutterBackingStore backing_store, + sk_sp render_surface, + std::shared_ptr impeller_surface, + fml::closure on_release) : backing_store_(backing_store), render_surface_(std::move(render_surface)), + impeller_surface_(std::move(impeller_surface)), on_release_(std::move(on_release)) { // TODO(38468): The optimization to elide backing store updates between frames // has not been implemented yet. diff --git a/shell/platform/embedder/embedder_render_target.h b/shell/platform/embedder/embedder_render_target.h index 8afbed31e30f0..85a02f38291d9 100644 --- a/shell/platform/embedder/embedder_render_target.h +++ b/shell/platform/embedder/embedder_render_target.h @@ -8,6 +8,7 @@ #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "impeller/core/texture.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSurface.h" @@ -36,6 +37,7 @@ class EmbedderRenderTarget { /// EmbedderRenderTarget(FlutterBackingStore backing_store, sk_sp render_surface, + std::shared_ptr impeller_surface, fml::closure on_release); //---------------------------------------------------------------------------- @@ -68,6 +70,7 @@ class EmbedderRenderTarget { private: FlutterBackingStore backing_store_; sk_sp render_surface_; + std::shared_ptr impeller_surface_; fml::closure on_release_; FML_DISALLOW_COPY_AND_ASSIGN(EmbedderRenderTarget); From c9bcbe2f9c8f58fcb3ca15fd7285f02b531fbd39 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 30 May 2023 03:52:57 -0700 Subject: [PATCH 03/34] Render target wrapping --- ci/licenses_golden/licenses_flutter | 8 ++ flow/BUILD.gn | 1 + flow/embedded_views.cc | 6 +- flow/embedded_views.h | 4 +- impeller/renderer/backend/metal/BUILD.gn | 2 + impeller/renderer/backend/metal/texture_mtl.h | 6 +- .../renderer/backend/metal/texture_mtl.mm | 17 ++- .../backend/metal/texture_wrapper_mtl.h | 16 +++ .../backend/metal/texture_wrapper_mtl.mm | 20 +++ shell/common/BUILD.gn | 1 + shell/common/rasterizer.cc | 5 +- shell/common/rasterizer_unittests.cc | 4 +- .../shell_test_external_view_embedder.cc | 2 +- .../shell_test_external_view_embedder.h | 2 +- .../external_view_embedder.cc | 2 +- .../external_view_embedder.h | 2 +- .../external_view_embedder_unittests.cc | 18 +-- .../darwin/ios/ios_external_view_embedder.h | 2 +- .../darwin/ios/ios_external_view_embedder.mm | 2 +- shell/platform/embedder/BUILD.gn | 8 +- shell/platform/embedder/embedder.cc | 124 ++++++++++-------- .../embedder/embedder_external_view.cc | 25 +++- .../embedder_external_view_embedder.cc | 6 +- .../embedder_external_view_embedder.h | 5 +- .../embedder/embedder_render_target.cc | 35 ++++- .../embedder/embedder_render_target.h | 37 +++++- .../embedder/embedder_render_target_cache.cc | 3 +- .../embedder_surface_metal_impeller.h | 2 +- .../embedder_surface_metal_impeller.mm | 2 +- 29 files changed, 256 insertions(+), 111 deletions(-) create mode 100644 impeller/renderer/backend/metal/texture_wrapper_mtl.h create mode 100644 impeller/renderer/backend/metal/texture_wrapper_mtl.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 834ba5aec7f6f..c246e26536c24 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1480,6 +1480,8 @@ ORIGIN: ../../../flutter/impeller/renderer/backend/metal/surface_mtl.h + ../../. ORIGIN: ../../../flutter/impeller/renderer/backend/metal/surface_mtl.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/metal/texture_mtl.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/metal/texture_mtl.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/renderer/backend/metal/texture_wrapper_mtl.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/renderer/backend/metal/texture_wrapper_mtl.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/renderer/backend/vulkan/allocator_vk.cc + ../../../flutter/LICENSE @@ -2801,6 +2803,8 @@ ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_gl.cc + ../../ ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_gl.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_metal.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_metal.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_metal_impeller.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_metal_impeller.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_software.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_software.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_vulkan.cc + ../../../flutter/LICENSE @@ -4139,6 +4143,8 @@ FILE: ../../../flutter/impeller/renderer/backend/metal/surface_mtl.h FILE: ../../../flutter/impeller/renderer/backend/metal/surface_mtl.mm FILE: ../../../flutter/impeller/renderer/backend/metal/texture_mtl.h FILE: ../../../flutter/impeller/renderer/backend/metal/texture_mtl.mm +FILE: ../../../flutter/impeller/renderer/backend/metal/texture_wrapper_mtl.h +FILE: ../../../flutter/impeller/renderer/backend/metal/texture_wrapper_mtl.mm FILE: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.h FILE: ../../../flutter/impeller/renderer/backend/metal/vertex_descriptor_mtl.mm FILE: ../../../flutter/impeller/renderer/backend/vulkan/allocator_vk.cc @@ -5476,6 +5482,8 @@ FILE: ../../../flutter/shell/platform/embedder/embedder_surface_gl.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface_gl.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_metal.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_metal.mm +FILE: ../../../flutter/shell/platform/embedder/embedder_surface_metal_impeller.h +FILE: ../../../flutter/shell/platform/embedder/embedder_surface_metal_impeller.mm FILE: ../../../flutter/shell/platform/embedder/embedder_surface_software.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface_software.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_vulkan.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index efda895393f26..489af89e76915 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -93,6 +93,7 @@ source_set("flow") { "//flutter/common", "//flutter/common/graphics", "//flutter/fml", + "//flutter/impeller/aiks:aiks", "//third_party/skia", ] diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index b76c9730af903..c19f1c198e3e3 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -42,8 +42,10 @@ bool DisplayListEmbedderViewSlice::recording_ended() { return builder_ == nullptr; } -void ExternalViewEmbedder::SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) { +void ExternalViewEmbedder::SubmitFrame( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) { frame->Submit(); }; diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 71986a618caa2..ffeb3317e8a93 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -14,7 +14,7 @@ #include "flutter/flow/surface_frame.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/raster_thread_merger.h" -#include "impeller/renderer/context.h" +#include "impeller/aiks/aiks_context.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -418,7 +418,7 @@ class ExternalViewEmbedder { // It can also allocate frames for overlay surfaces to compose hybrid views. virtual void SubmitFrame( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame); // This method provides the embedder a way to do additional tasks after diff --git a/impeller/renderer/backend/metal/BUILD.gn b/impeller/renderer/backend/metal/BUILD.gn index 7ad03e9cea138..9a0f6a631e3d7 100644 --- a/impeller/renderer/backend/metal/BUILD.gn +++ b/impeller/renderer/backend/metal/BUILD.gn @@ -42,6 +42,8 @@ impeller_component("metal") { "surface_mtl.mm", "texture_mtl.h", "texture_mtl.mm", + "texture_wrapper_mtl.h", + "texture_wrapper_mtl.mm", "vertex_descriptor_mtl.h", "vertex_descriptor_mtl.mm", ] diff --git a/impeller/renderer/backend/metal/texture_mtl.h b/impeller/renderer/backend/metal/texture_mtl.h index 9d9378d1b6ce7..91cd8a122da11 100644 --- a/impeller/renderer/backend/metal/texture_mtl.h +++ b/impeller/renderer/backend/metal/texture_mtl.h @@ -19,8 +19,10 @@ class TextureMTL final : public Texture, id texture, bool wrapped = false); - static std::shared_ptr Wrapper(TextureDescriptor desc, - id texture); + static std::shared_ptr Wrapper( + TextureDescriptor desc, + id texture, + std::function deletion_proc = nullptr); // |Texture| ~TextureMTL() override; diff --git a/impeller/renderer/backend/metal/texture_mtl.mm b/impeller/renderer/backend/metal/texture_mtl.mm index 5c63624c014c6..98a812914308d 100644 --- a/impeller/renderer/backend/metal/texture_mtl.mm +++ b/impeller/renderer/backend/metal/texture_mtl.mm @@ -9,6 +9,13 @@ namespace impeller { +std::shared_ptr WrapperMTL(TextureDescriptor desc, + const void* mtl_texture, + std::function deletion_proc) { + return TextureMTL::Wrapper(desc, (__bridge id)mtl_texture, + std::move(deletion_proc)); +} + TextureMTL::TextureMTL(TextureDescriptor p_desc, id texture, bool wrapped) @@ -28,9 +35,13 @@ is_valid_ = true; } -std::shared_ptr TextureMTL::Wrapper(TextureDescriptor desc, - id texture) { - return std::make_shared(desc, texture, true); +std::shared_ptr TextureMTL::Wrapper( + TextureDescriptor desc, + id texture, + std::function deletion_proc) { + return std::shared_ptr(new TextureMTL(desc, texture, true), + [deletion_proc = std::move(deletion_proc)]( + TextureMTL* t) { deletion_proc(); }); } TextureMTL::~TextureMTL() = default; diff --git a/impeller/renderer/backend/metal/texture_wrapper_mtl.h b/impeller/renderer/backend/metal/texture_wrapper_mtl.h new file mode 100644 index 0000000000000..e6fe71f0f22e6 --- /dev/null +++ b/impeller/renderer/backend/metal/texture_wrapper_mtl.h @@ -0,0 +1,16 @@ +// 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. + +#pragma once + +#include "impeller/core/texture.h" + +namespace impeller { + +std::shared_ptr WrapTextureMTL( + TextureDescriptor desc, + const void* mtl_texture, + std::function deletion_proc = nullptr); + +} // namespace impeller diff --git a/impeller/renderer/backend/metal/texture_wrapper_mtl.mm b/impeller/renderer/backend/metal/texture_wrapper_mtl.mm new file mode 100644 index 0000000000000..a1a550433f0b0 --- /dev/null +++ b/impeller/renderer/backend/metal/texture_wrapper_mtl.mm @@ -0,0 +1,20 @@ +// 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/renderer/backend/metal/texture_wrapper_mtl.h" + +#include + +#include "impeller/renderer/backend/metal/texture_mtl.h" + +namespace impeller { + +std::shared_ptr WrapTextureMTL(TextureDescriptor desc, + const void* mtl_texture, + std::function deletion_proc) { + return TextureMTL::Wrapper(desc, (__bridge id)mtl_texture, + std::move(deletion_proc)); +} + +} // namespace impeller diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 19009938162fc..1185c5994456e 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -315,6 +315,7 @@ if (enable_unittests) { ":shell_unittests_fixtures", "//flutter/assets", "//flutter/common/graphics", + "//flutter/impeller/aiks:aiks", "//flutter/shell/profiling:profiling_unittests", "//flutter/shell/version", "//flutter/testing:fixture_test", diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 0410dc87d54b5..40aea5b7481d0 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -635,11 +635,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( if (external_view_embedder_ && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - auto aiks_context = surface_->GetAiksContext(); external_view_embedder_->SubmitFrame( - surface_->GetContext(), - !!aiks_context ? aiks_context->GetContext() : nullptr, - std::move(frame)); + surface_->GetContext(), surface_->GetAiksContext(), std::move(frame)); } else { frame->Submit(); } diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index e81781cf18faf..257f5e981037f 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -14,7 +14,7 @@ #include "flutter/fml/time/time_point.h" #include "flutter/shell/common/thread_host.h" #include "flutter/testing/testing.h" -#include "impeller/renderer/context.h" +#include "impeller/aiks/aiks_context.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkSurface.h" @@ -77,7 +77,7 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { MOCK_METHOD1(CompositeEmbeddedView, DlCanvas*(int64_t view_id)); MOCK_METHOD3(SubmitFrame, void(GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame)); MOCK_METHOD2(EndFrame, void(bool should_resubmit_frame, diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc index 55dde74369dc9..22b9bfe13554b 100644 --- a/shell/common/shell_test_external_view_embedder.cc +++ b/shell/common/shell_test_external_view_embedder.cc @@ -91,7 +91,7 @@ DlCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView( // |ExternalViewEmbedder| void ShellTestExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) { if (!frame) { return; diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h index 0df8389db16ca..36a392d208856 100644 --- a/shell/common/shell_test_external_view_embedder.h +++ b/shell/common/shell_test_external_view_embedder.h @@ -75,7 +75,7 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.cc b/shell/platform/android/external_view_embedder/external_view_embedder.cc index 79859cb9c0eac..d29a80eb16a8c 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -64,7 +64,7 @@ SkRect AndroidExternalViewEmbedder::GetViewRect(int64_t view_id) const { // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) { TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame"); diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.h b/shell/platform/android/external_view_embedder/external_view_embedder.h index 229c0301e91fd..33b876674f6c3 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -46,7 +46,7 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc index 3c08eef409281..e6417a08f0800 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc @@ -313,7 +313,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); // Submits frame if no Android view in the current frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -381,7 +381,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); // Doesn't submit frame if there aren't Android views in the previous frame. EXPECT_FALSE(did_submit_frame); // Resubmits frame. @@ -446,7 +446,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); // Submits frame if there are Android views in the previous frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -553,7 +553,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -656,7 +656,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -724,7 +724,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -825,7 +825,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -912,7 +912,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -1023,7 +1023,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) { SkSurfaces::Null(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.h b/shell/platform/darwin/ios/ios_external_view_embedder.h index a3f567e196e30..d83b435930f21 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -51,7 +51,7 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index da13b874092bf..67112e999d13d 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -68,7 +68,7 @@ // |ExternalViewEmbedder| void IOSExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); FML_CHECK(platform_views_controller_); diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 9c827ac38bd3c..1f6f2974807a1 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -91,6 +91,8 @@ template("embedder_source_set") { "vsync_waiter_embedder.h", ] + public_deps = [ ":embedder_headers" ] + if (embedder_enable_gl) { sources += [ "embedder_external_texture_gl.cc", @@ -122,11 +124,15 @@ template("embedder_source_set") { "embedder_external_texture_metal.mm", "embedder_surface_metal.h", "embedder_surface_metal.mm", + "embedder_surface_metal_impeller.h", + "embedder_surface_metal_impeller.mm", ] cflags_objc = flutter_cflags_objc cflags_objcc = flutter_cflags_objcc + public_deps += [ "//flutter/impeller/renderer/backend/metal" ] + deps += [ "//flutter/shell/platform/darwin/graphics" ] } @@ -142,8 +148,6 @@ template("embedder_source_set") { ] } - public_deps = [ ":embedder_headers" ] - public_configs += [ ":embedder_gpu_configuration_config", ":embedder_header_config", diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 00ea711e80312..892da1e20705d 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "impeller/core/formats.h" -#include "impeller/core/texture_descriptor.h" -#include "impeller/renderer/backend/metal/texture_mtl.h" #define FML_USED_ON_EMBEDDER #define RAPIDJSON_HAS_STDSTRING 1 @@ -20,6 +17,8 @@ #include "flutter/fml/make_copyable.h" #include "flutter/fml/native_library.h" #include "flutter/fml/thread.h" +#include "impeller/core/texture.h" +#include "impeller/renderer/render_target.h" #include "third_party/dart/runtime/bin/elf_loader.h" #include "third_party/dart/runtime/include/dart_native_api.h" #include "third_party/skia/include/core/SkSurface.h" @@ -72,6 +71,7 @@ extern const intptr_t kPlatformStrongDillSize; #ifdef SHELL_ENABLE_METAL #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" +#include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" #endif const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; @@ -916,63 +916,71 @@ static sk_sp MakeSkSurfaceFromBackingStore( #endif } -static std::shared_ptr MakeImpellerSurfaceFromBackingStore( - std::shared_ptr impeller_context, +static std::optional +MakeImpellerSurfaceFromBackingStore( + const std::shared_ptr& aiks_context, const FlutterBackingStoreConfig& config, const FlutterMetalBackingStore* metal) { #ifdef SHELL_ENABLE_METAL if (!metal->texture.texture) { FML_LOG(ERROR) << "Embedder supplied null Metal texture."; - return nullptr; + return std::nullopt; + } + + const auto size = impeller::ISize(config.size.width, config.size.height); + const auto color_format = impeller::PixelFormat::kR8G8B8A8UNormInt; + + impeller::TextureDescriptor msaa_tex_desc; + msaa_tex_desc.storage_mode = impeller::StorageMode::kDeviceTransient; + msaa_tex_desc.type = impeller::TextureType::kTexture2DMultisample; + msaa_tex_desc.sample_count = impeller::SampleCount::kCount4; + msaa_tex_desc.format = color_format; + msaa_tex_desc.size = size; + msaa_tex_desc.usage = + static_cast(impeller::TextureUsage::kRenderTarget); + + auto msaa_tex = + aiks_context->GetContext()->GetResourceAllocator()->CreateTexture( + msaa_tex_desc); + if (!msaa_tex) { + FML_LOG(ERROR) << "Could not allocate MSAA color texture."; + return std::nullopt; + } + msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA"); + + impeller::TextureDescriptor resolve_tex_desc; + resolve_tex_desc.size = size; + resolve_tex_desc.format = color_format; + resolve_tex_desc.mip_count = 0; + resolve_tex_desc.sample_count = impeller::SampleCount::kCount1; + resolve_tex_desc.storage_mode = impeller::StorageMode::kDevicePrivate; + resolve_tex_desc.usage = + static_cast(impeller::TextureUsage::kRenderTarget) | + static_cast(impeller::TextureUsage::kShaderRead); + auto resolve_tex = impeller::WrapTextureMTL( + resolve_tex_desc, metal->texture.texture, + [callback = metal->texture.destruction_callback, + user_data = metal->texture.user_data]() { callback(user_data); }); + + if (!resolve_tex) { + FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture."; + return std::nullopt; } + resolve_tex->SetLabel("ImpellerBackingStoreResolve"); - impeller::TextureDescriptor desc; - desc.size = ISize(config.size.width, config.size.height); - desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; - desc.mip_count = 0; - desc.sample_count = impeller::SampleCount::kCount1; - desc.usage = static_cast(TextureUsage::kRenderTarget) | - static_cast(TextureUsage::kShaderRead); - auto texture = impeller::TextureMTL::Wrapper(desc, metal->texture.texture); // WRAP THE DESTRUCTION CALLBACK HERE - - - - - - - - GrMtlTextureInfo texture_info; - GrBackendTexture backend_texture(config.size.width, // - config.size.height, // - GrMipMapped::kNo, // - texture_info // - ); - - SkSurfaceProps surface_properties(0, kUnknown_SkPixelGeometry); - - auto surface = SkSurfaces::WrapBackendTexture( - context, // context - backend_texture, // back-end texture - kTopLeft_GrSurfaceOrigin, // surface origin - // TODO(dnfield): Update this when embedders support MSAA, see - // https://github.com/flutter/flutter/issues/100392 - 1, // sample count - kBGRA_8888_SkColorType, // color type - nullptr, // color space - &surface_properties, // surface properties - static_cast( - metal->texture.destruction_callback), // release proc - metal->texture.user_data // release context - ); + impeller::ColorAttachment color0; + color0.texture = msaa_tex; + color0.clear_color = impeller::Color::DarkSlateGray(); + color0.load_action = impeller::LoadAction::kClear; + color0.store_action = impeller::StoreAction::kMultisampleResolve; + color0.resolve_texture = resolve_tex; - if (!surface) { - FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture."; - return nullptr; - } + impeller::RenderTarget render_target_desc; + render_target_desc.SetColorAttachment(color0, 0u); - return surface; + return render_target_desc; #else - return nullptr; + return std::nullopt; #endif } @@ -1034,7 +1042,7 @@ CreateEmbedderRenderTarget( const FlutterCompositor* compositor, const FlutterBackingStoreConfig& config, GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, bool enable_impeller) { FlutterBackingStore backing_store = {}; backing_store.struct_size = sizeof(backing_store); @@ -1071,7 +1079,7 @@ CreateEmbedderRenderTarget( // the struct. sk_sp skia_surface; - std::shared_ptr impeller_surface; + std::optional impeller_target; switch (backing_store.type) { case kFlutterBackingStoreTypeOpenGL: @@ -1096,8 +1104,8 @@ CreateEmbedderRenderTarget( break; case kFlutterBackingStoreTypeMetal: if (enable_impeller) { - impeller_surface = MakeImpellerSurfaceFromBackingStore( - impeller_context, config, &backing_store.metal); + impeller_target = MakeImpellerSurfaceFromBackingStore( + aiks_context, config, &backing_store.metal); } else { skia_surface = MakeSkSurfaceFromBackingStore(context, config, &backing_store.metal); @@ -1110,14 +1118,14 @@ CreateEmbedderRenderTarget( break; }; - if (!(skia_surface || impeller_surface)) { + if (!(skia_surface || impeller_target.has_value())) { FML_LOG(ERROR) << "Could not create a surface from an embedder provided " "render target."; return nullptr; } return std::make_unique( - backing_store, std::move(skia_surface), std::move(impeller_surface), + backing_store, std::move(skia_surface), aiks_context, impeller_target, collect_callback.Release()); } @@ -1150,10 +1158,10 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor, create_render_target_callback = [captured_compositor, enable_impeller]( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, const auto& config) { return CreateEmbedderRenderTarget(&captured_compositor, config, - context, impeller_context, + context, aiks_context, enable_impeller); }; diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index cd72a3e4978b6..f2a3bba99e570 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -3,8 +3,10 @@ // found in the LICENSE file. #include "flutter/shell/platform/embedder/embedder_external_view.h" +#include "flutter/display_list/dl_builder.h" #include "flutter/fml/trace_event.h" #include "flutter/shell/common/dl_op_spy.h" +#include "impeller/display_list/dl_dispatcher.h" namespace flutter { @@ -83,15 +85,28 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { << "Unnecessarily asked to render into a render target when there was " "nothing to render."; - auto surface = render_target.GetRenderSurface(); - if (!surface) { + auto impeller_target = render_target.GetImpellerRenderTarget(); + if (impeller_target.has_value()) { + auto aiks_context = render_target.GetAiksContext(); + + DisplayListBuilder dl_builder; + dl_builder.SetTransform(&surface_transformation_); + slice_->render_into(&dl_builder); + + auto dispatcher = impeller::DlDispatcher(); + dispatcher.drawDisplayList(dl_builder.Build(), 1); + aiks_context->Render(dispatcher.EndRecordingAsPicture(), *impeller_target); + return true; + } + + auto skia_surface = render_target.GetRenderSurface(); + if (!skia_surface) { return false; } - FML_DCHECK(SkISize::Make(surface->width(), surface->height()) == - render_surface_size_); + FML_DCHECK(render_target.GetRenderTargetSize() == render_surface_size_); - auto canvas = surface->getCanvas(); + auto canvas = skia_surface->getCanvas(); if (!canvas) { return false; } diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index 496fdc450e5d7..f87d451a6af26 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -125,7 +125,7 @@ static FlutterBackingStoreConfig MakeBackingStoreConfig( // |ExternalViewEmbedder| void EmbedderExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) { auto [matched_render_targets, pending_keys] = render_target_cache_.GetExistingTargetsInCache(pending_views_); @@ -173,8 +173,8 @@ void EmbedderExternalViewEmbedder::SubmitFrame( // the context must be reset. // // @warning: Embedder may trample on our OpenGL context here. - auto render_target = - create_render_target_callback_(context, impeller_context, backing_store_config); + auto render_target = create_render_target_callback_(context, aiks_context, + backing_store_config); if (!render_target) { FML_LOG(ERROR) << "Embedder did not return a valid render target."; diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index abffe0970516f..014f7393c416e 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -14,7 +14,6 @@ #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder_external_view.h" #include "flutter/shell/platform/embedder/embedder_render_target_cache.h" -#include "impeller/renderer/context.h" namespace flutter { @@ -33,7 +32,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { using CreateRenderTargetCallback = std::function( GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, const FlutterBackingStoreConfig& config)>; using PresentCallback = std::function& layers)>; @@ -98,7 +97,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& impeller_context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| diff --git a/shell/platform/embedder/embedder_render_target.cc b/shell/platform/embedder/embedder_render_target.cc index e7c15c6e77368..729a62bf4e613 100644 --- a/shell/platform/embedder/embedder_render_target.cc +++ b/shell/platform/embedder/embedder_render_target.cc @@ -4,10 +4,13 @@ #include "flutter/shell/platform/embedder/embedder_render_target.h" +#include #include #include "flutter/fml/logging.h" +#include "impeller/aiks/aiks_context.h" +#include "impeller/renderer/render_target.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { @@ -15,16 +18,24 @@ namespace flutter { EmbedderRenderTarget::EmbedderRenderTarget( FlutterBackingStore backing_store, sk_sp render_surface, - std::shared_ptr impeller_surface, + std::shared_ptr aiks_context, + std::optional impeller_target, fml::closure on_release) : backing_store_(backing_store), render_surface_(std::move(render_surface)), - impeller_surface_(std::move(impeller_surface)), + aiks_context_(std::move(aiks_context)), + impeller_target_(std::move(impeller_target)), on_release_(std::move(on_release)) { // TODO(38468): The optimization to elide backing store updates between frames // has not been implemented yet. backing_store_.did_update = true; - FML_DCHECK(render_surface_); + + if (impeller_target_) { + FML_DCHECK(aiks_context_); + FML_DCHECK(!render_surface_); + } else { + FML_CHECK(render_surface_); + } } EmbedderRenderTarget::~EmbedderRenderTarget() { @@ -41,4 +52,22 @@ sk_sp EmbedderRenderTarget::GetRenderSurface() const { return render_surface_; } +std::optional +EmbedderRenderTarget::GetImpellerRenderTarget() const { + return impeller_target_; +} + +std::shared_ptr EmbedderRenderTarget::GetAiksContext() + const { + return aiks_context_; +} + +SkISize EmbedderRenderTarget::GetRenderTargetSize() const { + if (impeller_target_.has_value()) { + auto size = impeller_target_->GetRenderTargetSize(); + return SkISize::Make(size.width, size.height); + } + return SkISize::Make(render_surface_->width(), render_surface_->height()); +} + } // namespace flutter diff --git a/shell/platform/embedder/embedder_render_target.h b/shell/platform/embedder/embedder_render_target.h index 85a02f38291d9..3c29a4f3a5c8d 100644 --- a/shell/platform/embedder/embedder_render_target.h +++ b/shell/platform/embedder/embedder_render_target.h @@ -5,11 +5,15 @@ #ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_H_ +#include +#include #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "impeller/core/texture.h" +#include "impeller/aiks/aiks_context.h" +#include "impeller/renderer/render_target.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { @@ -37,7 +41,8 @@ class EmbedderRenderTarget { /// EmbedderRenderTarget(FlutterBackingStore backing_store, sk_sp render_surface, - std::shared_ptr impeller_surface, + std::shared_ptr aiks_context, + std::optional impeller_target, fml::closure on_release); //---------------------------------------------------------------------------- @@ -55,6 +60,29 @@ class EmbedderRenderTarget { /// sk_sp GetRenderSurface() const; + //---------------------------------------------------------------------------- + /// @brief An impeller render target the rasterizer can use to draw into + /// the backing store. + /// + /// @return The Impeller render target. + /// + std::optional GetImpellerRenderTarget() const; + + //---------------------------------------------------------------------------- + /// @brief Returns the AiksContext that should be used for rendering, if + /// this render target is backed by Impeller. + /// + /// @return The Impeller Aiks context. + /// + std::shared_ptr GetAiksContext() const; + + //---------------------------------------------------------------------------- + /// @brief Returns the size of the render target. + /// + /// @return The size of the render target. + /// + SkISize GetRenderTargetSize() const; + //---------------------------------------------------------------------------- /// @brief The embedder backing store descriptor. This is the descriptor /// that was given to the engine by the embedder. This descriptor @@ -70,7 +98,10 @@ class EmbedderRenderTarget { private: FlutterBackingStore backing_store_; sk_sp render_surface_; - std::shared_ptr impeller_surface_; + + std::shared_ptr aiks_context_; + std::optional impeller_target_; + fml::closure on_release_; FML_DISALLOW_COPY_AND_ASSIGN(EmbedderRenderTarget); diff --git a/shell/platform/embedder/embedder_render_target_cache.cc b/shell/platform/embedder/embedder_render_target_cache.cc index 1347b032791d1..3d0e6b4c99858 100644 --- a/shell/platform/embedder/embedder_render_target_cache.cc +++ b/shell/platform/embedder/embedder_render_target_cache.cc @@ -56,9 +56,8 @@ void EmbedderRenderTargetCache::CacheRenderTarget( if (target == nullptr) { return; } - auto surface = target->GetRenderSurface(); auto desc = EmbedderExternalView::RenderTargetDescriptor{ - view_identifier, SkISize::Make(surface->width(), surface->height())}; + view_identifier, target->GetRenderTargetSize()}; cached_render_targets_[desc].push(std::move(target)); } diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.h b/shell/platform/embedder/embedder_surface_metal_impeller.h index f723b838ed06b..00406030f8256 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.h +++ b/shell/platform/embedder/embedder_surface_metal_impeller.h @@ -17,7 +17,7 @@ namespace flutter { class EmbedderSurfaceMetalImpeller final : public EmbedderSurface, - public GPUSurfaceMetalDelegate { + public GPUSurfaceMetalDelegate { public: struct MetalDispatchTable { std::function present; // required diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index 110d27221d871..a97b98fd0a7bf 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -11,7 +11,7 @@ #include "flutter/fml/synchronization/sync_switch.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "flutter/shell/gpu/gpu_surface_metal_impeller.h" -#include "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h" +#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalImpeller.h" #include "impeller/entity/mtl/entity_shaders.h" #include "impeller/entity/mtl/framebuffer_blend_shaders.h" #include "impeller/entity/mtl/modern_shaders.h" From d631207313c96c5790fc39b830adc0ed3551306f Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 30 May 2023 13:39:09 -0700 Subject: [PATCH 04/34] Add texture-only path --- common/settings.h | 2 +- .../backend/metal/playground_impl_mtl.mm | 2 +- impeller/renderer/backend/metal/surface_mtl.h | 12 +- .../renderer/backend/metal/surface_mtl.mm | 162 ++++++++++++------ shell/gpu/gpu_surface_metal_impeller.h | 9 +- shell/gpu/gpu_surface_metal_impeller.mm | 136 +++++++++++++-- .../embedder_surface_metal_impeller.mm | 3 +- 7 files changed, 260 insertions(+), 66 deletions(-) diff --git a/common/settings.h b/common/settings.h index 9e9fa7dea24d9..ea4e00a15d01f 100644 --- a/common/settings.h +++ b/common/settings.h @@ -214,7 +214,7 @@ struct Settings { #if FML_OS_IOS || FML_OS_IOS_SIMULATOR bool enable_impeller = true; #else - bool enable_impeller = false; + bool enable_impeller = true; #endif // Enable Vulkan validation on backends that support it. The validation layers diff --git a/impeller/playground/backend/metal/playground_impl_mtl.mm b/impeller/playground/backend/metal/playground_impl_mtl.mm index 25f108666ebe0..55e17871f70a5 100644 --- a/impeller/playground/backend/metal/playground_impl_mtl.mm +++ b/impeller/playground/backend/metal/playground_impl_mtl.mm @@ -121,7 +121,7 @@ auto drawable = SurfaceMTL::GetMetalDrawableAndValidate(context, data_->metal_layer); - return SurfaceMTL::WrapCurrentMetalLayerDrawable(context, drawable); + return SurfaceMTL::MakeFromMetalLayerDrawable(context, drawable); } } // namespace impeller diff --git a/impeller/renderer/backend/metal/surface_mtl.h b/impeller/renderer/backend/metal/surface_mtl.h index cebc43e340451..3a7db1c1300d7 100644 --- a/impeller/renderer/backend/metal/surface_mtl.h +++ b/impeller/renderer/backend/metal/surface_mtl.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "flutter/fml/macros.h" #include "impeller/geometry/rect.h" @@ -37,10 +38,15 @@ class SurfaceMTL final : public Surface { const std::shared_ptr& context, CAMetalLayer* layer); - static std::unique_ptr WrapCurrentMetalLayerDrawable( + static std::unique_ptr MakeFromMetalLayerDrawable( const std::shared_ptr& context, id drawable, std::optional clip_rect = std::nullopt); + + static std::unique_ptr MakeFromTexture( + const std::shared_ptr& context, + id texture, + std::optional clip_rect); #pragma GCC diagnostic pop // |Surface| @@ -58,6 +64,8 @@ class SurfaceMTL final : public Surface { std::weak_ptr context_; std::shared_ptr resolve_texture_; id drawable_ = nil; + std::shared_ptr source_texture_; + std::shared_ptr destination_texture_; bool requires_blit_ = false; std::optional clip_rect_; @@ -67,6 +75,8 @@ class SurfaceMTL final : public Surface { const RenderTarget& target, std::shared_ptr resolve_texture, id drawable, + std::shared_ptr source_texture, + std::shared_ptr destination_texture, bool requires_blit, std::optional clip_rect); diff --git a/impeller/renderer/backend/metal/surface_mtl.mm b/impeller/renderer/backend/metal/surface_mtl.mm index 05eec4964b49d..8fcda54405999 100644 --- a/impeller/renderer/backend/metal/surface_mtl.mm +++ b/impeller/renderer/backend/metal/surface_mtl.mm @@ -7,6 +7,7 @@ #include "flutter/fml/trace_event.h" #include "flutter/impeller/renderer/command_buffer.h" #include "impeller/base/validation.h" +#include "impeller/core/texture_descriptor.h" #include "impeller/renderer/backend/metal/context_mtl.h" #include "impeller/renderer/backend/metal/formats_mtl.h" #include "impeller/renderer/backend/metal/texture_mtl.h" @@ -39,17 +40,11 @@ return current_drawable; } -std::unique_ptr SurfaceMTL::WrapCurrentMetalLayerDrawable( - const std::shared_ptr& context, - id drawable, +static std::optional WrapTextureWithRenderTarget( + Allocator& allocator, + id texture, + bool requires_blit, std::optional clip_rect) { - bool requires_blit = ShouldPerformPartialRepaint(clip_rect); - const auto color_format = FromMTLPixelFormat(drawable.texture.pixelFormat); - - if (color_format == PixelFormat::kUnknown) { - VALIDATION_LOG << "Unknown drawable color format."; - return nullptr; - } // compositor_context.cc will offset the rendering by the clip origin. Here we // shrink to the size of the clip. This has the same effect as clipping the // rendering but also creates smaller intermediate passes. @@ -57,76 +52,140 @@ if (requires_blit) { root_size = ISize(clip_rect->size.width, clip_rect->size.height); } else { - root_size = {static_cast(drawable.texture.width), - static_cast(drawable.texture.height)}; + root_size = {static_cast(texture.width), + static_cast(texture.height)}; } - TextureDescriptor msaa_tex_desc; - msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient; - msaa_tex_desc.type = TextureType::kTexture2DMultisample; - msaa_tex_desc.sample_count = SampleCount::kCount4; - msaa_tex_desc.format = color_format; - msaa_tex_desc.size = root_size; - msaa_tex_desc.usage = static_cast(TextureUsage::kRenderTarget); - - auto msaa_tex = context->GetResourceAllocator()->CreateTexture(msaa_tex_desc); - if (!msaa_tex) { - VALIDATION_LOG << "Could not allocate MSAA color texture."; - return nullptr; - } - msaa_tex->SetLabel("ImpellerOnscreenColorMSAA"); - TextureDescriptor resolve_tex_desc; - resolve_tex_desc.format = color_format; - resolve_tex_desc.size = msaa_tex_desc.size; + resolve_tex_desc.format = FromMTLPixelFormat(texture.pixelFormat); + resolve_tex_desc.size = root_size; resolve_tex_desc.usage = static_cast(TextureUsage::kRenderTarget) | static_cast(TextureUsage::kShaderRead); resolve_tex_desc.sample_count = SampleCount::kCount1; resolve_tex_desc.storage_mode = StorageMode::kDevicePrivate; + if (resolve_tex_desc.format == PixelFormat::kUnknown) { + VALIDATION_LOG << "Unknown drawable color format."; + return std::nullopt; + } + // Create color resolve texture. std::shared_ptr resolve_tex; if (requires_blit) { resolve_tex_desc.compression_type = CompressionType::kLossy; - resolve_tex = - context->GetResourceAllocator()->CreateTexture(resolve_tex_desc); + resolve_tex = allocator.CreateTexture(resolve_tex_desc); } else { - resolve_tex = - std::make_shared(resolve_tex_desc, drawable.texture); + resolve_tex = std::make_shared(resolve_tex_desc, texture); } if (!resolve_tex) { VALIDATION_LOG << "Could not wrap resolve texture."; - return nullptr; + return std::nullopt; } resolve_tex->SetLabel("ImpellerOnscreenResolve"); + TextureDescriptor msaa_tex_desc; + msaa_tex_desc.storage_mode = StorageMode::kDeviceTransient; + msaa_tex_desc.type = TextureType::kTexture2DMultisample; + msaa_tex_desc.sample_count = SampleCount::kCount4; + msaa_tex_desc.format = resolve_tex->GetTextureDescriptor().format; + msaa_tex_desc.size = resolve_tex->GetSize(); + msaa_tex_desc.usage = static_cast(TextureUsage::kRenderTarget); + + auto msaa_tex = allocator.CreateTexture(msaa_tex_desc); + if (!msaa_tex) { + VALIDATION_LOG << "Could not allocate MSAA color texture."; + return std::nullopt; + } + msaa_tex->SetLabel("ImpellerOnscreenColorMSAA"); + ColorAttachment color0; color0.texture = msaa_tex; color0.clear_color = Color::DarkSlateGray(); color0.load_action = LoadAction::kClear; color0.store_action = StoreAction::kMultisampleResolve; - color0.resolve_texture = resolve_tex; + color0.resolve_texture = std::move(resolve_tex); RenderTarget render_target_desc; render_target_desc.SetColorAttachment(color0, 0u); - // The constructor is private. So make_unique may not be used. - return std::unique_ptr(new SurfaceMTL(context, render_target_desc, - resolve_tex, drawable, - requires_blit, clip_rect)); + return render_target_desc; +} + +std::unique_ptr SurfaceMTL::MakeFromMetalLayerDrawable( + const std::shared_ptr& context, + id drawable, + std::optional clip_rect) { + bool requires_blit = ShouldPerformPartialRepaint(clip_rect); + + auto render_target = + WrapTextureWithRenderTarget(*context->GetResourceAllocator(), + drawable.texture, requires_blit, clip_rect); + if (!render_target) { + return nullptr; + } + + auto source_texture = + requires_blit ? render_target->GetRenderTargetTexture() : nullptr; + auto destination_texture = TextureMTL::Wrapper( + render_target->GetRenderTargetTexture()->GetTextureDescriptor(), + drawable.texture); + + return std::unique_ptr(new SurfaceMTL( + context, // context + *render_target, // target + render_target->GetRenderTargetTexture(), // resolve_texture + drawable, // drawable + source_texture, // source_texture + destination_texture, // destination_texture + requires_blit, // requires_blit + clip_rect // clip_rect + )); +} + +std::unique_ptr SurfaceMTL::MakeFromTexture( + const std::shared_ptr& context, + id texture, + std::optional clip_rect) { + bool requires_blit = ShouldPerformPartialRepaint(clip_rect); + + auto render_target = WrapTextureWithRenderTarget( + *context->GetResourceAllocator(), texture, requires_blit, clip_rect); + if (!render_target) { + return nullptr; + } + + auto source_texture = + requires_blit ? render_target->GetRenderTargetTexture() : nullptr; + auto destination_texture = TextureMTL::Wrapper( + render_target->GetRenderTargetTexture()->GetTextureDescriptor(), texture); + + return std::unique_ptr(new SurfaceMTL( + context, // context + *render_target, // target + render_target->GetRenderTargetTexture(), // resolve_texture + nil, // drawable + source_texture, // source_texture + destination_texture, // destination_texture + requires_blit, // requires_blit + clip_rect // clip_rect + )); } SurfaceMTL::SurfaceMTL(const std::weak_ptr& context, const RenderTarget& target, std::shared_ptr resolve_texture, id drawable, + std::shared_ptr source_texture, + std::shared_ptr destination_texture, bool requires_blit, std::optional clip_rect) : Surface(target), context_(context), resolve_texture_(std::move(resolve_texture)), drawable_(drawable), + source_texture_(std::move(source_texture)), + destination_texture_(std::move(destination_texture)), requires_blit_(requires_blit), clip_rect_(clip_rect) {} @@ -169,23 +228,22 @@ static bool ShouldWaitForCommandBuffer() { // |Surface| bool SurfaceMTL::Present() const { - if (drawable_ == nil) { - return false; - } - auto context = context_.lock(); if (!context) { return false; } if (requires_blit_) { + if (!(source_texture_ && destination_texture_)) { + return false; + } + auto blit_command_buffer = context->CreateCommandBuffer(); if (!blit_command_buffer) { return false; } auto blit_pass = blit_command_buffer->CreateBlitPass(); - auto current = TextureMTL::Wrapper({}, drawable_.texture); - blit_pass->AddCopy(resolve_texture_, current, std::nullopt, + blit_pass->AddCopy(source_texture_, destination_texture_, std::nullopt, clip_rect_->origin); blit_pass->EncodeCommands(context->GetResourceAllocator()); if (!blit_command_buffer->SubmitCommands()) { @@ -193,13 +251,15 @@ static bool ShouldWaitForCommandBuffer() { } } - if (ShouldWaitForCommandBuffer()) { - id command_buffer = - ContextMTL::Cast(context.get())->CreateMTLCommandBuffer(); - [command_buffer commit]; - [command_buffer waitUntilScheduled]; + if (drawable_) { + if (ShouldWaitForCommandBuffer()) { + id command_buffer = + ContextMTL::Cast(context.get())->CreateMTLCommandBuffer(); + [command_buffer commit]; + [command_buffer waitUntilScheduled]; + } + [drawable_ present]; } - [drawable_ present]; return true; } diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index d99383dfed11d..df3a81fef8bfe 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -33,9 +33,10 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { private: const GPUSurfaceMetalDelegate* delegate_; + const MTLRenderTargetType render_target_type_; std::shared_ptr impeller_renderer_; std::shared_ptr aiks_context_; - fml::scoped_nsprotocol> last_drawable_; + fml::scoped_nsprotocol> last_texture_; // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. This is a // hack to make avoid allocating resources for the root surface when an @@ -50,6 +51,12 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { std::unique_ptr AcquireFrame( const SkISize& frame_size) override; + std::unique_ptr AcquireFrameFromCAMetalLayer( + const SkISize& frame_size); + + std::unique_ptr AcquireFrameFromMTLTexture( + const SkISize& frame_size); + // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index d8a7f9b232e24..32b2f28325394 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -32,6 +32,7 @@ const std::shared_ptr& context, bool render_to_surface) : delegate_(delegate), + render_target_type_(delegate->GetRenderTargetType()), impeller_renderer_(CreateImpellerRenderer(context)), aiks_context_( std::make_shared(impeller_renderer_ ? context : nullptr)), @@ -71,7 +72,22 @@ [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, frame_size); } + switch (render_target_type_) { + case MTLRenderTargetType::kCAMetalLayer: + return AcquireFrameFromCAMetalLayer(frame_size); + case MTLRenderTargetType::kMTLTexture: + return AcquireFrameFromMTLTexture(frame_size); + default: + FML_CHECK(false) << "Unknown MTLRenderTargetType type."; + } + + return nullptr; +} + +std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrameFromCAMetalLayer( + const SkISize& frame_size) { auto layer = delegate_->GetCAMetalLayer(frame_size); + if (!layer) { FML_LOG(ERROR) << "Invalid CAMetalLayer given by the embedder."; return nullptr; @@ -82,15 +98,16 @@ auto drawable = impeller::SurfaceMTL::GetMetalDrawableAndValidate( impeller_renderer_->GetContext(), mtl_layer); if (Settings::kSurfaceDataAccessible) { - last_drawable_.reset([drawable retain]); + last_texture_.reset([drawable.texture retain]); } - id metal_drawable = static_cast>(last_drawable_); + id last_texture = static_cast>(last_texture_); SurfaceFrame::SubmitCallback submit_callback = fml::MakeCopyable([this, // renderer = impeller_renderer_, // aiks_context = aiks_context_, // - metal_drawable // + drawable, // + last_texture // ](SurfaceFrame& surface_frame, DlCanvas* canvas) mutable -> bool { if (!aiks_context) { return false; @@ -103,7 +120,7 @@ } if (!disable_partial_repaint_) { - uintptr_t texture = reinterpret_cast(metal_drawable.texture); + uintptr_t texture = reinterpret_cast(last_texture); for (auto& entry : damage_) { if (entry.first != texture) { @@ -124,8 +141,106 @@ buffer_damage->width(), buffer_damage->height()); } - auto surface = impeller::SurfaceMTL::WrapCurrentMetalLayerDrawable( - impeller_renderer_->GetContext(), metal_drawable, clip_rect); + auto surface = impeller::SurfaceMTL::MakeFromMetalLayerDrawable( + impeller_renderer_->GetContext(), drawable, clip_rect); + + if (clip_rect && (clip_rect->size.width == 0 || clip_rect->size.height == 0)) { + return surface->Present(); + } + + impeller::IRect cull_rect = surface->coverage(); + SkIRect sk_cull_rect = SkIRect::MakeWH(cull_rect.size.width, cull_rect.size.height); + impeller::DlDispatcher impeller_dispatcher(cull_rect); + display_list->Dispatch(impeller_dispatcher, sk_cull_rect); + auto picture = impeller_dispatcher.EndRecordingAsPicture(); + + return renderer->Render( + std::move(surface), + fml::MakeCopyable([aiks_context, picture = std::move(picture)]( + impeller::RenderTarget& render_target) -> bool { + return aiks_context->Render(picture, render_target); + })); + }); + + SurfaceFrame::FramebufferInfo framebuffer_info; + framebuffer_info.supports_readback = true; + + if (!disable_partial_repaint_) { + // Provide accumulated damage to rasterizer (area in current framebuffer that lags behind + // front buffer) + uintptr_t texture = reinterpret_cast(drawable.texture); + auto i = damage_.find(texture); + if (i != damage_.end()) { + framebuffer_info.existing_damage = i->second; + } + framebuffer_info.supports_partial_repaint = true; + } + + return std::make_unique(nullptr, // surface + framebuffer_info, // framebuffer info + submit_callback, // submit callback + frame_size, // frame size + nullptr, // context result + true // display list fallback + ); +} + +std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrameFromMTLTexture( + const SkISize& frame_size) { + GPUMTLTextureInfo texture_info = delegate_->GetMTLTexture(frame_size); + id mtl_texture = (id)(texture_info.texture); + + if (!mtl_texture) { + FML_LOG(ERROR) << "Invalid MTLTexture given by the embedder."; + return nullptr; + } + + if (Settings::kSurfaceDataAccessible) { + last_texture_.reset([mtl_texture retain]); + } + + SurfaceFrame::SubmitCallback submit_callback = + fml::MakeCopyable([this, // + renderer = impeller_renderer_, // + aiks_context = aiks_context_, // + texture_info, // + mtl_texture, // + delegate = delegate_ // + ](SurfaceFrame& surface_frame, DlCanvas* canvas) mutable -> bool { + if (!aiks_context) { + return false; + } + + auto display_list = surface_frame.BuildDisplayList(); + if (!display_list) { + FML_LOG(ERROR) << "Could not build display list for surface frame."; + return false; + } + + if (!disable_partial_repaint_) { + uintptr_t texture_ptr = reinterpret_cast(mtl_texture); + + for (auto& entry : damage_) { + if (entry.first != texture_ptr) { + // Accumulate damage for other framebuffers + if (surface_frame.submit_info().frame_damage) { + entry.second.join(*surface_frame.submit_info().frame_damage); + } + } + } + // Reset accumulated damage for current framebuffer + damage_[texture_ptr] = SkIRect::MakeEmpty(); + } + + std::optional clip_rect; + if (surface_frame.submit_info().buffer_damage.has_value()) { + auto buffer_damage = surface_frame.submit_info().buffer_damage; + clip_rect = impeller::IRect::MakeXYWH(buffer_damage->x(), buffer_damage->y(), + buffer_damage->width(), buffer_damage->height()); + } + + auto surface = + impeller::SurfaceMTL::MakeFromTexture(renderer->GetContext(), mtl_texture, clip_rect); if (clip_rect && (clip_rect->size.width == 0 || clip_rect->size.height == 0)) { return surface->Present(); @@ -143,6 +258,8 @@ impeller::RenderTarget& render_target) -> bool { return aiks_context->Render(picture, render_target); })); + + delegate->PresentTexture(texture_info); }); SurfaceFrame::FramebufferInfo framebuffer_info; @@ -151,7 +268,7 @@ if (!disable_partial_repaint_) { // Provide accumulated damage to rasterizer (area in current framebuffer that lags behind // front buffer) - uintptr_t texture = reinterpret_cast(metal_drawable.texture); + uintptr_t texture = reinterpret_cast(mtl_texture); auto i = damage_.find(texture); if (i != damage_.end()) { framebuffer_info.existing_damage = i->second; @@ -201,11 +318,10 @@ } Surface::SurfaceData GPUSurfaceMetalImpeller::GetSurfaceData() const { - if (!(last_drawable_ && [last_drawable_ conformsToProtocol:@protocol(CAMetalDrawable)])) { + if (!(last_texture_ && [last_texture_ conformsToProtocol:@protocol(MTLTexture)])) { return {}; } - id metal_drawable = static_cast>(last_drawable_); - id texture = metal_drawable.texture; + id texture = last_texture_.get(); int bytesPerPixel = 0; std::string pixel_format; switch (texture.pixelFormat) { diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index a97b98fd0a7bf..e800e0e6218ce 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -68,7 +68,8 @@ return nullptr; } - auto surface = std::make_unique(this, context_); + const bool render_to_surface = !external_view_embedder_; + auto surface = std::make_unique(this, context_, render_to_surface); if (!surface->IsValid()) { return nullptr; From 3a9d4a58f582c4f2e9748af74b8aad068dfe03ba Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 30 May 2023 18:55:59 -0700 Subject: [PATCH 05/34] It's alive! --- flow/BUILD.gn | 6 ++- .../renderer/backend/metal/texture_mtl.mm | 11 +++-- .../backend/metal/texture_wrapper_mtl.mm | 6 ++- shell/platform/embedder/BUILD.gn | 2 + shell/platform/embedder/embedder.cc | 41 +++++++++---------- .../embedder/embedder_external_view.cc | 4 +- 6 files changed, 39 insertions(+), 31 deletions(-) diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 489af89e76915..b69d5a02cfac8 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -93,11 +93,13 @@ source_set("flow") { "//flutter/common", "//flutter/common/graphics", "//flutter/fml", - "//flutter/impeller/aiks:aiks", "//third_party/skia", ] - public_deps = [ "//flutter/display_list" ] + public_deps = [ + "//flutter/display_list", + "//flutter/impeller/aiks:aiks", + ] } if (enable_unittests) { diff --git a/impeller/renderer/backend/metal/texture_mtl.mm b/impeller/renderer/backend/metal/texture_mtl.mm index 98a812914308d..bc57684363a7d 100644 --- a/impeller/renderer/backend/metal/texture_mtl.mm +++ b/impeller/renderer/backend/metal/texture_mtl.mm @@ -39,9 +39,14 @@ TextureDescriptor desc, id texture, std::function deletion_proc) { - return std::shared_ptr(new TextureMTL(desc, texture, true), - [deletion_proc = std::move(deletion_proc)]( - TextureMTL* t) { deletion_proc(); }); + if (deletion_proc) { + return std::shared_ptr( + new TextureMTL(desc, texture, true), + [deletion_proc = std::move(deletion_proc)](TextureMTL* t) { + deletion_proc(); + }); + } + return std::shared_ptr(new TextureMTL(desc, texture, true)); } TextureMTL::~TextureMTL() = default; diff --git a/impeller/renderer/backend/metal/texture_wrapper_mtl.mm b/impeller/renderer/backend/metal/texture_wrapper_mtl.mm index a1a550433f0b0..2b6a908f6d7cb 100644 --- a/impeller/renderer/backend/metal/texture_wrapper_mtl.mm +++ b/impeller/renderer/backend/metal/texture_wrapper_mtl.mm @@ -6,6 +6,7 @@ #include +#include "impeller/renderer/backend/metal/formats_mtl.h" #include "impeller/renderer/backend/metal/texture_mtl.h" namespace impeller { @@ -13,8 +14,9 @@ std::shared_ptr WrapTextureMTL(TextureDescriptor desc, const void* mtl_texture, std::function deletion_proc) { - return TextureMTL::Wrapper(desc, (__bridge id)mtl_texture, - std::move(deletion_proc)); + auto texture = (__bridge id)mtl_texture; + desc.format = FromMTLPixelFormat(texture.pixelFormat); + return TextureMTL::Wrapper(desc, texture, std::move(deletion_proc)); } } // namespace impeller diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 1f6f2974807a1..359f62c4b02e0 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -5,6 +5,7 @@ import("//build/toolchain/clang.gni") import("//flutter/build/zip_bundle.gni") import("//flutter/common/config.gni") +import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/gpu/gpu.gni") import("//flutter/shell/platform/embedder/embedder.gni") import("//flutter/testing/testing.gni") @@ -150,6 +151,7 @@ template("embedder_source_set") { public_configs += [ ":embedder_gpu_configuration_config", + "//flutter/impeller:impeller_public_config", ":embedder_header_config", "//flutter:config", ] diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 892da1e20705d..d2c6e0555b021 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -928,46 +928,43 @@ MakeImpellerSurfaceFromBackingStore( } const auto size = impeller::ISize(config.size.width, config.size.height); - const auto color_format = impeller::PixelFormat::kR8G8B8A8UNormInt; - - impeller::TextureDescriptor msaa_tex_desc; - msaa_tex_desc.storage_mode = impeller::StorageMode::kDeviceTransient; - msaa_tex_desc.type = impeller::TextureType::kTexture2DMultisample; - msaa_tex_desc.sample_count = impeller::SampleCount::kCount4; - msaa_tex_desc.format = color_format; - msaa_tex_desc.size = size; - msaa_tex_desc.usage = - static_cast(impeller::TextureUsage::kRenderTarget); - - auto msaa_tex = - aiks_context->GetContext()->GetResourceAllocator()->CreateTexture( - msaa_tex_desc); - if (!msaa_tex) { - FML_LOG(ERROR) << "Could not allocate MSAA color texture."; - return std::nullopt; - } - msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA"); impeller::TextureDescriptor resolve_tex_desc; resolve_tex_desc.size = size; - resolve_tex_desc.format = color_format; - resolve_tex_desc.mip_count = 0; resolve_tex_desc.sample_count = impeller::SampleCount::kCount1; resolve_tex_desc.storage_mode = impeller::StorageMode::kDevicePrivate; resolve_tex_desc.usage = static_cast(impeller::TextureUsage::kRenderTarget) | static_cast(impeller::TextureUsage::kShaderRead); + auto resolve_tex = impeller::WrapTextureMTL( resolve_tex_desc, metal->texture.texture, [callback = metal->texture.destruction_callback, user_data = metal->texture.user_data]() { callback(user_data); }); - if (!resolve_tex) { FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture."; return std::nullopt; } resolve_tex->SetLabel("ImpellerBackingStoreResolve"); + impeller::TextureDescriptor msaa_tex_desc; + msaa_tex_desc.storage_mode = impeller::StorageMode::kDeviceTransient; + msaa_tex_desc.type = impeller::TextureType::kTexture2DMultisample; + msaa_tex_desc.sample_count = impeller::SampleCount::kCount4; + msaa_tex_desc.format = resolve_tex->GetTextureDescriptor().format; + msaa_tex_desc.size = size; + msaa_tex_desc.usage = + static_cast(impeller::TextureUsage::kRenderTarget); + + auto msaa_tex = + aiks_context->GetContext()->GetResourceAllocator()->CreateTexture( + msaa_tex_desc); + if (!msaa_tex) { + FML_LOG(ERROR) << "Could not allocate MSAA color texture."; + return std::nullopt; + } + msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA"); + impeller::ColorAttachment color0; color0.texture = msaa_tex; color0.clear_color = impeller::Color::DarkSlateGray(); diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index f2a3bba99e570..f5f6c5ca4341b 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -95,8 +95,8 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { auto dispatcher = impeller::DlDispatcher(); dispatcher.drawDisplayList(dl_builder.Build(), 1); - aiks_context->Render(dispatcher.EndRecordingAsPicture(), *impeller_target); - return true; + return aiks_context->Render(dispatcher.EndRecordingAsPicture(), + *impeller_target); } auto skia_surface = render_target.GetRenderSurface(); From fc9fd8976889f6acebceea8733e4f3a445147b73 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Tue, 30 May 2023 19:22:31 -0700 Subject: [PATCH 06/34] Derp --- common/settings.h | 2 +- flow/BUILD.gn | 3 ++- shell/platform/embedder/BUILD.gn | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/common/settings.h b/common/settings.h index ea4e00a15d01f..9e9fa7dea24d9 100644 --- a/common/settings.h +++ b/common/settings.h @@ -214,7 +214,7 @@ struct Settings { #if FML_OS_IOS || FML_OS_IOS_SIMULATOR bool enable_impeller = true; #else - bool enable_impeller = true; + bool enable_impeller = false; #endif // Enable Vulkan validation on backends that support it. The validation layers diff --git a/flow/BUILD.gn b/flow/BUILD.gn index b69d5a02cfac8..677a545626655 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -4,6 +4,7 @@ import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") +import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/config.gni") import("//flutter/testing/testing.gni") @@ -98,7 +99,7 @@ source_set("flow") { public_deps = [ "//flutter/display_list", - "//flutter/impeller/aiks:aiks", + "//flutter/impeller", ] } diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 359f62c4b02e0..d9930174a9440 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -110,6 +110,7 @@ template("embedder_source_set") { "//flutter/common/graphics", "//flutter/flow", "//flutter/fml", + "//flutter/impeller", "//flutter/lib/ui", "//flutter/runtime:libdart", "//flutter/shell/common", @@ -151,7 +152,6 @@ template("embedder_source_set") { public_configs += [ ":embedder_gpu_configuration_config", - "//flutter/impeller:impeller_public_config", ":embedder_header_config", "//flutter:config", ] From 2167ade5b4cbfe5f3c3332eb69304afa01ea2d3e Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 00:02:50 -0700 Subject: [PATCH 07/34] Deps --- shell/platform/embedder/BUILD.gn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index d9930174a9440..7008cf21f7733 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -110,7 +110,8 @@ template("embedder_source_set") { "//flutter/common/graphics", "//flutter/flow", "//flutter/fml", - "//flutter/impeller", + "//flutter/impeller/aiks", + "//flutter/impeller/renderer", "//flutter/lib/ui", "//flutter/runtime:libdart", "//flutter/shell/common", From 84c2343d61b39a4bca19661dee18d9868961ab88 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 00:17:36 -0700 Subject: [PATCH 08/34] Address comments --- flow/BUILD.gn | 2 +- shell/platform/embedder/embedder_external_view.cc | 2 +- shell/platform/embedder/embedder_render_target.cc | 2 +- shell/platform/embedder/embedder_surface_metal_impeller.mm | 6 +----- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 677a545626655..adf3d0ef666ea 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -4,7 +4,6 @@ import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") -import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/config.gni") import("//flutter/testing/testing.gni") @@ -100,6 +99,7 @@ source_set("flow") { public_deps = [ "//flutter/display_list", "//flutter/impeller", + "//flutter/impeller/aiks", ] } diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index f5f6c5ca4341b..1a8b3bde3b800 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -89,7 +89,7 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { if (impeller_target.has_value()) { auto aiks_context = render_target.GetAiksContext(); - DisplayListBuilder dl_builder; + auto dl_builder = DisplayListBuilder(); dl_builder.SetTransform(&surface_transformation_); slice_->render_into(&dl_builder); diff --git a/shell/platform/embedder/embedder_render_target.cc b/shell/platform/embedder/embedder_render_target.cc index 729a62bf4e613..32604dcdf4297 100644 --- a/shell/platform/embedder/embedder_render_target.cc +++ b/shell/platform/embedder/embedder_render_target.cc @@ -34,7 +34,7 @@ EmbedderRenderTarget::EmbedderRenderTarget( FML_DCHECK(aiks_context_); FML_DCHECK(!render_surface_); } else { - FML_CHECK(render_surface_); + FML_DCHECK(render_surface_); } } diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index e800e0e6218ce..08fc5957d2722 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -59,11 +59,7 @@ return valid_; } -std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() API_AVAILABLE(ios(13.0)) { - if (@available(iOS 13.0, *)) { - } else { - return nullptr; - } +std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() { if (!IsValid()) { return nullptr; } From 9499a124578d1df4cf71920f39d9d1136a9a2bb7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 10:20:37 -0700 Subject: [PATCH 09/34] Build... --- shell/gpu/gpu_surface_metal_impeller.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index df3a81fef8bfe..17c30ae43e79c 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -5,7 +5,7 @@ #ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ #define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ -#include +#include #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" @@ -17,7 +17,7 @@ namespace flutter { -class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { +class GPUSurfaceMetalImpeller : public Surface { public: GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, const std::shared_ptr& context, From 367a71e899e7e4df936682101579f832f8abbe42 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 10:39:19 -0700 Subject: [PATCH 10/34] Build shaders for fuchsia --- impeller/tools/impeller.gni | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index 2c20acf26d590..ed2933133a9eb 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -18,7 +18,7 @@ declare_args() { impeller_enable_opengles = is_linux || is_win || is_android # Whether the Vulkan backend is enabled. - impeller_enable_vulkan = is_linux || is_win || is_android + impeller_enable_vulkan = is_linux || is_win || is_android || is_fuchsia # Whether to use a prebuilt impellerc. # If this is the empty string, impellerc will be built. @@ -756,7 +756,7 @@ template("impeller_shaders") { } if (!impeller_supports_rendering) { - not_needed(invoker, "*") + #not_needed(invoker, "*") } group(target_name) { From ba6188a0097319e3c21323d9664c04c8a2636fac Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 10:41:25 -0700 Subject: [PATCH 11/34] Add iOS version check again --- shell/platform/embedder/embedder_surface_metal_impeller.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index 08fc5957d2722..e800e0e6218ce 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -59,7 +59,11 @@ return valid_; } -std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() { +std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() API_AVAILABLE(ios(13.0)) { + if (@available(iOS 13.0, *)) { + } else { + return nullptr; + } if (!IsValid()) { return nullptr; } From 0cd0373348dc9c323e7439dd797cb77a0f845c8e Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 10:50:56 -0700 Subject: [PATCH 12/34] Add fuchsia to vulkan backend build check --- impeller/renderer/backend/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/renderer/backend/BUILD.gn b/impeller/renderer/backend/BUILD.gn index 2f6b15b0d9a55..1cae4ded7423d 100644 --- a/impeller/renderer/backend/BUILD.gn +++ b/impeller/renderer/backend/BUILD.gn @@ -18,7 +18,7 @@ group("backend") { } if (impeller_enable_vulkan) { - assert(is_mac || is_linux || is_win || is_android) + assert(is_mac || is_linux || is_win || is_android || is_fuchsia) public_deps += [ "vulkan" ] } } From 36fc4ae7bedd60aceaa43f88771243b59871ebfd Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 11:20:53 -0700 Subject: [PATCH 13/34] Revert "Add fuchsia to vulkan backend build check" This reverts commit 78a6136732cec63c03cf13f1624ae4a11f229bd9. --- impeller/renderer/backend/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/renderer/backend/BUILD.gn b/impeller/renderer/backend/BUILD.gn index 1cae4ded7423d..2f6b15b0d9a55 100644 --- a/impeller/renderer/backend/BUILD.gn +++ b/impeller/renderer/backend/BUILD.gn @@ -18,7 +18,7 @@ group("backend") { } if (impeller_enable_vulkan) { - assert(is_mac || is_linux || is_win || is_android || is_fuchsia) + assert(is_mac || is_linux || is_win || is_android) public_deps += [ "vulkan" ] } } From 6fa7e42cff0a9eadb8a7377855b01dbf56996aa2 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 11:21:07 -0700 Subject: [PATCH 14/34] Revert "Build shaders for fuchsia" This reverts commit 085fb38d9ac4152a2905e542f25f2c51a5862832. --- impeller/tools/impeller.gni | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/tools/impeller.gni b/impeller/tools/impeller.gni index ed2933133a9eb..2c20acf26d590 100644 --- a/impeller/tools/impeller.gni +++ b/impeller/tools/impeller.gni @@ -18,7 +18,7 @@ declare_args() { impeller_enable_opengles = is_linux || is_win || is_android # Whether the Vulkan backend is enabled. - impeller_enable_vulkan = is_linux || is_win || is_android || is_fuchsia + impeller_enable_vulkan = is_linux || is_win || is_android # Whether to use a prebuilt impellerc. # If this is the empty string, impellerc will be built. @@ -756,7 +756,7 @@ template("impeller_shaders") { } if (!impeller_supports_rendering) { - #not_needed(invoker, "*") + not_needed(invoker, "*") } group(target_name) { From 67633cf4f84cabd8c6f1701fbe8f5ef2fabb9b8a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 11:35:11 -0700 Subject: [PATCH 15/34] Forward declare instead --- flow/embedded_views.h | 11 ++++++++++- .../fuchsia/flutter/gfx_external_view_embedder.cc | 1 + .../fuchsia/flutter/gfx_external_view_embedder.h | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/flow/embedded_views.h b/flow/embedded_views.h index ffeb3317e8a93..5293babc419a9 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -14,7 +14,6 @@ #include "flutter/flow/surface_frame.h" #include "flutter/fml/memory/ref_counted.h" #include "flutter/fml/raster_thread_merger.h" -#include "impeller/aiks/aiks_context.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkPictureRecorder.h" @@ -24,6 +23,16 @@ #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" +#if IMPELLER_SUPPORTS_RENDERING +#include "flutter/impeller/aiks/aiks_context.h" // nogncheck +#include "flutter/impeller/renderer/context.h" // nogncheck +#else // IMPELLER_SUPPORTS_RENDERING +namespace impeller { +class Context; +class AiksContext; +} // namespace impeller +#endif // !IMPELLER_SUPPORTS_RENDERING + class GrDirectContext; namespace flutter { diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc index 21c6810c4e11b..37e8d6a474431 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc @@ -231,6 +231,7 @@ void GfxExternalViewEmbedder::EndFrame( void GfxExternalViewEmbedder::SubmitFrame( GrDirectContext* context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) { TRACE_EVENT0("flutter", "GfxExternalViewEmbedder::SubmitFrame"); std::vector> frame_surfaces; diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h index eb37d2e7e2d1f..6d0bc30061047 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h @@ -110,6 +110,7 @@ class GfxExternalViewEmbedder final : public flutter::ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| From 8a53fc82db65337659fa4b1e7f05c53d846a63f3 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 11:59:01 -0700 Subject: [PATCH 16/34] Metal macro --- impeller/renderer/backend/metal/context_mtl.h | 6 ++++++ shell/gpu/gpu_surface_metal_impeller.h | 3 ++- shell/platform/embedder/embedder_surface_metal_impeller.mm | 6 +----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index ef443b39aa40f..3fe68d7714180 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -21,6 +21,12 @@ #include "impeller/renderer/capabilities.h" #include "impeller/renderer/context.h" +#if TARGET_OS_SIMULATOR +#define IMPELLER_METAL_AVAILABLE @available(macos(10.11), ios(13.0)) +#else // TARGET_OS_SIMULATOR +#define IMPELLER_METAL_AVAILABLE @available(macos(10.11), ios(8.0)) +#endif // TARGET_OS_SIMULATOR + namespace impeller { class ContextMTL final : public Context, diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 17c30ae43e79c..9f4bf2bcd6fd3 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -11,13 +11,14 @@ #include "flutter/fml/macros.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/impeller/aiks/aiks_context.h" +#include "flutter/impeller/renderer/backend/metal/context_mtl.h" #include "flutter/impeller/renderer/renderer.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "third_party/skia/include/gpu/mtl/GrMtlTypes.h" namespace flutter { -class GPUSurfaceMetalImpeller : public Surface { +class IMPELLER_METAL_AVAILABLE GPUSurfaceMetalImpeller : public Surface { public: GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, const std::shared_ptr& context, diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index e800e0e6218ce..08fc5957d2722 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -59,11 +59,7 @@ return valid_; } -std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() API_AVAILABLE(ios(13.0)) { - if (@available(iOS 13.0, *)) { - } else { - return nullptr; - } +std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() { if (!IsValid()) { return nullptr; } From bd5667511be5c4ca8351763bc16d76045d07e71a Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 12:12:05 -0700 Subject: [PATCH 17/34] Metal --- impeller/renderer/backend/metal/context_mtl.h | 4 ++-- shell/gpu/gpu_surface_metal_impeller.h | 3 ++- shell/platform/embedder/embedder_surface_metal_impeller.mm | 3 ++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/impeller/renderer/backend/metal/context_mtl.h b/impeller/renderer/backend/metal/context_mtl.h index 3fe68d7714180..820c0e216e2de 100644 --- a/impeller/renderer/backend/metal/context_mtl.h +++ b/impeller/renderer/backend/metal/context_mtl.h @@ -22,9 +22,9 @@ #include "impeller/renderer/context.h" #if TARGET_OS_SIMULATOR -#define IMPELLER_METAL_AVAILABLE @available(macos(10.11), ios(13.0)) +#define IMPELLER_CA_METAL_LAYER_AVAILABLE API_AVAILABLE(macos(10.11), ios(13.0)) #else // TARGET_OS_SIMULATOR -#define IMPELLER_METAL_AVAILABLE @available(macos(10.11), ios(8.0)) +#define IMPELLER_CA_METAL_LAYER_AVAILABLE API_AVAILABLE(macos(10.11), ios(8.0)) #endif // TARGET_OS_SIMULATOR namespace impeller { diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 9f4bf2bcd6fd3..d89e5bf208166 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -18,7 +18,8 @@ namespace flutter { -class IMPELLER_METAL_AVAILABLE GPUSurfaceMetalImpeller : public Surface { +class IMPELLER_CA_METAL_LAYER_AVAILABLE GPUSurfaceMetalImpeller + : public Surface { public: GPUSurfaceMetalImpeller(GPUSurfaceMetalDelegate* delegate, const std::shared_ptr& context, diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.mm b/shell/platform/embedder/embedder_surface_metal_impeller.mm index 08fc5957d2722..c7984f4f386ef 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.mm +++ b/shell/platform/embedder/embedder_surface_metal_impeller.mm @@ -59,7 +59,8 @@ return valid_; } -std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() { +std::unique_ptr EmbedderSurfaceMetalImpeller::CreateGPUSurface() + IMPELLER_CA_METAL_LAYER_AVAILABLE { if (!IsValid()) { return nullptr; } From 6cab1eb92acd3847d25fa87f6498bedf533da3d4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 12:12:41 -0700 Subject: [PATCH 18/34] Fix flow impeller include --- flow/BUILD.gn | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/flow/BUILD.gn b/flow/BUILD.gn index adf3d0ef666ea..560b067e7e22b 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -4,6 +4,7 @@ import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") +import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/config.gni") import("//flutter/testing/testing.gni") @@ -96,11 +97,11 @@ source_set("flow") { "//third_party/skia", ] - public_deps = [ - "//flutter/display_list", - "//flutter/impeller", - "//flutter/impeller/aiks", - ] + if (impeller_supports_rendering) { + deps += [ "//flutter/impeller" ] + } + + public_deps = [ "//flutter/display_list" ] } if (enable_unittests) { From cba3f6a8e81d9725807981b9df5c79957ee5725c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 12:32:11 -0700 Subject: [PATCH 19/34] More build fixes --- flow/BUILD.gn | 5 ----- shell/common/BUILD.gn | 1 - shell/common/rasterizer_unittests.cc | 1 - shell/platform/embedder/BUILD.gn | 4 ---- 4 files changed, 11 deletions(-) diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 560b067e7e22b..efda895393f26 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -4,7 +4,6 @@ import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") -import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/config.gni") import("//flutter/testing/testing.gni") @@ -97,10 +96,6 @@ source_set("flow") { "//third_party/skia", ] - if (impeller_supports_rendering) { - deps += [ "//flutter/impeller" ] - } - public_deps = [ "//flutter/display_list" ] } diff --git a/shell/common/BUILD.gn b/shell/common/BUILD.gn index 1185c5994456e..19009938162fc 100644 --- a/shell/common/BUILD.gn +++ b/shell/common/BUILD.gn @@ -315,7 +315,6 @@ if (enable_unittests) { ":shell_unittests_fixtures", "//flutter/assets", "//flutter/common/graphics", - "//flutter/impeller/aiks:aiks", "//flutter/shell/profiling:profiling_unittests", "//flutter/shell/version", "//flutter/testing:fixture_test", diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 257f5e981037f..daf36364851b1 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -14,7 +14,6 @@ #include "flutter/fml/time/time_point.h" #include "flutter/shell/common/thread_host.h" #include "flutter/testing/testing.h" -#include "impeller/aiks/aiks_context.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkSurface.h" diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 7008cf21f7733..5b05393db2ee0 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -110,8 +110,6 @@ template("embedder_source_set") { "//flutter/common/graphics", "//flutter/flow", "//flutter/fml", - "//flutter/impeller/aiks", - "//flutter/impeller/renderer", "//flutter/lib/ui", "//flutter/runtime:libdart", "//flutter/shell/common", @@ -134,8 +132,6 @@ template("embedder_source_set") { cflags_objc = flutter_cflags_objc cflags_objcc = flutter_cflags_objcc - public_deps += [ "//flutter/impeller/renderer/backend/metal" ] - deps += [ "//flutter/shell/platform/darwin/graphics" ] } From cbdea4d3a8709888571a79abafeb1a5c0ecf66a0 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 12:52:34 -0700 Subject: [PATCH 20/34] Build fixes --- flow/BUILD.gn | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/flow/BUILD.gn b/flow/BUILD.gn index efda895393f26..560b067e7e22b 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -4,6 +4,7 @@ import("//build/fuchsia/sdk.gni") import("//flutter/common/config.gni") +import("//flutter/impeller/tools/impeller.gni") import("//flutter/shell/config.gni") import("//flutter/testing/testing.gni") @@ -96,6 +97,10 @@ source_set("flow") { "//third_party/skia", ] + if (impeller_supports_rendering) { + deps += [ "//flutter/impeller" ] + } + public_deps = [ "//flutter/display_list" ] } From 679b888050b68add5eeafb2f5543f47121f5abd7 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 13:24:19 -0700 Subject: [PATCH 21/34] More build fixes --- shell/platform/embedder/BUILD.gn | 13 +++++++++++-- shell/platform/embedder/embedder.cc | 4 ++-- .../embedder/embedder_surface_metal_impeller.h | 5 ++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 5b05393db2ee0..bd9bbb3b89b11 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -119,16 +119,25 @@ template("embedder_source_set") { "//third_party/skia", ] + if (impeller_supports_rendering) { + deps += [ "//flutter/impeller" ] + } + if (embedder_enable_metal) { sources += [ "embedder_external_texture_metal.h", "embedder_external_texture_metal.mm", "embedder_surface_metal.h", "embedder_surface_metal.mm", - "embedder_surface_metal_impeller.h", - "embedder_surface_metal_impeller.mm", ] + if (impeller_supports_rendering) { + sources += [ + "embedder_surface_metal_impeller.h", + "embedder_surface_metal_impeller.mm", + ] + } + cflags_objc = flutter_cflags_objc cflags_objcc = flutter_cflags_objcc diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index d2c6e0555b021..ffa515325ae76 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -68,7 +68,7 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/shell/platform/embedder/embedder_external_texture_gl.h" #endif -#ifdef SHELL_ENABLE_METAL +#if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING) #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" #include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" @@ -921,7 +921,7 @@ MakeImpellerSurfaceFromBackingStore( const std::shared_ptr& aiks_context, const FlutterBackingStoreConfig& config, const FlutterMetalBackingStore* metal) { -#ifdef SHELL_ENABLE_METAL +#if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING) if (!metal->texture.texture) { FML_LOG(ERROR) << "Embedder supplied null Metal texture."; return std::nullopt; diff --git a/shell/platform/embedder/embedder_surface_metal_impeller.h b/shell/platform/embedder/embedder_surface_metal_impeller.h index 00406030f8256..4fb2b990029c6 100644 --- a/shell/platform/embedder/embedder_surface_metal_impeller.h +++ b/shell/platform/embedder/embedder_surface_metal_impeller.h @@ -12,7 +12,10 @@ #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" #include "flutter/shell/platform/embedder/embedder_surface.h" #include "fml/concurrent_message_loop.h" -#include "impeller/renderer/context.h" + +namespace impeller { +class Context; +} namespace flutter { From 37597b7f5635daf387aad63d0e9b1b3935273407 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 18:08:08 -0700 Subject: [PATCH 22/34] Dyn dispatch for EmbedderRenderTarget --- ci/licenses_golden/licenses_flutter | 8 ++ shell/platform/embedder/BUILD.gn | 7 ++ shell/platform/embedder/embedder.cc | 102 ++++++++++++------ .../embedder/embedder_external_view.cc | 7 +- .../embedder/embedder_render_target.cc | 45 +------- .../embedder/embedder_render_target.h | 58 +++++----- .../embedder_render_target_impeller.cc | 45 ++++++++ .../embedder_render_target_impeller.h | 44 ++++++++ .../embedder/embedder_render_target_skia.cc | 40 +++++++ .../embedder/embedder_render_target_skia.h | 41 +++++++ 10 files changed, 286 insertions(+), 111 deletions(-) create mode 100644 shell/platform/embedder/embedder_render_target_impeller.cc create mode 100644 shell/platform/embedder/embedder_render_target_impeller.h create mode 100644 shell/platform/embedder/embedder_render_target_skia.cc create mode 100644 shell/platform/embedder/embedder_render_target_skia.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index c246e26536c24..76d9f07914555 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2796,6 +2796,10 @@ ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target.cc + ../ ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_struct_macros.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface.h + ../../../flutter/LICENSE @@ -5475,6 +5479,10 @@ FILE: ../../../flutter/shell/platform/embedder/embedder_render_target.cc FILE: ../../../flutter/shell/platform/embedder/embedder_render_target.h FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.cc FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.h +FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_impeller.h +FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_skia.h FILE: ../../../flutter/shell/platform/embedder/embedder_struct_macros.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface.h diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index bd9bbb3b89b11..c84bba1aa94ad 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -76,6 +76,8 @@ template("embedder_source_set") { "embedder_render_target.h", "embedder_render_target_cache.cc", "embedder_render_target_cache.h", + "embedder_render_target_skia.cc", + "embedder_render_target_skia.h", "embedder_struct_macros.h", "embedder_surface.cc", "embedder_surface.h", @@ -120,6 +122,11 @@ template("embedder_source_set") { ] if (impeller_supports_rendering) { + sources += [ + "embedder_render_target_impeller.cc", + "embedder_render_target_impeller.h", + ] + deps += [ "//flutter/impeller" ] } diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index ffa515325ae76..31e56370a50d3 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -56,6 +56,7 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/shell/platform/embedder/embedder_external_texture_resolver.h" #include "flutter/shell/platform/embedder/embedder_platform_message_response.h" #include "flutter/shell/platform/embedder/embedder_render_target.h" +#include "flutter/shell/platform/embedder/embedder_render_target_skia.h" #include "flutter/shell/platform/embedder/embedder_struct_macros.h" #include "flutter/shell/platform/embedder/embedder_task_runner.h" #include "flutter/shell/platform/embedder/embedder_thread_host.h" @@ -69,6 +70,7 @@ extern const intptr_t kPlatformStrongDillSize; #endif #if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING) +#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" #include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" @@ -916,15 +918,17 @@ static sk_sp MakeSkSurfaceFromBackingStore( #endif } -static std::optional -MakeImpellerSurfaceFromBackingStore( +static std::unique_ptr +MakeRenderTargetFromBackingStoreImpeller( + FlutterBackingStore backing_store, + fml::closure on_release, const std::shared_ptr& aiks_context, const FlutterBackingStoreConfig& config, const FlutterMetalBackingStore* metal) { #if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING) if (!metal->texture.texture) { FML_LOG(ERROR) << "Embedder supplied null Metal texture."; - return std::nullopt; + return nullptr; } const auto size = impeller::ISize(config.size.width, config.size.height); @@ -943,7 +947,7 @@ MakeImpellerSurfaceFromBackingStore( user_data = metal->texture.user_data]() { callback(user_data); }); if (!resolve_tex) { FML_LOG(ERROR) << "Could not wrap embedder supplied Metal render texture."; - return std::nullopt; + return nullptr; } resolve_tex->SetLabel("ImpellerBackingStoreResolve"); @@ -961,7 +965,7 @@ MakeImpellerSurfaceFromBackingStore( msaa_tex_desc); if (!msaa_tex) { FML_LOG(ERROR) << "Could not allocate MSAA color texture."; - return std::nullopt; + return nullptr; } msaa_tex->SetLabel("ImpellerBackingStoreColorMSAA"); @@ -975,9 +979,12 @@ MakeImpellerSurfaceFromBackingStore( impeller::RenderTarget render_target_desc; render_target_desc.SetColorAttachment(color0, 0u); - return render_target_desc; + return std::make_unique( + backing_store, aiks_context, + std::make_unique(std::move(render_target_desc)), + std::move(on_release)); #else - return std::nullopt; + return nullptr; #endif } @@ -1034,6 +1041,17 @@ static sk_sp MakeSkSurfaceFromBackingStore( #endif } +static std::unique_ptr +MakeRenderTargetFromSkSurface(FlutterBackingStore backing_store, + sk_sp skia_surface, + fml::closure on_release) { + if (!skia_surface) { + return nullptr; + } + return std::make_unique( + backing_store, std::move(skia_surface), std::move(on_release)); +} + static std::unique_ptr CreateEmbedderRenderTarget( const FlutterCompositor* compositor, @@ -1075,55 +1093,71 @@ CreateEmbedderRenderTarget( // No safe access checks on the renderer are necessary since we allocated // the struct. - sk_sp skia_surface; - std::optional impeller_target; + std::unique_ptr render_target; switch (backing_store.type) { - case kFlutterBackingStoreTypeOpenGL: + case kFlutterBackingStoreTypeOpenGL: { switch (backing_store.open_gl.type) { - case kFlutterOpenGLTargetTypeTexture: - skia_surface = MakeSkSurfaceFromBackingStore( + case kFlutterOpenGLTargetTypeTexture: { + auto skia_surface = MakeSkSurfaceFromBackingStore( context, config, &backing_store.open_gl.texture); + render_target = MakeRenderTargetFromSkSurface( + backing_store, std::move(skia_surface), + collect_callback.Release()); break; - case kFlutterOpenGLTargetTypeFramebuffer: - skia_surface = MakeSkSurfaceFromBackingStore( + } + case kFlutterOpenGLTargetTypeFramebuffer: { + auto skia_surface = MakeSkSurfaceFromBackingStore( context, config, &backing_store.open_gl.framebuffer); + render_target = MakeRenderTargetFromSkSurface( + backing_store, std::move(skia_surface), + collect_callback.Release()); break; + } } break; - case kFlutterBackingStoreTypeSoftware: - skia_surface = MakeSkSurfaceFromBackingStore(context, config, - &backing_store.software); + } + case kFlutterBackingStoreTypeSoftware: { + auto skia_surface = MakeSkSurfaceFromBackingStore( + context, config, &backing_store.software); + render_target = MakeRenderTargetFromSkSurface( + backing_store, std::move(skia_surface), collect_callback.Release()); break; - case kFlutterBackingStoreTypeSoftware2: - skia_surface = MakeSkSurfaceFromBackingStore(context, config, - &backing_store.software2); + } + case kFlutterBackingStoreTypeSoftware2: { + auto skia_surface = MakeSkSurfaceFromBackingStore( + context, config, &backing_store.software2); + render_target = MakeRenderTargetFromSkSurface( + backing_store, std::move(skia_surface), collect_callback.Release()); break; - case kFlutterBackingStoreTypeMetal: + } + case kFlutterBackingStoreTypeMetal: { if (enable_impeller) { - impeller_target = MakeImpellerSurfaceFromBackingStore( - aiks_context, config, &backing_store.metal); + auto impeller_target = MakeRenderTargetFromBackingStoreImpeller( + backing_store, collect_callback.Release(), aiks_context, config, + &backing_store.metal); } else { - skia_surface = MakeSkSurfaceFromBackingStore(context, config, - &backing_store.metal); + auto skia_surface = MakeSkSurfaceFromBackingStore(context, config, + &backing_store.metal); + render_target = MakeRenderTargetFromSkSurface( + backing_store, std::move(skia_surface), collect_callback.Release()); } break; - - case kFlutterBackingStoreTypeVulkan: - skia_surface = + } + case kFlutterBackingStoreTypeVulkan: { + auto skia_surface = MakeSkSurfaceFromBackingStore(context, config, &backing_store.vulkan); + render_target = MakeRenderTargetFromSkSurface( + backing_store, std::move(skia_surface), collect_callback.Release()); break; + } }; - if (!(skia_surface || impeller_target.has_value())) { + if (!render_target) { FML_LOG(ERROR) << "Could not create a surface from an embedder provided " "render target."; - return nullptr; } - - return std::make_unique( - backing_store, std::move(skia_surface), aiks_context, impeller_target, - collect_callback.Release()); + return render_target; } static std::pair, diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index 1a8b3bde3b800..9002fcfe1c263 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/shell/platform/embedder/embedder_external_view.h" + #include "flutter/display_list/dl_builder.h" #include "flutter/fml/trace_event.h" #include "flutter/shell/common/dl_op_spy.h" @@ -85,8 +86,8 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { << "Unnecessarily asked to render into a render target when there was " "nothing to render."; - auto impeller_target = render_target.GetImpellerRenderTarget(); - if (impeller_target.has_value()) { + auto* impeller_target = render_target.GetImpellerRenderTarget(); + if (impeller_target) { auto aiks_context = render_target.GetAiksContext(); auto dl_builder = DisplayListBuilder(); @@ -99,7 +100,7 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { *impeller_target); } - auto skia_surface = render_target.GetRenderSurface(); + auto skia_surface = render_target.GetSkiaSurface(); if (!skia_surface) { return false; } diff --git a/shell/platform/embedder/embedder_render_target.cc b/shell/platform/embedder/embedder_render_target.cc index 32604dcdf4297..c0f993c4ffe61 100644 --- a/shell/platform/embedder/embedder_render_target.cc +++ b/shell/platform/embedder/embedder_render_target.cc @@ -7,35 +7,18 @@ #include #include -#include "flutter/fml/logging.h" - #include "impeller/aiks/aiks_context.h" #include "impeller/renderer/render_target.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { -EmbedderRenderTarget::EmbedderRenderTarget( - FlutterBackingStore backing_store, - sk_sp render_surface, - std::shared_ptr aiks_context, - std::optional impeller_target, - fml::closure on_release) - : backing_store_(backing_store), - render_surface_(std::move(render_surface)), - aiks_context_(std::move(aiks_context)), - impeller_target_(std::move(impeller_target)), - on_release_(std::move(on_release)) { +EmbedderRenderTarget::EmbedderRenderTarget(FlutterBackingStore backing_store, + fml::closure on_release) + : backing_store_(backing_store), on_release_(std::move(on_release)) { // TODO(38468): The optimization to elide backing store updates between frames // has not been implemented yet. backing_store_.did_update = true; - - if (impeller_target_) { - FML_DCHECK(aiks_context_); - FML_DCHECK(!render_surface_); - } else { - FML_DCHECK(render_surface_); - } } EmbedderRenderTarget::~EmbedderRenderTarget() { @@ -48,26 +31,4 @@ const FlutterBackingStore* EmbedderRenderTarget::GetBackingStore() const { return &backing_store_; } -sk_sp EmbedderRenderTarget::GetRenderSurface() const { - return render_surface_; -} - -std::optional -EmbedderRenderTarget::GetImpellerRenderTarget() const { - return impeller_target_; -} - -std::shared_ptr EmbedderRenderTarget::GetAiksContext() - const { - return aiks_context_; -} - -SkISize EmbedderRenderTarget::GetRenderTargetSize() const { - if (impeller_target_.has_value()) { - auto size = impeller_target_->GetRenderTargetSize(); - return SkISize::Make(size.width, size.height); - } - return SkISize::Make(render_surface_->width(), render_surface_->height()); -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_render_target.h b/shell/platform/embedder/embedder_render_target.h index 3c29a4f3a5c8d..cfbb67c07f5f3 100644 --- a/shell/platform/embedder/embedder_render_target.h +++ b/shell/platform/embedder/embedder_render_target.h @@ -6,16 +6,17 @@ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_H_ #include -#include #include "flutter/fml/closure.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "impeller/aiks/aiks_context.h" -#include "impeller/renderer/render_target.h" -#include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkSize.h" #include "third_party/skia/include/core/SkSurface.h" +namespace impeller { +class RenderTarget; +class AiksContext; +} // namespace impeller + namespace flutter { //------------------------------------------------------------------------------ @@ -26,31 +27,12 @@ namespace flutter { /// class EmbedderRenderTarget { public: - //---------------------------------------------------------------------------- - /// @brief Creates a render target whose backing store is managed by the - /// embedder. The way this render target is exposed to the engine - /// is via an SkSurface and a callback that is invoked by this - /// object in its destructor. - /// - /// @param[in] backing_store The backing store describing this render - /// target. - /// @param[in] render_surface The surface for this target. - /// @param[in] on_release The callback to invoke (eventually forwarded - /// to the embedder) when the backing store is no - /// longer required by the engine. - /// - EmbedderRenderTarget(FlutterBackingStore backing_store, - sk_sp render_surface, - std::shared_ptr aiks_context, - std::optional impeller_target, - fml::closure on_release); - //---------------------------------------------------------------------------- /// @brief Destroys this instance of the render target and invokes the /// callback for the embedder to release its resource associated /// with the particular backing store. /// - ~EmbedderRenderTarget(); + virtual ~EmbedderRenderTarget(); //---------------------------------------------------------------------------- /// @brief A render surface the rasterizer can use to draw into the @@ -58,7 +40,7 @@ class EmbedderRenderTarget { /// /// @return The render surface. /// - sk_sp GetRenderSurface() const; + virtual sk_sp GetSkiaSurface() const = 0; //---------------------------------------------------------------------------- /// @brief An impeller render target the rasterizer can use to draw into @@ -66,7 +48,7 @@ class EmbedderRenderTarget { /// /// @return The Impeller render target. /// - std::optional GetImpellerRenderTarget() const; + virtual impeller::RenderTarget* GetImpellerRenderTarget() const = 0; //---------------------------------------------------------------------------- /// @brief Returns the AiksContext that should be used for rendering, if @@ -74,14 +56,14 @@ class EmbedderRenderTarget { /// /// @return The Impeller Aiks context. /// - std::shared_ptr GetAiksContext() const; + virtual std::shared_ptr GetAiksContext() const = 0; //---------------------------------------------------------------------------- /// @brief Returns the size of the render target. /// /// @return The size of the render target. /// - SkISize GetRenderTargetSize() const; + virtual SkISize GetRenderTargetSize() const = 0; //---------------------------------------------------------------------------- /// @brief The embedder backing store descriptor. This is the descriptor @@ -95,12 +77,24 @@ class EmbedderRenderTarget { /// const FlutterBackingStore* GetBackingStore() const; + protected: + //---------------------------------------------------------------------------- + /// @brief Creates a render target whose backing store is managed by the + /// embedder. The way this render target is exposed to the engine + /// is via an SkSurface and a callback that is invoked by this + /// object in its destructor. + /// + /// @param[in] backing_store The backing store describing this render + /// target. + /// @param[in] on_release The callback to invoke (eventually forwarded + /// to the embedder) when the backing store is no + /// longer required by the engine. + /// + EmbedderRenderTarget(FlutterBackingStore backing_store, + fml::closure on_release); + private: FlutterBackingStore backing_store_; - sk_sp render_surface_; - - std::shared_ptr aiks_context_; - std::optional impeller_target_; fml::closure on_release_; diff --git a/shell/platform/embedder/embedder_render_target_impeller.cc b/shell/platform/embedder/embedder_render_target_impeller.cc new file mode 100644 index 0000000000000..44f23b62654d2 --- /dev/null +++ b/shell/platform/embedder/embedder_render_target_impeller.cc @@ -0,0 +1,45 @@ +// 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/embedder_render_target_impeller.h" + +#include "flutter/fml/logging.h" +#include "flutter/impeller/renderer/render_target.h" + +namespace flutter { + +EmbedderRenderTargetImpeller::EmbedderRenderTargetImpeller( + FlutterBackingStore backing_store, + std::shared_ptr aiks_context, + std::unique_ptr impeller_target, + fml::closure on_release) + : EmbedderRenderTarget(backing_store, std::move(on_release)), + aiks_context_(std::move(aiks_context)), + impeller_target_(std::move(impeller_target)) { + FML_DCHECK(aiks_context_); + FML_DCHECK(impeller_target_); +} + +EmbedderRenderTargetImpeller::~EmbedderRenderTargetImpeller() = default; + +sk_sp EmbedderRenderTargetImpeller::GetSkiaSurface() const { + return nullptr; +} + +impeller::RenderTarget* EmbedderRenderTargetImpeller::GetImpellerRenderTarget() + const { + return impeller_target_.get(); +} + +std::shared_ptr +EmbedderRenderTargetImpeller::GetAiksContext() const { + return aiks_context_; +} + +SkISize EmbedderRenderTargetImpeller::GetRenderTargetSize() const { + auto size = impeller_target_->GetRenderTargetSize(); + return SkISize::Make(size.width, size.height); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_render_target_impeller.h b/shell/platform/embedder/embedder_render_target_impeller.h new file mode 100644 index 0000000000000..2425402008f8a --- /dev/null +++ b/shell/platform/embedder/embedder_render_target_impeller.h @@ -0,0 +1,44 @@ +// 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_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_IMPELLER_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_IMPELLER_H_ + +#include "flutter/shell/platform/embedder/embedder_render_target.h" + +namespace flutter { + +class EmbedderRenderTargetImpeller final : public EmbedderRenderTarget { + public: + EmbedderRenderTargetImpeller( + FlutterBackingStore backing_store, + std::shared_ptr aiks_context, + std::unique_ptr impeller_target, + fml::closure on_release); + + // |EmbedderRenderTarget| + ~EmbedderRenderTargetImpeller() override; + + // |EmbedderRenderTarget| + sk_sp GetSkiaSurface() const override; + + // |EmbedderRenderTarget| + impeller::RenderTarget* GetImpellerRenderTarget() const override; + + // |EmbedderRenderTarget| + std::shared_ptr GetAiksContext() const override; + + // |EmbedderRenderTarget| + SkISize GetRenderTargetSize() const override; + + private: + std::shared_ptr aiks_context_; + std::unique_ptr impeller_target_; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderRenderTargetImpeller); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_IMPELLER_H_ diff --git a/shell/platform/embedder/embedder_render_target_skia.cc b/shell/platform/embedder/embedder_render_target_skia.cc new file mode 100644 index 0000000000000..e8d60ca60890f --- /dev/null +++ b/shell/platform/embedder/embedder_render_target_skia.cc @@ -0,0 +1,40 @@ +// 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/embedder_render_target_skia.h" + +#include "flutter/fml/logging.h" + +namespace flutter { + +EmbedderRenderTargetSkia::EmbedderRenderTargetSkia( + FlutterBackingStore backing_store, + sk_sp render_surface, + fml::closure on_release) + : EmbedderRenderTarget(backing_store, std::move(on_release)), + render_surface_(std::move(render_surface)) { + FML_DCHECK(render_surface_); +} + +EmbedderRenderTargetSkia::~EmbedderRenderTargetSkia() = default; + +sk_sp EmbedderRenderTargetSkia::GetSkiaSurface() const { + return render_surface_; +} + +impeller::RenderTarget* EmbedderRenderTargetSkia::GetImpellerRenderTarget() + const { + return nullptr; +} + +std::shared_ptr +EmbedderRenderTargetSkia::GetAiksContext() const { + return nullptr; +} + +SkISize EmbedderRenderTargetSkia::GetRenderTargetSize() const { + return SkISize::Make(render_surface_->width(), render_surface_->height()); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_render_target_skia.h b/shell/platform/embedder/embedder_render_target_skia.h new file mode 100644 index 0000000000000..2ccacfee33a2e --- /dev/null +++ b/shell/platform/embedder/embedder_render_target_skia.h @@ -0,0 +1,41 @@ +// 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_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_SKIA_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_SKIA_H_ + +#include "flutter/shell/platform/embedder/embedder_render_target.h" + +namespace flutter { + +class EmbedderRenderTargetSkia final : public EmbedderRenderTarget { + public: + EmbedderRenderTargetSkia(FlutterBackingStore backing_store, + sk_sp render_surface, + fml::closure on_release); + + // |EmbedderRenderTarget| + ~EmbedderRenderTargetSkia() override; + + // |EmbedderRenderTarget| + sk_sp GetSkiaSurface() const override; + + // |EmbedderRenderTarget| + impeller::RenderTarget* GetImpellerRenderTarget() const override; + + // |EmbedderRenderTarget| + std::shared_ptr GetAiksContext() const override; + + // |EmbedderRenderTarget| + SkISize GetRenderTargetSize() const override; + + private: + sk_sp render_surface_; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderRenderTargetSkia); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_RENDER_TARGET_SKIA_H_ From 76833bd3e4b9cba3a894beff9dea87d2bd4623c9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 18:24:32 -0700 Subject: [PATCH 23/34] Fix includes --- shell/platform/embedder/embedder.cc | 4 ++-- shell/platform/embedder/embedder_render_target.cc | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 31e56370a50d3..4f4a6e43b5977 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -17,8 +17,6 @@ #include "flutter/fml/make_copyable.h" #include "flutter/fml/native_library.h" #include "flutter/fml/thread.h" -#include "impeller/core/texture.h" -#include "impeller/renderer/render_target.h" #include "third_party/dart/runtime/bin/elf_loader.h" #include "third_party/dart/runtime/include/dart_native_api.h" #include "third_party/skia/include/core/SkSurface.h" @@ -73,7 +71,9 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" +#include "impeller/core/texture.h" #include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" +#include "impeller/renderer/render_target.h" #endif const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; diff --git a/shell/platform/embedder/embedder_render_target.cc b/shell/platform/embedder/embedder_render_target.cc index c0f993c4ffe61..69259e3ab206d 100644 --- a/shell/platform/embedder/embedder_render_target.cc +++ b/shell/platform/embedder/embedder_render_target.cc @@ -7,10 +7,6 @@ #include #include -#include "impeller/aiks/aiks_context.h" -#include "impeller/renderer/render_target.h" -#include "third_party/skia/include/core/SkSurface.h" - namespace flutter { EmbedderRenderTarget::EmbedderRenderTarget(FlutterBackingStore backing_store, From e8b47f2eec0a1f803115ef162e619d47e5b39698 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 18:47:35 -0700 Subject: [PATCH 24/34] Build fixes --- shell/platform/embedder/BUILD.gn | 1 + shell/platform/embedder/embedder_surface.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index c84bba1aa94ad..aa43f3f48b755 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -167,6 +167,7 @@ template("embedder_source_set") { ":embedder_gpu_configuration_config", ":embedder_header_config", "//flutter:config", + "//flutter/impeller:impeller_public_config", ] } } diff --git a/shell/platform/embedder/embedder_surface.h b/shell/platform/embedder/embedder_surface.h index 99b8de1342335..32873f1a944a5 100644 --- a/shell/platform/embedder/embedder_surface.h +++ b/shell/platform/embedder/embedder_surface.h @@ -9,7 +9,6 @@ #include "flutter/flow/embedded_views.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" -#include "impeller/renderer/context.h" namespace flutter { From fe76983ad86930a6d4d11679686977a7c7999491 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 19:13:30 -0700 Subject: [PATCH 25/34] Make GN understand defines? --- shell/platform/embedder/embedder.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 4f4a6e43b5977..9b847bd0e733d 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -67,14 +67,16 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/shell/platform/embedder/embedder_external_texture_gl.h" #endif -#if defined(SHELL_ENABLE_METAL) && defined(IMPELLER_SUPPORTS_RENDERING) -#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" +#ifdef SHELL_ENABLE_METAL #include "flutter/shell/platform/embedder/embedder_surface_metal.h" +#ifdef IMPELLER_SUPPORTS_RENDERING +#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" #include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" #include "impeller/core/texture.h" #include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" #include "impeller/renderer/render_target.h" -#endif +#endif // IMPELLER_SUPPORTS_RENDERING +#endif // SHELL_ENABLE_METAL const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; const int32_t kFlutterSemanticsCustomActionIdBatchEnd = -1; From f792fb86637f5b33de2fbcde3aab1734be326136 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 19:31:41 -0700 Subject: [PATCH 26/34] Make GN happy 2 --- shell/platform/embedder/embedder.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 9b847bd0e733d..c7bef4410936d 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -70,11 +70,11 @@ extern const intptr_t kPlatformStrongDillSize; #ifdef SHELL_ENABLE_METAL #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #ifdef IMPELLER_SUPPORTS_RENDERING -#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" -#include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" -#include "impeller/core/texture.h" -#include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" -#include "impeller/renderer/render_target.h" +#include "flutter/shell/platform/embedder/embedder_render_target_impeller.h" // nogncheck +#include "flutter/shell/platform/embedder/embedder_surface_metal_impeller.h" // nogncheck +#include "impeller/core/texture.h" // nogncheck +#include "impeller/renderer/backend/metal/texture_wrapper_mtl.h" // nogncheck +#include "impeller/renderer/render_target.h" // nogncheck #endif // IMPELLER_SUPPORTS_RENDERING #endif // SHELL_ENABLE_METAL From 05d19c7055957ec29d8a431a518a750e839e703c Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 19:47:17 -0700 Subject: [PATCH 27/34] Fuchsia --- .../platform/fuchsia/flutter/flatland_external_view_embedder.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc index 901bd8c078e97..366b72bc0b429 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc @@ -132,6 +132,7 @@ void FlatlandExternalViewEmbedder::EndFrame( void FlatlandExternalViewEmbedder::SubmitFrame( GrDirectContext* context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) { TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::SubmitFrame"); std::vector> frame_surfaces; From e03bbc812d45b46bf95e5d73c17d872ce1c122ae Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 20:03:31 -0700 Subject: [PATCH 28/34] Fuchsia --- shell/platform/fuchsia/flutter/flatland_external_view_embedder.h | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h index 00a845cde2e85..5a3142eb5d2f6 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h @@ -87,6 +87,7 @@ class FlatlandExternalViewEmbedder final // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override; // |ExternalViewEmbedder| From 1e4be50eaddb070f5f6c5bc2d13fac17939abdc6 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 20:18:02 -0700 Subject: [PATCH 29/34] Fuchsia --- ...atland_external_view_embedder_unittests.cc | 22 ++++++++++--------- .../tests/flatland_platform_view_unittest.cc | 1 + 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc index 35f734d2044ac..58af0ccb88526 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc @@ -335,11 +335,12 @@ void DrawSimpleFrame(FlatlandExternalViewEmbedder& external_view_embedder, flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, std::move(framebuffer_info), - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, nullptr, + std::make_unique( + nullptr, std::move(framebuffer_info), + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } void DrawFrameWithView( @@ -365,11 +366,12 @@ void DrawFrameWithView( flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, std::move(framebuffer_info), - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, nullptr, + std::make_unique( + nullptr, std::move(framebuffer_info), + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } }; // namespace diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index ce1d55fdc1c91..78f6f9588958a 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -53,6 +53,7 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { fml::RefPtr raster_thread_merger) override {} void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override {} void PrerollCompositeEmbeddedView( From 4b9b8224a8d82661faca4560d2f597f363bbe3f9 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 20:33:18 -0700 Subject: [PATCH 30/34] Fuchsia --- .../flutter/tests/gfx_external_view_embedder_unittests.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc index 77c04bb6ab7ed..e06a2dd09f740 100644 --- a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc @@ -459,7 +459,7 @@ void DrawSimpleFrame(GfxExternalViewEmbedder& external_view_embedder, flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( nullptr, std::make_unique( - nullptr, framebuffer_info, + nullptr, nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, frame_size)); @@ -488,7 +488,7 @@ void DrawFrameWithView( flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( nullptr, std::make_unique( - nullptr, framebuffer_info, + nullptr, nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, frame_size)); From e7613efec308cd6e0cc1e70530e72abf7e5083f2 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 21:54:07 -0700 Subject: [PATCH 31/34] Fuchsia --- .../gfx_external_view_embedder_unittests.cc | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc index e06a2dd09f740..eba9a2dc0ad5c 100644 --- a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc @@ -458,11 +458,12 @@ void DrawSimpleFrame(GfxExternalViewEmbedder& external_view_embedder, external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, nullptr, framebuffer_info, - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, nullptr, + std::make_unique( + nullptr, framebuffer_info, + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } void DrawFrameWithView( @@ -487,11 +488,12 @@ void DrawFrameWithView( external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, nullptr, framebuffer_info, - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, nullptr, + std::make_unique( + nullptr, framebuffer_info, + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } FramePresentedInfo MakeFramePresentedInfoForOnePresent( From 14870a23084012c2d71aa0e708b1cc3d197d9f14 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 22:05:44 -0700 Subject: [PATCH 32/34] Fuchsia --- shell/platform/fuchsia/flutter/platform_view_unittest.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 4959461c8a115..c0aa42e0a5dbf 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -54,6 +54,7 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { fml::RefPtr raster_thread_merger) override {} void SubmitFrame(GrDirectContext* context, + const std::shared_ptr& aiks_context, std::unique_ptr frame) override {} void PrerollCompositeEmbeddedView( From 52964f6b03a779b021e402f8d86ed5172dd944f4 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 22:25:35 -0700 Subject: [PATCH 33/34] Fuchsia --- shell/platform/embedder/embedder_external_view.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index 9002fcfe1c263..fe013ef312f8b 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -7,7 +7,10 @@ #include "flutter/display_list/dl_builder.h" #include "flutter/fml/trace_event.h" #include "flutter/shell/common/dl_op_spy.h" + +#ifdef IMPELLER_SUPPORTS_RENDERING #include "impeller/display_list/dl_dispatcher.h" +#endif // IMPELLER_SUPPORTS_RENDERING namespace flutter { @@ -86,6 +89,7 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { << "Unnecessarily asked to render into a render target when there was " "nothing to render."; +#ifdef IMPELLER_SUPPORTS_RENDERING auto* impeller_target = render_target.GetImpellerRenderTarget(); if (impeller_target) { auto aiks_context = render_target.GetAiksContext(); @@ -99,6 +103,7 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) { return aiks_context->Render(dispatcher.EndRecordingAsPicture(), *impeller_target); } +#endif // IMPELLER_SUPPORTS_RENDERING auto skia_surface = render_target.GetSkiaSurface(); if (!skia_surface) { From 248415c2a8329f23c31d99ee622f678a5aa3d8f3 Mon Sep 17 00:00:00 2001 From: Brandon DeRosier Date: Wed, 31 May 2023 23:29:12 -0700 Subject: [PATCH 34/34] Lint --- shell/platform/embedder/embedder.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index c7bef4410936d..7e026d86cb055 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -923,7 +923,7 @@ static sk_sp MakeSkSurfaceFromBackingStore( static std::unique_ptr MakeRenderTargetFromBackingStoreImpeller( FlutterBackingStore backing_store, - fml::closure on_release, + const fml::closure& on_release, const std::shared_ptr& aiks_context, const FlutterBackingStoreConfig& config, const FlutterMetalBackingStore* metal) { @@ -984,7 +984,7 @@ MakeRenderTargetFromBackingStoreImpeller( return std::make_unique( backing_store, aiks_context, std::make_unique(std::move(render_target_desc)), - std::move(on_release)); + on_release); #else return nullptr; #endif