| /* |
| * Copyright (C) 2022 Metrological Group B.V. |
| * Copyright (C) 2022 Igalia S.L. |
| * |
| * 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. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. |
| */ |
| |
| #pragma once |
| |
| #include <array> |
| #include <cstddef> |
| #include <cstdint> |
| |
| namespace WebCore { |
| |
| namespace DMABufFormatImpl { |
| |
| static constexpr uint32_t createFourCC(char a, char b, char c, char d) |
| { |
| return uint32_t(a) | (uint32_t(b) << 8) | (uint32_t(c) << 16) | (uint32_t(d) << 24); |
| } |
| |
| } |
| |
| struct DMABufFormat { |
| enum class FourCC : uint32_t { |
| Invalid = 0, |
| |
| R8 = DMABufFormatImpl::createFourCC('R', '8', ' ', ' '), |
| GR88 = DMABufFormatImpl::createFourCC('G', 'R', '8', '8'), |
| |
| XRGB8888 = DMABufFormatImpl::createFourCC('X', 'R', '2', '4'), |
| XBGR8888 = DMABufFormatImpl::createFourCC('X', 'B', '2', '4'), |
| RGBX8888 = DMABufFormatImpl::createFourCC('R', 'X', '2', '4'), |
| BGRX8888 = DMABufFormatImpl::createFourCC('B', 'X', '2', '4'), |
| ARGB8888 = DMABufFormatImpl::createFourCC('A', 'R', '2', '4'), |
| ABGR8888 = DMABufFormatImpl::createFourCC('A', 'B', '2', '4'), |
| RGBA8888 = DMABufFormatImpl::createFourCC('R', 'A', '2', '4'), |
| BGRA8888 = DMABufFormatImpl::createFourCC('B', 'A', '2', '4'), |
| RGB888 = DMABufFormatImpl::createFourCC('R', 'G', '2', '4'), |
| BGR888 = DMABufFormatImpl::createFourCC('B', 'G', '2', '4'), |
| |
| I420 = DMABufFormatImpl::createFourCC('I', '4', '2', '0'), |
| YV12 = DMABufFormatImpl::createFourCC('Y', 'V', '1', '2'), |
| A420 = DMABufFormatImpl::createFourCC('A', '4', '2', '0'), |
| NV12 = DMABufFormatImpl::createFourCC('N', 'V', '1', '2'), |
| NV21 = DMABufFormatImpl::createFourCC('N', 'V', '2', '1'), |
| |
| YUY2 = DMABufFormatImpl::createFourCC('Y', 'U', 'Y', '2'), |
| YVYU = DMABufFormatImpl::createFourCC('Y', 'V', 'Y', 'U'), |
| UYVY = DMABufFormatImpl::createFourCC('U', 'Y', 'V', 'Y'), |
| VYUY = DMABufFormatImpl::createFourCC('V', 'Y', 'U', 'Y'), |
| VUYA = DMABufFormatImpl::createFourCC('V', 'U', 'Y', 'A'), |
| AYUV = DMABufFormatImpl::createFourCC('A', 'Y', 'U', 'V'), |
| |
| Y444 = DMABufFormatImpl::createFourCC('Y', '4', '4', '4'), |
| Y41B = DMABufFormatImpl::createFourCC('Y', '4', '1', 'B'), |
| Y42B = DMABufFormatImpl::createFourCC('Y', '4', '2', 'B'), |
| }; |
| |
| static constexpr unsigned c_maxPlanes = 4; |
| |
| template<FourCC> static DMABufFormat create() = delete; |
| static DMABufFormat create(uint32_t); |
| |
| template<FourCC fourccValue, typename... PlaneDefinitionTypes> |
| static DMABufFormat instantiate(); |
| |
| FourCC fourcc { FourCC::Invalid }; |
| unsigned numPlanes { 0 }; |
| |
| uint32_t planeWidth(unsigned planeIndex, uint32_t width) const |
| { |
| ASSERT(planeIndex < c_maxPlanes); |
| return (width >> planes[planeIndex].horizontalSubsampling); |
| } |
| |
| uint32_t planeHeight(unsigned planeIndex, uint32_t height) const |
| { |
| ASSERT(planeIndex < c_maxPlanes); |
| return (height >> planes[planeIndex].verticalSubsampling); |
| } |
| |
| template<FourCC fourccValue, unsigned hsValue, unsigned vsValue> |
| struct PlaneDefinition { |
| static constexpr FourCC fourcc = fourccValue; |
| static constexpr unsigned horizontalSubsampling = hsValue; |
| static constexpr unsigned verticalSubsampling = vsValue; |
| }; |
| |
| struct Plane { |
| Plane() = default; |
| |
| template<typename PlaneDefitionType> |
| Plane(const PlaneDefitionType&) |
| : fourcc(PlaneDefitionType::fourcc) |
| , horizontalSubsampling(PlaneDefitionType::horizontalSubsampling) |
| , verticalSubsampling(PlaneDefitionType::verticalSubsampling) |
| { } |
| |
| FourCC fourcc { FourCC::Invalid }; |
| unsigned horizontalSubsampling { 0 }; |
| unsigned verticalSubsampling { 0 }; |
| }; |
| std::array<Plane, c_maxPlanes> planes; |
| }; |
| |
| namespace DMABufFormatImpl { |
| |
| template<DMABufFormat::FourCC fourccValue> |
| inline DMABufFormat createSinglePlaneRGBA() |
| { |
| return DMABufFormat::instantiate<fourccValue, |
| DMABufFormat::PlaneDefinition<fourccValue, 0, 0>>(); |
| } |
| |
| template<size_t Index, size_t Size, typename PlaneDefinitionType, typename... PlaneDefinitionTypes> |
| void definePlane(std::array<DMABufFormat::Plane, DMABufFormat::c_maxPlanes>& planes) |
| { |
| new (&planes[Index]) DMABufFormat::Plane(PlaneDefinitionType { }); |
| if constexpr ((Index + 1) < Size) |
| definePlane<Index + 1, Size, PlaneDefinitionTypes...>(planes); |
| } |
| |
| } |
| |
| template<DMABufFormat::FourCC fourccValue, typename... PlaneDefinitionTypes> |
| inline DMABufFormat DMABufFormat::instantiate() |
| { |
| static_assert(sizeof...(PlaneDefinitionTypes) <= 4); |
| |
| DMABufFormat format; |
| format.fourcc = fourccValue; |
| format.numPlanes = sizeof...(PlaneDefinitionTypes); |
| DMABufFormatImpl::definePlane<0, sizeof...(PlaneDefinitionTypes), PlaneDefinitionTypes...>(format.planes); |
| return format; |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::XRGB8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::XRGB8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::XBGR8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::XBGR8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::RGBX8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::RGBX8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::BGRX8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::BGRX8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::ARGB8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::ARGB8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::ABGR8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::ABGR8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::RGBA8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::RGBA8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::BGRA8888>() |
| { |
| return DMABufFormatImpl::createSinglePlaneRGBA<FourCC::BGRA8888>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::I420>() |
| { |
| return DMABufFormat::instantiate<FourCC::I420, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 1, 1>, |
| PlaneDefinition<FourCC::R8, 1, 1>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::YV12>() |
| { |
| return DMABufFormat::instantiate<FourCC::YV12, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 1, 1>, |
| PlaneDefinition<FourCC::R8, 1, 1>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::A420>() |
| { |
| return DMABufFormat::instantiate<FourCC::A420, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 1, 1>, |
| PlaneDefinition<FourCC::R8, 1, 1>, |
| PlaneDefinition<FourCC::R8, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::NV12>() |
| { |
| return DMABufFormat::instantiate<FourCC::NV12, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::GR88, 1, 1>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::NV21>() |
| { |
| return DMABufFormat::instantiate<FourCC::NV21, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::GR88, 1, 1>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::YUY2>() |
| { |
| return DMABufFormat::instantiate<FourCC::YUY2, |
| PlaneDefinition<FourCC::GR88, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::YVYU>() |
| { |
| return DMABufFormat::instantiate<FourCC::YVYU, |
| PlaneDefinition<FourCC::GR88, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::UYVY>() |
| { |
| return DMABufFormat::instantiate<FourCC::UYVY, |
| PlaneDefinition<FourCC::GR88, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::VYUY>() |
| { |
| return DMABufFormat::instantiate<FourCC::VYUY, |
| PlaneDefinition<FourCC::GR88, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::VUYA>() |
| { |
| return DMABufFormat::instantiate<FourCC::VUYA, |
| PlaneDefinition<FourCC::ABGR8888, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::AYUV>() |
| { |
| return DMABufFormat::instantiate<FourCC::AYUV, |
| PlaneDefinition<FourCC::ABGR8888, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::Y444>() |
| { |
| return DMABufFormat::instantiate<FourCC::Y444, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 0, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::Y41B>() |
| { |
| return DMABufFormat::instantiate<FourCC::Y41B, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 2, 0>, |
| PlaneDefinition<FourCC::R8, 2, 0>>(); |
| } |
| |
| template<> |
| inline DMABufFormat DMABufFormat::create<DMABufFormat::FourCC::Y42B>() |
| { |
| return DMABufFormat::instantiate<FourCC::Y42B, |
| PlaneDefinition<FourCC::R8, 0, 0>, |
| PlaneDefinition<FourCC::R8, 1, 0>, |
| PlaneDefinition<FourCC::R8, 1, 0>>(); |
| } |
| |
| inline DMABufFormat DMABufFormat::create(uint32_t fourccValue) |
| { |
| #define CREATE_FORMAT_FOR_FOURCC(FourCCValue) \ |
| case uint32_t(FourCC::FourCCValue): \ |
| return create<FourCC::FourCCValue>(); |
| |
| switch (fourccValue) { |
| CREATE_FORMAT_FOR_FOURCC(XRGB8888); |
| CREATE_FORMAT_FOR_FOURCC(XBGR8888); |
| CREATE_FORMAT_FOR_FOURCC(RGBX8888); |
| CREATE_FORMAT_FOR_FOURCC(BGRX8888); |
| CREATE_FORMAT_FOR_FOURCC(ARGB8888); |
| CREATE_FORMAT_FOR_FOURCC(ABGR8888); |
| CREATE_FORMAT_FOR_FOURCC(RGBA8888); |
| CREATE_FORMAT_FOR_FOURCC(BGRA8888); |
| CREATE_FORMAT_FOR_FOURCC(I420); |
| CREATE_FORMAT_FOR_FOURCC(YV12); |
| CREATE_FORMAT_FOR_FOURCC(A420); |
| CREATE_FORMAT_FOR_FOURCC(NV12); |
| CREATE_FORMAT_FOR_FOURCC(NV21); |
| CREATE_FORMAT_FOR_FOURCC(YUY2); |
| CREATE_FORMAT_FOR_FOURCC(YVYU); |
| CREATE_FORMAT_FOR_FOURCC(UYVY); |
| CREATE_FORMAT_FOR_FOURCC(VYUY); |
| CREATE_FORMAT_FOR_FOURCC(VUYA); |
| CREATE_FORMAT_FOR_FOURCC(AYUV); |
| CREATE_FORMAT_FOR_FOURCC(Y444); |
| CREATE_FORMAT_FOR_FOURCC(Y41B); |
| CREATE_FORMAT_FOR_FOURCC(Y42B); |
| default: |
| break; |
| } |
| |
| #undef CREATE_FORMAT_FOR_FOURCC |
| |
| return { }; |
| } |
| |
| } // namespace WebCore |