diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 2499aea6902af..ef69cbb78849f 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -226,9 +226,9 @@ ../../../flutter/shell/common/variable_refresh_rate_display_unittests.cc ../../../flutter/shell/common/vsync_waiter_unittests.cc ../../../flutter/shell/platform/android/.gitignore +../../../flutter/shell/platform/android/android_context_gl_impeller_unittests.cc ../../../flutter/shell/platform/android/android_context_gl_unittests.cc ../../../flutter/shell/platform/android/android_shell_holder_unittests.cc -../../../flutter/shell/platform/android/android_surface_gl_impeller_unittests.cc ../../../flutter/shell/platform/android/apk_asset_provider_unittests.cc ../../../flutter/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc ../../../flutter/shell/platform/android/external_view_embedder/surface_pool_unittests.cc diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index d008405849d57..8e31f539c527f 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2226,6 +2226,8 @@ ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_impeller.cc + ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_impeller.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_skia.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/android_context_gl_skia.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/android_display.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/android_display.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/android_egl_surface.cc + ../../../flutter/LICENSE @@ -4843,6 +4845,8 @@ FILE: ../../../flutter/shell/platform/android/android_context_gl_impeller.cc FILE: ../../../flutter/shell/platform/android/android_context_gl_impeller.h FILE: ../../../flutter/shell/platform/android/android_context_gl_skia.cc FILE: ../../../flutter/shell/platform/android/android_context_gl_skia.h +FILE: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.cc +FILE: ../../../flutter/shell/platform/android/android_context_vulkan_impeller.h FILE: ../../../flutter/shell/platform/android/android_display.cc FILE: ../../../flutter/shell/platform/android/android_display.h FILE: ../../../flutter/shell/platform/android/android_egl_surface.cc diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 37ad46e02e680..f42e052fa3343 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -39,9 +39,9 @@ executable("flutter_shell_native_unittests") { visibility = [ "*" ] testonly = true sources = [ + "android_context_gl_impeller_unittests.cc", "android_context_gl_unittests.cc", "android_shell_holder_unittests.cc", - "android_surface_gl_impeller_unittests.cc", "apk_asset_provider_unittests.cc", "flutter_shell_native_unittests.cc", ] @@ -72,6 +72,8 @@ source_set("flutter_shell_native_src") { "android_context_gl_impeller.h", "android_context_gl_skia.cc", "android_context_gl_skia.h", + "android_context_vulkan_impeller.cc", + "android_context_vulkan_impeller.h", "android_display.cc", "android_display.h", "android_egl_surface.cc", diff --git a/shell/platform/android/android_context_gl_impeller.cc b/shell/platform/android/android_context_gl_impeller.cc index ff4f59a576f98..a4bcd9fbc7f5c 100644 --- a/shell/platform/android/android_context_gl_impeller.cc +++ b/shell/platform/android/android_context_gl_impeller.cc @@ -4,15 +4,228 @@ #include "flutter/shell/platform/android/android_context_gl_impeller.h" +#include "flutter/impeller/renderer/backend/gles/context_gles.h" +#include "flutter/impeller/renderer/backend/gles/proc_table_gles.h" +#include "flutter/impeller/renderer/backend/gles/reactor_gles.h" +#include "flutter/impeller/toolkit/egl/context.h" +#include "flutter/impeller/toolkit/egl/surface.h" +#include "impeller/entity/gles/entity_shaders_gles.h" +#include "impeller/scene/shaders/gles/scene_shaders_gles.h" + namespace flutter { -AndroidContextGLImpeller::AndroidContextGLImpeller() - : AndroidContext(AndroidRenderingAPI::kOpenGLES) {} +class AndroidContextGLImpeller::ReactorWorker final + : public impeller::ReactorGLES::Worker { + public: + ReactorWorker() = default; + + // |impeller::ReactorGLES::Worker| + ~ReactorWorker() override = default; + + // |impeller::ReactorGLES::Worker| + bool CanReactorReactOnCurrentThreadNow( + const impeller::ReactorGLES& reactor) const override { + impeller::ReaderLock lock(mutex_); + auto found = reactions_allowed_.find(std::this_thread::get_id()); + if (found == reactions_allowed_.end()) { + return false; + } + return found->second; + } + + void SetReactionsAllowedOnCurrentThread(bool allowed) { + impeller::WriterLock lock(mutex_); + reactions_allowed_[std::this_thread::get_id()] = allowed; + } + + private: + mutable impeller::RWMutex mutex_; + std::map reactions_allowed_ IPLR_GUARDED_BY(mutex_); + + FML_DISALLOW_COPY_AND_ASSIGN(ReactorWorker); +}; + +static std::shared_ptr CreateImpellerContext( + const std::shared_ptr& worker) { + auto proc_table = std::make_unique( + impeller::egl::CreateProcAddressResolver()); + + if (!proc_table->IsValid()) { + FML_LOG(ERROR) << "Could not create OpenGL proc table."; + return nullptr; + } + + std::vector> shader_mappings = { + std::make_shared( + impeller_entity_shaders_gles_data, + impeller_entity_shaders_gles_length), + std::make_shared( + impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length), + }; + + auto context = + impeller::ContextGLES::Create(std::move(proc_table), shader_mappings); + if (!context) { + FML_LOG(ERROR) << "Could not create OpenGLES Impeller Context."; + return nullptr; + } + + if (!context->AddReactorWorker(worker).has_value()) { + FML_LOG(ERROR) << "Could not add reactor worker."; + return nullptr; + } + FML_LOG(ERROR) << "Using the Impeller rendering backend."; + return context; +} + +AndroidContextGLImpeller::AndroidContextGLImpeller( + std::unique_ptr display) + : AndroidContext(AndroidRenderingAPI::kOpenGLES), + reactor_worker_(std::shared_ptr(new ReactorWorker())), + display_(std::move(display)) { + if (!display_ || !display_->IsValid()) { + FML_DLOG(ERROR) << "Could not create context with invalid EGL display."; + return; + } + + impeller::egl::ConfigDescriptor desc; + desc.api = impeller::egl::API::kOpenGLES2; + desc.color_format = impeller::egl::ColorFormat::kRGBA8888; + desc.depth_bits = impeller::egl::DepthBits::kZero; + desc.stencil_bits = impeller::egl::StencilBits::kEight; + desc.samples = impeller::egl::Samples::kFour; + + desc.surface_type = impeller::egl::SurfaceType::kWindow; + std::unique_ptr onscreen_config = + display_->ChooseConfig(desc); + if (!onscreen_config) { + // Fallback for Android emulator. + desc.samples = impeller::egl::Samples::kOne; + onscreen_config = display_->ChooseConfig(desc); + if (onscreen_config) { + FML_LOG(INFO) << "Warning: This device doesn't support MSAA for onscreen " + "framebuffers. Falling back to a single sample."; + } else { + FML_DLOG(ERROR) << "Could not choose onscreen config."; + return; + } + } + + desc.surface_type = impeller::egl::SurfaceType::kPBuffer; + auto offscreen_config = display_->ChooseConfig(desc); + if (!offscreen_config) { + FML_DLOG(ERROR) << "Could not choose offscreen config."; + return; + } + + auto onscreen_context = display_->CreateContext(*onscreen_config, nullptr); + if (!onscreen_context) { + FML_DLOG(ERROR) << "Could not create onscreen context."; + return; + } + + auto offscreen_context = + display_->CreateContext(*offscreen_config, onscreen_context.get()); + if (!offscreen_context) { + FML_DLOG(ERROR) << "Could not create offscreen context."; + return; + } + + // Creating the impeller::Context requires a current context, which requires + // some surface. + auto offscreen_surface = + display_->CreatePixelBufferSurface(*offscreen_config, 1u, 1u); + if (!offscreen_context->MakeCurrent(*offscreen_surface)) { + FML_DLOG(ERROR) << "Could not make offscreen context current."; + return; + } + + auto impeller_context = CreateImpellerContext(reactor_worker_); + + if (!impeller_context) { + FML_DLOG(ERROR) << "Could not create Impeller context."; + return; + } + + if (!offscreen_context->ClearCurrent()) { + FML_DLOG(ERROR) << "Could not clear offscreen context."; + return; + } + // Setup context listeners. + impeller::egl::Context::LifecycleListener listener = + [worker = + reactor_worker_](impeller::egl ::Context::LifecycleEvent event) { + switch (event) { + case impeller::egl::Context::LifecycleEvent::kDidMakeCurrent: + worker->SetReactionsAllowedOnCurrentThread(true); + break; + case impeller::egl::Context::LifecycleEvent::kWillClearCurrent: + worker->SetReactionsAllowedOnCurrentThread(false); + break; + } + }; + if (!onscreen_context->AddLifecycleListener(listener).has_value() || + !offscreen_context->AddLifecycleListener(listener).has_value()) { + FML_DLOG(ERROR) << "Could not add lifecycle listeners"; + } + + onscreen_config_ = std::move(onscreen_config); + offscreen_config_ = std::move(offscreen_config); + onscreen_context_ = std::move(onscreen_context); + offscreen_context_ = std::move(offscreen_context); + SetImpellerContext(impeller_context); + + is_valid_ = true; +} AndroidContextGLImpeller::~AndroidContextGLImpeller() = default; bool AndroidContextGLImpeller::IsValid() const { - return true; + return is_valid_; +} + +bool AndroidContextGLImpeller::ResourceContextClearCurrent() { + if (!offscreen_context_) { + return false; + } + + return offscreen_context_->ClearCurrent(); +} + +bool AndroidContextGLImpeller::ResourceContextMakeCurrent( + impeller::egl::Surface* offscreen_surface) { + if (!offscreen_context_ || !offscreen_surface) { + return false; + } + + return offscreen_context_->MakeCurrent(*offscreen_surface); +} + +std::unique_ptr +AndroidContextGLImpeller::CreateOffscreenSurface() { + return display_->CreatePixelBufferSurface(*offscreen_config_, 1u, 1u); +} + +bool AndroidContextGLImpeller::OnscreenContextMakeCurrent( + impeller::egl::Surface* onscreen_surface) { + if (!onscreen_surface || !onscreen_context_) { + return false; + } + + return onscreen_context_->MakeCurrent(*onscreen_surface); +} + +bool AndroidContextGLImpeller::OnscreenContextClearCurrent() { + if (!onscreen_context_) { + return false; + } + + return onscreen_context_->ClearCurrent(); +} + +std::unique_ptr +AndroidContextGLImpeller::CreateOnscreenSurface(EGLNativeWindowType window) { + return display_->CreateWindowSurface(*onscreen_config_, window); } } // namespace flutter diff --git a/shell/platform/android/android_context_gl_impeller.h b/shell/platform/android/android_context_gl_impeller.h index 51e9f7b128489..90466db683a8a 100644 --- a/shell/platform/android/android_context_gl_impeller.h +++ b/shell/platform/android/android_context_gl_impeller.h @@ -6,20 +6,40 @@ #define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_GL_IMPELLER_H_ #include "flutter/fml/macros.h" +#include "flutter/impeller/toolkit/egl/display.h" #include "flutter/shell/platform/android/context/android_context.h" namespace flutter { class AndroidContextGLImpeller : public AndroidContext { public: - AndroidContextGLImpeller(); + explicit AndroidContextGLImpeller( + std::unique_ptr display); ~AndroidContextGLImpeller(); // |AndroidContext| bool IsValid() const override; + bool ResourceContextMakeCurrent(impeller::egl::Surface* offscreen_surface); + bool ResourceContextClearCurrent(); + std::unique_ptr CreateOffscreenSurface(); + bool OnscreenContextMakeCurrent(impeller::egl::Surface* onscreen_surface); + bool OnscreenContextClearCurrent(); + std::unique_ptr CreateOnscreenSurface( + EGLNativeWindowType window); + private: + class ReactorWorker; + + std::shared_ptr reactor_worker_; + std::unique_ptr display_; + std::unique_ptr onscreen_config_; + std::unique_ptr offscreen_config_; + std::unique_ptr onscreen_context_; + std::unique_ptr offscreen_context_; + bool is_valid_ = false; + FML_DISALLOW_COPY_AND_ASSIGN(AndroidContextGLImpeller); }; diff --git a/shell/platform/android/android_surface_gl_impeller_unittests.cc b/shell/platform/android/android_context_gl_impeller_unittests.cc similarity index 78% rename from shell/platform/android/android_surface_gl_impeller_unittests.cc rename to shell/platform/android/android_context_gl_impeller_unittests.cc index 37f11aaa3f1cf..a3dace6e68c7d 100644 --- a/shell/platform/android/android_surface_gl_impeller_unittests.cc +++ b/shell/platform/android/android_context_gl_impeller_unittests.cc @@ -1,5 +1,4 @@ -#include "flutter/shell/platform/android/android_surface_gl_impeller.h" -#include "flutter/shell/platform/android/jni/jni_mock.h" +#include "flutter/shell/platform/android/android_context_gl_impeller.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -24,10 +23,7 @@ class MockDisplay : public impeller::egl::Display { }; } // namespace -TEST(AndroidSurfaceGLImpeller, MSAAFirstAttempt) { - auto context = - std::make_shared(AndroidRenderingAPI::kSoftware); - auto jni = std::make_shared(); +TEST(AndroidContextGLImpeller, MSAAFirstAttempt) { auto display = std::make_unique(); EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true)); auto first_result = std::make_unique(ConfigDescriptor(), EGLConfig()); @@ -46,15 +42,11 @@ TEST(AndroidSurfaceGLImpeller, MSAAFirstAttempt) { .WillOnce(Return(ByMove(std::move(second_result)))); ON_CALL(*display, ChooseConfig(_)) .WillByDefault(Return(ByMove(std::unique_ptr()))); - auto surface = std::make_unique(context, jni, - std::move(display)); - ASSERT_TRUE(surface); + auto context = std::make_unique(std::move(display)); + ASSERT_TRUE(context); } -TEST(AndroidSurfaceGLImpeller, FallbackForEmulator) { - auto context = - std::make_shared(AndroidRenderingAPI::kSoftware); - auto jni = std::make_shared(); +TEST(AndroidContextGLImpeller, FallbackForEmulator) { auto display = std::make_unique(); EXPECT_CALL(*display, IsValid).WillRepeatedly(Return(true)); std::unique_ptr first_result; @@ -81,9 +73,8 @@ TEST(AndroidSurfaceGLImpeller, FallbackForEmulator) { .WillOnce(Return(ByMove(std::move(third_result)))); ON_CALL(*display, ChooseConfig(_)) .WillByDefault(Return(ByMove(std::unique_ptr()))); - auto surface = std::make_unique(context, jni, - std::move(display)); - ASSERT_TRUE(surface); + auto context = std::make_unique(std::move(display)); + ASSERT_TRUE(context); } } // namespace testing } // namespace flutter diff --git a/shell/platform/android/android_context_gl_unittests.cc b/shell/platform/android/android_context_gl_unittests.cc index 200b7eb8ff6a5..500ec7e74c313 100644 --- a/shell/platform/android/android_context_gl_unittests.cc +++ b/shell/platform/android/android_context_gl_unittests.cc @@ -6,7 +6,6 @@ #include "flutter/shell/platform/android/android_egl_surface.h" #include "flutter/shell/platform/android/android_environment_gl.h" #include "flutter/shell/platform/android/android_surface_gl_skia.h" -#include "flutter/shell/platform/android/jni/platform_view_android_jni.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -14,55 +13,6 @@ namespace flutter { namespace testing { namespace android { namespace { -class MockPlatformViewAndroidJNI : public PlatformViewAndroidJNI { - public: - MOCK_METHOD2(FlutterViewHandlePlatformMessage, - void(std::unique_ptr message, - int responseId)); - MOCK_METHOD2(FlutterViewHandlePlatformMessageResponse, - void(int responseId, std::unique_ptr data)); - MOCK_METHOD3(FlutterViewUpdateSemantics, - void(std::vector buffer, - std::vector strings, - std::vector> string_attribute_args)); - MOCK_METHOD2(FlutterViewUpdateCustomAccessibilityActions, - void(std::vector actions_buffer, - std::vector strings)); - MOCK_METHOD0(FlutterViewOnFirstFrame, void()); - MOCK_METHOD0(FlutterViewOnPreEngineRestart, void()); - MOCK_METHOD2(SurfaceTextureAttachToGLContext, - void(JavaLocalRef surface_texture, int textureId)); - MOCK_METHOD1(SurfaceTextureUpdateTexImage, - void(JavaLocalRef surface_texture)); - MOCK_METHOD2(SurfaceTextureGetTransformMatrix, - void(JavaLocalRef surface_texture, SkMatrix& transform)); - MOCK_METHOD1(SurfaceTextureDetachFromGLContext, - void(JavaLocalRef surface_texture)); - MOCK_METHOD8(FlutterViewOnDisplayPlatformView, - void(int view_id, - int x, - int y, - int width, - int height, - int viewWidth, - int viewHeight, - MutatorsStack mutators_stack)); - MOCK_METHOD5(FlutterViewDisplayOverlaySurface, - void(int surface_id, int x, int y, int width, int height)); - MOCK_METHOD0(FlutterViewBeginFrame, void()); - MOCK_METHOD0(FlutterViewEndFrame, void()); - MOCK_METHOD0(FlutterViewCreateOverlaySurface, - std::unique_ptr()); - MOCK_METHOD0(FlutterViewDestroyOverlaySurfaces, void()); - MOCK_METHOD1(FlutterViewComputePlatformResolvedLocale, - std::unique_ptr>( - std::vector supported_locales_data)); - MOCK_METHOD0(GetDisplayRefreshRate, double()); - MOCK_METHOD0(GetDisplayWidth, double()); - MOCK_METHOD0(GetDisplayHeight, double()); - MOCK_METHOD0(GetDisplayDensity, double()); - MOCK_METHOD1(RequestDartDeferredLibrary, bool(int loading_unit_id)); -}; TaskRunners MakeTaskRunners(const std::string& thread_label, const ThreadHost& thread_host) { @@ -131,9 +81,8 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNotNull) { TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); auto android_context = std::make_shared( AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); - auto jni = std::make_shared(); auto android_surface = - std::make_unique(android_context, jni); + std::make_unique(android_context); auto window = fml::MakeRefCounted( nullptr, /*is_fake_window=*/true); android_surface->SetNativeWindow(window); @@ -159,9 +108,8 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNull) { TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); auto android_context = std::make_shared( AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); - auto jni = std::make_shared(); auto android_surface = - std::make_unique(android_context, jni); + std::make_unique(android_context); EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr); android_surface->CreateSnapshotSurface(); EXPECT_NE(android_surface->GetOnscreenSurface(), nullptr); diff --git a/shell/platform/android/android_context_vulkan_impeller.cc b/shell/platform/android/android_context_vulkan_impeller.cc new file mode 100644 index 0000000000000..8f523d4a2c356 --- /dev/null +++ b/shell/platform/android/android_context_vulkan_impeller.cc @@ -0,0 +1,58 @@ +// 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/android/android_context_vulkan_impeller.h" + +#include "flutter/fml/paths.h" +#include "flutter/impeller/entity/vk/entity_shaders_vk.h" +#include "flutter/impeller/entity/vk/modern_shaders_vk.h" +#include "flutter/impeller/renderer/backend/vulkan/context_vk.h" +#include "flutter/impeller/scene/shaders/vk/scene_shaders_vk.h" + +namespace flutter { + +static std::shared_ptr CreateImpellerContext( + const fml::RefPtr& proc_table, + const std::shared_ptr& concurrent_loop, + bool enable_vulkan_validation) { + std::vector> shader_mappings = { + std::make_shared(impeller_entity_shaders_vk_data, + impeller_entity_shaders_vk_length), + std::make_shared(impeller_scene_shaders_vk_data, + impeller_scene_shaders_vk_length), + std::make_shared(impeller_modern_shaders_vk_data, + impeller_modern_shaders_vk_length), + }; + + PFN_vkGetInstanceProcAddr instance_proc_addr = + proc_table->NativeGetInstanceProcAddr(); + + impeller::ContextVK::Settings settings; + settings.proc_address_callback = instance_proc_addr; + settings.shader_libraries_data = std::move(shader_mappings); + settings.cache_directory = fml::paths::GetCachesDirectory(); + settings.worker_task_runner = concurrent_loop->GetTaskRunner(); + settings.enable_validation = enable_vulkan_validation; + return impeller::ContextVK::Create(std::move(settings)); +} + +AndroidContextVulkanImpeller::AndroidContextVulkanImpeller( + bool enable_validation) + : AndroidContext(AndroidRenderingAPI::kVulkan), + proc_table_(fml::MakeRefCounted()), + workers_(fml::ConcurrentMessageLoop::Create()) { + auto impeller_context = + CreateImpellerContext(proc_table_, workers_, enable_validation); + SetImpellerContext(impeller_context); + is_valid_ = + proc_table_->HasAcquiredMandatoryProcAddresses() && impeller_context; +} + +AndroidContextVulkanImpeller::~AndroidContextVulkanImpeller() = default; + +bool AndroidContextVulkanImpeller::IsValid() const { + return is_valid_; +} + +} // namespace flutter diff --git a/shell/platform/android/android_context_vulkan_impeller.h b/shell/platform/android/android_context_vulkan_impeller.h new file mode 100644 index 0000000000000..3fe5c627e593b --- /dev/null +++ b/shell/platform/android/android_context_vulkan_impeller.h @@ -0,0 +1,35 @@ +// 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_ANDROID_ANDROID_CONTEXT_VULKAN_IMPELLER_H_ +#define FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_VULKAN_IMPELLER_H_ + +#include "flutter/fml/concurrent_message_loop.h" +#include "flutter/fml/macros.h" +#include "flutter/impeller/toolkit/egl/display.h" +#include "flutter/shell/platform/android/context/android_context.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" + +namespace flutter { + +class AndroidContextVulkanImpeller : public AndroidContext { + public: + explicit AndroidContextVulkanImpeller(bool enable_validation); + + ~AndroidContextVulkanImpeller(); + + // |AndroidContext| + bool IsValid() const override; + + private: + fml::RefPtr proc_table_; + std::shared_ptr workers_; + bool is_valid_ = false; + + FML_DISALLOW_COPY_AND_ASSIGN(AndroidContextVulkanImpeller); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_ANDROID_ANDROID_CONTEXT_VULKAN_IMPELLER_H_ diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index fb2abdff6db34..662541ab64b55 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -5,184 +5,21 @@ #include "flutter/shell/platform/android/android_surface_gl_impeller.h" #include "flutter/fml/logging.h" -#include "flutter/impeller/renderer/backend/gles/context_gles.h" -#include "flutter/impeller/renderer/backend/gles/proc_table_gles.h" -#include "flutter/impeller/toolkit/egl/context.h" #include "flutter/impeller/toolkit/egl/surface.h" #include "flutter/shell/gpu/gpu_surface_gl_impeller.h" -#include "impeller/entity/gles/entity_shaders_gles.h" -#include "impeller/scene/shaders/gles/scene_shaders_gles.h" namespace flutter { -class AndroidSurfaceGLImpeller::ReactorWorker final - : public impeller::ReactorGLES::Worker { - public: - ReactorWorker() = default; - - // |impeller::ReactorGLES::Worker| - ~ReactorWorker() override = default; - - // |impeller::ReactorGLES::Worker| - bool CanReactorReactOnCurrentThreadNow( - const impeller::ReactorGLES& reactor) const override { - impeller::ReaderLock lock(mutex_); - auto found = reactions_allowed_.find(std::this_thread::get_id()); - if (found == reactions_allowed_.end()) { - return false; - } - return found->second; - } - - void SetReactionsAllowedOnCurrentThread(bool allowed) { - impeller::WriterLock lock(mutex_); - reactions_allowed_[std::this_thread::get_id()] = allowed; - } - - private: - mutable impeller::RWMutex mutex_; - std::map reactions_allowed_ IPLR_GUARDED_BY(mutex_); - - FML_DISALLOW_COPY_AND_ASSIGN(ReactorWorker); -}; - -static std::shared_ptr CreateImpellerContext( - const std::shared_ptr& worker) { - auto proc_table = std::make_unique( - impeller::egl::CreateProcAddressResolver()); - - if (!proc_table->IsValid()) { - FML_LOG(ERROR) << "Could not create OpenGL proc table."; - return nullptr; - } - - std::vector> shader_mappings = { - std::make_shared( - impeller_entity_shaders_gles_data, - impeller_entity_shaders_gles_length), - std::make_shared( - impeller_scene_shaders_gles_data, impeller_scene_shaders_gles_length), - }; - - auto context = - impeller::ContextGLES::Create(std::move(proc_table), shader_mappings); - if (!context) { - FML_LOG(ERROR) << "Could not create OpenGLES Impeller Context."; - return nullptr; - } - - if (!context->AddReactorWorker(worker).has_value()) { - FML_LOG(ERROR) << "Could not add reactor worker."; - return nullptr; - } - FML_LOG(ERROR) << "Using the Impeller rendering backend."; - return context; -} - AndroidSurfaceGLImpeller::AndroidSurfaceGLImpeller( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade, - std::unique_ptr display) - : AndroidSurface(android_context), - reactor_worker_(std::shared_ptr(new ReactorWorker())), - display_(std::move(display)) { - if (!display_->IsValid()) { - FML_DLOG(ERROR) << "Could not create surface with invalid Display."; - return; - } - - impeller::egl::ConfigDescriptor desc; - desc.api = impeller::egl::API::kOpenGLES2; - desc.color_format = impeller::egl::ColorFormat::kRGBA8888; - desc.depth_bits = impeller::egl::DepthBits::kZero; - desc.stencil_bits = impeller::egl::StencilBits::kEight; - desc.samples = impeller::egl::Samples::kFour; - - desc.surface_type = impeller::egl::SurfaceType::kWindow; - std::unique_ptr onscreen_config = - display_->ChooseConfig(desc); - if (!onscreen_config) { - // Fallback for Android emulator. - desc.samples = impeller::egl::Samples::kOne; - onscreen_config = display_->ChooseConfig(desc); - if (onscreen_config) { - FML_LOG(INFO) << "Warning: This device doesn't support MSAA for onscreen " - "framebuffers. Falling back to a single sample."; - } else { - FML_DLOG(ERROR) << "Could not choose onscreen config."; - return; - } - } - - desc.surface_type = impeller::egl::SurfaceType::kPBuffer; - auto offscreen_config = display_->ChooseConfig(desc); - if (!offscreen_config) { - FML_DLOG(ERROR) << "Could not choose offscreen config."; - return; - } - - auto onscreen_context = display_->CreateContext(*onscreen_config, nullptr); - if (!onscreen_context) { - FML_DLOG(ERROR) << "Could not create onscreen context."; - return; - } - - auto offscreen_context = - display_->CreateContext(*offscreen_config, onscreen_context.get()); - if (!offscreen_context) { - FML_DLOG(ERROR) << "Could not create offscreen context."; - return; - } + const std::shared_ptr& android_context) + : android_context_(android_context) { + offscreen_surface_ = android_context_->CreateOffscreenSurface(); - auto offscreen_surface = - display_->CreatePixelBufferSurface(*offscreen_config, 1u, 1u); - if (!offscreen_surface) { + if (!offscreen_surface_) { FML_DLOG(ERROR) << "Could not create offscreen surface."; return; } - if (!offscreen_context->MakeCurrent(*offscreen_surface)) { - FML_DLOG(ERROR) << "Could not make offscreen context current."; - return; - } - - auto impeller_context = CreateImpellerContext(reactor_worker_); - - if (!impeller_context) { - FML_DLOG(ERROR) << "Could not create Impeller context."; - return; - } - - if (!offscreen_context->ClearCurrent()) { - FML_DLOG(ERROR) << "Could not clear offscreen context."; - return; - } - - // Setup context listeners. - impeller::egl::Context::LifecycleListener listener = - [worker = - reactor_worker_](impeller::egl ::Context::LifecycleEvent event) { - switch (event) { - case impeller::egl::Context::LifecycleEvent::kDidMakeCurrent: - worker->SetReactionsAllowedOnCurrentThread(true); - break; - case impeller::egl::Context::LifecycleEvent::kWillClearCurrent: - worker->SetReactionsAllowedOnCurrentThread(false); - break; - } - }; - if (!onscreen_context->AddLifecycleListener(listener).has_value() || - !offscreen_context->AddLifecycleListener(listener).has_value()) { - FML_DLOG(ERROR) << "Could not add lifecycle listeners"; - } - - onscreen_config_ = std::move(onscreen_config); - offscreen_config_ = std::move(offscreen_config); - offscreen_surface_ = std::move(offscreen_surface); - onscreen_context_ = std::move(onscreen_context); - offscreen_context_ = std::move(offscreen_context); - impeller_context_ = std::move(impeller_context); - // The onscreen surface will be acquired once the native window is set. is_valid_ = true; @@ -198,10 +35,10 @@ bool AndroidSurfaceGLImpeller::IsValid() const { // |AndroidSurface| std::unique_ptr AndroidSurfaceGLImpeller::CreateGPUSurface( GrDirectContext* gr_context) { - auto surface = - std::make_unique(this, // delegate - impeller_context_ // context - ); + auto surface = std::make_unique( + this, // delegate + android_context_->GetImpellerContext() // context + ); if (!surface->IsValid()) { return nullptr; } @@ -223,20 +60,15 @@ bool AndroidSurfaceGLImpeller::OnScreenSurfaceResize(const SkISize& size) { // |AndroidSurface| bool AndroidSurfaceGLImpeller::ResourceContextMakeCurrent() { - if (!offscreen_context_ || !offscreen_surface_) { + if (!offscreen_surface_) { return false; } - - return offscreen_context_->MakeCurrent(*offscreen_surface_); + return android_context_->ResourceContextMakeCurrent(offscreen_surface_.get()); } // |AndroidSurface| bool AndroidSurfaceGLImpeller::ResourceContextClearCurrent() { - if (!offscreen_context_ || !offscreen_surface_) { - return false; - } - - return offscreen_context_->ClearCurrent(); + return android_context_->ResourceContextClearCurrent(); } // |AndroidSurface| @@ -254,7 +86,7 @@ std::unique_ptr AndroidSurfaceGLImpeller::CreateSnapshotSurface() { // |AndroidSurface| std::shared_ptr AndroidSurfaceGLImpeller::GetImpellerContext() { - return impeller_context_; + return android_context_->GetImpellerContext(); } // |GPUSurfaceGLDelegate| @@ -264,20 +96,20 @@ AndroidSurfaceGLImpeller::GLContextMakeCurrent() { } bool AndroidSurfaceGLImpeller::OnGLContextMakeCurrent() { - if (!onscreen_surface_ || !onscreen_context_) { + if (!onscreen_surface_) { return false; } - return onscreen_context_->MakeCurrent(*onscreen_surface_); + return android_context_->OnscreenContextMakeCurrent(onscreen_surface_.get()); } // |GPUSurfaceGLDelegate| bool AndroidSurfaceGLImpeller::GLContextClearCurrent() { - if (!onscreen_surface_ || !onscreen_context_) { + if (!onscreen_surface_) { return false; } - return onscreen_context_->ClearCurrent(); + return android_context_->OnscreenContextClearCurrent(); } // |GPUSurfaceGLDelegate| @@ -326,8 +158,8 @@ bool AndroidSurfaceGLImpeller:: return false; } onscreen_surface_.reset(); - auto onscreen_surface = display_->CreateWindowSurface( - *onscreen_config_, native_window_->handle()); + auto onscreen_surface = + android_context_->CreateOnscreenSurface(native_window_->handle()); if (!onscreen_surface) { FML_DLOG(ERROR) << "Could not create onscreen surface."; return false; diff --git a/shell/platform/android/android_surface_gl_impeller.h b/shell/platform/android/android_surface_gl_impeller.h index 19109743f87b2..3066a8552ee25 100644 --- a/shell/platform/android/android_surface_gl_impeller.h +++ b/shell/platform/android/android_surface_gl_impeller.h @@ -7,8 +7,8 @@ #include "flutter/fml/macros.h" #include "flutter/impeller/renderer/context.h" -#include "flutter/impeller/toolkit/egl/display.h" #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" +#include "flutter/shell/platform/android/android_context_gl_impeller.h" #include "flutter/shell/platform/android/surface/android_native_window.h" #include "flutter/shell/platform/android/surface/android_surface.h" @@ -17,10 +17,8 @@ namespace flutter { class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate, public AndroidSurface { public: - AndroidSurfaceGLImpeller( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade, - std::unique_ptr display); + explicit AndroidSurfaceGLImpeller( + const std::shared_ptr& android_context); // |AndroidSurface| ~AndroidSurfaceGLImpeller() override; @@ -75,17 +73,9 @@ class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate, sk_sp GetGLInterface() const override; private: - class ReactorWorker; - - std::shared_ptr reactor_worker_; - std::unique_ptr display_; - std::unique_ptr onscreen_config_; - std::unique_ptr offscreen_config_; + std::shared_ptr android_context_; std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; - std::unique_ptr onscreen_context_; - std::unique_ptr offscreen_context_; - std::shared_ptr impeller_context_; fml::RefPtr native_window_; bool is_valid_ = false; diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 343d691e2ae75..d6ec0c3cf3d96 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -21,14 +21,13 @@ constexpr char kEmulatorRendererPrefix[] = } // anonymous namespace AndroidSurfaceGLSkia::AndroidSurfaceGLSkia( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade) - : AndroidSurface(android_context), + const std::shared_ptr& android_context) + : android_context_(android_context), native_window_(nullptr), onscreen_surface_(nullptr), offscreen_surface_(nullptr) { // Acquire the offscreen surface. - offscreen_surface_ = GLContextPtr()->CreateOffscreenSurface(); + offscreen_surface_ = android_context_->CreateOffscreenSurface(); if (!offscreen_surface_->IsValid()) { offscreen_surface_ = nullptr; } @@ -40,12 +39,12 @@ void AndroidSurfaceGLSkia::TeardownOnScreenContext() { // When the onscreen surface is destroyed, the context and the surface // instance should be deleted. Issue: // https://github.com/flutter/flutter/issues/64414 - GLContextPtr()->ClearCurrent(); + android_context_->ClearCurrent(); onscreen_surface_ = nullptr; } bool AndroidSurfaceGLSkia::IsValid() const { - return offscreen_surface_ && GLContextPtr()->IsValid(); + return offscreen_surface_ && android_context_->IsValid(); } std::unique_ptr AndroidSurfaceGLSkia::CreateGPUSurface( @@ -55,10 +54,10 @@ std::unique_ptr AndroidSurfaceGLSkia::CreateGPUSurface( true); } else { sk_sp main_skia_context = - GLContextPtr()->GetMainSkiaContext(); + android_context_->GetMainSkiaContext(); if (!main_skia_context) { main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this); - GLContextPtr()->SetMainSkiaContext(main_skia_context); + android_context_->SetMainSkiaContext(main_skia_context); } return std::make_unique(main_skia_context, this, true); } @@ -73,12 +72,12 @@ bool AndroidSurfaceGLSkia::OnScreenSurfaceResize(const SkISize& size) { return true; } - GLContextPtr()->ClearCurrent(); + android_context_->ClearCurrent(); // Ensure the destructor is called since it destroys the `EGLSurface` before // creating a new onscreen surface. onscreen_surface_ = nullptr; - onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(native_window_); + onscreen_surface_ = android_context_->CreateOnscreenSurface(native_window_); if (!onscreen_surface_->IsValid()) { FML_LOG(ERROR) << "Unable to create EGL window surface on resize."; return false; @@ -109,7 +108,7 @@ bool AndroidSurfaceGLSkia::SetNativeWindow( // creating a new onscreen surface. onscreen_surface_ = nullptr; // Create the onscreen surface. - onscreen_surface_ = GLContextPtr()->CreateOnscreenSurface(window); + onscreen_surface_ = android_context_->CreateOnscreenSurface(window); if (!onscreen_surface_->IsValid()) { return false; } @@ -127,7 +126,7 @@ std::unique_ptr AndroidSurfaceGLSkia::GLContextMakeCurrent() { bool AndroidSurfaceGLSkia::GLContextClearCurrent() { FML_DCHECK(IsValid()); - return GLContextPtr()->ClearCurrent(); + return android_context_->ClearCurrent(); } SurfaceFrame::FramebufferInfo AndroidSurfaceGLSkia::GLContextFramebufferInfo() @@ -186,7 +185,7 @@ sk_sp AndroidSurfaceGLSkia::GetGLInterface() const { reinterpret_cast(glGetString(GL_RENDERER)); if (gl_renderer && strncmp(gl_renderer, kEmulatorRendererPrefix, strlen(kEmulatorRendererPrefix)) == 0) { - EGLContext new_context = GLContextPtr()->CreateNewContext(); + EGLContext new_context = android_context_->CreateNewContext(); if (new_context != EGL_NO_CONTEXT) { EGLContext old_context = eglGetCurrentContext(); EGLDisplay display = eglGetCurrentDisplay(); @@ -205,19 +204,15 @@ sk_sp AndroidSurfaceGLSkia::GetGLInterface() const { return GPUSurfaceGLDelegate::GetGLInterface(); } -AndroidContextGLSkia* AndroidSurfaceGLSkia::GLContextPtr() const { - return reinterpret_cast(android_context_.get()); -} - std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotSurface() { if (!onscreen_surface_ || !onscreen_surface_->IsValid()) { - onscreen_surface_ = GLContextPtr()->CreatePbufferSurface(); + onscreen_surface_ = android_context_->CreatePbufferSurface(); } sk_sp main_skia_context = - GLContextPtr()->GetMainSkiaContext(); + android_context_->GetMainSkiaContext(); if (!main_skia_context) { main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this); - GLContextPtr()->SetMainSkiaContext(main_skia_context); + android_context_->SetMainSkiaContext(main_skia_context); } return std::make_unique(main_skia_context, this, true); diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index 274c28f2c6760..1c35692dc3a0e 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -21,9 +21,8 @@ namespace flutter { class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, public AndroidSurface { public: - AndroidSurfaceGLSkia( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade); + explicit AndroidSurfaceGLSkia( + const std::shared_ptr& android_context); ~AndroidSurfaceGLSkia() override; @@ -82,16 +81,11 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, } private: + std::shared_ptr android_context_; fml::RefPtr native_window_; std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; - //---------------------------------------------------------------------------- - /// @brief Takes the super class AndroidSurface's AndroidContext and - /// return a raw pointer to an AndroidContextGL. - /// - AndroidContextGLSkia* GLContextPtr() const; - FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceGLSkia); }; diff --git a/shell/platform/android/android_surface_software.cc b/shell/platform/android/android_surface_software.cc index fdfc8d9d509ac..0d1a2d9e2c180 100644 --- a/shell/platform/android/android_surface_software.cc +++ b/shell/platform/android/android_surface_software.cc @@ -40,10 +40,7 @@ bool GetSkColorType(int32_t buffer_format, } // anonymous namespace -AndroidSurfaceSoftware::AndroidSurfaceSoftware( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade) - : AndroidSurface(android_context) { +AndroidSurfaceSoftware::AndroidSurfaceSoftware() { GetSkColorType(WINDOW_FORMAT_RGBA_8888, &target_color_type_, &target_alpha_type_); } diff --git a/shell/platform/android/android_surface_software.h b/shell/platform/android/android_surface_software.h index 38e4c498f3843..1b7083aa7dda1 100644 --- a/shell/platform/android/android_surface_software.h +++ b/shell/platform/android/android_surface_software.h @@ -19,9 +19,7 @@ namespace flutter { class AndroidSurfaceSoftware final : public AndroidSurface, public GPUSurfaceSoftwareDelegate { public: - AndroidSurfaceSoftware( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade); + AndroidSurfaceSoftware(); ~AndroidSurfaceSoftware() override; diff --git a/shell/platform/android/android_surface_vulkan_impeller.cc b/shell/platform/android/android_surface_vulkan_impeller.cc index 0e5ac734e3b89..e5d2416af90bb 100644 --- a/shell/platform/android/android_surface_vulkan_impeller.cc +++ b/shell/platform/android/android_surface_vulkan_impeller.cc @@ -10,52 +10,16 @@ #include "flutter/fml/concurrent_message_loop.h" #include "flutter/fml/logging.h" #include "flutter/fml/memory/ref_ptr.h" -#include "flutter/fml/paths.h" #include "flutter/impeller/renderer/backend/vulkan/context_vk.h" #include "flutter/shell/gpu/gpu_surface_vulkan_impeller.h" #include "flutter/vulkan/vulkan_native_surface_android.h" -#include "impeller/entity/vk/entity_shaders_vk.h" -#include "impeller/entity/vk/modern_shaders_vk.h" -#include "impeller/scene/shaders/vk/scene_shaders_vk.h" namespace flutter { -static std::shared_ptr CreateImpellerContext( - const fml::RefPtr& proc_table, - const std::shared_ptr& concurrent_loop, - bool enable_vulkan_validation) { - std::vector> shader_mappings = { - std::make_shared(impeller_entity_shaders_vk_data, - impeller_entity_shaders_vk_length), - std::make_shared(impeller_scene_shaders_vk_data, - impeller_scene_shaders_vk_length), - std::make_shared(impeller_modern_shaders_vk_data, - impeller_modern_shaders_vk_length), - }; - - PFN_vkGetInstanceProcAddr instance_proc_addr = - proc_table->NativeGetInstanceProcAddr(); - - impeller::ContextVK::Settings settings; - settings.proc_address_callback = instance_proc_addr; - settings.shader_libraries_data = std::move(shader_mappings); - settings.cache_directory = fml::paths::GetCachesDirectory(); - settings.worker_task_runner = concurrent_loop->GetTaskRunner(); - settings.enable_validation = enable_vulkan_validation; - return impeller::ContextVK::Create(std::move(settings)); -} - AndroidSurfaceVulkanImpeller::AndroidSurfaceVulkanImpeller( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade, - bool enable_vulkan_validation) - : AndroidSurface(android_context), - proc_table_(fml::MakeRefCounted()), - workers_(fml::ConcurrentMessageLoop::Create()) { - impeller_context_ = - CreateImpellerContext(proc_table_, workers_, enable_vulkan_validation); - is_valid_ = - proc_table_->HasAcquiredMandatoryProcAddresses() && impeller_context_; + const std::shared_ptr& android_context) + : android_context_(android_context) { + is_valid_ = android_context_->IsValid(); } AndroidSurfaceVulkanImpeller::~AndroidSurfaceVulkanImpeller() = default; @@ -79,7 +43,8 @@ std::unique_ptr AndroidSurfaceVulkanImpeller::CreateGPUSurface( } std::unique_ptr gpu_surface = - std::make_unique(impeller_context_); + std::make_unique( + android_context_->GetImpellerContext()); if (!gpu_surface->IsValid()) { return nullptr; @@ -105,7 +70,8 @@ bool AndroidSurfaceVulkanImpeller::SetNativeWindow( native_window_ = std::move(window); bool success = native_window_ && native_window_->IsValid(); if (success) { - auto& context_vk = impeller::ContextVK::Cast(*impeller_context_); + auto& context_vk = + impeller::ContextVK::Cast(*android_context_->GetImpellerContext()); auto surface = context_vk.CreateAndroidSurface(native_window_->handle()); if (!surface) { @@ -122,7 +88,7 @@ bool AndroidSurfaceVulkanImpeller::SetNativeWindow( std::shared_ptr AndroidSurfaceVulkanImpeller::GetImpellerContext() { - return impeller_context_; + return android_context_->GetImpellerContext(); } } // namespace flutter diff --git a/shell/platform/android/android_surface_vulkan_impeller.h b/shell/platform/android/android_surface_vulkan_impeller.h index 3fff43d9d974c..548a0a5a4cf69 100644 --- a/shell/platform/android/android_surface_vulkan_impeller.h +++ b/shell/platform/android/android_surface_vulkan_impeller.h @@ -7,18 +7,16 @@ #include "flutter/fml/concurrent_message_loop.h" #include "flutter/fml/macros.h" #include "flutter/impeller/renderer/context.h" +#include "flutter/shell/platform/android/android_context_vulkan_impeller.h" #include "flutter/shell/platform/android/surface/android_native_window.h" #include "flutter/shell/platform/android/surface/android_surface.h" -#include "flutter/vulkan/procs/vulkan_proc_table.h" namespace flutter { class AndroidSurfaceVulkanImpeller : public AndroidSurface { public: - AndroidSurfaceVulkanImpeller( - const std::shared_ptr& android_context, - const std::shared_ptr& jni_facade, - bool enable_vulkan_validation); + explicit AndroidSurfaceVulkanImpeller( + const std::shared_ptr& android_context); ~AndroidSurfaceVulkanImpeller() override; @@ -48,10 +46,8 @@ class AndroidSurfaceVulkanImpeller : public AndroidSurface { bool SetNativeWindow(fml::RefPtr window) override; private: - fml::RefPtr proc_table_; + std::shared_ptr android_context_; fml::RefPtr native_window_; - std::shared_ptr workers_; - std::shared_ptr impeller_context_; bool is_valid_ = false; FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceVulkanImpeller); diff --git a/shell/platform/android/context/BUILD.gn b/shell/platform/android/context/BUILD.gn index 89918491187d3..a75549cab04d5 100644 --- a/shell/platform/android/context/BUILD.gn +++ b/shell/platform/android/context/BUILD.gn @@ -15,6 +15,7 @@ source_set("context") { deps = [ "//flutter/fml", + "//flutter/impeller/renderer", "//third_party/skia", ] diff --git a/shell/platform/android/context/android_context.cc b/shell/platform/android/context/android_context.cc index 1d4badf9543b7..3d7c4e619d97b 100644 --- a/shell/platform/android/context/android_context.cc +++ b/shell/platform/android/context/android_context.cc @@ -32,4 +32,13 @@ sk_sp AndroidContext::GetMainSkiaContext() const { return main_context_; } +std::shared_ptr AndroidContext::GetImpellerContext() const { + return impeller_context_; +} + +void AndroidContext::SetImpellerContext( + const std::shared_ptr& context) { + impeller_context_ = context; +} + } // namespace flutter diff --git a/shell/platform/android/context/android_context.h b/shell/platform/android/context/android_context.h index 0bed23e398674..ac3b7d49dee8a 100644 --- a/shell/platform/android/context/android_context.h +++ b/shell/platform/android/context/android_context.h @@ -7,6 +7,7 @@ #include "flutter/fml/macros.h" #include "flutter/fml/task_runner.h" +#include "flutter/impeller/renderer/context.h" #include "third_party/skia/include/gpu/GrDirectContext.h" namespace flutter { @@ -14,6 +15,7 @@ namespace flutter { enum class AndroidRenderingAPI { kSoftware, kOpenGLES, + kVulkan, }; //------------------------------------------------------------------------------ @@ -54,12 +56,25 @@ class AndroidContext { /// sk_sp GetMainSkiaContext() const; + //---------------------------------------------------------------------------- + /// @brief Accessor for the Impeller context associated with + /// AndroidSurfaces and the raster thread. + /// + std::shared_ptr GetImpellerContext() const; + + protected: + /// Intended to be called from a subclass constructor after setup work for the + /// context has completed. + void SetImpellerContext(const std::shared_ptr& context); + private: const AndroidRenderingAPI rendering_api_; // This is the Skia context used for on-screen rendering. sk_sp main_context_; + std::shared_ptr impeller_context_; + FML_DISALLOW_COPY_AND_ASSIGN(AndroidContext); }; 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 b9c527b16c710..c2d90ae2b10de 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 @@ -264,7 +264,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { auto frame_size = SkISize::Make(1000, 1000); SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size, framebuffer_info]() { + [gr_context, window, frame_size, framebuffer_info]() { auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { @@ -284,8 +284,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { .WillOnce(Return(ByMove(std::move(surface_frame_1)))) .WillOnce(Return(ByMove(std::move(surface_frame_2)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) @@ -472,7 +471,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { auto frame_size = SkISize::Make(1000, 1000); SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size, framebuffer_info]() { + [gr_context, window, frame_size, framebuffer_info]() { auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { @@ -485,8 +484,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { .Times(1 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) @@ -571,7 +569,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { auto frame_size = SkISize::Make(1000, 1000); SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size, framebuffer_info]() { + [gr_context, window, frame_size, framebuffer_info]() { auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { @@ -584,8 +582,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { .Times(1 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) @@ -675,7 +672,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { auto frame_size = SkISize::Make(1000, 1000); SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size, framebuffer_info]() { + [gr_context, window, frame_size, framebuffer_info]() { auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { @@ -688,8 +685,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { .Times(1 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) @@ -764,7 +760,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { auto frame_size = SkISize::Make(1000, 1000); SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size, framebuffer_info]() { + [gr_context, window, frame_size, framebuffer_info]() { auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { @@ -776,8 +772,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) @@ -853,7 +848,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { auto frame_size = SkISize::Make(1000, 1000); SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size, framebuffer_info]() { + [gr_context, window, frame_size, framebuffer_info]() { auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { @@ -865,8 +860,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) @@ -978,7 +972,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) { auto gr_context = GrDirectContext::MakeMock(nullptr); auto frame_size = SkISize::Make(1000, 1000); auto surface_factory = std::make_shared( - [&android_context, gr_context, window, frame_size]() { + [gr_context, window, frame_size]() { SurfaceFrame::FramebufferInfo framebuffer_info; auto surface_frame_1 = std::make_unique( SkSurface::MakeNull(1000, 1000), framebuffer_info, @@ -991,8 +985,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) { EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); - auto android_surface_mock = - std::make_unique(android_context); + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())) .WillOnce(Return(ByMove(std::move(surface_mock)))); diff --git a/shell/platform/android/external_view_embedder/surface_pool_unittests.cc b/shell/platform/android/external_view_embedder/surface_pool_unittests.cc index ecf4e1a6c78e9..d0c505675fe09 100644 --- a/shell/platform/android/external_view_embedder/surface_pool_unittests.cc +++ b/shell/platform/android/external_view_embedder/surface_pool_unittests.cc @@ -50,10 +50,9 @@ TEST(SurfacePool, GetLayerAllocateOneLayer) { ByMove(std::make_unique( 0, window)))); - auto surface_factory = std::make_shared( - [&android_context, gr_context, window]() { - auto android_surface_mock = - std::make_unique(android_context); + auto surface_factory = + std::make_shared([gr_context, window]() { + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())); EXPECT_CALL(*android_surface_mock, SetNativeWindow(window)); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); @@ -82,10 +81,9 @@ TEST(SurfacePool, GetUnusedLayers) { ByMove(std::make_unique( 0, window)))); - auto surface_factory = std::make_shared( - [&android_context, gr_context, window]() { - auto android_surface_mock = - std::make_unique(android_context); + auto surface_factory = + std::make_shared([gr_context, window]() { + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())); EXPECT_CALL(*android_surface_mock, SetNativeWindow(window)); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); @@ -118,9 +116,8 @@ TEST(SurfacePool, GetLayerRecycle) { auto gr_context_2 = GrDirectContext::MakeMock(nullptr); auto surface_factory = std::make_shared( - [&android_context, gr_context_1, gr_context_2, window]() { - auto android_surface_mock = - std::make_unique(android_context); + [gr_context_1, gr_context_2, window]() { + auto android_surface_mock = std::make_unique(); // Allocate two GPU surfaces for each gr context. EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context_1.get())); @@ -166,10 +163,9 @@ TEST(SurfacePool, GetLayerAllocateTwoLayers) { ByMove(std::make_unique( 1, window)))); - auto surface_factory = std::make_shared( - [&android_context, gr_context, window]() { - auto android_surface_mock = - std::make_unique(android_context); + auto surface_factory = + std::make_shared([gr_context, window]() { + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())); EXPECT_CALL(*android_surface_mock, SetNativeWindow(window)); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); @@ -206,10 +202,9 @@ TEST(SurfacePool, DestroyLayers) { ByMove(std::make_unique( 0, window)))); - auto surface_factory = std::make_shared( - [&android_context, gr_context, window]() { - auto android_surface_mock = - std::make_unique(android_context); + auto surface_factory = + std::make_shared([gr_context, window]() { + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())); EXPECT_CALL(*android_surface_mock, SetNativeWindow(window)); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); @@ -236,10 +231,9 @@ TEST(SurfacePool, DestroyLayersFrameSizeChanged) { auto window = fml::MakeRefCounted(nullptr); - auto surface_factory = std::make_shared( - [&android_context, gr_context, window]() { - auto android_surface_mock = - std::make_unique(android_context); + auto surface_factory = + std::make_shared([gr_context, window]() { + auto android_surface_mock = std::make_unique(); EXPECT_CALL(*android_surface_mock, CreateGPUSurface(gr_context.get())); EXPECT_CALL(*android_surface_mock, SetNativeWindow(window)); EXPECT_CALL(*android_surface_mock, IsValid()).WillOnce(Return(true)); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index bb34af3cf2c3e..769f1a0feae8f 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -31,37 +31,29 @@ namespace flutter { AndroidSurfaceFactoryImpl::AndroidSurfaceFactoryImpl( const std::shared_ptr& context, - std::shared_ptr jni_facade, - bool enable_impeller, - bool enable_vulkan_validation) - : android_context_(context), - jni_facade_(std::move(jni_facade)), - enable_impeller_(enable_impeller), - enable_vulkan_validation_(enable_vulkan_validation) {} + bool enable_impeller) + : android_context_(context), enable_impeller_(enable_impeller) {} AndroidSurfaceFactoryImpl::~AndroidSurfaceFactoryImpl() = default; std::unique_ptr AndroidSurfaceFactoryImpl::CreateSurface() { switch (android_context_->RenderingApi()) { case AndroidRenderingAPI::kSoftware: - return std::make_unique(android_context_, - jni_facade_); + return std::make_unique(); case AndroidRenderingAPI::kOpenGLES: if (enable_impeller_) { -// TODO(kaushikiska@): Enable this after wiring a preference for Vulkan backend. -#if false - return std::make_unique( - android_context_, jni_facade_, enable_vulkan_validation_); - -#else return std::make_unique( - android_context_, jni_facade_, - std::make_unique()); -#endif + std::static_pointer_cast( + android_context_)); } else { - return std::make_unique(android_context_, - jni_facade_); + return std::make_unique( + std::static_pointer_cast(android_context_)); } + case AndroidRenderingAPI::kVulkan: + FML_DCHECK(enable_impeller_); + return std::make_unique( + std::static_pointer_cast( + android_context_)); default: FML_DCHECK(false); return nullptr; @@ -72,12 +64,20 @@ static std::shared_ptr CreateAndroidContext( bool use_software_rendering, const flutter::TaskRunners& task_runners, uint8_t msaa_samples, - bool enable_impeller) { + bool enable_impeller, + bool enable_vulkan_validation) { if (use_software_rendering) { return std::make_shared(AndroidRenderingAPI::kSoftware); } if (enable_impeller) { - return std::make_unique(); + // TODO(kaushikiska@): Enable this after wiring a preference for Vulkan + // backend. +#if false + return std::make_unique(enable_vulkan_validation); +#else + return std::make_unique( + std::make_unique()); +#endif } return std::make_unique( AndroidRenderingAPI::kOpenGLES, // @@ -101,7 +101,8 @@ PlatformViewAndroid::PlatformViewAndroid( use_software_rendering, task_runners, msaa_samples, - delegate.OnPlatformViewGetSettings().enable_impeller)) {} + delegate.OnPlatformViewGetSettings().enable_impeller, + delegate.OnPlatformViewGetSettings().enable_vulkan_validation)) {} PlatformViewAndroid::PlatformViewAndroid( PlatformView::Delegate& delegate, @@ -117,10 +118,8 @@ PlatformViewAndroid::PlatformViewAndroid( FML_CHECK(android_context_->IsValid()) << "Could not create surface from invalid Android context."; surface_factory_ = std::make_shared( - android_context_, // - jni_facade_, // - delegate.OnPlatformViewGetSettings().enable_impeller, // - delegate.OnPlatformViewGetSettings().enable_vulkan_validation // + android_context_, // + delegate.OnPlatformViewGetSettings().enable_impeller // ); android_surface_ = surface_factory_->CreateSurface(); FML_CHECK(android_surface_ && android_surface_->IsValid()) diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index d7a8e8ce65751..069b2f920b3af 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -27,9 +27,7 @@ namespace flutter { class AndroidSurfaceFactoryImpl : public AndroidSurfaceFactory { public: AndroidSurfaceFactoryImpl(const std::shared_ptr& context, - std::shared_ptr jni_facade, - bool enable_impeller, - bool enable_vulkan_validation); + bool enable_impeller); ~AndroidSurfaceFactoryImpl() override; @@ -37,9 +35,7 @@ class AndroidSurfaceFactoryImpl : public AndroidSurfaceFactory { private: const std::shared_ptr& android_context_; - std::shared_ptr jni_facade_; const bool enable_impeller_; - const bool enable_vulkan_validation_; }; class PlatformViewAndroid final : public PlatformView { diff --git a/shell/platform/android/surface/android_surface.cc b/shell/platform/android/surface/android_surface.cc index ab96387edbd77..e301491b5fce0 100644 --- a/shell/platform/android/surface/android_surface.cc +++ b/shell/platform/android/surface/android_surface.cc @@ -7,11 +7,7 @@ namespace flutter { -AndroidSurface::AndroidSurface( - const std::shared_ptr& android_context) { - FML_DCHECK(android_context->IsValid()); - android_context_ = android_context; -} +AndroidSurface::AndroidSurface() = default; AndroidSurface::~AndroidSurface() = default; diff --git a/shell/platform/android/surface/android_surface.h b/shell/platform/android/surface/android_surface.h index 485f619e1a81b..7eae6c68e7d71 100644 --- a/shell/platform/android/surface/android_surface.h +++ b/shell/platform/android/surface/android_surface.h @@ -46,9 +46,7 @@ class AndroidSurface { virtual std::shared_ptr GetImpellerContext(); protected: - explicit AndroidSurface( - const std::shared_ptr& android_context); - std::shared_ptr android_context_; + AndroidSurface(); }; class AndroidSurfaceFactory { diff --git a/shell/platform/android/surface/android_surface_mock.cc b/shell/platform/android/surface/android_surface_mock.cc index 8f718fcae667a..0f7c6d1a6d80c 100644 --- a/shell/platform/android/surface/android_surface_mock.cc +++ b/shell/platform/android/surface/android_surface_mock.cc @@ -6,10 +6,6 @@ namespace flutter { -AndroidSurfaceMock::AndroidSurfaceMock( - const std::shared_ptr& android_context) - : AndroidSurface(android_context) {} - std::unique_ptr AndroidSurfaceMock::GLContextMakeCurrent() { return std::make_unique(/*static_result=*/true); } diff --git a/shell/platform/android/surface/android_surface_mock.h b/shell/platform/android/surface/android_surface_mock.h index 3f326a21920b7..411816698cb74 100644 --- a/shell/platform/android/surface/android_surface_mock.h +++ b/shell/platform/android/surface/android_surface_mock.h @@ -18,9 +18,6 @@ namespace flutter { class AndroidSurfaceMock final : public GPUSurfaceGLDelegate, public AndroidSurface { public: - explicit AndroidSurfaceMock( - const std::shared_ptr& android_context); - MOCK_METHOD(bool, IsValid, (), (const, override)); MOCK_METHOD(void, TeardownOnScreenContext, (), (override));