| // 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 "src/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 OpaqueYCbCrAndroid. | |
| case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420: | |
| return wgpu::TextureFormat::OpaqueYCbCrAndroid; | |
| case AHARDWAREBUFFER_FORMAT_YCbCr_P010: | |
| return wgpu::TextureFormat::OpaqueYCbCrAndroid; | |
| // RGB formats with no direct representation in WebGPU. They could be sampleable and | |
| // renderable in Vulkan and GLES but data uploads couldn't be supported without more work. | |
| case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: | |
| return wgpu::TextureFormat::Undefined; | |
| case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM: | |
| return wgpu::TextureFormat::Undefined; | |
| // 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::OpaqueYCbCrAndroid; | |
| } | |
| } | |
| } // 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 |