xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/android/vk_android_utils.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // vk_android_utils.cpp: Vulkan utilities for using the Android platform
8 
9 #include "libANGLE/renderer/vulkan/android/vk_android_utils.h"
10 
11 #include "common/android_util.h"
12 #include "libANGLE/renderer/vulkan/ContextVk.h"
13 #include "libANGLE/renderer/vulkan/vk_renderer.h"
14 #include "libANGLE/renderer/vulkan/vk_utils.h"
15 
16 #if defined(ANGLE_PLATFORM_ANDROID)
17 #    include "libANGLE/Display.h"
18 #    include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
19 #    include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
20 #endif
21 
22 namespace rx
23 {
24 namespace vk
25 {
26 namespace
27 {
28 #if defined(ANGLE_PLATFORM_ANDROID)
GetDisplayVkAndroid(Renderer * renderer)29 DisplayVkAndroid *GetDisplayVkAndroid(Renderer *renderer)
30 {
31     DisplayVk *displayVk = static_cast<DisplayVk *>(renderer->getGlobalOps());
32     return static_cast<DisplayVkAndroid *>(displayVk);
33 }
34 #endif
35 }  // anonymous namespace
36 
GetClientBufferMemoryRequirements(Context * context,const AHardwareBuffer * hardwareBuffer,VkMemoryRequirements & memRequirements)37 angle::Result GetClientBufferMemoryRequirements(Context *context,
38                                                 const AHardwareBuffer *hardwareBuffer,
39                                                 VkMemoryRequirements &memRequirements)
40 {
41 #if defined(ANGLE_PLATFORM_ANDROID)
42     const AHBFunctions &ahbFunctions =
43         GetDisplayVkAndroid(context->getRenderer())->getAHBFunctions();
44     ASSERT(ahbFunctions.valid());
45 
46     AHardwareBuffer_Desc aHardwareBufferDescription = {};
47     ahbFunctions.describe(hardwareBuffer, &aHardwareBufferDescription);
48     if (aHardwareBufferDescription.format != AHARDWAREBUFFER_FORMAT_BLOB)
49     {
50         ERR() << "Trying to import non-BLOB AHB as client buffer.";
51         return angle::Result::Stop;
52     }
53 
54     // Get Android Buffer Properties
55     VkAndroidHardwareBufferPropertiesANDROID bufferProperties = {};
56     bufferProperties.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
57     bufferProperties.pNext = nullptr;
58 
59     VkDevice device = context->getRenderer()->getDevice();
60     ANGLE_VK_TRY(context, vkGetAndroidHardwareBufferPropertiesANDROID(device, hardwareBuffer,
61                                                                       &bufferProperties));
62 
63     memRequirements.size           = bufferProperties.allocationSize;
64     memRequirements.alignment      = 0;
65     memRequirements.memoryTypeBits = bufferProperties.memoryTypeBits;
66 
67     return angle::Result::Continue;
68 #else
69     ANGLE_VK_UNREACHABLE(context);
70     return angle::Result::Stop;
71 
72 #endif
73 }
74 
InitAndroidExternalMemory(Context * context,EGLClientBuffer clientBuffer,VkMemoryPropertyFlags memoryProperties,Buffer * buffer,VkMemoryPropertyFlags * memoryPropertyFlagsOut,uint32_t * memoryTypeIndexOut,DeviceMemory * deviceMemoryOut,VkDeviceSize * sizeOut)75 angle::Result InitAndroidExternalMemory(Context *context,
76                                         EGLClientBuffer clientBuffer,
77                                         VkMemoryPropertyFlags memoryProperties,
78                                         Buffer *buffer,
79                                         VkMemoryPropertyFlags *memoryPropertyFlagsOut,
80                                         uint32_t *memoryTypeIndexOut,
81                                         DeviceMemory *deviceMemoryOut,
82                                         VkDeviceSize *sizeOut)
83 {
84 #if defined(ANGLE_PLATFORM_ANDROID)
85     const AHBFunctions &functions = GetDisplayVkAndroid(context->getRenderer())->getAHBFunctions();
86     ASSERT(functions.valid());
87 
88     struct AHardwareBuffer *hardwareBuffer =
89         angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
90 
91     VkMemoryRequirements externalMemoryRequirements = {};
92     ANGLE_TRY(
93         GetClientBufferMemoryRequirements(context, hardwareBuffer, externalMemoryRequirements));
94 
95     // Import Vulkan DeviceMemory from Android Hardware Buffer.
96     VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
97     importHardwareBufferInfo.sType  = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
98     importHardwareBufferInfo.buffer = hardwareBuffer;
99 
100     ANGLE_VK_TRY(context, AllocateBufferMemoryWithRequirements(
101                               context, MemoryAllocationType::BufferExternal, memoryProperties,
102                               externalMemoryRequirements, &importHardwareBufferInfo, buffer,
103                               memoryPropertyFlagsOut, memoryTypeIndexOut, deviceMemoryOut));
104     *sizeOut = externalMemoryRequirements.size;
105 
106     functions.acquire(hardwareBuffer);
107 
108     return angle::Result::Continue;
109 #else
110     ANGLE_VK_UNREACHABLE(context);
111     return angle::Result::Stop;
112 #endif
113 }
114 
ReleaseAndroidExternalMemory(Renderer * renderer,EGLClientBuffer clientBuffer)115 void ReleaseAndroidExternalMemory(Renderer *renderer, EGLClientBuffer clientBuffer)
116 {
117 #if defined(ANGLE_PLATFORM_ANDROID)
118     const AHBFunctions &functions = GetDisplayVkAndroid(renderer)->getAHBFunctions();
119     ASSERT(functions.valid());
120     struct AHardwareBuffer *hardwareBuffer =
121         angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
122     functions.release(hardwareBuffer);
123 #endif
124 }
125 }  // namespace vk
126 }  // namespace rx
127