mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Refactor NDK helpers some more, add methods for SurfaceControl/Transaction, tests (flutter/engine#50540)
Adds more dynamic method lookups in service of https://github.com/flutter/flutter/issues/143105 Moves the TU out to FML so that Impeller can more easily use it. Adds checking on `AHardwareBuffer_getId` so that it checks the return value before returning what is potentially garbage. Adds some smoke tests to make sure these things actually work/look up meaningful symbols. Test is in the shell because we have testing infra for this kind of thing there.
This commit is contained in:
parent
daaedbbe2b
commit
2f964dfe37
@ -100,6 +100,7 @@
|
||||
../../../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
|
||||
|
||||
@ -4832,6 +4832,8 @@ 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
|
||||
@ -6474,8 +6476,6 @@ 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
|
||||
@ -7663,6 +7663,8 @@ 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
|
||||
@ -9324,8 +9326,6 @@ 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
|
||||
|
||||
@ -184,6 +184,8 @@ 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",
|
||||
|
||||
258
engine/src/flutter/fml/platform/android/ndk_helpers.cc
Normal file
258
engine/src/flutter/fml/platform/android/ndk_helpers.cc
Normal file
@ -0,0 +1,258 @@
|
||||
// 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 <android/hardware_buffer.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
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<fml::NativeLibrary> android =
|
||||
fml::NativeLibrary::Create("libandroid.so");
|
||||
FML_CHECK(android.get() != nullptr);
|
||||
static fml::RefPtr<fml::NativeLibrary> egl =
|
||||
fml::NativeLibrary::Create("libEGL.so");
|
||||
FML_CHECK(egl.get() != nullptr);
|
||||
|
||||
#define LOOKUP(lib, func) \
|
||||
_##func = lib->ResolveFunction<fp_##func>(#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<HardwareBufferKey> 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
|
||||
100
engine/src/flutter/fml/platform/android/ndk_helpers.h
Normal file
100
engine/src/flutter/fml/platform/android/ndk_helpers.h
Normal file
@ -0,0 +1,100 @@
|
||||
// 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 <EGL/egl.h>
|
||||
#include <android/choreographer.h>
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <android/surface_control.h>
|
||||
#include <android/trace.h>
|
||||
#include <jni.h>
|
||||
#include <optional>
|
||||
|
||||
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<HardwareBufferKey> AHardwareBuffer_getId(
|
||||
AHardwareBuffer* _Nonnull buffer);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_FML_PLATFORM_ANDROID_NDK_HELPERS_H_
|
||||
121
engine/src/flutter/fml/platform/android/ndk_helpers_unittests.cc
Normal file
121
engine/src/flutter/fml/platform/android/ndk_helpers_unittests.cc
Normal file
@ -0,0 +1,121 @@
|
||||
// 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
|
||||
@ -42,6 +42,7 @@ 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",
|
||||
@ -53,6 +54,7 @@ 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",
|
||||
@ -113,8 +115,6 @@ 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",
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -4,8 +4,9 @@
|
||||
#include <android/hardware_buffer_jni.h>
|
||||
#include <android/sensor.h>
|
||||
|
||||
#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 {
|
||||
|
||||
|
||||
@ -8,11 +8,11 @@
|
||||
#include <android/sensor.h>
|
||||
|
||||
#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"
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "flutter/shell/platform/android/image_external_texture_vk.h"
|
||||
#include <cstdint>
|
||||
|
||||
#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"
|
||||
@ -9,7 +10,6 @@
|
||||
#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 {
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include "display_list/image/dl_image.h"
|
||||
#include "shell/platform/android/ndk_helpers.h"
|
||||
#include "fml/platform/android/ndk_helpers.h"
|
||||
|
||||
namespace flutter {
|
||||
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -1,217 +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 "flutter/shell/platform/android/ndk_helpers.h"
|
||||
|
||||
#include "fml/native_library.h"
|
||||
|
||||
#include "flutter/fml/logging.h"
|
||||
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
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<fml::NativeLibrary> android =
|
||||
fml::NativeLibrary::Create("libandroid.so");
|
||||
FML_CHECK(android.get() != nullptr);
|
||||
static fml::RefPtr<fml::NativeLibrary> egl =
|
||||
fml::NativeLibrary::Create("libEGL.so");
|
||||
FML_CHECK(egl.get() != nullptr);
|
||||
_eglGetNativeClientBufferANDROID =
|
||||
egl->ResolveFunction<fp_eglGetNativeClientBufferANDROID>(
|
||||
"eglGetNativeClientBufferANDROID")
|
||||
.value_or(nullptr);
|
||||
_AHardwareBuffer_fromHardwareBuffer =
|
||||
android
|
||||
->ResolveFunction<fp_AHardwareBuffer_fromHardwareBuffer>(
|
||||
"AHardwareBuffer_fromHardwareBuffer")
|
||||
.value_or(nullptr);
|
||||
_AHardwareBuffer_acquire = android
|
||||
->ResolveFunction<fp_AHardwareBuffer_acquire>(
|
||||
"AHardwareBuffer_acquire")
|
||||
.value_or(nullptr);
|
||||
_AHardwareBuffer_release = android
|
||||
->ResolveFunction<fp_AHardwareBuffer_release>(
|
||||
"AHardwareBuffer_release")
|
||||
.value_or(nullptr);
|
||||
_AHardwareBuffer_getId =
|
||||
android
|
||||
->ResolveFunction<fp_AHardwareBuffer_getId>("AHardwareBuffer_getId")
|
||||
.value_or(nullptr);
|
||||
_AHardwareBuffer_describe =
|
||||
android
|
||||
->ResolveFunction<fp_AHardwareBuffer_describe>(
|
||||
"AHardwareBuffer_describe")
|
||||
.value_or(nullptr);
|
||||
|
||||
_ATrace_isEnabled =
|
||||
android->ResolveFunction<fp_ATrace_isEnabled>("ATrace_isEnabled")
|
||||
.value_or(nullptr);
|
||||
|
||||
_AChoreographer_getInstance =
|
||||
android
|
||||
->ResolveFunction<fp_AChoreographer_getInstance>(
|
||||
"AChoreographer_getInstance")
|
||||
.value_or(nullptr);
|
||||
if (_AChoreographer_getInstance) {
|
||||
_AChoreographer_postFrameCallback64 =
|
||||
android
|
||||
->ResolveFunction<fp_AChoreographer_postFrameCallback64>(
|
||||
"AChoreographer_postFrameCallback64")
|
||||
.value_or(nullptr);
|
||||
#if FML_ARCH_CPU_64_BITS
|
||||
if (!_AChoreographer_postFrameCallback64) {
|
||||
_AChoreographer_postFrameCallback =
|
||||
android
|
||||
->ResolveFunction<fp_AChoreographer_postFrameCallback>(
|
||||
"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<HardwareBufferKey> 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
|
||||
@ -1,78 +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_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 <android/choreographer.h>
|
||||
#include <android/hardware_buffer.h>
|
||||
#include <android/surface_control.h>
|
||||
#include <android/trace.h>
|
||||
|
||||
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<HardwareBufferKey> AHardwareBuffer_getId(
|
||||
AHardwareBuffer* buffer);
|
||||
};
|
||||
|
||||
} // namespace flutter
|
||||
|
||||
#endif // FLUTTER_SHELL_PLATFORM_ANDROID_NDK_HELPERS_H_
|
||||
@ -12,7 +12,7 @@
|
||||
#include <sstream>
|
||||
#include <utility>
|
||||
|
||||
#include "flutter/shell/platform/android/ndk_helpers.h"
|
||||
#include "flutter/fml/platform/android/ndk_helpers.h"
|
||||
#include "include/android/SkImageAndroid.h"
|
||||
#include "unicode/uchar.h"
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user