blob: 4fe1a0089beb2ea7271ab8b4fb7b90562e0e88c1 [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.
#ifndef FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
#define FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_
#include <optional>
#include "flutter/fml/unique_object.h"
#include "impeller/base/mask.h"
#include "impeller/geometry/size.h"
#include "impeller/toolkit/android/proc_table.h"
namespace impeller::android {
enum class HardwareBufferFormat {
//----------------------------------------------------------------------------
/// This format is guaranteed to be supported on all versions of Android. This
/// format can also be converted to an Impeller and Vulkan format.
///
/// @see Vulkan Format: VK_FORMAT_R8G8B8A8_UNORM
/// @see OpenGL ES Format: GL_RGBA8
///
/// Why have many format when one format do trick?
///
kR8G8B8A8UNormInt,
};
enum class HardwareBufferUsageFlags {
kNone = 0u,
kFrameBufferAttachment = 1u << 0u,
kCompositorOverlay = 1u << 1u,
kSampledImage = 1u << 2u,
};
using HardwareBufferUsage = Mask<HardwareBufferUsageFlags>;
//------------------------------------------------------------------------------
/// @brief A descriptor use to specify hardware buffer allocations.
///
struct HardwareBufferDescriptor {
HardwareBufferFormat format = HardwareBufferFormat::kR8G8B8A8UNormInt;
ISize size;
HardwareBufferUsage usage = HardwareBufferUsageFlags::kNone;
//----------------------------------------------------------------------------
/// @brief Create a descriptor of the given size that is suitable for use
/// as a swapchain image.
///
/// @warning Descriptors of zero size are not allocatable. The next best
/// valid size is picked. So make sure to check the actual size of
/// the descriptor after this call is made to determine the size
/// of the allocated hardware buffer.
///
/// @param[in] size The size. See the restrictions about valid sizes above.
///
/// @return The hardware buffer descriptor.
///
static HardwareBufferDescriptor MakeForSwapchainImage(const ISize& size);
//----------------------------------------------------------------------------
/// @brief If hardware buffers can be created using this descriptor.
/// Allocatable descriptors may still cause failing allocations in
/// case of resource exhaustion.
///
/// @return `true` if allocatable (unless resource exhaustion).
///
bool IsAllocatable() const;
constexpr bool operator==(const HardwareBufferDescriptor& o) const {
return format == o.format && size == o.size && usage == o.usage;
}
constexpr bool operator!=(const HardwareBufferDescriptor& o) const {
return !(*this == o);
}
};
//------------------------------------------------------------------------------
/// @brief A wrapper for AHardwareBuffer
/// https://developer.android.com/ndk/reference/group/a-hardware-buffer
///
/// This wrapper creates and owns a handle to a managed hardware
/// buffer. That is, there is no ability to take a reference to an
/// externally created hardware buffer.
///
/// This wrapper is only available on Android API 29 and above.
///
class HardwareBuffer {
public:
static bool IsAvailableOnPlatform();
explicit HardwareBuffer(HardwareBufferDescriptor descriptor);
~HardwareBuffer();
HardwareBuffer(const HardwareBuffer&) = delete;
HardwareBuffer& operator=(const HardwareBuffer&) = delete;
bool IsValid() const;
AHardwareBuffer* GetHandle() const;
const HardwareBufferDescriptor& GetDescriptor() const;
const AHardwareBuffer_Desc& GetAndroidDescriptor() const;
static std::optional<AHardwareBuffer_Desc> Describe(AHardwareBuffer* buffer);
//----------------------------------------------------------------------------
/// @brief Get the system wide unique ID of the hardware buffer if
/// possible. This is only available on Android API 31 and above.
/// Within the process, the handle are unique.
///
/// @return The system unique id if one can be obtained.
///
std::optional<uint64_t> GetSystemUniqueID() const;
//----------------------------------------------------------------------------
/// @brief Get the system wide unique ID of the hardware buffer if
/// possible. This is only available on Android API 31 and above.
/// Within the process, the handle are unique.
///
/// @return The system unique id if one can be obtained.
///
static std::optional<uint64_t> GetSystemUniqueID(AHardwareBuffer* buffer);
private:
struct UniqueAHardwareBufferTraits {
static AHardwareBuffer* InvalidValue() { return nullptr; }
static bool IsValid(AHardwareBuffer* value) {
return value != InvalidValue();
}
static void Free(AHardwareBuffer* value) {
GetProcTable().AHardwareBuffer_release(value);
}
};
const HardwareBufferDescriptor descriptor_;
const AHardwareBuffer_Desc android_descriptor_;
fml::UniqueObject<AHardwareBuffer*, UniqueAHardwareBufferTraits> buffer_;
bool is_valid_ = false;
};
} // namespace impeller::android
namespace impeller {
IMPELLER_ENUM_IS_MASK(android::HardwareBufferUsageFlags);
} // namespace impeller
#endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_HARDWARE_BUFFER_H_