15
15
*/
16
16
#include < backend/platforms/VulkanPlatform.h>
17
17
18
+ #include < backend/DriverEnums.h>
19
+ #include < backend/platforms/VulkanPlatformAndroid.h>
20
+ #include < private/backend/BackendUtilsAndroid.h>
21
+
18
22
#include " vulkan/VulkanConstants.h"
19
23
20
24
#include < utils/Panic.h>
24
28
#include < android/hardware_buffer.h>
25
29
#include < android/native_window.h>
26
30
31
+ #include < utility>
32
+
27
33
using namespace bluevk ;
28
34
29
35
namespace filament ::backend {
30
36
31
37
namespace {
32
- void getVKFormatAndUsage (const AHardwareBuffer_Desc& desc, VkFormat& format,
33
- VkImageUsageFlags& usage, bool & isProtected) {
38
+
39
+ VkFormat transformVkFormat (VkFormat format, bool sRGB ) {
40
+ if (!sRGB ) {
41
+ return format;
42
+ }
43
+
44
+ switch (format) {
45
+ case VK_FORMAT_R8G8B8A8_UNORM:
46
+ format = VK_FORMAT_R8G8B8A8_SRGB;
47
+ break ;
48
+ case VK_FORMAT_R8G8B8_UNORM:
49
+ format = VK_FORMAT_R8G8B8_SRGB;
50
+ break ;
51
+ default :
52
+ break ;
53
+ }
54
+
55
+ return format;
56
+ }
57
+
58
+ bool isProtectedFromUsage (uint64_t usage) {
59
+ return (usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) ? true : false ;
60
+ }
61
+
62
+ std::pair<VkFormat, VkImageUsageFlags> getVKFormatAndUsage (const AHardwareBuffer_Desc& desc,
63
+ bool sRGB ) {
64
+ VkFormat format = VK_FORMAT_UNDEFINED;
65
+ VkImageUsageFlags usage = 0 ;
34
66
// Refer to "11.2.17. External Memory Handle Types" in the spec, and
35
67
// Tables 13/14 for how the following derivation works.
36
68
bool isDepthFormat = false ;
37
- isProtected = false ;
38
69
switch (desc.format ) {
39
70
case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
40
71
format = VK_FORMAT_R8G8B8A8_UNORM;
@@ -82,6 +113,8 @@ void getVKFormatAndUsage(const AHardwareBuffer_Desc& desc, VkFormat& format,
82
113
format = VK_FORMAT_UNDEFINED;
83
114
}
84
115
116
+ format = transformVkFormat (format, sRGB );
117
+
85
118
// The following only concern usage flags derived from Table 14.
86
119
usage = 0 ;
87
120
if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) {
@@ -98,16 +131,13 @@ void getVKFormatAndUsage(const AHardwareBuffer_Desc& desc, VkFormat& format,
98
131
if (desc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) {
99
132
usage = VK_IMAGE_USAGE_STORAGE_BIT;
100
133
}
101
- if (desc.usage & AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT) {
102
- isProtected = true ;
103
- }
134
+
135
+ return { format, usage };
104
136
}
105
137
106
- VulkanPlatform::ImageData allocateExternalImage (void * externalBuffer,
107
- VkDevice device, const VkAllocationCallbacks* allocator,
138
+ VulkanPlatform::ImageData allocateExternalImage (AHardwareBuffer* buffer, VkDevice device,
108
139
VulkanPlatform::ExternalImageMetadata const & metadata) {
109
140
VulkanPlatform::ImageData data;
110
- AHardwareBuffer* buffer = static_cast <AHardwareBuffer*>(externalBuffer);
111
141
112
142
// if external format we need to specifiy it in the allocation
113
143
const bool useExternalFormat = metadata.format == VK_FORMAT_UNDEFINED;
@@ -140,7 +170,7 @@ VulkanPlatform::ImageData allocateExternalImage(void* externalBuffer,
140
170
if (metadata.isProtected == false )
141
171
imageInfo.usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
142
172
143
- VkResult result = vkCreateImage (device, &imageInfo, allocator , &data.first );
173
+ VkResult result = vkCreateImage (device, &imageInfo, VKALLOC , &data.first );
144
174
FILAMENT_CHECK_POSTCONDITION (result == VK_SUCCESS)
145
175
<< " vkCreateImage failed with error=" << static_cast <int32_t >(result);
146
176
@@ -160,27 +190,57 @@ VulkanPlatform::ImageData allocateExternalImage(void* externalBuffer,
160
190
.pNext = &memoryDedicatedAllocateInfo,
161
191
.allocationSize = metadata.allocationSize ,
162
192
.memoryTypeIndex = metadata.memoryTypeBits };
163
- result = vkAllocateMemory (device, &allocInfo, allocator , &data.second );
193
+ result = vkAllocateMemory (device, &allocInfo, VKALLOC , &data.second );
164
194
FILAMENT_CHECK_POSTCONDITION (result == VK_SUCCESS)
165
195
<< " vkAllocateMemory failed with error=" << static_cast <int32_t >(result);
166
196
167
197
return data;
168
198
}
169
199
170
- }// namespace
200
+ } // namespace
201
+
202
+ namespace fvkandroid {
203
+
204
+ ExternalImageVulkanAndroid::~ExternalImageVulkanAndroid () = default ;
205
+
206
+ Platform::ExternalImageHandle createExternalImage (AHardwareBuffer const * buffer,
207
+ bool sRGB ) noexcept {
208
+ if (__builtin_available (android 26 , *)) {
209
+ AHardwareBuffer_Desc hardwareBufferDescription = {};
210
+ AHardwareBuffer_describe (buffer, &hardwareBufferDescription);
211
+
212
+ auto * const p = new (std::nothrow) ExternalImageVulkanAndroid;
213
+ p->aHardwareBuffer = const_cast <AHardwareBuffer*>(buffer);
214
+ p->sRGB = sRGB ;
215
+ p->height = hardwareBufferDescription.height ;
216
+ p->width = hardwareBufferDescription.width ;
217
+ TextureFormat textureFormat = mapToFilamentFormat (hardwareBufferDescription.format , sRGB );
218
+ p->format = textureFormat;
219
+ p->usage = mapToFilamentUsage (hardwareBufferDescription.usage , textureFormat);
220
+ return Platform::ExternalImageHandle{ p };
221
+ }
222
+
223
+ return Platform::ExternalImageHandle{};
224
+ }
225
+
226
+ } // namespace fvkandroid
227
+
228
+ VulkanPlatform::ExternalImageMetadata VulkanPlatform::getExternalImageMetadataImpl (
229
+ ExternalImageHandleRef externalImage, VkDevice device) {
230
+ auto const * fvkExternalImage =
231
+ static_cast <fvkandroid::ExternalImageVulkanAndroid const *>(externalImage.get ());
171
232
172
- VulkanPlatform::ExternalImageMetadata VulkanPlatform::getExternalImageMetadataImpl (void * externalImage,
173
- VkDevice device) {
174
233
ExternalImageMetadata metadata;
175
- AHardwareBuffer* buffer = static_cast <AHardwareBuffer*>(externalImage) ;
234
+ AHardwareBuffer* buffer = fvkExternalImage-> aHardwareBuffer ;
176
235
if (__builtin_available (android 26 , *)) {
177
236
AHardwareBuffer_Desc bufferDesc;
178
237
AHardwareBuffer_describe (buffer, &bufferDesc);
179
238
metadata.width = bufferDesc.width ;
180
239
metadata.height = bufferDesc.height ;
181
240
metadata.layers = bufferDesc.layers ;
182
-
183
- getVKFormatAndUsage (bufferDesc, metadata.format , metadata.usage , metadata.isProtected );
241
+ metadata.isProtected = isProtectedFromUsage (bufferDesc.usage );
242
+ std::tie (metadata.format , metadata.usage ) =
243
+ getVKFormatAndUsage (bufferDesc, fvkExternalImage->sRGB );
184
244
}
185
245
// In the unprotected case add R/W capabilities
186
246
if (metadata.isProtected == false ) {
@@ -197,20 +257,25 @@ VulkanPlatform::ExternalImageMetadata VulkanPlatform::getExternalImageMetadataIm
197
257
};
198
258
VkResult result = vkGetAndroidHardwareBufferPropertiesANDROID (device, buffer, &properties);
199
259
FILAMENT_CHECK_POSTCONDITION (result == VK_SUCCESS)
200
- << " vkGetAndroidHardwareBufferProperties failed with error="
201
- << static_cast <int32_t >(result);
202
- FILAMENT_CHECK_POSTCONDITION (metadata.format == formatInfo.format )
203
- << " mismatched image format for external image (AHB)" ;
260
+ << " vkGetAndroidHardwareBufferProperties failed with error="
261
+ << static_cast <int32_t >(result);
262
+
263
+ VkFormat bufferPropertiesFormat = transformVkFormat (formatInfo.format , fvkExternalImage->sRGB );
264
+ FILAMENT_CHECK_POSTCONDITION (metadata.format == bufferPropertiesFormat)
265
+ << " mismatched image format( " << metadata.format << " ) and queried format("
266
+ << bufferPropertiesFormat << " ) for external image (AHB)" ;
204
267
metadata.externalFormat = formatInfo.externalFormat ;
205
268
metadata.allocationSize = properties.allocationSize ;
206
269
metadata.memoryTypeBits = properties.memoryTypeBits ;
207
270
return metadata;
208
271
}
209
272
210
- VulkanPlatform::ImageData VulkanPlatform::createExternalImageImpl ( void * externalImage,
211
- VkDevice device, const VkAllocationCallbacks* allocator ,
273
+ VulkanPlatform::ImageData VulkanPlatform::createExternalImageDataImpl (
274
+ ExternalImageHandleRef externalImage, VkDevice device ,
212
275
const ExternalImageMetadata& metadata) {
213
- ImageData data = allocateExternalImage (externalImage, device, allocator, metadata);
276
+ auto const * fvkExternalImage =
277
+ static_cast <fvkandroid::ExternalImageVulkanAndroid const *>(externalImage.get ());
278
+ ImageData data = allocateExternalImage (fvkExternalImage->aHardwareBuffer , device, metadata);
214
279
VkResult result = vkBindImageMemory (device, data.first , data.second , 0 );
215
280
FILAMENT_CHECK_POSTCONDITION (result == VK_SUCCESS)
216
281
<< " vkBindImageMemory error=" << static_cast <int32_t >(result);
0 commit comments