blob: d47e1eb57edc77ceddd29a5b0a1711010f9e7c37 [file] [log] [blame]
/*
* 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