diff --git a/engine/src/flutter/ci/licenses_golden/licenses_flutter b/engine/src/flutter/ci/licenses_golden/licenses_flutter index 5080f5b095e..47b45071df7 100644 --- a/engine/src/flutter/ci/licenses_golden/licenses_flutter +++ b/engine/src/flutter/ci/licenses_golden/licenses_flutter @@ -603,6 +603,8 @@ FILE: ../../../flutter/shell/gpu/gpu_surface_software_delegate.cc FILE: ../../../flutter/shell/gpu/gpu_surface_software_delegate.h FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.cc FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan.h +FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.cc +FILE: ../../../flutter/shell/gpu/gpu_surface_vulkan_delegate.h FILE: ../../../flutter/shell/platform/android/AndroidManifest.xml FILE: ../../../flutter/shell/platform/android/android_context_gl.cc FILE: ../../../flutter/shell/platform/android/android_context_gl.h diff --git a/engine/src/flutter/shell/gpu/BUILD.gn b/engine/src/flutter/shell/gpu/BUILD.gn index 400a528ff28..2f91e20b43a 100644 --- a/engine/src/flutter/shell/gpu/BUILD.gn +++ b/engine/src/flutter/shell/gpu/BUILD.gn @@ -16,6 +16,7 @@ gpu_common_deps = [ source_set("gpu_surface_software") { sources = [ + "$gpu_dir/gpu_surface_delegate.h", "$gpu_dir/gpu_surface_software.cc", "$gpu_dir/gpu_surface_software.h", "$gpu_dir/gpu_surface_software_delegate.cc", @@ -39,8 +40,11 @@ source_set("gpu_surface_gl") { source_set("gpu_surface_vulkan") { sources = [ + "$gpu_dir/gpu_surface_delegate.h", "$gpu_dir/gpu_surface_vulkan.cc", "$gpu_dir/gpu_surface_vulkan.h", + "$gpu_dir/gpu_surface_vulkan_delegate.cc", + "$gpu_dir/gpu_surface_vulkan_delegate.h", ] deps = gpu_common_deps + [ diff --git a/engine/src/flutter/shell/gpu/gpu_surface_delegate.h b/engine/src/flutter/shell/gpu/gpu_surface_delegate.h index 4f9f16fdbb4..4eb5c468858 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_delegate.h +++ b/engine/src/flutter/shell/gpu/gpu_surface_delegate.h @@ -2,14 +2,24 @@ #define FLUTTER_SHELL_GPU_GPU_SURFACE_DELEGATE_H_ #include "flutter/flow/embedded_views.h" -#include "flutter/fml/macros.h" namespace flutter { class GPUSurfaceDelegate { public: - // Get a reference to the external views embedder. This happens on the same - // thread that the renderer is operating on. + virtual ~GPUSurfaceDelegate() {} + + //---------------------------------------------------------------------------- + /// @brief Gets the view embedder that controls how the Flutter layer + /// hierarchy split into multiple chunks should be composited back + /// on-screen. This field is optional and the Flutter rasterizer + /// will render into a single on-screen surface if this call + /// returns a null external view embedder. This happens on the GPU + /// thread. + /// + /// @return The external view embedder, or, null if Flutter is rendering + /// into a single on-screen surface. + /// virtual ExternalViewEmbedder* GetExternalViewEmbedder() = 0; }; diff --git a/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.cc b/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.cc index df7ad4ef073..91efd5130dd 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.cc +++ b/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.cc @@ -8,6 +8,8 @@ namespace flutter { +GPUSurfaceGLDelegate::~GPUSurfaceGLDelegate() = default; + bool GPUSurfaceGLDelegate::GLContextFBOResetAfterPresent() const { return false; } @@ -95,4 +97,8 @@ GPUSurfaceGLDelegate::GetDefaultPlatformGLInterface() { return CreateGLInterface(nullptr); } +ExternalViewEmbedder* GPUSurfaceGLDelegate::GetExternalViewEmbedder() { + return nullptr; +} + } // namespace flutter diff --git a/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.h b/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.h index bf51d15c8b7..cf0600aea4d 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.h +++ b/engine/src/flutter/shell/gpu/gpu_surface_gl_delegate.h @@ -15,6 +15,11 @@ namespace flutter { class GPUSurfaceGLDelegate : public GPUSurfaceDelegate { public: + ~GPUSurfaceGLDelegate() override; + + // |GPUSurfaceDelegate| + ExternalViewEmbedder* GetExternalViewEmbedder() override; + // Called to make the main GL context current on the current thread. virtual bool GLContextMakeCurrent() = 0; diff --git a/engine/src/flutter/shell/gpu/gpu_surface_software_delegate.h b/engine/src/flutter/shell/gpu/gpu_surface_software_delegate.h index 1c24e13c827..920e4f8a831 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_software_delegate.h +++ b/engine/src/flutter/shell/gpu/gpu_surface_software_delegate.h @@ -7,6 +7,7 @@ #include "flutter/flow/embedded_views.h" #include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_delegate.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { @@ -24,9 +25,12 @@ namespace flutter { /// @see |IOSurfaceSoftware|, |AndroidSurfaceSoftware|, /// |EmbedderSurfaceSoftware|. /// -class GPUSurfaceSoftwareDelegate { +class GPUSurfaceSoftwareDelegate : public GPUSurfaceDelegate { public: - virtual ~GPUSurfaceSoftwareDelegate(); + ~GPUSurfaceSoftwareDelegate() override; + + // |GPUSurfaceDelegate| + ExternalViewEmbedder* GetExternalViewEmbedder() override; //---------------------------------------------------------------------------- /// @brief Called when the GPU surface needs a new buffer to render a new @@ -48,18 +52,6 @@ class GPUSurfaceSoftwareDelegate { /// the screen. /// virtual bool PresentBackingStore(sk_sp backing_store) = 0; - - //---------------------------------------------------------------------------- - /// @brief Gets the view embedder that controls how the Flutter layer - /// hierarchy split into multiple chunks should be composited back - /// on-screen. This field is optional and the Flutter rasterizer - /// will render into a single on-screen surface if this call - /// returns a null external view embedder. - /// - /// @return The external view embedder, or, null if Flutter is rendering - /// into a single on-screen surface. - /// - virtual ExternalViewEmbedder* GetExternalViewEmbedder() = 0; }; } // namespace flutter diff --git a/engine/src/flutter/shell/gpu/gpu_surface_vulkan.cc b/engine/src/flutter/shell/gpu/gpu_surface_vulkan.cc index f7d07f580a5..3d83eb8afca 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_vulkan.cc +++ b/engine/src/flutter/shell/gpu/gpu_surface_vulkan.cc @@ -8,21 +8,31 @@ namespace flutter { GPUSurfaceVulkan::GPUSurfaceVulkan( - fml::RefPtr proc_table, - std::unique_ptr native_surface) - : window_(std::move(proc_table), std::move(native_surface)), + GPUSurfaceVulkanDelegate* delegate, + std::unique_ptr native_surface, + bool render_to_surface) + : window_(delegate->vk(), std::move(native_surface), render_to_surface), + delegate_(delegate), + render_to_surface_(render_to_surface), weak_factory_(this) {} GPUSurfaceVulkan::~GPUSurfaceVulkan() = default; -// |Surface| bool GPUSurfaceVulkan::IsValid() { return window_.IsValid(); } -// |Surface| std::unique_ptr GPUSurfaceVulkan::AcquireFrame( const SkISize& size) { + // TODO(38466): Refactor GPU surface APIs take into account the fact that an + // external view embedder may want to render to the root surface. + if (!render_to_surface_) { + return std::make_unique( + nullptr, true, [](const SurfaceFrame& surface_frame, SkCanvas* canvas) { + return true; + }); + } + auto surface = window_.AcquireSurface(); if (surface == nullptr) { @@ -44,7 +54,6 @@ std::unique_ptr GPUSurfaceVulkan::AcquireFrame( std::move(callback)); } -// |Surface| SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { // This backend does not support delegating to the underlying platform to // query for root surface transformations. Just return identity. @@ -53,9 +62,12 @@ SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { return matrix; } -// |Surface| GrContext* GPUSurfaceVulkan::GetContext() { return window_.GetSkiaGrContext(); } +flutter::ExternalViewEmbedder* GPUSurfaceVulkan::GetExternalViewEmbedder() { + return delegate_->GetExternalViewEmbedder(); +} + } // namespace flutter diff --git a/engine/src/flutter/shell/gpu/gpu_surface_vulkan.h b/engine/src/flutter/shell/gpu/gpu_surface_vulkan.h index 7c410dd526c..1d876b7c493 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_vulkan.h +++ b/engine/src/flutter/shell/gpu/gpu_surface_vulkan.h @@ -10,6 +10,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/common/surface.h" +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/vulkan/vulkan_native_surface.h" #include "flutter/vulkan/vulkan_window.h" @@ -17,8 +18,9 @@ namespace flutter { class GPUSurfaceVulkan : public Surface { public: - GPUSurfaceVulkan(fml::RefPtr proc_table, - std::unique_ptr native_surface); + GPUSurfaceVulkan(GPUSurfaceVulkanDelegate* delegate, + std::unique_ptr native_surface, + bool render_to_surface); ~GPUSurfaceVulkan() override; @@ -34,8 +36,14 @@ class GPUSurfaceVulkan : public Surface { // |Surface| GrContext* GetContext() override; + // |Surface| + flutter::ExternalViewEmbedder* GetExternalViewEmbedder() override; + private: vulkan::VulkanWindow window_; + GPUSurfaceVulkanDelegate* delegate_; + const bool render_to_surface_; + fml::WeakPtrFactory weak_factory_; FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkan); diff --git a/engine/src/flutter/shell/gpu/gpu_surface_vulkan_delegate.cc b/engine/src/flutter/shell/gpu/gpu_surface_vulkan_delegate.cc new file mode 100644 index 00000000000..8b336faec2f --- /dev/null +++ b/engine/src/flutter/shell/gpu/gpu_surface_vulkan_delegate.cc @@ -0,0 +1,15 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" + +namespace flutter { + +GPUSurfaceVulkanDelegate::~GPUSurfaceVulkanDelegate() = default; + +ExternalViewEmbedder* GPUSurfaceVulkanDelegate::GetExternalViewEmbedder() { + return nullptr; +} + +} // namespace flutter diff --git a/engine/src/flutter/shell/gpu/gpu_surface_vulkan_delegate.h b/engine/src/flutter/shell/gpu/gpu_surface_vulkan_delegate.h new file mode 100644 index 00000000000..991720f26f1 --- /dev/null +++ b/engine/src/flutter/shell/gpu/gpu_surface_vulkan_delegate.h @@ -0,0 +1,27 @@ +// 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_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_ +#define FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_ + +#include "flutter/fml/memory/ref_ptr.h" +#include "flutter/shell/gpu/gpu_surface_delegate.h" +#include "flutter/vulkan/vulkan_proc_table.h" + +namespace flutter { + +class GPUSurfaceVulkanDelegate : public GPUSurfaceDelegate { + public: + ~GPUSurfaceVulkanDelegate() override; + + // |GPUSurfaceDelegate| + ExternalViewEmbedder* GetExternalViewEmbedder() override; + + // Obtain a reference to the Vulkan implementation's proc table. + virtual fml::RefPtr vk() = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_VULKAN_DELEGATE_H_ diff --git a/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc b/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc index 66cde9731d5..ffcf52ac3a3 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc +++ b/engine/src/flutter/shell/platform/android/android_surface_vulkan.cc @@ -21,12 +21,10 @@ bool AndroidSurfaceVulkan::IsValid() const { return proc_table_->HasAcquiredMandatoryProcAddresses(); } -// |AndroidSurface| void AndroidSurfaceVulkan::TeardownOnScreenContext() { // Nothing to do. } -// |AndroidSurface| std::unique_ptr AndroidSurfaceVulkan::CreateGPUSurface() { if (!IsValid()) { return nullptr; @@ -45,7 +43,7 @@ std::unique_ptr AndroidSurfaceVulkan::CreateGPUSurface() { } auto gpu_surface = std::make_unique( - proc_table_, std::move(vulkan_surface_android)); + this, std::move(vulkan_surface_android), true); if (!gpu_surface->IsValid()) { return nullptr; @@ -54,28 +52,32 @@ std::unique_ptr AndroidSurfaceVulkan::CreateGPUSurface() { return gpu_surface; } -// |AndroidSurface| bool AndroidSurfaceVulkan::OnScreenSurfaceResize(const SkISize& size) const { return true; } -// |AndroidSurface| bool AndroidSurfaceVulkan::ResourceContextMakeCurrent() { FML_DLOG(ERROR) << "The vulkan backend does not support resource contexts."; return false; } -// |AndroidSurface| bool AndroidSurfaceVulkan::ResourceContextClearCurrent() { FML_DLOG(ERROR) << "The vulkan backend does not support resource contexts."; return false; } -// |AndroidSurface| bool AndroidSurfaceVulkan::SetNativeWindow( fml::RefPtr window) { native_window_ = std::move(window); return native_window_ && native_window_->IsValid(); } +ExternalViewEmbedder* AndroidSurfaceVulkan::GetExternalViewEmbedder() { + return nullptr; +} + +fml::RefPtr AndroidSurfaceVulkan::vk() { + return proc_table_; +} + } // namespace flutter diff --git a/engine/src/flutter/shell/platform/android/android_surface_vulkan.h b/engine/src/flutter/shell/platform/android/android_surface_vulkan.h index 5c025b8e051..d97973002ee 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_vulkan.h +++ b/engine/src/flutter/shell/platform/android/android_surface_vulkan.h @@ -8,13 +8,15 @@ #include #include #include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/shell/platform/android/android_native_window.h" #include "flutter/shell/platform/android/android_surface.h" #include "flutter/vulkan/vulkan_window.h" namespace flutter { -class AndroidSurfaceVulkan : public AndroidSurface { +class AndroidSurfaceVulkan : public AndroidSurface, + public GPUSurfaceVulkanDelegate { public: AndroidSurfaceVulkan(); @@ -41,6 +43,12 @@ class AndroidSurfaceVulkan : public AndroidSurface { // |AndroidSurface| bool SetNativeWindow(fml::RefPtr window) override; + // |GPUSurfaceVulkanDelegate| + ExternalViewEmbedder* GetExternalViewEmbedder() override; + + // |GPUSurfaceVulkanDelegate| + fml::RefPtr vk() override; + private: fml::RefPtr proc_table_; fml::RefPtr native_window_; diff --git a/engine/src/flutter/vulkan/vulkan_window.cc b/engine/src/flutter/vulkan/vulkan_window.cc index 44ef7f4a227..9c7aa69729a 100644 --- a/engine/src/flutter/vulkan/vulkan_window.cc +++ b/engine/src/flutter/vulkan/vulkan_window.cc @@ -17,7 +17,8 @@ namespace vulkan { VulkanWindow::VulkanWindow(fml::RefPtr proc_table, - std::unique_ptr native_surface) + std::unique_ptr native_surface, + bool render_to_surface) : valid_(false), vk(std::move(proc_table)) { if (!vk || !vk->HasAcquiredMandatoryProcAddresses()) { FML_DLOG(INFO) << "Proc table has not acquired mandatory proc addresses."; @@ -58,8 +59,13 @@ VulkanWindow::VulkanWindow(fml::RefPtr proc_table, return; } - // Create the logical surface from the native platform surface. + // TODO(38466): Refactor GPU surface APIs take into account the fact that an + // external view embedder may want to render to the root surface. + if (!render_to_surface) { + return; + } + // Create the logical surface from the native platform surface. surface_ = std::make_unique(*vk, *application_, std::move(native_surface)); diff --git a/engine/src/flutter/vulkan/vulkan_window.h b/engine/src/flutter/vulkan/vulkan_window.h index ade09d57ac7..30c10e28e47 100644 --- a/engine/src/flutter/vulkan/vulkan_window.h +++ b/engine/src/flutter/vulkan/vulkan_window.h @@ -32,7 +32,8 @@ class VulkanBackbuffer; class VulkanWindow { public: VulkanWindow(fml::RefPtr proc_table, - std::unique_ptr native_surface); + std::unique_ptr native_surface, + bool render_to_surface); ~VulkanWindow();