diff --git a/common/settings.h b/common/settings.h index ec4e8f5a842fa..a62f1b44a82cb 100644 --- a/common/settings.h +++ b/common/settings.h @@ -22,6 +22,14 @@ namespace flutter { +// The combination of targeted graphics API and Impeller support. +enum class AndroidRenderingAPI { + kSoftware, + kImpellerOpenGLES, + kImpellerVulkan, + kSkiaOpenGLES +}; + class FrameTiming { public: enum Phase { @@ -221,8 +229,12 @@ struct Settings { bool enable_impeller = false; #endif - // Requests a particular backend to be used (ex "opengles" or "vulkan") - std::optional impeller_backend; + // The selected Android rendering API. + AndroidRenderingAPI android_rendering_api = + AndroidRenderingAPI::kSkiaOpenGLES; + + // Requests a specific rendering backend. + std::optional requested_rendering_backend; // Enable Vulkan validation on backends that support it. The validation layers // must be available to the application. diff --git a/shell/common/switches.cc b/shell/common/switches.cc index 0c28e81d5af1c..fd3d9508fb8c9 100644 --- a/shell/common/switches.cc +++ b/shell/common/switches.cc @@ -459,7 +459,7 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) { if (command_line.GetOptionValue(FlagForSwitch(Switch::ImpellerBackend), &impeller_backend_value)) { if (!impeller_backend_value.empty()) { - settings.impeller_backend = impeller_backend_value; + settings.requested_rendering_backend = impeller_backend_value; } } } diff --git a/shell/platform/android/android_context_gl_impeller.cc b/shell/platform/android/android_context_gl_impeller.cc index 73cec9af7d9e1..d96e55e878055 100644 --- a/shell/platform/android/android_context_gl_impeller.cc +++ b/shell/platform/android/android_context_gl_impeller.cc @@ -91,7 +91,7 @@ static std::shared_ptr CreateImpellerContext( AndroidContextGLImpeller::AndroidContextGLImpeller( std::unique_ptr display, bool enable_gpu_tracing) - : AndroidContext(AndroidRenderingAPI::kOpenGLES), + : AndroidContext(AndroidRenderingAPI::kImpellerOpenGLES), reactor_worker_(std::shared_ptr(new ReactorWorker())), display_(std::move(display)) { if (!display_ || !display_->IsValid()) { diff --git a/shell/platform/android/android_context_gl_skia.cc b/shell/platform/android/android_context_gl_skia.cc index a784c6d2259bd..8ad49cf82c5e8 100644 --- a/shell/platform/android/android_context_gl_skia.cc +++ b/shell/platform/android/android_context_gl_skia.cc @@ -65,11 +65,10 @@ static bool TeardownContext(EGLDisplay display, EGLContext context) { } AndroidContextGLSkia::AndroidContextGLSkia( - AndroidRenderingAPI rendering_api, fml::RefPtr environment, const TaskRunners& task_runners, uint8_t msaa_samples) - : AndroidContext(AndroidRenderingAPI::kOpenGLES), + : AndroidContext(AndroidRenderingAPI::kSkiaOpenGLES), environment_(std::move(environment)), task_runners_(task_runners) { if (!environment_->IsValid()) { diff --git a/shell/platform/android/android_context_gl_skia.h b/shell/platform/android/android_context_gl_skia.h index 1c9e092ff3a33..af19ef789d8de 100644 --- a/shell/platform/android/android_context_gl_skia.h +++ b/shell/platform/android/android_context_gl_skia.h @@ -27,8 +27,7 @@ class AndroidEGLSurface; /// class AndroidContextGLSkia : public AndroidContext { public: - AndroidContextGLSkia(AndroidRenderingAPI rendering_api, - fml::RefPtr environment, + AndroidContextGLSkia(fml::RefPtr environment, const TaskRunners& taskRunners, uint8_t msaa_samples); diff --git a/shell/platform/android/android_context_gl_unittests.cc b/shell/platform/android/android_context_gl_unittests.cc index ec6690b912548..bd28354383727 100644 --- a/shell/platform/android/android_context_gl_unittests.cc +++ b/shell/platform/android/android_context_gl_unittests.cc @@ -104,8 +104,8 @@ TEST(AndroidContextGl, Create) { thread_label, ThreadHost::Type::kUi | ThreadHost::Type::kRaster | ThreadHost::Type::kIo)); TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); - auto context = std::make_unique( - AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); + auto context = + std::make_unique(environment, task_runners, 0); context->SetMainSkiaContext(main_context); EXPECT_NE(context.get(), nullptr); context.reset(); @@ -115,7 +115,7 @@ TEST(AndroidContextGl, Create) { TEST(AndroidContextGl, CreateImpeller) { auto impeller_context = std::make_shared(); auto android_context = std::make_unique( - impeller_context, AndroidRenderingAPI::kOpenGLES); + impeller_context, AndroidRenderingAPI::kImpellerOpenGLES); EXPECT_FALSE(impeller_context->did_shutdown); android_context.reset(); @@ -136,8 +136,8 @@ TEST(AndroidContextGl, CreateSingleThread) { TaskRunners task_runners = TaskRunners(thread_label, platform_runner, platform_runner, platform_runner, platform_runner); - auto context = std::make_unique( - AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); + auto context = + std::make_unique(environment, task_runners, 0); context->SetMainSkiaContext(main_context); EXPECT_NE(context.get(), nullptr); context.reset(); @@ -155,8 +155,8 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNotNull) { thread_label, ThreadHost::Type::kUi | ThreadHost::Type::kRaster | ThreadHost::Type::kIo)); TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); - auto android_context = std::make_shared( - AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); + auto android_context = + std::make_shared(environment, task_runners, 0); auto android_surface = std::make_unique(android_context); auto window = fml::MakeRefCounted( @@ -182,8 +182,8 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNull) { ThreadHost thread_host(host_config); TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); - auto android_context = std::make_shared( - AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); + auto android_context = + std::make_shared(environment, task_runners, 0); auto android_surface = std::make_unique(android_context); EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr); @@ -204,8 +204,8 @@ TEST(AndroidContextGl, DISABLED_MSAAx4) { thread_label, ThreadHost::Type::kUi | ThreadHost::Type::kRaster | ThreadHost::Type::kIo)); TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); - auto context = std::make_unique( - AndroidRenderingAPI::kOpenGLES, environment, task_runners, 4); + auto context = + std::make_unique(environment, task_runners, 4); context->SetMainSkiaContext(main_context); EGLint sample_count; @@ -226,8 +226,8 @@ TEST(AndroidContextGl, EnsureMakeCurrentChecksCurrentContextStatus) { thread_label, ThreadHost::Type::kUi | ThreadHost::Type::kRaster | ThreadHost::Type::kIo)); TaskRunners task_runners = MakeTaskRunners(thread_label, thread_host); - auto context = std::make_unique( - AndroidRenderingAPI::kOpenGLES, environment, task_runners, 0); + auto context = + std::make_unique(environment, task_runners, 0); auto pbuffer_surface = context->CreatePbufferSurface(); auto status = pbuffer_surface->MakeCurrent(); diff --git a/shell/platform/android/android_context_vulkan_impeller.cc b/shell/platform/android/android_context_vulkan_impeller.cc index d9d23ebe31122..ecbeea6405f5d 100644 --- a/shell/platform/android/android_context_vulkan_impeller.cc +++ b/shell/platform/android/android_context_vulkan_impeller.cc @@ -19,7 +19,8 @@ namespace flutter { static std::shared_ptr CreateImpellerContext( const fml::RefPtr& vulkan_dylib, bool enable_vulkan_validation, - bool enable_gpu_tracing) { + bool enable_gpu_tracing, + bool quiet) { if (!vulkan_dylib) { VALIDATION_LOG << "Could not open the Vulkan dylib."; return nullptr; @@ -57,12 +58,14 @@ static std::shared_ptr CreateImpellerContext( auto context = impeller::ContextVK::Create(std::move(settings)); - if (context && impeller::CapabilitiesVK::Cast(*context->GetCapabilities()) - .AreValidationsEnabled()) { - FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (Vulkan with " - "Validation Layers)."; - } else { - FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (Vulkan)."; + if (!quiet) { + if (context && impeller::CapabilitiesVK::Cast(*context->GetCapabilities()) + .AreValidationsEnabled()) { + FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (Vulkan with " + "Validation Layers)."; + } else { + FML_LOG(IMPORTANT) << "Using the Impeller rendering backend (Vulkan)."; + } } return context; @@ -70,11 +73,12 @@ static std::shared_ptr CreateImpellerContext( AndroidContextVulkanImpeller::AndroidContextVulkanImpeller( bool enable_validation, - bool enable_gpu_tracing) - : AndroidContext(AndroidRenderingAPI::kVulkan), + bool enable_gpu_tracing, + bool quiet) + : AndroidContext(AndroidRenderingAPI::kImpellerVulkan), vulkan_dylib_(fml::NativeLibrary::Create("libvulkan.so")) { auto impeller_context = CreateImpellerContext( - vulkan_dylib_, enable_validation, enable_gpu_tracing); + vulkan_dylib_, enable_validation, enable_gpu_tracing, quiet); SetImpellerContext(impeller_context); is_valid_ = !!impeller_context; } diff --git a/shell/platform/android/android_context_vulkan_impeller.h b/shell/platform/android/android_context_vulkan_impeller.h index 266843d534f15..cd9be6946ad76 100644 --- a/shell/platform/android/android_context_vulkan_impeller.h +++ b/shell/platform/android/android_context_vulkan_impeller.h @@ -14,7 +14,9 @@ namespace flutter { class AndroidContextVulkanImpeller : public AndroidContext { public: - AndroidContextVulkanImpeller(bool enable_validation, bool enable_gpu_tracing); + AndroidContextVulkanImpeller(bool enable_validation, + bool enable_gpu_tracing, + bool quiet = false); ~AndroidContextVulkanImpeller(); diff --git a/shell/platform/android/context/BUILD.gn b/shell/platform/android/context/BUILD.gn index 1de85c8144376..31c5f0ecb95ab 100644 --- a/shell/platform/android/context/BUILD.gn +++ b/shell/platform/android/context/BUILD.gn @@ -14,6 +14,7 @@ source_set("context") { public_configs = [ "//flutter:config" ] deps = [ + "//flutter/common", "//flutter/fml", "//flutter/impeller/renderer", "//flutter/skia", diff --git a/shell/platform/android/context/android_context.h b/shell/platform/android/context/android_context.h index e49ddcf58ffd6..598787fd70117 100644 --- a/shell/platform/android/context/android_context.h +++ b/shell/platform/android/context/android_context.h @@ -5,6 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_ANDROID_CONTEXT_ANDROID_CONTEXT_H_ #define FLUTTER_SHELL_PLATFORM_ANDROID_CONTEXT_ANDROID_CONTEXT_H_ +#include "common/settings.h" #include "flutter/fml/macros.h" #include "flutter/fml/task_runner.h" #include "flutter/impeller/renderer/context.h" @@ -12,15 +13,6 @@ namespace flutter { -enum class AndroidRenderingAPI { - kSoftware, - kOpenGLES, - kVulkan, - /// @brief Attempt to create a Vulkan surface, if that fails then fall back - /// to GLES. - kAutoselect, -}; - //------------------------------------------------------------------------------ /// @brief Holds state that is shared across Android surfaces. /// diff --git a/shell/platform/android/flutter_main.cc b/shell/platform/android/flutter_main.cc index 6ad57a7ca04cc..d3ad35ee6b23b 100644 --- a/shell/platform/android/flutter_main.cc +++ b/shell/platform/android/flutter_main.cc @@ -4,15 +4,14 @@ #define FML_USED_ON_EMBEDDER -#include "flutter/shell/platform/android/flutter_main.h" - #include - #include #include +#include "common/settings.h" #include "flutter/fml/command_line.h" #include "flutter/fml/file.h" +#include "flutter/fml/logging.h" #include "flutter/fml/macros.h" #include "flutter/fml/message_loop.h" #include "flutter/fml/native_library.h" @@ -25,11 +24,16 @@ #include "flutter/runtime/dart_vm.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/common/switches.h" +#include "flutter/shell/platform/android/android_context_vulkan_impeller.h" +#include "flutter/shell/platform/android/flutter_main.h" +#include "impeller/base/validation.h" #include "third_party/dart/runtime/include/dart_tools_api.h" #include "txt/platform.h" namespace flutter { +constexpr int kMinimumAndroidApiLevelForVulkan = 29; + extern "C" { #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG // Used for debugging dart:* sources. @@ -91,6 +95,18 @@ void FlutterMain::Init(JNIEnv* env, } } + settings.android_rendering_api = SelectedRenderingAPI(settings); + switch (settings.android_rendering_api) { + case AndroidRenderingAPI::kSoftware: + case AndroidRenderingAPI::kSkiaOpenGLES: + settings.enable_impeller = false; + break; + case AndroidRenderingAPI::kImpellerOpenGLES: + case AndroidRenderingAPI::kImpellerVulkan: + settings.enable_impeller = true; + break; + } + #if FLUTTER_RELEASE // On most platforms the timeline is always disabled in release mode. // On Android, enable it in release mode only when using systrace. @@ -211,4 +227,53 @@ bool FlutterMain::Register(JNIEnv* env) { return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0; } +// static +AndroidRenderingAPI FlutterMain::SelectedRenderingAPI( + const flutter::Settings& settings) { + if (settings.enable_software_rendering) { + FML_CHECK(!settings.enable_impeller) + << "Impeller does not support software rendering. Either disable " + "software rendering or disable impeller."; + return AndroidRenderingAPI::kSoftware; + } + // Debug/Profile only functionality for testing a specific + // backend configuration. +#ifndef FLUTTER_RELEASE + if (settings.requested_rendering_backend == "opengles" & + settings.enable_impeller) { + return AndroidRenderingAPI::kImpellerOpenGLES; + } + if (settings.requested_rendering_backend == "vulkan" && + settings.enable_impeller) { + return AndroidRenderingAPI::kImpellerVulkan; + } +#endif + + if (settings.enable_impeller) { + // Vulkan must only be used on API level 29+, as older API levels do not + // have requisite features to support platform views. + // + // Even if this check returns true, Impeller may determine it cannot use + // Vulkan for some other reason, such as a missing required extension or + // feature. + int api_level = android_get_device_api_level(); + if (api_level < kMinimumAndroidApiLevelForVulkan) { + return AndroidRenderingAPI::kImpellerOpenGLES; + } + // Determine if Vulkan is supported by creating a Vulkan context and + // checking if it is valid. + impeller::ScopedValidationDisable disable_validation; + auto vulkan_backend = std::make_unique( + /*enable_vulkan_validation=*/false, + /*enable_vulkan_gpu_tracing=*/false, + /*quiet=*/true); + if (!vulkan_backend->IsValid()) { + return AndroidRenderingAPI::kImpellerOpenGLES; + } + return AndroidRenderingAPI::kImpellerVulkan; + } + + return AndroidRenderingAPI::kSkiaOpenGLES; +} + } // namespace flutter diff --git a/shell/platform/android/flutter_main.h b/shell/platform/android/flutter_main.h index 5bd9f298a1c5a..c572b458fbc29 100644 --- a/shell/platform/android/flutter_main.h +++ b/shell/platform/android/flutter_main.h @@ -23,6 +23,9 @@ class FlutterMain { const flutter::Settings& GetSettings() const; + static AndroidRenderingAPI SelectedRenderingAPI( + const flutter::Settings& settings); + private: const flutter::Settings settings_; DartServiceIsolate::CallbackHandle vm_service_uri_callback_ = 0; diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index b8d1f80fafe8b..15abb985bb73a 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -20,6 +20,7 @@ #include "flutter/shell/platform/android/android_surface_software.h" #include "flutter/shell/platform/android/image_external_texture_gl.h" #include "flutter/shell/platform/android/surface_texture_external_texture_gl.h" +#include "fml/logging.h" #if IMPELLER_ENABLE_VULKAN // b/258506856 for why this is behind an if #include "flutter/shell/platform/android/android_surface_vulkan_impeller.h" #include "flutter/shell/platform/android/image_external_texture_vk.h" @@ -34,8 +35,6 @@ namespace flutter { -constexpr int kMinimumAndroidApiLevelForVulkan = 29; - AndroidSurfaceFactoryImpl::AndroidSurfaceFactoryImpl( const std::shared_ptr& context, bool enable_impeller) @@ -47,100 +46,46 @@ std::unique_ptr AndroidSurfaceFactoryImpl::CreateSurface() { switch (android_context_->RenderingApi()) { case AndroidRenderingAPI::kSoftware: return std::make_unique(); - case AndroidRenderingAPI::kOpenGLES: - if (enable_impeller_) { - return std::make_unique( - std::static_pointer_cast( - android_context_)); - } else { - return std::make_unique( - std::static_pointer_cast(android_context_)); - } - case AndroidRenderingAPI::kVulkan: - FML_DCHECK(enable_impeller_); + case AndroidRenderingAPI::kImpellerOpenGLES: + return std::make_unique( + std::static_pointer_cast(android_context_)); + case AndroidRenderingAPI::kSkiaOpenGLES: + return std::make_unique( + std::static_pointer_cast(android_context_)); + case AndroidRenderingAPI::kImpellerVulkan: return std::make_unique( std::static_pointer_cast( android_context_)); - default: - FML_DCHECK(false); - return nullptr; } + FML_UNREACHABLE(); } static std::shared_ptr CreateAndroidContext( bool use_software_rendering, const flutter::TaskRunners& task_runners, uint8_t msaa_samples, - bool enable_impeller, - const std::optional& impeller_backend, + AndroidRenderingAPI android_rendering_api, bool enable_vulkan_validation, bool enable_opengl_gpu_tracing, bool enable_vulkan_gpu_tracing) { - if (use_software_rendering) { - FML_DCHECK(!enable_impeller); - return std::make_shared(AndroidRenderingAPI::kSoftware); - } - if (enable_impeller) { - // Vulkan must only be used on API level 29+, as older API levels do not - // have requisite features to support platform views. - // - // Even if this check returns true, Impeller may determine it cannot use - // Vulkan for some other reason, such as a missing required extension or - // feature. - int api_level = android_get_device_api_level(); - if (api_level < kMinimumAndroidApiLevelForVulkan) { - if (impeller_backend.value_or("") == "vulkan") { - FML_LOG(WARNING) - << "Impeller Vulkan requested, but detected Android API level " - << api_level - << " does not support required features for Vulkan with platform " - "views. Falling back to OpenGLES."; - } + switch (android_rendering_api) { + case AndroidRenderingAPI::kSoftware: + return std::make_shared(AndroidRenderingAPI::kSoftware); + case AndroidRenderingAPI::kImpellerOpenGLES: return std::make_unique( std::make_unique(), enable_opengl_gpu_tracing); - } - - // Default value is Vulkan with GLES fallback. - AndroidRenderingAPI backend = AndroidRenderingAPI::kAutoselect; - if (impeller_backend.has_value()) { - if (impeller_backend.value() == "opengles") { - backend = AndroidRenderingAPI::kOpenGLES; - } else if (impeller_backend.value() == "vulkan") { - backend = AndroidRenderingAPI::kVulkan; - } else { - FML_CHECK(impeller_backend.value() == "vulkan" || - impeller_backend.value() == "opengles"); - } - } - switch (backend) { - case AndroidRenderingAPI::kOpenGLES: - return std::make_unique( - std::make_unique(), - enable_opengl_gpu_tracing); - case AndroidRenderingAPI::kVulkan: - return std::make_unique( - enable_vulkan_validation, enable_vulkan_gpu_tracing); - case AndroidRenderingAPI::kAutoselect: { - auto vulkan_backend = std::make_unique( - enable_vulkan_validation, enable_vulkan_gpu_tracing); - if (!vulkan_backend->IsValid()) { - return std::make_unique( - std::make_unique(), - enable_opengl_gpu_tracing); - } - return vulkan_backend; - } - default: - FML_UNREACHABLE(); - } + case AndroidRenderingAPI::kImpellerVulkan: + return std::make_unique( + enable_vulkan_validation, enable_vulkan_gpu_tracing); + case AndroidRenderingAPI::kSkiaOpenGLES: + return std::make_unique( + fml::MakeRefCounted(), // + task_runners, // + msaa_samples // + ); } - return std::make_unique( - AndroidRenderingAPI::kOpenGLES, // - fml::MakeRefCounted(), // - task_runners, // - msaa_samples // - ); + FML_UNREACHABLE(); } PlatformViewAndroid::PlatformViewAndroid( @@ -157,8 +102,7 @@ PlatformViewAndroid::PlatformViewAndroid( use_software_rendering, task_runners, msaa_samples, - delegate.OnPlatformViewGetSettings().enable_impeller, - delegate.OnPlatformViewGetSettings().impeller_backend, + delegate.OnPlatformViewGetSettings().android_rendering_api, delegate.OnPlatformViewGetSettings().enable_vulkan_validation, delegate.OnPlatformViewGetSettings().enable_opengl_gpu_tracing, delegate.OnPlatformViewGetSettings().enable_vulkan_gpu_tracing)) { @@ -333,48 +277,56 @@ void PlatformViewAndroid::UpdateSemantics( void PlatformViewAndroid::RegisterExternalTexture( int64_t texture_id, const fml::jni::ScopedJavaGlobalRef& surface_texture) { - if (android_context_->RenderingApi() == AndroidRenderingAPI::kOpenGLES) { - if (android_context_->GetImpellerContext()) { + switch (android_context_->RenderingApi()) { + case AndroidRenderingAPI::kImpellerOpenGLES: // Impeller GLES. RegisterTexture(std::make_shared( std::static_pointer_cast( android_context_->GetImpellerContext()), texture_id, surface_texture, jni_facade_)); - } else { + break; + case AndroidRenderingAPI::kSkiaOpenGLES: // Legacy GL. RegisterTexture(std::make_shared( texture_id, surface_texture, jni_facade_)); - } - } else { - FML_LOG(INFO) << "Attempted to use a SurfaceTextureExternalTexture with an " - "unsupported rendering API."; + break; + case AndroidRenderingAPI::kSoftware: + case AndroidRenderingAPI::kImpellerVulkan: + FML_LOG(INFO) + << "Attempted to use a SurfaceTextureExternalTexture with an " + "unsupported rendering API."; + break; } } void PlatformViewAndroid::RegisterImageTexture( int64_t texture_id, const fml::jni::ScopedJavaGlobalRef& image_texture_entry) { - if (android_context_->RenderingApi() == AndroidRenderingAPI::kOpenGLES) { - if (android_context_->GetImpellerContext()) { + switch (android_context_->RenderingApi()) { + case AndroidRenderingAPI::kImpellerOpenGLES: // Impeller GLES. RegisterTexture(std::make_shared( std::static_pointer_cast( android_context_->GetImpellerContext()), texture_id, image_texture_entry, jni_facade_)); - } else { + break; + case AndroidRenderingAPI::kSkiaOpenGLES: // Legacy GL. RegisterTexture(std::make_shared( std::static_pointer_cast(android_context_), texture_id, image_texture_entry, jni_facade_)); - } - } else if (android_context_->RenderingApi() == AndroidRenderingAPI::kVulkan) { - RegisterTexture(std::make_shared( - std::static_pointer_cast( - android_context_->GetImpellerContext()), - texture_id, image_texture_entry, jni_facade_)); - } else { - FML_LOG(INFO) << "Attempted to use a HardwareBuffer texture with an " - "unsupported rendering API."; + break; + case AndroidRenderingAPI::kImpellerVulkan: + RegisterTexture(std::make_shared( + std::static_pointer_cast( + android_context_->GetImpellerContext()), + texture_id, image_texture_entry, jni_facade_)); + break; + case AndroidRenderingAPI::kSoftware: + FML_LOG(INFO) + << "Attempted to use a SurfaceTextureExternalTexture with an " + "unsupported rendering API."; + break; } } diff --git a/shell/platform/android/platform_view_android_unittests.cc b/shell/platform/android/platform_view_android_unittests.cc index c757c71001508..fc1c2d9d1b17d 100644 --- a/shell/platform/android/platform_view_android_unittests.cc +++ b/shell/platform/android/platform_view_android_unittests.cc @@ -2,132 +2,37 @@ // 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/platform_view_android.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -#include "shell/platform/android/context/android_context.h" +#include "shell/platform/android/flutter_main.h" #include "third_party/googletest/googlemock/include/gmock/gmock-nice-strict.h" namespace flutter { namespace testing { -using ::testing::NiceMock; -using ::testing::ReturnRef; - -namespace { -class MockPlatformViewDelegate : public PlatformView::Delegate { - public: - MOCK_METHOD(void, - OnPlatformViewCreated, - (std::unique_ptr surface), - (override)); - - MOCK_METHOD(void, OnPlatformViewDestroyed, (), (override)); - - MOCK_METHOD(void, OnPlatformViewScheduleFrame, (), (override)); - - MOCK_METHOD(void, - OnPlatformViewSetNextFrameCallback, - (const fml::closure& closure), - (override)); - - MOCK_METHOD(void, - OnPlatformViewSetViewportMetrics, - (int64_t view_id, const ViewportMetrics& metrics), - (override)); - - MOCK_METHOD(void, - OnPlatformViewDispatchPlatformMessage, - (std::unique_ptr message), - (override)); - - MOCK_METHOD(void, - OnPlatformViewDispatchPointerDataPacket, - (std::unique_ptr packet), - (override)); - - MOCK_METHOD(void, - OnPlatformViewDispatchSemanticsAction, - (int32_t id, SemanticsAction action, fml::MallocMapping args), - (override)); - - MOCK_METHOD(void, - OnPlatformViewSetSemanticsEnabled, - (bool enabled), - (override)); - - MOCK_METHOD(void, - OnPlatformViewSetAccessibilityFeatures, - (int32_t flags), - (override)); - - MOCK_METHOD(void, - OnPlatformViewRegisterTexture, - (std::shared_ptr texture), - (override)); - - MOCK_METHOD(void, - OnPlatformViewUnregisterTexture, - (int64_t texture_id), - (override)); - - MOCK_METHOD(void, - OnPlatformViewMarkTextureFrameAvailable, - (int64_t texture_id), - (override)); - - MOCK_METHOD(const Settings&, - OnPlatformViewGetSettings, - (), - (const, override)); - - MOCK_METHOD(void, - LoadDartDeferredLibrary, - (intptr_t loading_unit_id, - std::unique_ptr snapshot_data, - std::unique_ptr snapshot_instructions), - (override)); - - MOCK_METHOD(void, - LoadDartDeferredLibraryError, - (intptr_t loading_unit_id, - const std::string error_message, - bool transient), - (override)); - - MOCK_METHOD(void, - UpdateAssetResolverByType, - (std::unique_ptr updated_asset_resolver, - AssetResolver::AssetResolverType type), - (override)); -}; -} // namespace - TEST(AndroidPlatformView, SelectsVulkanBasedOnApiLevel) { Settings settings; settings.enable_software_rendering = false; settings.enable_impeller = true; - settings.impeller_backend = "vulkan"; - NiceMock mock_delegate; - EXPECT_CALL(mock_delegate, OnPlatformViewGetSettings) - .WillRepeatedly(ReturnRef(settings)); - TaskRunners task_runners("test", nullptr, nullptr, nullptr, nullptr); - PlatformViewAndroid platform_view(/*delegate=*/mock_delegate, - /*task_runners=*/task_runners, - /*jni_facade=*/nullptr, - /*use_software_rendering=*/false, - /*msaa_samples=*/1); - auto context = platform_view.GetAndroidContext(); - EXPECT_TRUE(context); int api_level = android_get_device_api_level(); EXPECT_GT(api_level, 0); if (api_level >= 29) { - EXPECT_TRUE(context->RenderingApi() == AndroidRenderingAPI::kVulkan); + EXPECT_EQ(FlutterMain::SelectedRenderingAPI(settings), + AndroidRenderingAPI::kImpellerVulkan); } else { - EXPECT_TRUE(context->RenderingApi() == AndroidRenderingAPI::kOpenGLES); + EXPECT_EQ(FlutterMain::SelectedRenderingAPI(settings), + AndroidRenderingAPI::kImpellerOpenGLES); } } +TEST(AndroidPlatformView, SoftwareRenderingNotSupportedWithImpeller) { + Settings settings; + settings.enable_software_rendering = true; + settings.enable_impeller = true; + + ASSERT_DEATH(FlutterMain::SelectedRenderingAPI(settings), ""); +} + } // namespace testing } // namespace flutter