From f3d1a1156fb954664e746de08d6983f2b497e702 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Feb 2024 19:47:43 -0800 Subject: [PATCH] =?UTF-8?q?Revert=20"Refactor=20NDK=20helpers=20some=20mor?= =?UTF-8?q?e,=20add=20methods=20for=20SurfaceControl/Transa=E2=80=A6"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a119a0dca83ec2818830fcc775058a1d3d84392a. --- ci/licenses_golden/excluded_files | 1 - ci/licenses_golden/licenses_flutter | 8 +- fml/BUILD.gn | 2 - fml/platform/android/ndk_helpers.cc | 258 ------------------ fml/platform/android/ndk_helpers.h | 100 ------- fml/platform/android/ndk_helpers_unittests.cc | 121 -------- shell/platform/android/BUILD.gn | 4 +- shell/platform/android/flutter_main.cc | 2 +- .../android/image_external_texture.cc | 3 +- .../android/image_external_texture_gl.cc | 2 +- .../android/image_external_texture_gl.h | 2 +- .../android/image_external_texture_vk.cc | 2 +- shell/platform/android/image_lru.h | 2 +- shell/platform/android/library_loader.cc | 2 +- shell/platform/android/ndk_helpers.cc | 217 +++++++++++++++ shell/platform/android/ndk_helpers.h | 78 ++++++ .../android/platform_view_android_jni_impl.cc | 2 +- .../platform/android/vsync_waiter_android.cc | 2 +- 18 files changed, 310 insertions(+), 498 deletions(-) delete mode 100644 fml/platform/android/ndk_helpers.cc delete mode 100644 fml/platform/android/ndk_helpers.h delete mode 100644 fml/platform/android/ndk_helpers_unittests.cc create mode 100644 shell/platform/android/ndk_helpers.cc create mode 100644 shell/platform/android/ndk_helpers.h diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index eb6faa7c88be5..8a6468e316b3b 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -100,7 +100,6 @@ ../../../flutter/fml/message_loop_task_queues_unittests.cc ../../../flutter/fml/message_loop_unittests.cc ../../../flutter/fml/paths_unittests.cc -../../../flutter/fml/platform/android/ndk_helpers_unittests.cc ../../../flutter/fml/platform/darwin/cf_utils_unittests.mm ../../../flutter/fml/platform/darwin/scoped_nsobject_arc_unittests.mm ../../../flutter/fml/platform/darwin/scoped_nsobject_unittests.mm diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 970bc71de1ef0..8e04aaf5d599f 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -5012,8 +5012,6 @@ ORIGIN: ../../../flutter/fml/platform/android/jni_weak_ref.cc + ../../../flutter ORIGIN: ../../../flutter/fml/platform/android/jni_weak_ref.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/android/message_loop_android.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/android/message_loop_android.h + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/platform/android/ndk_helpers.cc + ../../../flutter/LICENSE -ORIGIN: ../../../flutter/fml/platform/android/ndk_helpers.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/android/paths_android.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/android/paths_android.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/fml/platform/android/scoped_java_ref.cc + ../../../flutter/LICENSE @@ -6656,6 +6654,8 @@ ORIGIN: ../../../flutter/shell/platform/android/jni/jni_mock.h + ../../../flutte ORIGIN: ../../../flutter/shell/platform/android/jni/platform_view_android_jni.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/jni/platform_view_android_jni.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/library_loader.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/android/ndk_helpers.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/android/ndk_helpers.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/platform_message_handler_android.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/platform_message_response_android.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/platform_message_response_android.h + ../../../flutter/LICENSE @@ -7843,8 +7843,6 @@ FILE: ../../../flutter/fml/platform/android/jni_weak_ref.cc FILE: ../../../flutter/fml/platform/android/jni_weak_ref.h FILE: ../../../flutter/fml/platform/android/message_loop_android.cc FILE: ../../../flutter/fml/platform/android/message_loop_android.h -FILE: ../../../flutter/fml/platform/android/ndk_helpers.cc -FILE: ../../../flutter/fml/platform/android/ndk_helpers.h FILE: ../../../flutter/fml/platform/android/paths_android.cc FILE: ../../../flutter/fml/platform/android/paths_android.h FILE: ../../../flutter/fml/platform/android/scoped_java_ref.cc @@ -9506,6 +9504,8 @@ FILE: ../../../flutter/shell/platform/android/jni/jni_mock.h FILE: ../../../flutter/shell/platform/android/jni/platform_view_android_jni.cc FILE: ../../../flutter/shell/platform/android/jni/platform_view_android_jni.h FILE: ../../../flutter/shell/platform/android/library_loader.cc +FILE: ../../../flutter/shell/platform/android/ndk_helpers.cc +FILE: ../../../flutter/shell/platform/android/ndk_helpers.h FILE: ../../../flutter/shell/platform/android/platform_message_handler_android.cc FILE: ../../../flutter/shell/platform/android/platform_message_handler_android.h FILE: ../../../flutter/shell/platform/android/platform_message_response_android.cc diff --git a/fml/BUILD.gn b/fml/BUILD.gn index 088c391bdfdbc..3267884785744 100644 --- a/fml/BUILD.gn +++ b/fml/BUILD.gn @@ -184,8 +184,6 @@ source_set("fml") { "platform/android/jni_weak_ref.h", "platform/android/message_loop_android.cc", "platform/android/message_loop_android.h", - "platform/android/ndk_helpers.cc", - "platform/android/ndk_helpers.h", "platform/android/paths_android.cc", "platform/android/paths_android.h", "platform/android/scoped_java_ref.cc", diff --git a/fml/platform/android/ndk_helpers.cc b/fml/platform/android/ndk_helpers.cc deleted file mode 100644 index 67267435a82c4..0000000000000 --- a/fml/platform/android/ndk_helpers.cc +++ /dev/null @@ -1,258 +0,0 @@ -// 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 "fml/platform/android/ndk_helpers.h" - -#include "fml/logging.h" -#include "fml/native_library.h" - -#include -#include - -namespace flutter { - -namespace { - -#define DECLARE_TYPES(ret, name, args) \ - typedef ret(*fp_##name) args; \ - ret(*_##name) args = nullptr - -DECLARE_TYPES(int, - AHardwareBuffer_allocate, - (const AHardwareBuffer_Desc* desc, AHardwareBuffer** outBuffer)); -DECLARE_TYPES(int, - AHardwareBuffer_isSupported, - (const AHardwareBuffer_Desc* desc)); -DECLARE_TYPES(AHardwareBuffer*, - AHardwareBuffer_fromHardwareBuffer, - (JNIEnv * env, jobject hardwareBufferObj)); -DECLARE_TYPES(void, AHardwareBuffer_release, (AHardwareBuffer * buffer)); -DECLARE_TYPES(void, - AHardwareBuffer_describe, - (AHardwareBuffer * buffer, AHardwareBuffer_Desc* desc)); -DECLARE_TYPES(int, - AHardwareBuffer_getId, - (AHardwareBuffer * buffer, uint64_t* outId)); - -DECLARE_TYPES(bool, ATrace_isEnabled, (void)); - -DECLARE_TYPES(ASurfaceControl*, - ASurfaceControl_createFromWindow, - (ANativeWindow * parent, const char* debug_name)); -DECLARE_TYPES(void, - ASurfaceControl_release, - (ASurfaceControl * surface_control)); -DECLARE_TYPES(ASurfaceTransaction*, ASurfaceTransaction_create, (void)); -DECLARE_TYPES(void, - ASurfaceTransaction_delete, - (ASurfaceTransaction * surface_transaction)); -DECLARE_TYPES(void, - ASurfaceTransaction_apply, - (ASurfaceTransaction * surface_transaction)); -DECLARE_TYPES(void, - ASurfaceTransaction_setBuffer, - (ASurfaceTransaction * transaction, - ASurfaceControl* surface_control, - AHardwareBuffer* buffer, - int acquire_fence_fd)); - -DECLARE_TYPES(AChoreographer*, AChoreographer_getInstance, (void)); -DECLARE_TYPES(void, - AChoreographer_postFrameCallback, - (AChoreographer * choreographer, - AChoreographer_frameCallback callbackk, - void* data)); -DECLARE_TYPES(void, - AChoreographer_postFrameCallback64, - (AChoreographer * choreographer, - AChoreographer_frameCallback64 callbackk, - void* data)); - -DECLARE_TYPES(EGLClientBuffer, - eglGetNativeClientBufferANDROID, - (AHardwareBuffer * buffer)); - -#undef DECLARE_TYPES - -std::once_flag init_once; - -void InitOnceCallback() { - static fml::RefPtr android = - fml::NativeLibrary::Create("libandroid.so"); - FML_CHECK(android.get() != nullptr); - static fml::RefPtr egl = - fml::NativeLibrary::Create("libEGL.so"); - FML_CHECK(egl.get() != nullptr); - -#define LOOKUP(lib, func) \ - _##func = lib->ResolveFunction(#func).value_or(nullptr) - - LOOKUP(egl, eglGetNativeClientBufferANDROID); - - LOOKUP(android, AHardwareBuffer_fromHardwareBuffer); - LOOKUP(android, AHardwareBuffer_release); - LOOKUP(android, AHardwareBuffer_getId); - LOOKUP(android, AHardwareBuffer_describe); - LOOKUP(android, AHardwareBuffer_allocate); - LOOKUP(android, AHardwareBuffer_isSupported); - LOOKUP(android, ATrace_isEnabled); - LOOKUP(android, AChoreographer_getInstance); - if (_AChoreographer_getInstance) { - LOOKUP(android, AChoreographer_postFrameCallback64); - if (!_AChoreographer_postFrameCallback64) { - LOOKUP(android, AChoreographer_postFrameCallback); - } - } - - LOOKUP(android, ASurfaceControl_createFromWindow); - LOOKUP(android, ASurfaceControl_release); - LOOKUP(android, ASurfaceTransaction_apply); - LOOKUP(android, ASurfaceTransaction_create); - LOOKUP(android, ASurfaceTransaction_delete); - LOOKUP(android, ASurfaceTransaction_setBuffer); -#undef LOOKUP -} - -} // namespace - -void NDKHelpers::Init() { - std::call_once(init_once, InitOnceCallback); -} - -bool NDKHelpers::ATrace_isEnabled() { - if (_ATrace_isEnabled) { - return _ATrace_isEnabled(); - } - return false; -} - -ChoreographerSupportStatus NDKHelpers::ChoreographerSupported() { - if (_AChoreographer_postFrameCallback64) { - return ChoreographerSupportStatus::kSupported64; - } - if (_AChoreographer_postFrameCallback) { - return ChoreographerSupportStatus::kSupported32; - } - return ChoreographerSupportStatus::kUnsupported; -} - -AChoreographer* NDKHelpers::AChoreographer_getInstance() { - FML_CHECK(_AChoreographer_getInstance); - return _AChoreographer_getInstance(); -} - -void NDKHelpers::AChoreographer_postFrameCallback( - AChoreographer* choreographer, - AChoreographer_frameCallback callback, - void* data) { - FML_CHECK(_AChoreographer_postFrameCallback); - return _AChoreographer_postFrameCallback(choreographer, callback, data); -} - -void NDKHelpers::AChoreographer_postFrameCallback64( - AChoreographer* choreographer, - AChoreographer_frameCallback64 callback, - void* data) { - FML_CHECK(_AChoreographer_postFrameCallback64); - return _AChoreographer_postFrameCallback64(choreographer, callback, data); -} - -bool NDKHelpers::HardwareBufferSupported() { - const bool r = _AHardwareBuffer_fromHardwareBuffer != nullptr; - return r; -} - -AHardwareBuffer* NDKHelpers::AHardwareBuffer_fromHardwareBuffer( - JNIEnv* env, - jobject hardwareBufferObj) { - FML_CHECK(_AHardwareBuffer_fromHardwareBuffer != nullptr); - return _AHardwareBuffer_fromHardwareBuffer(env, hardwareBufferObj); -} - -void NDKHelpers::AHardwareBuffer_release(AHardwareBuffer* buffer) { - FML_CHECK(_AHardwareBuffer_release != nullptr); - _AHardwareBuffer_release(buffer); -} - -void NDKHelpers::AHardwareBuffer_describe(AHardwareBuffer* buffer, - AHardwareBuffer_Desc* desc) { - FML_CHECK(_AHardwareBuffer_describe != nullptr); - _AHardwareBuffer_describe(buffer, desc); -} - -std::optional NDKHelpers::AHardwareBuffer_getId( - AHardwareBuffer* buffer) { - if (_AHardwareBuffer_getId == nullptr) { - return std::nullopt; - } - HardwareBufferKey outId; - int result = _AHardwareBuffer_getId(buffer, &outId); - if (result == 0) { - return outId; - } - return std::nullopt; -} - -EGLClientBuffer NDKHelpers::eglGetNativeClientBufferANDROID( - AHardwareBuffer* buffer) { - FML_CHECK(_eglGetNativeClientBufferANDROID != nullptr); - return _eglGetNativeClientBufferANDROID(buffer); -} - -bool NDKHelpers::SurfaceControlAndTransactionSupported() { - return _ASurfaceControl_createFromWindow && _ASurfaceControl_release && - _ASurfaceTransaction_create && _ASurfaceTransaction_apply && - _ASurfaceTransaction_delete && _ASurfaceTransaction_setBuffer; -} - -ASurfaceControl* NDKHelpers::ASurfaceControl_createFromWindow( - ANativeWindow* parent, - const char* debug_name) { - FML_CHECK(_ASurfaceControl_createFromWindow); - return _ASurfaceControl_createFromWindow(parent, debug_name); -} - -void NDKHelpers::ASurfaceControl_release(ASurfaceControl* surface_control) { - FML_CHECK(_ASurfaceControl_release); - return _ASurfaceControl_release(surface_control); -} - -ASurfaceTransaction* NDKHelpers::ASurfaceTransaction_create() { - FML_CHECK(_ASurfaceTransaction_create); - return _ASurfaceTransaction_create(); -} - -void NDKHelpers::ASurfaceTransaction_delete( - ASurfaceTransaction* surface_transaction) { - FML_CHECK(_ASurfaceTransaction_delete); - _ASurfaceTransaction_delete(surface_transaction); -} - -void NDKHelpers::ASurfaceTransaction_apply( - ASurfaceTransaction* surface_transaction) { - FML_CHECK(_ASurfaceTransaction_apply); - _ASurfaceTransaction_apply(surface_transaction); -} - -void NDKHelpers::ASurfaceTransaction_setBuffer(ASurfaceTransaction* transaction, - ASurfaceControl* surface_control, - AHardwareBuffer* buffer, - int acquire_fence_fd) { - FML_CHECK(_ASurfaceTransaction_setBuffer); - _ASurfaceTransaction_setBuffer(transaction, surface_control, buffer, - acquire_fence_fd); -} - -int NDKHelpers::AHardwareBuffer_isSupported(const AHardwareBuffer_Desc* desc) { - FML_CHECK(_AHardwareBuffer_isSupported); - return _AHardwareBuffer_isSupported(desc); -} - -int NDKHelpers::AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc, - AHardwareBuffer** outBuffer) { - FML_CHECK(_AHardwareBuffer_allocate); - return _AHardwareBuffer_allocate(desc, outBuffer); -} - -} // namespace flutter diff --git a/fml/platform/android/ndk_helpers.h b/fml/platform/android/ndk_helpers.h deleted file mode 100644 index 9299776e3e691..0000000000000 --- a/fml/platform/android/ndk_helpers.h +++ /dev/null @@ -1,100 +0,0 @@ -// 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_FML_PLATFORM_ANDROID_NDK_HELPERS_H_ -#define FLUTTER_FML_PLATFORM_ANDROID_NDK_HELPERS_H_ - -#include -#include -#include -#include -#include -#include -#include - -namespace flutter { - -using HardwareBufferKey = uint64_t; - -enum class ChoreographerSupportStatus { - // Unavailable, API level < 24. - kUnsupported, - // Available, but only with postFrameCallback. - kSupported32, - // Available, but only with postFrameCallback64. - kSupported64, -}; - -// A collection of NDK functions that are available depending on the version of -// the Android SDK we are linked with at runtime. -class NDKHelpers { - public: - // Safe to call multiple times. - // Normally called from JNI_OnLoad. - static void Init(); - - // API Version 23 - static bool ATrace_isEnabled(); - - // API Version 24 - static ChoreographerSupportStatus ChoreographerSupported(); - static AChoreographer* _Nullable AChoreographer_getInstance(); - // Deprecated in 29, available since 24. - static void AChoreographer_postFrameCallback( - AChoreographer* _Nonnull choreographer, - AChoreographer_frameCallback _Nonnull callback, - void* _Nullable data); - - // API Version 26 - static bool HardwareBufferSupported(); - static AHardwareBuffer* _Nonnull AHardwareBuffer_fromHardwareBuffer( - JNIEnv* _Nonnull env, - jobject _Nonnull hardwareBufferObj); - static void AHardwareBuffer_release(AHardwareBuffer* _Nonnull buffer); - static void AHardwareBuffer_describe(AHardwareBuffer* _Nonnull buffer, - AHardwareBuffer_Desc* _Nullable desc); - static int AHardwareBuffer_allocate( - const AHardwareBuffer_Desc* _Nonnull desc, - AHardwareBuffer* _Nullable* _Nullable outBuffer); - static EGLClientBuffer _Nonnull eglGetNativeClientBufferANDROID( - AHardwareBuffer* _Nonnull buffer); - - // API Version 29 - static int AHardwareBuffer_isSupported( - const AHardwareBuffer_Desc* _Nonnull desc); - - static void AChoreographer_postFrameCallback64( - AChoreographer* _Nonnull choreographer, - AChoreographer_frameCallback64 _Nonnull callback, - void* _Nullable data); - - static bool SurfaceControlAndTransactionSupported(); - - static ASurfaceControl* _Nonnull ASurfaceControl_createFromWindow( - ANativeWindow* _Nonnull parent, - const char* _Nullable debug_name); - static void ASurfaceControl_release( - ASurfaceControl* _Nonnull surface_control); - - static ASurfaceTransaction* _Nonnull ASurfaceTransaction_create(); - static void ASurfaceTransaction_delete( - ASurfaceTransaction* _Nonnull surface_transaction); - static void ASurfaceTransaction_apply( - ASurfaceTransaction* _Nonnull surface_transaction); - static void ASurfaceTransaction_setBuffer( - ASurfaceTransaction* _Nonnull transaction, - ASurfaceControl* _Nonnull surface_control, - AHardwareBuffer* _Nonnull buffer, - int acquire_fence_fd); - - // API Version 31 - - // Returns std::nullopt on API version 26 - 30. - static std::optional AHardwareBuffer_getId( - AHardwareBuffer* _Nonnull buffer); -}; - -} // namespace flutter - -#endif // FLUTTER_FML_PLATFORM_ANDROID_NDK_HELPERS_H_ diff --git a/fml/platform/android/ndk_helpers_unittests.cc b/fml/platform/android/ndk_helpers_unittests.cc deleted file mode 100644 index e6cab428cdbc8..0000000000000 --- a/fml/platform/android/ndk_helpers_unittests.cc +++ /dev/null @@ -1,121 +0,0 @@ -// 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 "fml/message_loop.h" -#include "fml/platform/android/ndk_helpers.h" - -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { -namespace android { - -class NdkHelpersTest : public ::testing::Test { - public: - void SetUp() override { NDKHelpers::Init(); } - - static void OnVsync(int64_t frame_nanos, void* data) {} - static void OnVsync32( - long frame_nanos, // NOLINT - compat for deprecated call - void* data) {} -}; - -TEST_F(NdkHelpersTest, ATrace) { - ASSERT_GT(android_get_device_api_level(), 22); - EXPECT_FALSE(NDKHelpers::ATrace_isEnabled()); -} - -TEST_F(NdkHelpersTest, AChoreographer32) { - if (android_get_device_api_level() >= 29) { - GTEST_SKIP() << "This test is for less than API 29."; - } - - EXPECT_EQ(NDKHelpers::ChoreographerSupported(), - ChoreographerSupportStatus::kSupported32); - - EXPECT_FALSE(NDKHelpers::AChoreographer_getInstance()); - - fml::MessageLoop::EnsureInitializedForCurrentThread(); - - EXPECT_TRUE(NDKHelpers::AChoreographer_getInstance()); - - NDKHelpers::AChoreographer_postFrameCallback( - NDKHelpers::AChoreographer_getInstance(), &OnVsync32, nullptr); -} - -TEST_F(NdkHelpersTest, AChoreographer64) { - if (android_get_device_api_level() < 29) { - GTEST_SKIP() << "This test is for API 29 and above."; - } - - EXPECT_EQ(NDKHelpers::ChoreographerSupported(), - ChoreographerSupportStatus::kSupported64); - - EXPECT_FALSE(NDKHelpers::AChoreographer_getInstance()); - - fml::MessageLoop::EnsureInitializedForCurrentThread(); - - EXPECT_TRUE(NDKHelpers::AChoreographer_getInstance()); - - NDKHelpers::AChoreographer_postFrameCallback64( - NDKHelpers::AChoreographer_getInstance(), &OnVsync, nullptr); -} - -TEST_F(NdkHelpersTest, HardwareBuffer) { - if (android_get_device_api_level() < 26) { - GTEST_SKIP() << "Test requires at least API 26."; - } - - ASSERT_TRUE(NDKHelpers::HardwareBufferSupported()); - - AHardwareBuffer_Desc desc{ - .width = 4, - .height = 4, - .layers = 1, - .format = AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, - }; - if (android_get_device_api_level() >= 29) { - EXPECT_TRUE(NDKHelpers::AHardwareBuffer_isSupported(&desc)); - } - - AHardwareBuffer* buffer = nullptr; - // AHardwareBuffer_allocate returns 0 on success. - EXPECT_EQ(NDKHelpers::AHardwareBuffer_allocate(&desc, &buffer), 0); - EXPECT_TRUE(buffer); - - AHardwareBuffer_Desc out_desc = {}; - NDKHelpers::AHardwareBuffer_describe(buffer, &out_desc); - EXPECT_EQ(desc.width, out_desc.width); - EXPECT_EQ(desc.height, out_desc.height); - EXPECT_EQ(desc.layers, out_desc.layers); - EXPECT_EQ(desc.format, out_desc.format); - - auto id = NDKHelpers::AHardwareBuffer_getId(buffer); - if (android_get_device_api_level() >= 31) { - EXPECT_TRUE(id.has_value()); - } else { - EXPECT_FALSE(id.has_value()); - } - - NDKHelpers::AHardwareBuffer_release(buffer); -} - -TEST_F(NdkHelpersTest, SurfaceTransaction) { - if (android_get_device_api_level() < 29) { - GTEST_SKIP() << "Test requires at least API 29."; - } - EXPECT_TRUE(NDKHelpers::SurfaceControlAndTransactionSupported()); - - // Need ANativeWindow to create ASurfaceControl and set a buffer to the - // transaction. Just create/apply/delete as a smoke test. - - ASurfaceTransaction* transaction = NDKHelpers::ASurfaceTransaction_create(); - EXPECT_TRUE(transaction); - NDKHelpers::ASurfaceTransaction_apply(transaction); - NDKHelpers::ASurfaceTransaction_delete(transaction); -} - -} // namespace android -} // namespace testing -} // namespace flutter diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index a6c4cb6078bc0..21429607f2435 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -42,7 +42,6 @@ executable("flutter_shell_native_unittests") { visibility = [ "*" ] testonly = true sources = [ - "//flutter/fml/platform/android/ndk_helpers_unittests.cc", "android_context_gl_impeller_unittests.cc", "android_context_gl_unittests.cc", "android_shell_holder_unittests.cc", @@ -54,7 +53,6 @@ executable("flutter_shell_native_unittests") { public_configs = [ "//flutter:config" ] deps = [ ":flutter_shell_native_src", - "//flutter/fml", "//flutter/shell/platform/android/jni:jni_mock", "//third_party/googletest:gmock", "//third_party/googletest:gtest", @@ -115,6 +113,8 @@ source_set("flutter_shell_native_src") { "image_lru.cc", "image_lru.h", "library_loader.cc", + "ndk_helpers.cc", + "ndk_helpers.h", "platform_message_handler_android.cc", "platform_message_handler_android.h", "platform_message_response_android.cc", diff --git a/shell/platform/android/flutter_main.cc b/shell/platform/android/flutter_main.cc index 6ad57a7ca04cc..8a2e9eaca5e66 100644 --- a/shell/platform/android/flutter_main.cc +++ b/shell/platform/android/flutter_main.cc @@ -18,13 +18,13 @@ #include "flutter/fml/native_library.h" #include "flutter/fml/paths.h" #include "flutter/fml/platform/android/jni_util.h" -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/fml/platform/android/paths_android.h" #include "flutter/fml/size.h" #include "flutter/lib/ui/plugins/callback_cache.h" #include "flutter/runtime/dart_vm.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/common/switches.h" +#include "flutter/shell/platform/android/ndk_helpers.h" #include "third_party/dart/runtime/include/dart_tools_api.h" #include "txt/platform.h" diff --git a/shell/platform/android/image_external_texture.cc b/shell/platform/android/image_external_texture.cc index 855b56d2b77d8..da6f55832672e 100644 --- a/shell/platform/android/image_external_texture.cc +++ b/shell/platform/android/image_external_texture.cc @@ -4,9 +4,8 @@ #include #include -#include "flutter/fml/platform/android/jni_util.h" -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/shell/platform/android/jni/platform_view_android_jni.h" +#include "flutter/shell/platform/android/ndk_helpers.h" namespace flutter { diff --git a/shell/platform/android/image_external_texture_gl.cc b/shell/platform/android/image_external_texture_gl.cc index 6a676e90cbf22..1dea2df1eed7e 100644 --- a/shell/platform/android/image_external_texture_gl.cc +++ b/shell/platform/android/image_external_texture_gl.cc @@ -8,11 +8,11 @@ #include #include "flutter/common/graphics/texture.h" -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/impeller/core/formats.h" #include "flutter/impeller/display_list/dl_image_impeller.h" #include "flutter/impeller/toolkit/egl/image.h" #include "flutter/impeller/toolkit/gles/texture.h" +#include "flutter/shell/platform/android/ndk_helpers.h" #include "third_party/skia/include/core/SkAlphaType.h" #include "third_party/skia/include/core/SkColorType.h" #include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" diff --git a/shell/platform/android/image_external_texture_gl.h b/shell/platform/android/image_external_texture_gl.h index 8aeec744ab0cd..e3040d5e58489 100644 --- a/shell/platform/android/image_external_texture_gl.h +++ b/shell/platform/android/image_external_texture_gl.h @@ -17,8 +17,8 @@ #include "flutter/impeller/toolkit/egl/image.h" #include "flutter/impeller/toolkit/gles/texture.h" -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/shell/platform/android/android_context_gl_skia.h" +#include "flutter/shell/platform/android/ndk_helpers.h" namespace flutter { diff --git a/shell/platform/android/image_external_texture_vk.cc b/shell/platform/android/image_external_texture_vk.cc index 9af0683340b1f..5eaf47083e6cb 100644 --- a/shell/platform/android/image_external_texture_vk.cc +++ b/shell/platform/android/image_external_texture_vk.cc @@ -2,7 +2,6 @@ #include "flutter/shell/platform/android/image_external_texture_vk.h" #include -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/impeller/core/formats.h" #include "flutter/impeller/core/texture_descriptor.h" #include "flutter/impeller/display_list/dl_image_impeller.h" @@ -10,6 +9,7 @@ #include "flutter/impeller/renderer/backend/vulkan/command_buffer_vk.h" #include "flutter/impeller/renderer/backend/vulkan/command_encoder_vk.h" #include "flutter/impeller/renderer/backend/vulkan/texture_vk.h" +#include "flutter/shell/platform/android/ndk_helpers.h" namespace flutter { diff --git a/shell/platform/android/image_lru.h b/shell/platform/android/image_lru.h index 28a31cd2bf842..34fa97c37cce4 100644 --- a/shell/platform/android/image_lru.h +++ b/shell/platform/android/image_lru.h @@ -9,7 +9,7 @@ #include #include "display_list/image/dl_image.h" -#include "fml/platform/android/ndk_helpers.h" +#include "shell/platform/android/ndk_helpers.h" namespace flutter { diff --git a/shell/platform/android/library_loader.cc b/shell/platform/android/library_loader.cc index 9f3691d818512..103a3aeb2a111 100644 --- a/shell/platform/android/library_loader.cc +++ b/shell/platform/android/library_loader.cc @@ -3,9 +3,9 @@ // found in the LICENSE file. #include "flutter/fml/platform/android/jni_util.h" -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/shell/platform/android/android_image_generator.h" #include "flutter/shell/platform/android/flutter_main.h" +#include "flutter/shell/platform/android/ndk_helpers.h" #include "flutter/shell/platform/android/platform_view_android.h" #include "flutter/shell/platform/android/vsync_waiter_android.h" diff --git a/shell/platform/android/ndk_helpers.cc b/shell/platform/android/ndk_helpers.cc new file mode 100644 index 0000000000000..65fc9368c8ad3 --- /dev/null +++ b/shell/platform/android/ndk_helpers.cc @@ -0,0 +1,217 @@ +// 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/ndk_helpers.h" + +#include "fml/native_library.h" + +#include "flutter/fml/logging.h" + +#include +#include + +namespace flutter { + +namespace { + +typedef AHardwareBuffer* (*fp_AHardwareBuffer_fromHardwareBuffer)( + JNIEnv* env, + jobject hardwareBufferObj); +typedef void (*fp_AHardwareBuffer_acquire)(AHardwareBuffer* buffer); +typedef void (*fp_AHardwareBuffer_release)(AHardwareBuffer* buffer); +typedef void (*fp_AHardwareBuffer_describe)(AHardwareBuffer* buffer, + AHardwareBuffer_Desc* desc); +typedef void (*fp_AHardwareBuffer_getId)(AHardwareBuffer* buffer, + uint64_t* outId); + +typedef bool (*fp_ATrace_isEnabled)(void); + +typedef AChoreographer* (*fp_AChoreographer_getInstance)(void); +typedef void (*fp_AChoreographer_postFrameCallback)( + AChoreographer* choreographer, + AChoreographer_frameCallback callbackk, + void* data); +typedef void (*fp_AChoreographer_postFrameCallback64)( + AChoreographer* choreographer, + AChoreographer_frameCallback64 callbackk, + void* data); + +typedef EGLClientBuffer (*fp_eglGetNativeClientBufferANDROID)( + AHardwareBuffer* buffer); + +AHardwareBuffer* (*_AHardwareBuffer_fromHardwareBuffer)( + JNIEnv* env, + jobject hardwareBufferObj) = nullptr; +void (*_AHardwareBuffer_acquire)(AHardwareBuffer* buffer) = nullptr; +void (*_AHardwareBuffer_release)(AHardwareBuffer* buffer) = nullptr; +void (*_AHardwareBuffer_describe)(AHardwareBuffer* buffer, + AHardwareBuffer_Desc* desc) = nullptr; +void (*_AHardwareBuffer_getId)(AHardwareBuffer* buffer, + uint64_t* outId) = nullptr; +bool (*_ATrace_isEnabled)() = nullptr; +AChoreographer* (*_AChoreographer_getInstance)() = nullptr; +void (*_AChoreographer_postFrameCallback)( + AChoreographer* choreographer, + AChoreographer_frameCallback callbackk, + void* data) = nullptr; +void (*_AChoreographer_postFrameCallback64)( + AChoreographer* choreographer, + AChoreographer_frameCallback64 callbackk, + void* data) = nullptr; + +EGLClientBuffer (*_eglGetNativeClientBufferANDROID)(AHardwareBuffer* buffer) = + nullptr; + +std::once_flag init_once; + +void InitOnceCallback() { + static fml::RefPtr android = + fml::NativeLibrary::Create("libandroid.so"); + FML_CHECK(android.get() != nullptr); + static fml::RefPtr egl = + fml::NativeLibrary::Create("libEGL.so"); + FML_CHECK(egl.get() != nullptr); + _eglGetNativeClientBufferANDROID = + egl->ResolveFunction( + "eglGetNativeClientBufferANDROID") + .value_or(nullptr); + _AHardwareBuffer_fromHardwareBuffer = + android + ->ResolveFunction( + "AHardwareBuffer_fromHardwareBuffer") + .value_or(nullptr); + _AHardwareBuffer_acquire = android + ->ResolveFunction( + "AHardwareBuffer_acquire") + .value_or(nullptr); + _AHardwareBuffer_release = android + ->ResolveFunction( + "AHardwareBuffer_release") + .value_or(nullptr); + _AHardwareBuffer_getId = + android + ->ResolveFunction("AHardwareBuffer_getId") + .value_or(nullptr); + _AHardwareBuffer_describe = + android + ->ResolveFunction( + "AHardwareBuffer_describe") + .value_or(nullptr); + + _ATrace_isEnabled = + android->ResolveFunction("ATrace_isEnabled") + .value_or(nullptr); + + _AChoreographer_getInstance = + android + ->ResolveFunction( + "AChoreographer_getInstance") + .value_or(nullptr); + if (_AChoreographer_getInstance) { + _AChoreographer_postFrameCallback64 = + android + ->ResolveFunction( + "AChoreographer_postFrameCallback64") + .value_or(nullptr); +#if FML_ARCH_CPU_64_BITS + if (!_AChoreographer_postFrameCallback64) { + _AChoreographer_postFrameCallback = + android + ->ResolveFunction( + "AChoreographer_postFrameCallback") + .value_or(nullptr); + } +#endif + } +} + +} // namespace + +void NDKHelpers::Init() { + std::call_once(init_once, InitOnceCallback); +} + +bool NDKHelpers::ATrace_isEnabled() { + if (_ATrace_isEnabled) { + return _ATrace_isEnabled(); + } + return false; +} + +ChoreographerSupportStatus NDKHelpers::ChoreographerSupported() { + if (_AChoreographer_postFrameCallback64) { + return ChoreographerSupportStatus::kSupported64; + } + if (_AChoreographer_postFrameCallback) { + return ChoreographerSupportStatus::kSupported32; + } + return ChoreographerSupportStatus::kUnsupported; +} + +AChoreographer* NDKHelpers::AChoreographer_getInstance() { + FML_CHECK(_AChoreographer_getInstance); + return _AChoreographer_getInstance(); +} + +void NDKHelpers::AChoreographer_postFrameCallback( + AChoreographer* choreographer, + AChoreographer_frameCallback callback, + void* data) { + FML_CHECK(_AChoreographer_postFrameCallback); + return _AChoreographer_postFrameCallback(choreographer, callback, data); +} + +void NDKHelpers::AChoreographer_postFrameCallback64( + AChoreographer* choreographer, + AChoreographer_frameCallback64 callback, + void* data) { + FML_CHECK(_AChoreographer_postFrameCallback64); + return _AChoreographer_postFrameCallback64(choreographer, callback, data); +} + +bool NDKHelpers::HardwareBufferSupported() { + const bool r = _AHardwareBuffer_fromHardwareBuffer != nullptr; + return r; +} + +AHardwareBuffer* NDKHelpers::AHardwareBuffer_fromHardwareBuffer( + JNIEnv* env, + jobject hardwareBufferObj) { + FML_CHECK(_AHardwareBuffer_fromHardwareBuffer != nullptr); + return _AHardwareBuffer_fromHardwareBuffer(env, hardwareBufferObj); +} + +void NDKHelpers::AHardwareBuffer_acquire(AHardwareBuffer* buffer) { + FML_CHECK(_AHardwareBuffer_acquire != nullptr); + _AHardwareBuffer_acquire(buffer); +} + +void NDKHelpers::AHardwareBuffer_release(AHardwareBuffer* buffer) { + FML_CHECK(_AHardwareBuffer_release != nullptr); + _AHardwareBuffer_release(buffer); +} + +void NDKHelpers::AHardwareBuffer_describe(AHardwareBuffer* buffer, + AHardwareBuffer_Desc* desc) { + FML_CHECK(_AHardwareBuffer_describe != nullptr); + _AHardwareBuffer_describe(buffer, desc); +} + +std::optional NDKHelpers::AHardwareBuffer_getId( + AHardwareBuffer* buffer) { + if (_AHardwareBuffer_getId == nullptr) { + return std::nullopt; + } + HardwareBufferKey outId; + _AHardwareBuffer_getId(buffer, &outId); + return outId; +} + +EGLClientBuffer NDKHelpers::eglGetNativeClientBufferANDROID( + AHardwareBuffer* buffer) { + FML_CHECK(_eglGetNativeClientBufferANDROID != nullptr); + return _eglGetNativeClientBufferANDROID(buffer); +} + +} // namespace flutter diff --git a/shell/platform/android/ndk_helpers.h b/shell/platform/android/ndk_helpers.h new file mode 100644 index 0000000000000..5b7856aa6e241 --- /dev/null +++ b/shell/platform/android/ndk_helpers.h @@ -0,0 +1,78 @@ +// 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_NDK_HELPERS_H_ +#define FLUTTER_SHELL_PLATFORM_ANDROID_NDK_HELPERS_H_ + +#include "flutter/fml/native_library.h" +#include "flutter/fml/platform/android/jni_util.h" + +#include "flutter/impeller/toolkit/egl/egl.h" + +#include +#include +#include +#include + +namespace flutter { + +using HardwareBufferKey = uint64_t; + +enum class ChoreographerSupportStatus { + // Unavailable, API level < 24. + kUnsupported, + // Available, but only with postFrameCallback. + kSupported32, + // Available, but only with postFrameCallback64. + kSupported64, +}; + +// A collection of NDK functions that are available depending on the version of +// the Android SDK we are linked with at runtime. +class NDKHelpers { + public: + // Safe to call multiple times. + // Normally called from JNI_OnLoad. + static void Init(); + + // API Version 23 + static bool ATrace_isEnabled(); + + // API Version 24 + static ChoreographerSupportStatus ChoreographerSupported(); + static AChoreographer* AChoreographer_getInstance(); + // Deprecated in 29, available since 24. + static void AChoreographer_postFrameCallback( + AChoreographer* choreographer, + AChoreographer_frameCallback callback, + void* data); + + // API Version 26 + static bool HardwareBufferSupported(); + static AHardwareBuffer* AHardwareBuffer_fromHardwareBuffer( + JNIEnv* env, + jobject hardwareBufferObj); + static void AHardwareBuffer_acquire(AHardwareBuffer* buffer); + static void AHardwareBuffer_release(AHardwareBuffer* buffer); + static void AHardwareBuffer_describe(AHardwareBuffer* buffer, + AHardwareBuffer_Desc* desc); + static EGLClientBuffer eglGetNativeClientBufferANDROID( + AHardwareBuffer* buffer); + + // API Version 29 + static void AChoreographer_postFrameCallback64( + AChoreographer* choreographer, + AChoreographer_frameCallback64 callback, + void* data); + + // API Version 31 + + // Returns std::nullopt on API version 26 - 30. + static std::optional AHardwareBuffer_getId( + AHardwareBuffer* buffer); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_ANDROID_NDK_HELPERS_H_ diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index b6d5dfc2f504f..7d13c10949a68 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -12,7 +12,7 @@ #include #include -#include "flutter/fml/platform/android/ndk_helpers.h" +#include "flutter/shell/platform/android/ndk_helpers.h" #include "include/android/SkImageAndroid.h" #include "unicode/uchar.h" diff --git a/shell/platform/android/vsync_waiter_android.cc b/shell/platform/android/vsync_waiter_android.cc index d0a8db383a0ce..7b7f136257ce2 100644 --- a/shell/platform/android/vsync_waiter_android.cc +++ b/shell/platform/android/vsync_waiter_android.cc @@ -10,10 +10,10 @@ #include "flutter/common/task_runners.h" #include "flutter/fml/logging.h" #include "flutter/fml/platform/android/jni_util.h" -#include "flutter/fml/platform/android/ndk_helpers.h" #include "flutter/fml/platform/android/scoped_java_ref.h" #include "flutter/fml/size.h" #include "flutter/fml/trace_event.h" +#include "flutter/shell/platform/android/ndk_helpers.h" namespace flutter {