Repository: google/filament
File: filament/backend/src/vulkan/platform/VulkanPlatformAndroid.cpp (C++)

Code before:
        usage = VK_IMAGE_USAGE_STORAGE_BIT;
    }

    return { format, usage };
}

std::pair<TextureFormat, TextureUsage> getFilamentFormatAndUsage(const AHardwareBuffer_Desc& desc,
        bool sRGB) {
    auto const format = mapToFilamentFormat(desc.format, sRGB);
    return {
        format,
        mapToFilamentUsage(desc.usage, format),
    };
}

}// namespace

VulkanPlatformAndroid::ExternalImageVulkanAndroid::~ExternalImageVulkanAndroid() {
    if (__builtin_available(android 26, *)) {
        if (aHardwareBuffer) {
            AHardwareBuffer_release(aHardwareBuffer);
        }
    }
}

bool VulkanPlatformAndroid::isUnifiedMemoryArchitecture() const noexcept {
    VkPhysicalDeviceMemoryProperties memoryProperties;
    vkGetPhysicalDeviceMemoryProperties(getPhysicalDevice(), &memoryProperties);

    // Try to identify if the platform is running on a Unified Memory Architecture by inspecting the
    // memory heap flags, if they are all VK_MEMORY_HEAP_DEVICE_LOCAL_BIT it's UMA, otherwise not
    // enough information to make a decision, so default to false.
    for (uint32_t i = 0; i < memoryProperties.memoryHeapCount; ++i) {
        if ((memoryProperties.memoryHeaps[i].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) == 0) {
            return false;
        }
    }
    return true;
}

Platform::ExternalImageHandle VulkanPlatformAndroid::createExternalImage(
        AHardwareBuffer const* buffer, bool sRGB) noexcept {
    if (__builtin_available(android 26, *)) {
        auto bufferImpl = const_cast<AHardwareBuffer*>(buffer);
        AHardwareBuffer_acquire(bufferImpl);

        AHardwareBuffer_Desc hardwareBufferDescription = {};
        AHardwareBuffer_describe(buffer, &hardwareBufferDescription);

        auto* const p = new (std::nothrow) ExternalImageVulkanAndroid;
        p->aHardwareBuffer = const_cast<AHardwareBuffer*>(buffer);

Review comment (suggestion):
Might be better to store this as a boolean in the `VulkanContext`.  I'm just afraid future people will call it too often. 

And then `isUnifiedMemoryArchitecture` can be protected.

Code after:
        usage = VK_IMAGE_USAGE_STORAGE_BIT;
    }

    return { format, usage };
}

std::pair<TextureFormat, TextureUsage> getFilamentFormatAndUsage(const AHardwareBuffer_Desc& desc,
        bool sRGB) {
    auto const format = mapToFilamentFormat(desc.format, sRGB);
    return {
        format,
        mapToFilamentUsage(desc.usage, format),
    };
}

}// namespace

VulkanPlatformAndroid::ExternalImageVulkanAndroid::~ExternalImageVulkanAndroid() {
    if (__builtin_available(android 26, *)) {
        if (aHardwareBuffer) {
            AHardwareBuffer_release(aHardwareBuffer);
        }
    }
}

Platform::ExternalImageHandle VulkanPlatformAndroid::createExternalImage(
        AHardwareBuffer const* buffer, bool sRGB) noexcept {
    if (__builtin_available(android 26, *)) {
        auto bufferImpl = const_cast<AHardwareBuffer*>(buffer);
        AHardwareBuffer_acquire(bufferImpl);

        AHardwareBuffer_Desc hardwareBufferDescription = {};
        AHardwareBuffer_describe(buffer, &hardwareBufferDescription);

        auto* const p = new (std::nothrow) ExternalImageVulkanAndroid;
        p->aHardwareBuffer = const_cast<AHardwareBuffer*>(buffer);
        p->sRGB = sRGB;
        return Platform::ExternalImageHandle{ p };
    }

    return Platform::ExternalImageHandle{};
}

VulkanPlatformAndroid::ExternalImageDescAndroid VulkanPlatformAndroid::getExternalImageDesc(
        ExternalImageHandleRef externalImage) const noexcept {
    auto metadata = extractExternalImageMetadata(externalImage);
    return {
        .width = metadata.width,
        .height = metadata.height,
        .format = metadata.filamentFormat,
        .usage = metadata.filamentUsage,