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/RendererVk.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 {
GetClientBufferMemoryRequirements(ContextVk * contextVk,const AHardwareBuffer * hardwareBuffer,VkMemoryRequirements & memRequirements)26 angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk,
27 const AHardwareBuffer *hardwareBuffer,
28 VkMemoryRequirements &memRequirements)
29 {
30 #if defined(ANGLE_PLATFORM_ANDROID)
31 const AHBFunctions &ahbFunctions =
32 GetImplAs<DisplayVkAndroid>(contextVk->getRenderer()->getDisplay())->getAHBFunctions();
33 ASSERT(ahbFunctions.valid());
34
35 AHardwareBuffer_Desc aHardwareBufferDescription = {};
36 ahbFunctions.describe(hardwareBuffer, &aHardwareBufferDescription);
37 if (aHardwareBufferDescription.format != AHARDWAREBUFFER_FORMAT_BLOB)
38 {
39 ERR() << "Trying to import non-BLOB AHB as client buffer.";
40 return angle::Result::Stop;
41 }
42
43 // Get Android Buffer Properties
44 VkAndroidHardwareBufferPropertiesANDROID bufferProperties = {};
45 bufferProperties.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
46 bufferProperties.pNext = nullptr;
47
48 VkDevice device = contextVk->getRenderer()->getDevice();
49 ANGLE_VK_TRY(contextVk, vkGetAndroidHardwareBufferPropertiesANDROID(device, hardwareBuffer,
50 &bufferProperties));
51
52 memRequirements.size = bufferProperties.allocationSize;
53 memRequirements.alignment = 0;
54 memRequirements.memoryTypeBits = bufferProperties.memoryTypeBits;
55
56 return angle::Result::Continue;
57 #else
58 ANGLE_VK_UNREACHABLE(contextVk);
59 return angle::Result::Stop;
60
61 #endif
62 }
63
InitAndroidExternalMemory(ContextVk * contextVk,EGLClientBuffer clientBuffer,VkMemoryPropertyFlags memoryProperties,Buffer * buffer,VkMemoryPropertyFlags * memoryPropertyFlagsOut,uint32_t * memoryTypeIndexOut,DeviceMemory * deviceMemoryOut,VkDeviceSize * sizeOut)64 angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
65 EGLClientBuffer clientBuffer,
66 VkMemoryPropertyFlags memoryProperties,
67 Buffer *buffer,
68 VkMemoryPropertyFlags *memoryPropertyFlagsOut,
69 uint32_t *memoryTypeIndexOut,
70 DeviceMemory *deviceMemoryOut,
71 VkDeviceSize *sizeOut)
72 {
73 #if defined(ANGLE_PLATFORM_ANDROID)
74 const AHBFunctions &functions =
75 GetImplAs<DisplayVkAndroid>(contextVk->getRenderer()->getDisplay())->getAHBFunctions();
76 ASSERT(functions.valid());
77
78 struct AHardwareBuffer *hardwareBuffer =
79 angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
80
81 VkMemoryRequirements externalMemoryRequirements = {};
82 ANGLE_TRY(
83 GetClientBufferMemoryRequirements(contextVk, hardwareBuffer, externalMemoryRequirements));
84
85 // Import Vulkan DeviceMemory from Android Hardware Buffer.
86 VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
87 importHardwareBufferInfo.sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
88 importHardwareBufferInfo.buffer = hardwareBuffer;
89
90 ANGLE_TRY(AllocateBufferMemoryWithRequirements(
91 contextVk, MemoryAllocationType::BufferExternal, memoryProperties,
92 externalMemoryRequirements, &importHardwareBufferInfo, buffer, memoryPropertyFlagsOut,
93 memoryTypeIndexOut, deviceMemoryOut));
94 *sizeOut = externalMemoryRequirements.size;
95
96 functions.acquire(hardwareBuffer);
97
98 return angle::Result::Continue;
99 #else
100 ANGLE_VK_UNREACHABLE(contextVk);
101 return angle::Result::Stop;
102 #endif
103 }
104
ReleaseAndroidExternalMemory(RendererVk * rendererVk,EGLClientBuffer clientBuffer)105 void ReleaseAndroidExternalMemory(RendererVk *rendererVk, EGLClientBuffer clientBuffer)
106 {
107 #if defined(ANGLE_PLATFORM_ANDROID)
108 const AHBFunctions &functions =
109 GetImplAs<DisplayVkAndroid>(rendererVk->getDisplay())->getAHBFunctions();
110 ASSERT(functions.valid());
111 struct AHardwareBuffer *hardwareBuffer =
112 angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
113 functions.release(hardwareBuffer);
114 #endif
115 }
116 } // namespace vk
117 } // namespace rx
118