2024-06-08 10:07:59 +02:00
|
|
|
#include "Format.hpp"
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include "../includes.hpp"
|
2025-12-18 17:23:24 +00:00
|
|
|
#include "debug/log/Logger.hpp"
|
2024-06-20 00:15:18 +02:00
|
|
|
#include "../macros.hpp"
|
2024-07-21 13:09:54 +02:00
|
|
|
#include <xf86drm.h>
|
|
|
|
|
#include <drm_fourcc.h>
|
2024-06-08 10:07:59 +02:00
|
|
|
|
|
|
|
|
inline const std::vector<SPixelFormat> GLES3_FORMATS = {
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_ARGB8888,
|
|
|
|
|
.glInternalFormat = GL_RGBA8,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XRGB8888,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_BGRA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_XRGB8888,
|
|
|
|
|
.glInternalFormat = GL_RGBA8,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XRGB8888,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_BGR1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_XBGR8888,
|
|
|
|
|
.glInternalFormat = GL_RGBA8,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR8888,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_ABGR8888,
|
|
|
|
|
.glInternalFormat = GL_RGBA8,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR8888,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_BGR888,
|
|
|
|
|
.glInternalFormat = GL_RGB8,
|
|
|
|
|
.glFormat = GL_RGB,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_BGR888,
|
|
|
|
|
.bytesPerBlock = 3,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_RGBX4444,
|
|
|
|
|
.glInternalFormat = GL_RGBA4,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT_4_4_4_4,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_RGBX4444,
|
|
|
|
|
.bytesPerBlock = 2,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_RGBA4444,
|
|
|
|
|
.glInternalFormat = GL_RGBA4,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT_4_4_4_4,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_RGBX4444,
|
|
|
|
|
.bytesPerBlock = 2,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_RGBX5551,
|
|
|
|
|
.glInternalFormat = GL_RGB5_A1,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT_5_5_5_1,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_RGBX5551,
|
|
|
|
|
.bytesPerBlock = 2,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_RGBA5551,
|
|
|
|
|
.glInternalFormat = GL_RGB5_A1,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT_5_5_5_1,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_RGBX5551,
|
|
|
|
|
.bytesPerBlock = 2,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_RGB565,
|
|
|
|
|
.glInternalFormat = GL_RGB565,
|
|
|
|
|
.glFormat = GL_RGB,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT_5_6_5,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_RGB565,
|
|
|
|
|
.bytesPerBlock = 2,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_XBGR2101010,
|
|
|
|
|
.glInternalFormat = GL_RGB10_A2,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR2101010,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_ABGR2101010,
|
|
|
|
|
.glInternalFormat = GL_RGB10_A2,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR2101010,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_XRGB2101010,
|
|
|
|
|
.glInternalFormat = GL_RGB10_A2,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XRGB2101010,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_BGR1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_ARGB2101010,
|
|
|
|
|
.glInternalFormat = GL_RGB10_A2,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_UNSIGNED_INT_2_10_10_10_REV,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XRGB2101010,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.swizzle = {SWIZZLE_BGRA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_XBGR16161616F,
|
|
|
|
|
.glInternalFormat = GL_RGBA16F,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_HALF_FLOAT,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR16161616F,
|
|
|
|
|
.bytesPerBlock = 8,
|
|
|
|
|
.swizzle = {SWIZZLE_RGB1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_ABGR16161616F,
|
|
|
|
|
.glInternalFormat = GL_RGBA16F,
|
|
|
|
|
.glFormat = GL_RGBA,
|
|
|
|
|
.glType = GL_HALF_FLOAT,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR16161616F,
|
|
|
|
|
.bytesPerBlock = 8,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_XBGR16161616,
|
|
|
|
|
.glInternalFormat = GL_RGBA16UI,
|
|
|
|
|
.glFormat = GL_RGBA_INTEGER,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT,
|
|
|
|
|
.withAlpha = false,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR16161616,
|
|
|
|
|
.bytesPerBlock = 8,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_ABGR16161616,
|
|
|
|
|
.glInternalFormat = GL_RGBA16UI,
|
|
|
|
|
.glFormat = GL_RGBA_INTEGER,
|
|
|
|
|
.glType = GL_UNSIGNED_SHORT,
|
|
|
|
|
.withAlpha = true,
|
|
|
|
|
.alphaStripped = DRM_FORMAT_XBGR16161616,
|
|
|
|
|
.bytesPerBlock = 8,
|
|
|
|
|
.swizzle = {SWIZZLE_RGBA},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.drmFormat = DRM_FORMAT_YVYU,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.blockSize = {2, 1},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
.drmFormat = DRM_FORMAT_VYUY,
|
|
|
|
|
.bytesPerBlock = 4,
|
|
|
|
|
.blockSize = {2, 1},
|
|
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_R8,
|
|
|
|
|
.glInternalFormat = GL_R8,
|
|
|
|
|
.glFormat = GL_RED,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.bytesPerBlock = 1,
|
|
|
|
|
.swizzle = {SWIZZLE_R001},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_GR88,
|
|
|
|
|
.glInternalFormat = GL_RG8,
|
|
|
|
|
.glFormat = GL_RG,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.bytesPerBlock = 2,
|
|
|
|
|
.swizzle = {SWIZZLE_RG01},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
{
|
2026-01-07 19:53:42 +01:00
|
|
|
.drmFormat = DRM_FORMAT_RGB888,
|
|
|
|
|
.glInternalFormat = GL_RGB8,
|
|
|
|
|
.glFormat = GL_RGB,
|
|
|
|
|
.glType = GL_UNSIGNED_BYTE,
|
|
|
|
|
.bytesPerBlock = 3,
|
|
|
|
|
.swizzle = {SWIZZLE_BGR1},
|
2024-06-08 10:07:59 +02:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
SHMFormat NFormatUtils::drmToShm(DRMFormat drm) {
|
2024-06-08 10:07:59 +02:00
|
|
|
switch (drm) {
|
|
|
|
|
case DRM_FORMAT_XRGB8888: return WL_SHM_FORMAT_XRGB8888;
|
|
|
|
|
case DRM_FORMAT_ARGB8888: return WL_SHM_FORMAT_ARGB8888;
|
|
|
|
|
default: return drm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return drm;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
DRMFormat NFormatUtils::shmToDRM(SHMFormat shm) {
|
2024-06-08 10:07:59 +02:00
|
|
|
switch (shm) {
|
|
|
|
|
case WL_SHM_FORMAT_XRGB8888: return DRM_FORMAT_XRGB8888;
|
|
|
|
|
case WL_SHM_FORMAT_ARGB8888: return DRM_FORMAT_ARGB8888;
|
|
|
|
|
default: return shm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return shm;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
const SPixelFormat* NFormatUtils::getPixelFormatFromDRM(DRMFormat drm) {
|
2024-08-26 20:24:30 +02:00
|
|
|
for (auto const& fmt : GLES3_FORMATS) {
|
2024-06-08 10:07:59 +02:00
|
|
|
if (fmt.drmFormat == drm)
|
|
|
|
|
return &fmt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
const SPixelFormat* NFormatUtils::getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha) {
|
2024-08-26 20:24:30 +02:00
|
|
|
for (auto const& fmt : GLES3_FORMATS) {
|
2025-08-14 19:44:56 +05:00
|
|
|
if (fmt.glFormat == sc<int>(glFormat) && fmt.glType == sc<int>(glType) && fmt.withAlpha == alpha)
|
2024-06-08 10:07:59 +02:00
|
|
|
return &fmt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-07 19:53:42 +01:00
|
|
|
bool NFormatUtils::isFormatYUV(uint32_t drmFormat) {
|
|
|
|
|
switch (drmFormat) {
|
|
|
|
|
case DRM_FORMAT_YUYV:
|
|
|
|
|
case DRM_FORMAT_YVYU:
|
|
|
|
|
case DRM_FORMAT_UYVY:
|
|
|
|
|
case DRM_FORMAT_VYUY:
|
|
|
|
|
case DRM_FORMAT_AYUV:
|
|
|
|
|
case DRM_FORMAT_NV12:
|
|
|
|
|
case DRM_FORMAT_NV21:
|
|
|
|
|
case DRM_FORMAT_NV16:
|
|
|
|
|
case DRM_FORMAT_NV61:
|
|
|
|
|
case DRM_FORMAT_YUV410:
|
|
|
|
|
case DRM_FORMAT_YUV411:
|
|
|
|
|
case DRM_FORMAT_YUV420:
|
|
|
|
|
case DRM_FORMAT_YUV422:
|
|
|
|
|
case DRM_FORMAT_YUV444: return true;
|
|
|
|
|
default: return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
bool NFormatUtils::isFormatOpaque(DRMFormat drm) {
|
|
|
|
|
const auto FMT = NFormatUtils::getPixelFormatFromDRM(drm);
|
2024-06-08 10:07:59 +02:00
|
|
|
if (!FMT)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return !FMT->withAlpha;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
int NFormatUtils::pixelsPerBlock(const SPixelFormat* const fmt) {
|
2024-06-08 10:07:59 +02:00
|
|
|
return fmt->blockSize.x * fmt->blockSize.y > 0 ? fmt->blockSize.x * fmt->blockSize.y : 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
int NFormatUtils::minStride(const SPixelFormat* const fmt, int32_t width) {
|
2024-06-08 10:07:59 +02:00
|
|
|
return std::ceil((width * fmt->bytesPerBlock) / pixelsPerBlock(fmt));
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
std::string NFormatUtils::drmFormatName(DRMFormat drm) {
|
2026-02-28 16:29:22 +01:00
|
|
|
auto n = drmGetFormatName(drm);
|
|
|
|
|
|
|
|
|
|
if (!n)
|
|
|
|
|
return "unknown";
|
|
|
|
|
|
2024-07-21 13:09:54 +02:00
|
|
|
std::string name = n;
|
2025-09-29 15:10:15 +03:00
|
|
|
free(n); // NOLINT(cppcoreguidelines-no-malloc,-warnings-as-errors)
|
2024-07-21 13:09:54 +02:00
|
|
|
return name;
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-07 18:51:18 +01:00
|
|
|
std::string NFormatUtils::drmModifierName(uint64_t mod) {
|
2026-02-28 16:29:22 +01:00
|
|
|
auto n = drmGetFormatModifierName(mod);
|
|
|
|
|
|
|
|
|
|
if (!n)
|
|
|
|
|
return "unknown";
|
|
|
|
|
|
2024-07-21 13:09:54 +02:00
|
|
|
std::string name = n;
|
2025-09-29 15:10:15 +03:00
|
|
|
free(n); // NOLINT(cppcoreguidelines-no-malloc,-warnings-as-errors)
|
2024-07-21 13:09:54 +02:00
|
|
|
return name;
|
|
|
|
|
}
|
2026-01-21 01:32:32 +11:00
|
|
|
|
|
|
|
|
DRMFormat NFormatUtils::alphaFormat(DRMFormat prevFormat) {
|
|
|
|
|
switch (prevFormat) {
|
|
|
|
|
case DRM_FORMAT_XRGB8888: return DRM_FORMAT_ARGB8888;
|
|
|
|
|
case DRM_FORMAT_XBGR8888: return DRM_FORMAT_ABGR8888;
|
|
|
|
|
case DRM_FORMAT_BGRX8888: return DRM_FORMAT_BGRA8888;
|
|
|
|
|
case DRM_FORMAT_RGBX8888: return DRM_FORMAT_RGBA8888;
|
|
|
|
|
case DRM_FORMAT_XRGB2101010: return DRM_FORMAT_ARGB2101010;
|
|
|
|
|
case DRM_FORMAT_XBGR2101010: return DRM_FORMAT_ABGR2101010;
|
|
|
|
|
case DRM_FORMAT_RGBX1010102: return DRM_FORMAT_RGBA1010102;
|
|
|
|
|
case DRM_FORMAT_BGRX1010102: return DRM_FORMAT_BGRA1010102;
|
|
|
|
|
default: return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|