• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // HardwareBufferImageSiblingVkAndroid.cpp: Implements HardwareBufferImageSiblingVkAndroid.
8 
9 #include "libANGLE/renderer/vulkan/android/HardwareBufferImageSiblingVkAndroid.h"
10 
11 #include "common/android_util.h"
12 
13 #include "libANGLE/Display.h"
14 #include "libANGLE/renderer/vulkan/DisplayVk.h"
15 #include "libANGLE/renderer/vulkan/RendererVk.h"
16 
17 namespace rx
18 {
19 
HardwareBufferImageSiblingVkAndroid(EGLClientBuffer buffer)20 HardwareBufferImageSiblingVkAndroid::HardwareBufferImageSiblingVkAndroid(EGLClientBuffer buffer)
21     : mBuffer(buffer),
22       mFormat(GL_NONE),
23       mRenderable(false),
24       mTextureable(false),
25       mSamples(0),
26       mImage(nullptr)
27 {}
28 
~HardwareBufferImageSiblingVkAndroid()29 HardwareBufferImageSiblingVkAndroid::~HardwareBufferImageSiblingVkAndroid() {}
30 
31 // Static
ValidateHardwareBuffer(RendererVk * renderer,EGLClientBuffer buffer)32 egl::Error HardwareBufferImageSiblingVkAndroid::ValidateHardwareBuffer(RendererVk *renderer,
33                                                                        EGLClientBuffer buffer)
34 {
35     struct ANativeWindowBuffer *windowBuffer =
36         angle::android::ClientBufferToANativeWindowBuffer(buffer);
37     struct AHardwareBuffer *hardwareBuffer =
38         angle::android::ANativeWindowBufferToAHardwareBuffer(windowBuffer);
39 
40     VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties = {};
41     bufferFormatProperties.sType =
42         VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
43     bufferFormatProperties.pNext = nullptr;
44 
45     VkAndroidHardwareBufferPropertiesANDROID bufferProperties = {};
46     bufferProperties.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
47     bufferProperties.pNext = &bufferFormatProperties;
48 
49     VkDevice device = renderer->getDevice();
50     VkResult result =
51         vkGetAndroidHardwareBufferPropertiesANDROID(device, hardwareBuffer, &bufferProperties);
52     if (result != VK_SUCCESS)
53     {
54         return egl::EglBadParameter() << "Failed to query AHardwareBuffer properties";
55     }
56 
57     if (!HasFullTextureFormatSupport(renderer, bufferFormatProperties.format))
58     {
59         return egl::EglBadParameter()
60                << "AHardwareBuffer format does not support enough features to use as a texture.";
61     }
62 
63     return egl::NoError();
64 }
65 
initialize(const egl::Display * display)66 egl::Error HardwareBufferImageSiblingVkAndroid::initialize(const egl::Display *display)
67 {
68     DisplayVk *displayVk = vk::GetImpl(display);
69     return angle::ToEGL(initImpl(displayVk), displayVk, EGL_BAD_PARAMETER);
70 }
71 
initImpl(DisplayVk * displayVk)72 angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk)
73 {
74     RendererVk *renderer = displayVk->getRenderer();
75 
76     struct ANativeWindowBuffer *windowBuffer =
77         angle::android::ClientBufferToANativeWindowBuffer(mBuffer);
78 
79     int pixelFormat = 0;
80     angle::android::GetANativeWindowBufferProperties(windowBuffer, &mSize.width, &mSize.height,
81                                                      &mSize.depth, &pixelFormat);
82     GLenum internalFormat = angle::android::NativePixelFormatToGLInternalFormat(pixelFormat);
83     mFormat               = gl::Format(internalFormat);
84 
85     struct AHardwareBuffer *hardwareBuffer =
86         angle::android::ANativeWindowBufferToAHardwareBuffer(windowBuffer);
87 
88     VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties;
89     bufferFormatProperties.sType =
90         VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
91     bufferFormatProperties.pNext = nullptr;
92 
93     VkAndroidHardwareBufferPropertiesANDROID bufferProperties = {};
94     bufferProperties.sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID;
95     bufferProperties.pNext = &bufferFormatProperties;
96 
97     VkDevice device = renderer->getDevice();
98     ANGLE_VK_TRY(displayVk, vkGetAndroidHardwareBufferPropertiesANDROID(device, hardwareBuffer,
99                                                                         &bufferProperties));
100 
101     const vk::Format &vkFormat       = renderer->getFormat(internalFormat);
102     const angle::Format &imageFormat = vkFormat.actualImageFormat();
103     bool isDepthOrStencilFormat      = imageFormat.depthBits > 0 || imageFormat.stencilBits > 0;
104     const VkImageUsageFlags usage =
105         VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
106         VK_IMAGE_USAGE_SAMPLED_BIT |
107         (imageFormat.redBits > 0 ? VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT : 0) |
108         (isDepthOrStencilFormat ? VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT : 0);
109 
110     VkExternalFormatANDROID externalFormat = {};
111     externalFormat.sType                   = VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID;
112     externalFormat.externalFormat          = 0;
113 
114     if (bufferFormatProperties.format == VK_FORMAT_UNDEFINED)
115     {
116         externalFormat.externalFormat = bufferFormatProperties.externalFormat;
117     }
118 
119     VkExternalMemoryImageCreateInfo externalMemoryImageCreateInfo = {};
120     externalMemoryImageCreateInfo.sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO;
121     externalMemoryImageCreateInfo.pNext = &externalFormat;
122     externalMemoryImageCreateInfo.handleTypes =
123         VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
124 
125     VkExtent3D vkExtents;
126     gl_vk::GetExtent(mSize, &vkExtents);
127 
128     mImage = new vk::ImageHelper();
129     ANGLE_TRY(mImage->initExternal(displayVk, gl::TextureType::_2D, vkExtents, vkFormat, 1, usage,
130                                    vk::ImageLayout::ExternalPreInitialized,
131                                    &externalMemoryImageCreateInfo, 0, 0, 1, 1));
132 
133     VkImportAndroidHardwareBufferInfoANDROID importHardwareBufferInfo = {};
134     importHardwareBufferInfo.sType  = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID;
135     importHardwareBufferInfo.buffer = hardwareBuffer;
136 
137     VkMemoryDedicatedAllocateInfo dedicatedAllocInfo = {};
138     dedicatedAllocInfo.sType  = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO;
139     dedicatedAllocInfo.pNext  = &importHardwareBufferInfo;
140     dedicatedAllocInfo.image  = mImage->getImage().getHandle();
141     dedicatedAllocInfo.buffer = VK_NULL_HANDLE;
142 
143     VkMemoryRequirements externalMemoryRequirements = {};
144     externalMemoryRequirements.size                 = bufferProperties.allocationSize;
145     externalMemoryRequirements.alignment            = 0;
146     externalMemoryRequirements.memoryTypeBits       = bufferProperties.memoryTypeBits;
147 
148     VkMemoryPropertyFlags flags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
149     ANGLE_TRY(mImage->initExternalMemory(displayVk, renderer->getMemoryProperties(),
150                                          externalMemoryRequirements, &dedicatedAllocInfo,
151                                          VK_QUEUE_FAMILY_FOREIGN_EXT, flags));
152 
153     constexpr uint32_t kColorRenderableRequiredBits        = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
154     constexpr uint32_t kDepthStencilRenderableRequiredBits = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
155     mRenderable =
156         renderer->hasImageFormatFeatureBits(vkFormat.vkImageFormat, kColorRenderableRequiredBits) ||
157         renderer->hasImageFormatFeatureBits(vkFormat.vkImageFormat,
158                                             kDepthStencilRenderableRequiredBits);
159 
160     constexpr uint32_t kTextureableRequiredBits =
161         VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT;
162     mTextureable =
163         renderer->hasImageFormatFeatureBits(vkFormat.vkImageFormat, kTextureableRequiredBits);
164 
165     return angle::Result::Continue;
166 }
167 
onDestroy(const egl::Display * display)168 void HardwareBufferImageSiblingVkAndroid::onDestroy(const egl::Display *display)
169 {
170     ASSERT(mImage == nullptr);
171 }
172 
getFormat() const173 gl::Format HardwareBufferImageSiblingVkAndroid::getFormat() const
174 {
175     return mFormat;
176 }
177 
isRenderable(const gl::Context * context) const178 bool HardwareBufferImageSiblingVkAndroid::isRenderable(const gl::Context *context) const
179 {
180     return mRenderable;
181 }
182 
isTexturable(const gl::Context * context) const183 bool HardwareBufferImageSiblingVkAndroid::isTexturable(const gl::Context *context) const
184 {
185     return mTextureable;
186 }
187 
getSize() const188 gl::Extents HardwareBufferImageSiblingVkAndroid::getSize() const
189 {
190     return mSize;
191 }
192 
getSamples() const193 size_t HardwareBufferImageSiblingVkAndroid::getSamples() const
194 {
195     return mSamples;
196 }
197 
198 // ExternalImageSiblingVk interface
getImage() const199 vk::ImageHelper *HardwareBufferImageSiblingVkAndroid::getImage() const
200 {
201     return mImage;
202 }
203 
release(RendererVk * renderer)204 void HardwareBufferImageSiblingVkAndroid::release(RendererVk *renderer)
205 {
206     if (mImage != nullptr)
207     {
208         mImage->releaseImage(renderer);
209         mImage->releaseStagingBuffer(renderer);
210         SafeDelete(mImage);
211     }
212 }
213 
214 }  // namespace rx
215