#include "Format.hpp" #include #include "../includes.hpp" #include "debug/log/Logger.hpp" #include "../macros.hpp" #include #include inline const std::vector GLES3_FORMATS = { { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .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}, }, { .drmFormat = DRM_FORMAT_YVYU, .bytesPerBlock = 4, .blockSize = {2, 1}, }, { .drmFormat = DRM_FORMAT_VYUY, .bytesPerBlock = 4, .blockSize = {2, 1}, }, { .drmFormat = DRM_FORMAT_R8, .glInternalFormat = GL_R8, .glFormat = GL_RED, .glType = GL_UNSIGNED_BYTE, .bytesPerBlock = 1, .swizzle = {SWIZZLE_R001}, }, { .drmFormat = DRM_FORMAT_GR88, .glInternalFormat = GL_RG8, .glFormat = GL_RG, .glType = GL_UNSIGNED_BYTE, .bytesPerBlock = 2, .swizzle = {SWIZZLE_RG01}, }, { .drmFormat = DRM_FORMAT_RGB888, .glInternalFormat = GL_RGB8, .glFormat = GL_RGB, .glType = GL_UNSIGNED_BYTE, .bytesPerBlock = 3, .swizzle = {SWIZZLE_BGR1}, }, }; SHMFormat NFormatUtils::drmToShm(DRMFormat drm) { 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; } DRMFormat NFormatUtils::shmToDRM(SHMFormat shm) { 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; } const SPixelFormat* NFormatUtils::getPixelFormatFromDRM(DRMFormat drm) { for (auto const& fmt : GLES3_FORMATS) { if (fmt.drmFormat == drm) return &fmt; } return nullptr; } const SPixelFormat* NFormatUtils::getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha) { for (auto const& fmt : GLES3_FORMATS) { if (fmt.glFormat == sc(glFormat) && fmt.glType == sc(glType) && fmt.withAlpha == alpha) return &fmt; } return nullptr; } 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; } } bool NFormatUtils::isFormatOpaque(DRMFormat drm) { const auto FMT = NFormatUtils::getPixelFormatFromDRM(drm); if (!FMT) return false; return !FMT->withAlpha; } int NFormatUtils::pixelsPerBlock(const SPixelFormat* const fmt) { return fmt->blockSize.x * fmt->blockSize.y > 0 ? fmt->blockSize.x * fmt->blockSize.y : 1; } int NFormatUtils::minStride(const SPixelFormat* const fmt, int32_t width) { return std::ceil((width * fmt->bytesPerBlock) / pixelsPerBlock(fmt)); } std::string NFormatUtils::drmFormatName(DRMFormat drm) { auto n = drmGetFormatName(drm); if (!n) return "unknown"; std::string name = n; free(n); // NOLINT(cppcoreguidelines-no-malloc,-warnings-as-errors) return name; } std::string NFormatUtils::drmModifierName(uint64_t mod) { auto n = drmGetFormatModifierName(mod); if (!n) return "unknown"; std::string name = n; free(n); // NOLINT(cppcoreguidelines-no-malloc,-warnings-as-errors) return name; } 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; } }