|  | // Copyright 2023 The Dawn & Tint Authors | 
|  | // | 
|  | // Redistribution and use in source and binary forms, with or without | 
|  | // modification, are permitted provided that the following conditions are met: | 
|  | // | 
|  | // 1. Redistributions of source code must retain the above copyright notice, this | 
|  | //    list of conditions and the following disclaimer. | 
|  | // | 
|  | // 2. Redistributions in binary form must reproduce the above copyright notice, | 
|  | //    this list of conditions and the following disclaimer in the documentation | 
|  | //    and/or other materials provided with the distribution. | 
|  | // | 
|  | // 3. Neither the name of the copyright holder nor the names of its | 
|  | //    contributors may be used to endorse or promote products derived from | 
|  | //    this software without specific prior written permission. | 
|  | // | 
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | 
|  | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
|  | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
|  | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | 
|  | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
|  | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | 
|  | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | 
|  | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 
|  | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  |  | 
|  | #include "dawn/native/AHBFunctions.h" | 
|  |  | 
|  | namespace dawn::native { | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | // Convert from AHardwareBuffer_Format to wgpu::TextureFormat. Returns: | 
|  | //  - The exact corresponding wgpu::TextureFormat if the AHardwareBuffer format matches channel and | 
|  | //  bit count. | 
|  | //  - External if the format miss-matches in channel count or bit count but is still usable as an | 
|  | //  OpenGL or Vulkan texture in Dawn. | 
|  | //  - Undefined if the format is not applicable for WebGPU to import as a texture. | 
|  | wgpu::TextureFormat FormatFromAHardwareBufferFormat(uint32_t ahbFormat) { | 
|  | switch (ahbFormat) { | 
|  | // Formats with exact WebGPU representations | 
|  | case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM: | 
|  | return wgpu::TextureFormat::RGBA8Unorm; | 
|  | case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT: | 
|  | return wgpu::TextureFormat::RGBA16Float; | 
|  | case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM: | 
|  | return wgpu::TextureFormat::RGB10A2Unorm; | 
|  | case AHARDWAREBUFFER_FORMAT_D16_UNORM: | 
|  | return wgpu::TextureFormat::Depth16Unorm; | 
|  | case AHARDWAREBUFFER_FORMAT_D24_UNORM: | 
|  | return wgpu::TextureFormat::Depth24Plus; | 
|  | case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT: | 
|  | return wgpu::TextureFormat::Depth24PlusStencil8; | 
|  | case AHARDWAREBUFFER_FORMAT_D32_FLOAT: | 
|  | return wgpu::TextureFormat::Depth32Float; | 
|  | case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT: | 
|  | return wgpu::TextureFormat::Depth32FloatStencil8; | 
|  | case AHARDWAREBUFFER_FORMAT_S8_UINT: | 
|  | return wgpu::TextureFormat::Stencil8; | 
|  | case AHARDWAREBUFFER_FORMAT_R8_UNORM: | 
|  | return wgpu::TextureFormat::R8Unorm; | 
|  | case AHARDWAREBUFFER_FORMAT_R16_UINT: | 
|  | return wgpu::TextureFormat::R16Uint; | 
|  | case AHARDWAREBUFFER_FORMAT_R16G16_UINT: | 
|  | return wgpu::TextureFormat::RG16Uint; | 
|  |  | 
|  | // R8G8B8X8 is used in Vulkan as VK_FORMAT_R8G8B8A8_UNORM and GLES as GL_RGB8. In Vulkan the | 
|  | // alpha channel can be read and written but GL always treats it as opaque. Data can be | 
|  | // uploaded as if it's RGBA8. | 
|  | case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: | 
|  | return wgpu::TextureFormat::RGBA8Unorm; | 
|  |  | 
|  | // YUV formats are sampleable with external Vulkan samplers or as opaque samplers in GLES. | 
|  | // Treat them as External. | 
|  | case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: | 
|  | return wgpu::TextureFormat::External; | 
|  | case AHARDWAREBUFFER_FORMAT_YCbCr_P010: | 
|  | return wgpu::TextureFormat::External; | 
|  |  | 
|  | // RGB formats with no direct representation in WebGPU. Trivially sampleable and renderable | 
|  | // in Vulkan and GLES but data uploads are not currently supported. | 
|  | case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: | 
|  | return wgpu::TextureFormat::External; | 
|  | case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: | 
|  | return wgpu::TextureFormat::External; | 
|  |  | 
|  | // R10G10B10A10 maps to Vulkan format VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16 and no | 
|  | // GLES format. Not supported with no known use case. | 
|  | case AHARDWAREBUFFER_FORMAT_R10G10B10A10_UNORM: | 
|  | return wgpu::TextureFormat::Undefined; | 
|  |  | 
|  | // Can be used as a Vulkan buffer or bound to a GLES buffer using GL_EXT_external_buffer. | 
|  | // These use cases are not currently supported. | 
|  | case AHARDWAREBUFFER_FORMAT_BLOB: | 
|  | return wgpu::TextureFormat::Undefined; | 
|  |  | 
|  | // Android drivers make use of formats outside of the defined enums to represent internal | 
|  | // YUV formats used by the camera and video decoder. Treat these all as external and | 
|  | // sampleable. | 
|  | default: | 
|  | return wgpu::TextureFormat::External; | 
|  | } | 
|  | } | 
|  |  | 
|  | }  // anonymous namespace | 
|  |  | 
|  | AHBFunctions::AHBFunctions() { | 
|  | if (!mNativeWindowLib.Open("libnativewindow.so") || | 
|  | !mNativeWindowLib.GetProc(&Acquire, "AHardwareBuffer_acquire") || | 
|  | !mNativeWindowLib.GetProc(&Release, "AHardwareBuffer_release") || | 
|  | !mNativeWindowLib.GetProc(&Describe, "AHardwareBuffer_describe")) { | 
|  | mNativeWindowLib.Close(); | 
|  | } | 
|  | } | 
|  |  | 
|  | AHBFunctions::~AHBFunctions() = default; | 
|  |  | 
|  | bool AHBFunctions::IsValid() const { | 
|  | return mNativeWindowLib.Valid(); | 
|  | } | 
|  |  | 
|  | SharedTextureMemoryProperties GetAHBSharedTextureMemoryProperties( | 
|  | const AHBFunctions* ahbFunctions, | 
|  | ::AHardwareBuffer* aHardwareBuffer) { | 
|  | AHardwareBuffer_Desc aHardwareBufferDesc{}; | 
|  | ahbFunctions->Describe(aHardwareBuffer, &aHardwareBufferDesc); | 
|  |  | 
|  | SharedTextureMemoryProperties properties; | 
|  | properties.size = {aHardwareBufferDesc.width, aHardwareBufferDesc.height, | 
|  | aHardwareBufferDesc.layers}; | 
|  | properties.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst; | 
|  | if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER) { | 
|  | properties.usage |= wgpu::TextureUsage::RenderAttachment; | 
|  | } | 
|  | if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE) { | 
|  | properties.usage |= wgpu::TextureUsage::TextureBinding; | 
|  | } | 
|  | if (aHardwareBufferDesc.usage & AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER) { | 
|  | properties.usage |= wgpu::TextureUsage::StorageBinding; | 
|  | } | 
|  | properties.format = FormatFromAHardwareBufferFormat(aHardwareBufferDesc.format); | 
|  |  | 
|  | return properties; | 
|  | } | 
|  |  | 
|  | }  // namespace dawn::native |