Skip to content

Commit aaa8ca0

Browse files
layers: Fix AHB Checks and better messages
1 parent 83d96b8 commit aaa8ca0

2 files changed

Lines changed: 135 additions & 72 deletions

File tree

layers/core_checks/cc_android.cpp

Lines changed: 92 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,53 @@ static inline const char *string_AHardwareBufferGpuUsage(uint64_t usage) {
7777
return "AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP";
7878
} else if (usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE) {
7979
return "AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE";
80+
} else if (usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) {
81+
return "AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT";
8082
} else {
8183
return "Unknown AHARDWAREBUFFER_USAGE_GPU";
8284
}
8385
}
8486

87+
static inline const char *string_AHardwareBufferFormat(uint32_t format) {
88+
switch (format) {
89+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
90+
return "AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM";
91+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
92+
return "AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM";
93+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
94+
return "AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM";
95+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
96+
return "AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM";
97+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
98+
return "AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT";
99+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
100+
return "AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM";
101+
case (uint32_t)AHARDWAREBUFFER_FORMAT_BLOB:
102+
return "AHARDWAREBUFFER_FORMAT_BLOB";
103+
case (uint32_t)AHARDWAREBUFFER_FORMAT_D16_UNORM:
104+
return "AHARDWAREBUFFER_FORMAT_D16_UNORM";
105+
case (uint32_t)AHARDWAREBUFFER_FORMAT_D24_UNORM:
106+
return "AHARDWAREBUFFER_FORMAT_D24_UNORM";
107+
case (uint32_t)AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
108+
return "AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT";
109+
case (uint32_t)AHARDWAREBUFFER_FORMAT_D32_FLOAT:
110+
return "AHARDWAREBUFFER_FORMAT_D32_FLOAT";
111+
case (uint32_t)AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
112+
return "AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT";
113+
case (uint32_t)AHARDWAREBUFFER_FORMAT_S8_UINT:
114+
return "AHARDWAREBUFFER_FORMAT_S8_UINT";
115+
case (uint32_t)AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
116+
return "AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420";
117+
case (uint32_t)AHARDWAREBUFFER_FORMAT_YCbCr_P010:
118+
return "AHARDWAREBUFFER_FORMAT_YCbCr_P010";
119+
case (uint32_t)AHARDWAREBUFFER_FORMAT_R8_UNORM:
120+
return "AHARDWAREBUFFER_FORMAT_R8_UNORM";
121+
default:
122+
break;
123+
}
124+
return "Unkown AHardwareBuffer_Format";
125+
}
126+
85127
static uint32_t FullMipChainLevels(VkExtent3D extent) {
86128
// uint cast applies floor()
87129
return 1u + static_cast<uint32_t>(log2(std::max({extent.height, extent.width, extent.depth})));
@@ -163,22 +205,6 @@ bool CoreChecks::ValidateAllocateMemoryANDROID(const VkMemoryAllocateInfo &alloc
163205
AHardwareBuffer_Desc ahb_desc = {};
164206
AHardwareBuffer_describe(import_ahb_info->buffer, &ahb_desc);
165207

166-
// Validate AHardwareBuffer_Desc::usage is a valid usage for imported AHB
167-
//
168-
// BLOB & GPU_DATA_BUFFER combo specifically allowed
169-
if ((AHARDWAREBUFFER_FORMAT_BLOB != ahb_desc.format) || (0 == (ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER))) {
170-
// Otherwise, must be a combination from the AHardwareBuffer Format and Usage Equivalence tables
171-
// Usage must have at least one bit from the table. It may have additional bits not in the table
172-
uint64_t ahb_equiv_usage_bits = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
173-
AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE |
174-
AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
175-
if (0 == (ahb_desc.usage & ahb_equiv_usage_bits)) {
176-
skip |= LogError("VUID-VkImportAndroidHardwareBufferInfoANDROID-buffer-01881", device, ahb_loc,
177-
"AHardwareBuffer_Desc's usage (0x%" PRIx64 ") is not compatible with Vulkan. (AHB = %p).",
178-
ahb_desc.usage, import_ahb_info->buffer);
179-
}
180-
}
181-
182208
// Collect external buffer info
183209
VkPhysicalDeviceExternalBufferInfo pdebi = vku::InitStructHelper();
184210
pdebi.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
@@ -254,18 +280,21 @@ bool CoreChecks::ValidateAllocateMemoryANDROID(const VkMemoryAllocateInfo &alloc
254280
allocate_info.memoryTypeIndex, ahb_loc.Fields().c_str(), ahb_props.memoryTypeBits, import_ahb_info->buffer);
255281
}
256282

283+
VkImageUsageFlags dedicated_image_usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; // dummy init value
284+
257285
// Checks for allocations without a dedicated allocation requirement
258286
if ((nullptr == mem_ded_alloc_info) || (VK_NULL_HANDLE == mem_ded_alloc_info->image)) {
259287
// the Android hardware buffer must have a format of AHARDWAREBUFFER_FORMAT_BLOB and a usage that includes
260288
// AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER
261289
if ((uint64_t)AHARDWAREBUFFER_FORMAT_BLOB != ahb_desc.format) {
262290
skip |= LogError("VUID-VkMemoryAllocateInfo-pNext-02384", device, ahb_loc,
263-
"AHardwareBuffer_Desc's format (%" PRIu32 ") is not AHARDWAREBUFFER_FORMAT_BLOB. (AHB = %p).",
264-
ahb_desc.format, import_ahb_info->buffer);
291+
"AHardwareBuffer_Desc's format %s (%" PRIu32
292+
") is not AHARDWAREBUFFER_FORMAT_BLOB (0x21). (AHB = %p).",
293+
string_AHardwareBufferFormat(ahb_desc.format), ahb_desc.format, import_ahb_info->buffer);
265294
} else if ((ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) == 0) {
266295
skip |= LogError("VUID-VkMemoryAllocateInfo-pNext-02384", device, ahb_loc,
267296
"AHardwareBuffer's usage (0x%" PRIx64
268-
") does not include AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER. (AHB = %p).",
297+
") does not include AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER (0x1000000). (AHB = %p).",
269298
ahb_desc.usage, import_ahb_info->buffer);
270299
}
271300
} else { // Checks specific to import with a dedicated allocation requirement
@@ -282,6 +311,8 @@ bool CoreChecks::ValidateAllocateMemoryANDROID(const VkMemoryAllocateInfo &alloc
282311
const auto *ici = &image_state->create_info;
283312
const Location &dedicated_image_loc = allocate_info_loc.dot(Struct::VkMemoryDedicatedAllocateInfo, Field::image);
284313

314+
dedicated_image_usage = ici->usage;
315+
285316
// the format of image must be VK_FORMAT_UNDEFINED or the format returned by
286317
// vkGetAndroidHardwareBufferPropertiesANDROID
287318
if (VK_FORMAT_UNDEFINED != ici->format) {
@@ -312,19 +343,21 @@ bool CoreChecks::ValidateAllocateMemoryANDROID(const VkMemoryAllocateInfo &alloc
312343

313344
if ((ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE) != 0) {
314345
if ((ici->mipLevels != 1) && (ici->mipLevels != FullMipChainLevels(ici->extent))) {
315-
skip |= LogError(
316-
"VUID-VkMemoryAllocateInfo-pNext-02389", mem_ded_alloc_info->image, ahb_loc,
317-
"AHardwareBuffer_Desc's usage includes AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE but %s mipLevels (%" PRIu32
318-
") is neither 1 nor full mip "
319-
"chain levels (%" PRIu32 "). (AHB = %p).",
320-
dedicated_image_loc.Fields().c_str(), ici->mipLevels, FullMipChainLevels(ici->extent),
321-
import_ahb_info->buffer);
346+
skip |= LogError("VUID-VkMemoryAllocateInfo-pNext-02389", mem_ded_alloc_info->image, ahb_loc,
347+
"AHardwareBuffer_Desc's usage (0x%" PRIx64
348+
") includes AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE but %s mipLevels (%" PRIu32
349+
") is neither 1 nor full mip chain levels (%" PRIu32 "). (AHB = %p).",
350+
ahb_desc.usage, dedicated_image_loc.Fields().c_str(), ici->mipLevels,
351+
FullMipChainLevels(ici->extent), import_ahb_info->buffer);
322352
}
323353
} else {
324354
if (ici->mipLevels != 1) {
325-
skip |= LogError("VUID-VkMemoryAllocateInfo-pNext-02586", mem_ded_alloc_info->image, ahb_loc,
326-
"AHardwareBuffer_Desc's usage is 0x%" PRIx64 " but %s mipLevels is %" PRIu32 ". (AHB = %p).",
327-
ahb_desc.usage, dedicated_image_loc.Fields().c_str(), ici->mipLevels, import_ahb_info->buffer);
355+
skip |=
356+
LogError("VUID-VkMemoryAllocateInfo-pNext-02586", mem_ded_alloc_info->image, ahb_loc,
357+
"AHardwareBuffer_Desc's usage (0x%" PRIx64
358+
") is missing 0x4000000 (AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE) but %s mipLevels is %" PRIu32
359+
". (AHB = %p).",
360+
ahb_desc.usage, dedicated_image_loc.Fields().c_str(), ici->mipLevels, import_ahb_info->buffer);
328361
}
329362
}
330363

@@ -352,16 +385,40 @@ bool CoreChecks::ValidateAllocateMemoryANDROID(const VkMemoryAllocateInfo &alloc
352385
for (const auto &[vk_usage, ahb_usage] : ahb_usage_map_v2a) {
353386
if (ici->usage & vk_usage) {
354387
if (0 == (ahb_usage & ahb_desc.usage)) {
355-
skip |= LogError(
356-
"VUID-VkMemoryAllocateInfo-pNext-02390", mem_ded_alloc_info->image, dedicated_image_loc,
357-
"was created with %s, but the AHB equivalent (%s) is not in AHardwareBuffer_Desc.usage (0x%" PRIx64
358-
"). (AHB = %p).",
359-
string_VkImageUsageFlags(vk_usage).c_str(), string_AHardwareBufferGpuUsage(ahb_usage), ahb_desc.usage,
360-
import_ahb_info->buffer);
388+
skip |= LogError("VUID-VkMemoryAllocateInfo-pNext-02390", mem_ded_alloc_info->image, dedicated_image_loc,
389+
"was created with %s, but the AHB equivalent 0x%" PRIx64
390+
" (%s) is not in AHardwareBuffer_Desc.usage (0x%" PRIx64 "). (AHB = %p).",
391+
string_VkImageUsageFlags(vk_usage).c_str(), ahb_usage,
392+
string_AHardwareBufferGpuUsage(ahb_usage), ahb_desc.usage, import_ahb_info->buffer);
361393
}
362394
}
363395
}
364396
}
397+
398+
// Validate AHardwareBuffer_Desc::usage is a valid usage for imported AHB
399+
const bool is_gpu_data = ((ahb_desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) != 0);
400+
// BLOB & GPU_DATA_BUFFER combo specifically allowed
401+
bool usage_exception_1 = is_gpu_data && AHARDWAREBUFFER_FORMAT_BLOB == ahb_desc.format;
402+
// Recently using VK_IMAGE_USAGE_STORAGE_BIT was also allowed
403+
bool usage_exception_2 = is_gpu_data && ((dedicated_image_usage & VK_IMAGE_USAGE_STORAGE_BIT) != 0);
404+
if (!usage_exception_1 && !usage_exception_2) {
405+
// Otherwise, must be a combination from the AHardwareBuffer Format and Usage Equivalence tables
406+
// Usage must have at least one bit from the table. It may have additional bits not in the table
407+
uint64_t ahb_equiv_usage_bits = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER |
408+
AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP | AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE |
409+
AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT;
410+
if (0 == (ahb_desc.usage & ahb_equiv_usage_bits)) {
411+
skip |= LogError(
412+
"VUID-VkImportAndroidHardwareBufferInfoANDROID-buffer-01881", device, ahb_loc,
413+
"AHardwareBuffer_Desc's usage (0x%" PRIx64
414+
") is not compatible with Vulkan. (Format = %s) (AHB = %p). There are 3 valid combinations:\n"
415+
"1. Use FORMAT_BLOB with USAGE_GPU_DATA_BUFFER\n"
416+
"2. Use USAGE_GPU_DATA_BUFFER with a dedicated VkImage with VK_IMAGE_USAGE_STORAGE_BIT\n"
417+
"3. Use AHB usage GPU_SAMPLED_IMAGE, GPU_FRAMEBUFFER, GPU_CUBE_MAP, GPU_MIPMAP_COMPLETE, or PROTECTED_CONTENT",
418+
ahb_desc.usage, string_AHardwareBufferFormat(ahb_desc.format), import_ahb_info->buffer);
419+
}
420+
}
421+
365422
} else { // Not an import
366423
// auto exp_mem_alloc_info = vku::FindStructInPNextChain<VkExportMemoryAllocateInfo>(allocate_info.pNext);
367424
// auto mem_ded_alloc_info = vku::FindStructInPNextChain<VkMemoryDedicatedAllocateInfo>(allocate_info.pNext);

tests/android/mock/android/hardware_buffer.h

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
2-
* Copyright (c) 2023 The Khronos Group Inc.
3-
* Copyright (c) 2023 Valve Corporation
4-
* Copyright (c) 2023 LunarG, Inc.
2+
* Copyright (c) 2023-2025 The Khronos Group Inc.
3+
* Copyright (c) 2023-2025 Valve Corporation
4+
* Copyright (c) 2023-2025 LunarG, Inc.
55
*
66
* Licensed under the Apache License, Version 2.0 (the "License");
77
* you may not use this file except in compliance with the License.
@@ -21,43 +21,49 @@
2121
#include <stdint.h>
2222

2323
enum AHardwareBuffer_Format {
24-
AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
25-
AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2,
26-
AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3,
27-
AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4,
28-
AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT = 0x16,
29-
AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b,
30-
AHARDWAREBUFFER_FORMAT_BLOB = 0x21,
31-
AHARDWAREBUFFER_FORMAT_D16_UNORM = 0x30,
32-
AHARDWAREBUFFER_FORMAT_D24_UNORM = 0x31,
33-
AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT = 0x32,
34-
AHARDWAREBUFFER_FORMAT_D32_FLOAT = 0x33,
35-
AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT = 0x34,
36-
AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35,
37-
AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
38-
AHARDWAREBUFFER_FORMAT_YCbCr_P010 = 0x36,
39-
AHARDWAREBUFFER_FORMAT_R8_UNORM = 0x38,
24+
AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM = 1,
25+
AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM = 2,
26+
AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM = 3,
27+
AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM = 4,
28+
AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT = 0x16,
29+
AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM = 0x2b,
30+
AHARDWAREBUFFER_FORMAT_BLOB = 0x21,
31+
AHARDWAREBUFFER_FORMAT_D16_UNORM = 0x30,
32+
AHARDWAREBUFFER_FORMAT_D24_UNORM = 0x31,
33+
AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT = 0x32,
34+
AHARDWAREBUFFER_FORMAT_D32_FLOAT = 0x33,
35+
AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT = 0x34,
36+
AHARDWAREBUFFER_FORMAT_S8_UINT = 0x35,
37+
AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420 = 0x23,
38+
AHARDWAREBUFFER_FORMAT_YCbCr_P010 = 0x36,
39+
AHARDWAREBUFFER_FORMAT_R8_UNORM = 0x38,
40+
// added after NDK 25 (current minimum)
41+
AHARDWAREBUFFER_FORMAT_R16_UINT = 0x39,
42+
AHARDWAREBUFFER_FORMAT_R16G16_UINT = 0x3a,
43+
AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM = 0x3b,
4044
};
4145

4246
enum AHardwareBuffer_UsageFlags {
43-
AHARDWAREBUFFER_USAGE_CPU_READ_NEVER = 0UL,
44-
AHARDWAREBUFFER_USAGE_CPU_READ_RARELY = 2UL,
45-
AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN = 3UL,
46-
AHARDWAREBUFFER_USAGE_CPU_READ_MASK = 0xFUL,
47-
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER = 0UL << 4,
48-
AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY = 2UL << 4,
49-
AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN = 3UL << 4,
50-
AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK = 0xFUL << 4,
51-
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE = 1UL << 8,
52-
AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER = 1UL << 9,
53-
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
54-
AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY = 1ULL << 11,
55-
AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT = 1UL << 14,
56-
AHARDWAREBUFFER_USAGE_VIDEO_ENCODE = 1UL << 16,
57-
AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA = 1UL << 23,
58-
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER = 1UL << 24,
59-
AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP = 1UL << 25,
60-
AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE = 1UL << 26,
47+
AHARDWAREBUFFER_USAGE_CPU_READ_NEVER = 0UL,
48+
AHARDWAREBUFFER_USAGE_CPU_READ_RARELY = 2UL,
49+
AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN = 3UL,
50+
AHARDWAREBUFFER_USAGE_CPU_READ_MASK = 0xFUL,
51+
AHARDWAREBUFFER_USAGE_CPU_WRITE_NEVER = 0UL << 4,
52+
AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY = 2UL << 4,
53+
AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN = 3UL << 4,
54+
AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK = 0xFUL << 4,
55+
AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE = 1UL << 8,
56+
AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER = 1UL << 9,
57+
AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
58+
AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY = 1ULL << 11,
59+
AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT = 1UL << 14,
60+
AHARDWAREBUFFER_USAGE_VIDEO_ENCODE = 1UL << 16,
61+
AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA = 1UL << 23,
62+
AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER = 1UL << 24,
63+
AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP = 1UL << 25,
64+
AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE = 1UL << 26,
65+
// added after NDK 25 (current minimum)
66+
AHARDWAREBUFFER_USAGE_FRONT_BUFFER = 1ULL << 32,
6167
};
6268

6369
typedef struct AHardwareBuffer_Desc {

0 commit comments

Comments
 (0)