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