blob: 9ff5d4ea3b6d150639aa80d4cd62f01883e1cea6 [file] [log] [blame]
// 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 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;
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_describe =
android
->ResolveFunction<fp_AHardwareBuffer_describe>(
"AHardwareBuffer_describe")
.value_or(nullptr);
}
} // namespace
void NDKHelpers::Init() {
std::call_once(init_once, InitOnceCallback);
}
bool NDKHelpers::HardwareBufferSupported() {
NDKHelpers::Init();
const bool r = _AHardwareBuffer_fromHardwareBuffer != nullptr;
return r;
}
AHardwareBuffer* NDKHelpers::AHardwareBuffer_fromHardwareBuffer(
JNIEnv* env,
jobject hardwareBufferObj) {
NDKHelpers::Init();
FML_CHECK(_AHardwareBuffer_fromHardwareBuffer != nullptr);
return _AHardwareBuffer_fromHardwareBuffer(env, hardwareBufferObj);
}
void NDKHelpers::AHardwareBuffer_acquire(AHardwareBuffer* buffer) {
NDKHelpers::Init();
FML_CHECK(_AHardwareBuffer_acquire != nullptr);
_AHardwareBuffer_acquire(buffer);
}
void NDKHelpers::AHardwareBuffer_release(AHardwareBuffer* buffer) {
NDKHelpers::Init();
FML_CHECK(_AHardwareBuffer_release != nullptr);
_AHardwareBuffer_release(buffer);
}
void NDKHelpers::AHardwareBuffer_describe(AHardwareBuffer* buffer,
AHardwareBuffer_Desc* desc) {
NDKHelpers::Init();
FML_CHECK(_AHardwareBuffer_describe != nullptr);
_AHardwareBuffer_describe(buffer, desc);
}
EGLClientBuffer NDKHelpers::eglGetNativeClientBufferANDROID(
AHardwareBuffer* buffer) {
NDKHelpers::Init();
FML_CHECK(_eglGetNativeClientBufferANDROID != nullptr);
return _eglGetNativeClientBufferANDROID(buffer);
}
} // namespace flutter