• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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