renderer/gl: add internal gl formats and reduce internal driver format conversions (#12879)

* format: add internal formats for drm formats

cross referenced with weston and added internal formats and types for a
lot of missing ones. also added a isFormatYUV helper.

* framebuffer: ensure we use right internalformat

ensure we use the right internal format to avoid internal driver
blitting, also since we only attach the GL_STENCIL_ATTACHMENT we might
just aswell only use the GL_STENCIL_INDEX8 to not confuse drivers that
we want a depth aswell.

* texture: use external on yuv or non linear mods

using external makes us use the gpu's internal detiler.
and this is makes intel a lot happier then having to format convert it
to a linear format internally.

* shaders: add external support to CM frag

add external support to CM frag, and correct ext.frag typo.

* formats: remove duplicates and fix a typo in cm.frag

remove duplicate formats and a typo in cm.frag

* formats: add swizzle logic to all formats

add swizzle logic from weston for all formats and use it in shm texture
paths.

* format: more format changes

use monitor drm format instead of forcing something different.

* shader: remove external from cm.frag

drivers want this resolved at compiletime cant use both
samplerExternalOES and sampler2d and then runtime branch it.

* screencopy: swizzle textures in screencopy

swizzle textures in screencopy, to get the right colors when copying.

* screencopy: restore old behaviour

try restore old behaviour before the gles3 format changes.
glReadPixels had the wrong format, so i went to far trying to mitigate
it. should be like before now.
This commit is contained in:
Tom Englund 2026-01-07 19:53:42 +01:00 committed by GitHub
parent a383ca1866
commit 918e2bb9be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 291 additions and 171 deletions

View file

@ -6,158 +6,186 @@
#include <xf86drm.h> #include <xf86drm.h>
#include <drm_fourcc.h> #include <drm_fourcc.h>
/*
DRM formats are LE, while OGL is BE. The two primary formats
will be flipped, so we will set flipRB which will later use swizzle
to flip the red and blue channels.
This will not work on GLES2, but I want to drop support for it one day anyways.
*/
inline const std::vector<SPixelFormat> GLES3_FORMATS = { inline const std::vector<SPixelFormat> GLES3_FORMATS = {
{ {
.drmFormat = DRM_FORMAT_ARGB8888, .drmFormat = DRM_FORMAT_ARGB8888,
.flipRB = true, .glInternalFormat = GL_RGBA8,
.glFormat = GL_RGBA, .glFormat = GL_RGBA,
.glType = GL_UNSIGNED_BYTE, .glType = GL_UNSIGNED_BYTE,
.withAlpha = true, .withAlpha = true,
.alphaStripped = DRM_FORMAT_XRGB8888, .alphaStripped = DRM_FORMAT_XRGB8888,
.bytesPerBlock = 4, .bytesPerBlock = 4,
.swizzle = {SWIZZLE_BGRA},
}, },
{ {
.drmFormat = DRM_FORMAT_XRGB8888, .drmFormat = DRM_FORMAT_XRGB8888,
.flipRB = true, .glInternalFormat = GL_RGBA8,
.glFormat = GL_RGBA, .glFormat = GL_RGBA,
.glType = GL_UNSIGNED_BYTE, .glType = GL_UNSIGNED_BYTE,
.withAlpha = false, .withAlpha = false,
.alphaStripped = DRM_FORMAT_XRGB8888, .alphaStripped = DRM_FORMAT_XRGB8888,
.bytesPerBlock = 4, .bytesPerBlock = 4,
.swizzle = {SWIZZLE_BGR1},
}, },
{ {
.drmFormat = DRM_FORMAT_XBGR8888, .drmFormat = DRM_FORMAT_XBGR8888,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGBA8,
.glType = GL_UNSIGNED_BYTE, .glFormat = GL_RGBA,
.withAlpha = false, .glType = GL_UNSIGNED_BYTE,
.alphaStripped = DRM_FORMAT_XBGR8888, .withAlpha = false,
.bytesPerBlock = 4, .alphaStripped = DRM_FORMAT_XBGR8888,
.bytesPerBlock = 4,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_ABGR8888, .drmFormat = DRM_FORMAT_ABGR8888,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGBA8,
.glType = GL_UNSIGNED_BYTE, .glFormat = GL_RGBA,
.withAlpha = true, .glType = GL_UNSIGNED_BYTE,
.alphaStripped = DRM_FORMAT_XBGR8888, .withAlpha = true,
.bytesPerBlock = 4, .alphaStripped = DRM_FORMAT_XBGR8888,
.bytesPerBlock = 4,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_BGR888, .drmFormat = DRM_FORMAT_BGR888,
.glFormat = GL_RGB, .glInternalFormat = GL_RGB8,
.glType = GL_UNSIGNED_BYTE, .glFormat = GL_RGB,
.withAlpha = false, .glType = GL_UNSIGNED_BYTE,
.alphaStripped = DRM_FORMAT_BGR888, .withAlpha = false,
.bytesPerBlock = 3, .alphaStripped = DRM_FORMAT_BGR888,
.bytesPerBlock = 3,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_RGBX4444, .drmFormat = DRM_FORMAT_RGBX4444,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGBA4,
.glType = GL_UNSIGNED_SHORT_4_4_4_4, .glFormat = GL_RGBA,
.withAlpha = false, .glType = GL_UNSIGNED_SHORT_4_4_4_4,
.alphaStripped = DRM_FORMAT_RGBX4444, .withAlpha = false,
.bytesPerBlock = 2, .alphaStripped = DRM_FORMAT_RGBX4444,
.bytesPerBlock = 2,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_RGBA4444, .drmFormat = DRM_FORMAT_RGBA4444,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGBA4,
.glType = GL_UNSIGNED_SHORT_4_4_4_4, .glFormat = GL_RGBA,
.withAlpha = true, .glType = GL_UNSIGNED_SHORT_4_4_4_4,
.alphaStripped = DRM_FORMAT_RGBX4444, .withAlpha = true,
.bytesPerBlock = 2, .alphaStripped = DRM_FORMAT_RGBX4444,
.bytesPerBlock = 2,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_RGBX5551, .drmFormat = DRM_FORMAT_RGBX5551,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGB5_A1,
.glType = GL_UNSIGNED_SHORT_5_5_5_1, .glFormat = GL_RGBA,
.withAlpha = false, .glType = GL_UNSIGNED_SHORT_5_5_5_1,
.alphaStripped = DRM_FORMAT_RGBX5551, .withAlpha = false,
.bytesPerBlock = 2, .alphaStripped = DRM_FORMAT_RGBX5551,
.bytesPerBlock = 2,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_RGBA5551, .drmFormat = DRM_FORMAT_RGBA5551,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGB5_A1,
.glType = GL_UNSIGNED_SHORT_5_5_5_1, .glFormat = GL_RGBA,
.withAlpha = true, .glType = GL_UNSIGNED_SHORT_5_5_5_1,
.alphaStripped = DRM_FORMAT_RGBX5551, .withAlpha = true,
.bytesPerBlock = 2, .alphaStripped = DRM_FORMAT_RGBX5551,
.bytesPerBlock = 2,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_RGB565, .drmFormat = DRM_FORMAT_RGB565,
.glFormat = GL_RGB, .glInternalFormat = GL_RGB565,
.glType = GL_UNSIGNED_SHORT_5_6_5, .glFormat = GL_RGB,
.withAlpha = false, .glType = GL_UNSIGNED_SHORT_5_6_5,
.alphaStripped = DRM_FORMAT_RGB565, .withAlpha = false,
.bytesPerBlock = 2, .alphaStripped = DRM_FORMAT_RGB565,
.bytesPerBlock = 2,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_XBGR2101010, .drmFormat = DRM_FORMAT_XBGR2101010,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGB10_A2,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV, .glFormat = GL_RGBA,
.withAlpha = false, .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.alphaStripped = DRM_FORMAT_XBGR2101010, .withAlpha = false,
.bytesPerBlock = 4, .alphaStripped = DRM_FORMAT_XBGR2101010,
.bytesPerBlock = 4,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_ABGR2101010, .drmFormat = DRM_FORMAT_ABGR2101010,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGB10_A2,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV, .glFormat = GL_RGBA,
.withAlpha = true, .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.alphaStripped = DRM_FORMAT_XBGR2101010, .withAlpha = true,
.bytesPerBlock = 4, .alphaStripped = DRM_FORMAT_XBGR2101010,
.bytesPerBlock = 4,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_XRGB2101010, .drmFormat = DRM_FORMAT_XRGB2101010,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGB10_A2,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV, .glFormat = GL_RGBA,
.withAlpha = false, .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.alphaStripped = DRM_FORMAT_XRGB2101010, .withAlpha = false,
.bytesPerBlock = 4, .alphaStripped = DRM_FORMAT_XRGB2101010,
.bytesPerBlock = 4,
.swizzle = {SWIZZLE_BGR1},
}, },
{ {
.drmFormat = DRM_FORMAT_ARGB2101010, .drmFormat = DRM_FORMAT_ARGB2101010,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGB10_A2,
.glType = GL_UNSIGNED_INT_2_10_10_10_REV, .glFormat = GL_RGBA,
.withAlpha = true, .glType = GL_UNSIGNED_INT_2_10_10_10_REV,
.alphaStripped = DRM_FORMAT_XRGB2101010, .withAlpha = true,
.bytesPerBlock = 4, .alphaStripped = DRM_FORMAT_XRGB2101010,
.bytesPerBlock = 4,
.swizzle = {SWIZZLE_BGRA},
}, },
{ {
.drmFormat = DRM_FORMAT_XBGR16161616F, .drmFormat = DRM_FORMAT_XBGR16161616F,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGBA16F,
.glType = GL_HALF_FLOAT, .glFormat = GL_RGBA,
.withAlpha = false, .glType = GL_HALF_FLOAT,
.alphaStripped = DRM_FORMAT_XBGR16161616F, .withAlpha = false,
.bytesPerBlock = 8, .alphaStripped = DRM_FORMAT_XBGR16161616F,
.bytesPerBlock = 8,
.swizzle = {SWIZZLE_RGB1},
}, },
{ {
.drmFormat = DRM_FORMAT_ABGR16161616F, .drmFormat = DRM_FORMAT_ABGR16161616F,
.glFormat = GL_RGBA, .glInternalFormat = GL_RGBA16F,
.glType = GL_HALF_FLOAT, .glFormat = GL_RGBA,
.withAlpha = true, .glType = GL_HALF_FLOAT,
.alphaStripped = DRM_FORMAT_XBGR16161616F, .withAlpha = true,
.bytesPerBlock = 8, .alphaStripped = DRM_FORMAT_XBGR16161616F,
.bytesPerBlock = 8,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_XBGR16161616, .drmFormat = DRM_FORMAT_XBGR16161616,
.glFormat = GL_RGBA16UI, .glInternalFormat = GL_RGBA16UI,
.glType = GL_UNSIGNED_SHORT, .glFormat = GL_RGBA_INTEGER,
.withAlpha = false, .glType = GL_UNSIGNED_SHORT,
.alphaStripped = DRM_FORMAT_XBGR16161616, .withAlpha = false,
.bytesPerBlock = 8, .alphaStripped = DRM_FORMAT_XBGR16161616,
.bytesPerBlock = 8,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_ABGR16161616, .drmFormat = DRM_FORMAT_ABGR16161616,
.glFormat = GL_RGBA16UI, .glInternalFormat = GL_RGBA16UI,
.glType = GL_UNSIGNED_SHORT, .glFormat = GL_RGBA_INTEGER,
.withAlpha = true, .glType = GL_UNSIGNED_SHORT,
.alphaStripped = DRM_FORMAT_XBGR16161616, .withAlpha = true,
.bytesPerBlock = 8, .alphaStripped = DRM_FORMAT_XBGR16161616,
.bytesPerBlock = 8,
.swizzle = {SWIZZLE_RGBA},
}, },
{ {
.drmFormat = DRM_FORMAT_YVYU, .drmFormat = DRM_FORMAT_YVYU,
@ -170,24 +198,28 @@ inline const std::vector<SPixelFormat> GLES3_FORMATS = {
.blockSize = {2, 1}, .blockSize = {2, 1},
}, },
{ {
.drmFormat = DRM_FORMAT_R8, .drmFormat = DRM_FORMAT_R8,
.bytesPerBlock = 1, .glInternalFormat = GL_R8,
.glFormat = GL_RED,
.glType = GL_UNSIGNED_BYTE,
.bytesPerBlock = 1,
.swizzle = {SWIZZLE_R001},
}, },
{ {
.drmFormat = DRM_FORMAT_GR88, .drmFormat = DRM_FORMAT_GR88,
.bytesPerBlock = 2, .glInternalFormat = GL_RG8,
.glFormat = GL_RG,
.glType = GL_UNSIGNED_BYTE,
.bytesPerBlock = 2,
.swizzle = {SWIZZLE_RG01},
}, },
{ {
.drmFormat = DRM_FORMAT_RGB888, .drmFormat = DRM_FORMAT_RGB888,
.bytesPerBlock = 3, .glInternalFormat = GL_RGB8,
}, .glFormat = GL_RGB,
{ .glType = GL_UNSIGNED_BYTE,
.drmFormat = DRM_FORMAT_BGR888, .bytesPerBlock = 3,
.bytesPerBlock = 3, .swizzle = {SWIZZLE_BGR1},
},
{
.drmFormat = DRM_FORMAT_RGBX4444,
.bytesPerBlock = 2,
}, },
}; };
@ -229,6 +261,26 @@ const SPixelFormat* NFormatUtils::getPixelFormatFromGL(uint32_t glFormat, uint32
return nullptr; 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) { bool NFormatUtils::isFormatOpaque(DRMFormat drm) {
const auto FMT = NFormatUtils::getPixelFormatFromDRM(drm); const auto FMT = NFormatUtils::getPixelFormatFromDRM(drm);
if (!FMT) if (!FMT)

View file

@ -2,22 +2,43 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <GLES3/gl32.h>
#include "math/Math.hpp" #include "math/Math.hpp"
#include <aquamarine/backend/Misc.hpp> #include <aquamarine/backend/Misc.hpp>
using DRMFormat = uint32_t; using DRMFormat = uint32_t;
using SHMFormat = uint32_t; using SHMFormat = uint32_t;
#define SWIZZLE_A1GB {GL_ALPHA, GL_ONE, GL_GREEN, GL_BLUE}
#define SWIZZLE_ABG1 {GL_ALPHA, GL_BLUE, GL_GREEN, GL_ONE}
#define SWIZZLE_ABGR {GL_ALPHA, GL_BLUE, GL_GREEN, GL_RED}
#define SWIZZLE_ARGB {GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE}
#define SWIZZLE_B1RG {GL_BLUE, GL_ONE, GL_RED, GL_GREEN}
#define SWIZZLE_BARG {GL_BLUE, GL_ALPHA, GL_RED, GL_GREEN}
#define SWIZZLE_BGR1 {GL_BLUE, GL_GREEN, GL_RED, GL_ONE}
#define SWIZZLE_BGRA {GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA}
#define SWIZZLE_G1AB {GL_GREEN, GL_ONE, GL_ALPHA, GL_BLUE}
#define SWIZZLE_GBA1 {GL_GREEN, GL_BLUE, GL_ALPHA, GL_ONE}
#define SWIZZLE_GBAR {GL_GREEN, GL_BLUE, GL_ALPHA, GL_RED}
#define SWIZZLE_GRAB {GL_GREEN, GL_RED, GL_ALPHA, GL_BLUE}
#define SWIZZLE_R001 {GL_RED, GL_ZERO, GL_ZERO, GL_ONE}
#define SWIZZLE_R1BG {GL_RED, GL_ONE, GL_BLUE, GL_GREEN}
#define SWIZZLE_RABG {GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN}
#define SWIZZLE_RG01 {GL_RED, GL_GREEN, GL_ZERO, GL_ONE}
#define SWIZZLE_GR01 {GL_GREEN, GL_RED, GL_ZERO, GL_ONE}
#define SWIZZLE_RGB1 {GL_RED, GL_GREEN, GL_BLUE, GL_ONE}
#define SWIZZLE_RGBA {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}
struct SPixelFormat { struct SPixelFormat {
DRMFormat drmFormat = 0; /* DRM_FORMAT_INVALID */ DRMFormat drmFormat = 0; /* DRM_FORMAT_INVALID */
bool flipRB = false; int glInternalFormat = 0;
int glInternalFormat = 0; int glFormat = 0;
int glFormat = 0; int glType = 0;
int glType = 0; bool withAlpha = true;
bool withAlpha = true; DRMFormat alphaStripped = 0; /* DRM_FORMAT_INVALID */
DRMFormat alphaStripped = 0; /* DRM_FORMAT_INVALID */ uint32_t bytesPerBlock = 0;
uint32_t bytesPerBlock = 0; Vector2D blockSize;
Vector2D blockSize; std::optional<std::array<GLint, 4>> swizzle = std::nullopt;
}; };
using SDRMFormat = Aquamarine::SDRMFormat; using SDRMFormat = Aquamarine::SDRMFormat;
@ -28,6 +49,7 @@ namespace NFormatUtils {
const SPixelFormat* getPixelFormatFromDRM(DRMFormat drm); const SPixelFormat* getPixelFormatFromDRM(DRMFormat drm);
const SPixelFormat* getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha); const SPixelFormat* getPixelFormatFromGL(uint32_t glFormat, uint32_t glType, bool alpha);
bool isFormatYUV(uint32_t drmFormat);
bool isFormatOpaque(DRMFormat drm); bool isFormatOpaque(DRMFormat drm);
int pixelsPerBlock(const SPixelFormat* const fmt); int pixelsPerBlock(const SPixelFormat* const fmt);
int minStride(const SPixelFormat* const fmt, int32_t width); int minStride(const SPixelFormat* const fmt, int32_t width);

View file

@ -192,8 +192,7 @@ void CScreencopyFrame::share() {
} }
void CScreencopyFrame::renderMon() { void CScreencopyFrame::renderMon() {
auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer); auto TEXTURE = makeShared<CTexture>(m_monitor->m_output->state->state().buffer);
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX}; CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
const bool IS_CM_AWARE = PROTO::colorManagement && PROTO::colorManagement->isClientCMAware(m_client->client()); const bool IS_CM_AWARE = PROTO::colorManagement && PROTO::colorManagement->isClientCMAware(m_client->client());
@ -385,8 +384,6 @@ bool CScreencopyFrame::copyShm() {
return false; return false;
} }
auto glFormat = PFORMAT->flipRB ? GL_BGRA_EXT : GL_RGBA;
g_pHyprOpenGL->m_renderData.blockScreenShader = true; g_pHyprOpenGL->m_renderData.blockScreenShader = true;
g_pHyprRenderer->endRender(); g_pHyprRenderer->endRender();
@ -396,8 +393,26 @@ bool CScreencopyFrame::copyShm() {
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
const auto drmFmt = NFormatUtils::getPixelFormatFromDRM(shm.format); uint32_t packStride = NFormatUtils::minStride(PFORMAT, m_box.w);
uint32_t packStride = NFormatUtils::minStride(drmFmt, m_box.w); int glFormat = PFORMAT->glFormat;
if (glFormat == GL_RGBA)
glFormat = GL_BGRA_EXT;
if (glFormat != GL_BGRA_EXT && glFormat != GL_RGB) {
if (PFORMAT->swizzle.has_value()) {
std::array<GLint, 4> RGBA = SWIZZLE_RGBA;
std::array<GLint, 4> BGRA = SWIZZLE_BGRA;
if (PFORMAT->swizzle == RGBA)
glFormat = GL_RGBA;
else if (PFORMAT->swizzle == BGRA)
glFormat = GL_BGRA_EXT;
else {
LOGM(Log::ERR, "Copied frame via shm might be broken or color flipped");
glFormat = GL_RGBA;
}
}
}
// This could be optimized by using a pixel buffer object to make this async, // This could be optimized by using a pixel buffer object to make this async,
// but really clients should just use a dma buffer anyways. // but really clients should just use a dma buffer anyways.

View file

@ -285,8 +285,6 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, outFB.getFBID()); glBindFramebuffer(GL_READ_FRAMEBUFFER, outFB.getFBID());
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
auto glFormat = PFORMAT->flipRB ? GL_BGRA_EXT : GL_RGBA;
auto origin = Vector2D(0, 0); auto origin = Vector2D(0, 0);
switch (PMONITOR->m_transform) { switch (PMONITOR->m_transform) {
case WL_OUTPUT_TRANSFORM_FLIPPED_180: case WL_OUTPUT_TRANSFORM_FLIPPED_180:
@ -308,6 +306,26 @@ bool CToplevelExportFrame::copyShm(const Time::steady_tp& now) {
default: break; default: break;
} }
int glFormat = PFORMAT->glFormat;
if (glFormat == GL_RGBA)
glFormat = GL_BGRA_EXT;
if (glFormat != GL_BGRA_EXT && glFormat != GL_RGB) {
if (PFORMAT->swizzle.has_value()) {
std::array<GLint, 4> RGBA = SWIZZLE_RGBA;
std::array<GLint, 4> BGRA = SWIZZLE_BGRA;
if (PFORMAT->swizzle == RGBA)
glFormat = GL_RGBA;
else if (PFORMAT->swizzle == BGRA)
glFormat = GL_BGRA_EXT;
else {
LOGM(Log::ERR, "Copied frame via shm might be broken or color flipped");
glFormat = GL_RGBA;
}
}
}
glReadPixels(origin.x, origin.y, m_box.width, m_box.height, glFormat, PFORMAT->glType, pixelData); glReadPixels(origin.x, origin.y, m_box.width, m_box.height, glFormat, PFORMAT->glType, pixelData);
if (overlayCursor) { if (overlayCursor) {

View file

@ -9,10 +9,8 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
bool firstAlloc = false; bool firstAlloc = false;
RASSERT((w > 0 && h > 0), "cannot alloc a FB with negative / zero size! (attempted {}x{})", w, h); RASSERT((w > 0 && h > 0), "cannot alloc a FB with negative / zero size! (attempted {}x{})", w, h);
const uint32_t glFormat = NFormatUtils::drmFormatToGL(drmFormat); const bool sizeChanged = (m_size != Vector2D(w, h));
const uint32_t glType = NFormatUtils::glFormatToType(glFormat); const bool formatChanged = (drmFormat != m_drmFormat);
const bool sizeChanged = (m_size != Vector2D(w, h));
const bool formatChanged = (drmFormat != m_drmFormat);
if (!m_tex) { if (!m_tex) {
m_tex = makeShared<CTexture>(); m_tex = makeShared<CTexture>();
@ -32,14 +30,15 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
} }
if (firstAlloc || sizeChanged || formatChanged) { if (firstAlloc || sizeChanged || formatChanged) {
const auto format = NFormatUtils::getPixelFormatFromDRM(drmFormat);
m_tex->bind(); m_tex->bind();
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, w, h, 0, GL_RGBA, glType, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, format->glInternalFormat ? format->glInternalFormat : format->glFormat, w, h, 0, format->glFormat, format->glType, nullptr);
glBindFramebuffer(GL_FRAMEBUFFER, m_fb); glBindFramebuffer(GL_FRAMEBUFFER, m_fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex->m_texID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_tex->m_texID, 0);
if (m_stencilTex) { if (m_stencilTex) {
m_stencilTex->bind(); m_stencilTex->bind();
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX8, w, h, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_stencilTex->m_texID, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_stencilTex->m_texID, 0);
} }
@ -59,9 +58,12 @@ bool CFramebuffer::alloc(int w, int h, uint32_t drmFormat) {
} }
void CFramebuffer::addStencil(SP<CTexture> tex) { void CFramebuffer::addStencil(SP<CTexture> tex) {
if (m_stencilTex == tex)
return;
m_stencilTex = tex; m_stencilTex = tex;
m_stencilTex->bind(); m_stencilTex->bind();
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, m_size.x, m_size.y, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr); glTexImage2D(GL_TEXTURE_2D, 0, GL_STENCIL_INDEX8, m_size.x, m_size.y, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, nullptr);
glBindFramebuffer(GL_FRAMEBUFFER, m_fb); glBindFramebuffer(GL_FRAMEBUFFER, m_fb);

View file

@ -3,13 +3,14 @@
#include "../defines.hpp" #include "../defines.hpp"
#include "../helpers/Format.hpp" #include "../helpers/Format.hpp"
#include "Texture.hpp" #include "Texture.hpp"
#include <drm_fourcc.h>
class CFramebuffer { class CFramebuffer {
public: public:
CFramebuffer(); CFramebuffer();
~CFramebuffer(); ~CFramebuffer();
bool alloc(int w, int h, uint32_t format = GL_RGBA); bool alloc(int w, int h, uint32_t format = DRM_FORMAT_ARGB8888);
void addStencil(SP<CTexture> tex); void addStencil(SP<CTexture> tex);
void bind(); void bind();
void unbind(); void unbind();

View file

@ -73,10 +73,8 @@ void CTexture::createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t strid
setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); setTexParameter(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); setTexParameter(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (format->flipRB) { if (format->swizzle.has_value())
setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE); swizzle(format->swizzle.value());
setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
}
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock)); GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock));
GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format->glInternalFormat ? format->glInternalFormat : format->glFormat, size_.x, size_.y, 0, format->glFormat, format->glType, pixels)); GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format->glInternalFormat ? format->glInternalFormat : format->glFormat, size_.x, size_.y, 0, format->glFormat, format->glType, pixels));
@ -96,10 +94,18 @@ void CTexture::createFromDma(const Aquamarine::SDMABUFAttrs& attrs, void* image)
} }
m_opaque = NFormatUtils::isFormatOpaque(attrs.format); m_opaque = NFormatUtils::isFormatOpaque(attrs.format);
// #TODO external only formats should be external aswell.
// also needs a seperate color shader.
/*if (NFormatUtils::isFormatYUV(attrs.format)) {
m_target = GL_TEXTURE_EXTERNAL_OES;
m_type = TEXTURE_EXTERNAL;
} else {*/
m_target = GL_TEXTURE_2D; m_target = GL_TEXTURE_2D;
m_type = TEXTURE_RGBA;
m_size = attrs.size;
m_type = NFormatUtils::isFormatOpaque(attrs.format) ? TEXTURE_RGBX : TEXTURE_RGBA; m_type = NFormatUtils::isFormatOpaque(attrs.format) ? TEXTURE_RGBX : TEXTURE_RGBA;
//}
m_size = attrs.size;
allocate(); allocate();
m_eglImage = image; m_eglImage = image;
@ -121,10 +127,8 @@ void CTexture::update(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, cons
bind(); bind();
if (format->flipRB) { if (format->swizzle.has_value())
setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE); swizzle(format->swizzle.value());
setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED);
}
damage.copy().intersect(CBox{{}, m_size}).forEachRect([&format, &stride, &pixels](const auto& rect) { damage.copy().intersect(CBox{{}, m_size}).forEachRect([&format, &stride, &pixels](const auto& rect) {
GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock)); GLCALL(glPixelStorei(GL_UNPACK_ROW_LENGTH_EXT, stride / format->bytesPerBlock));
@ -205,3 +209,10 @@ void CTexture::setTexParameter(GLenum pname, GLint param) {
m_cachedStates[idx] = param; m_cachedStates[idx] = param;
GLCALL(glTexParameteri(m_target, pname, param)); GLCALL(glTexParameteri(m_target, pname, param));
} }
void CTexture::swizzle(const std::array<GLint, 4>& colors) {
setTexParameter(GL_TEXTURE_SWIZZLE_R, colors.at(0));
setTexParameter(GL_TEXTURE_SWIZZLE_G, colors.at(1));
setTexParameter(GL_TEXTURE_SWIZZLE_B, colors.at(2));
setTexParameter(GL_TEXTURE_SWIZZLE_A, colors.at(3));
}

View file

@ -37,6 +37,7 @@ class CTexture {
void bind(); void bind();
void unbind(); void unbind();
void setTexParameter(GLenum pname, GLint param); void setTexParameter(GLenum pname, GLint param);
void swizzle(const std::array<GLint, 4>& colors);
eTextureType m_type = TEXTURE_RGBA; eTextureType m_type = TEXTURE_RGBA;
GLenum m_target = GL_TEXTURE_2D; GLenum m_target = GL_TEXTURE_2D;

View file

@ -1,11 +1,9 @@
#version 300 es #version 300 es
//#extension GL_OES_EGL_image_external : require
#extension GL_ARB_shading_language_include : enable #extension GL_ARB_shading_language_include : enable
precision highp float; precision highp float;
in vec2 v_texcoord; in vec2 v_texcoord;
uniform sampler2D tex; uniform sampler2D tex;
//uniform samplerExternalOES texture0;
uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext uniform int texType; // eTextureType: 0 - rgba, 1 - rgbx, 2 - ext
// uniform int skipCM; // uniform int skipCM;
@ -30,8 +28,8 @@ void main() {
vec4 pixColor; vec4 pixColor;
if (texType == 1) if (texType == 1)
pixColor = vec4(texture(tex, v_texcoord).rgb, 1.0); pixColor = vec4(texture(tex, v_texcoord).rgb, 1.0);
// else if (texType == 2) //else if (texType == 2)
// pixColor = texture(texture0, v_texcoord); // discard; // this shouldnt happen.
else // assume rgba else // assume rgba
pixColor = texture(tex, v_texcoord); pixColor = texture(tex, v_texcoord);

View file

@ -5,7 +5,7 @@
precision highp float; precision highp float;
in vec2 v_texcoord; in vec2 v_texcoord;
uniform samplerExternalOES texture0; uniform samplerExternalOES tex;
uniform float alpha; uniform float alpha;
#include "rounding.glsl" #include "rounding.glsl"
@ -20,7 +20,7 @@ uniform vec3 tint;
layout(location = 0) out vec4 fragColor; layout(location = 0) out vec4 fragColor;
void main() { void main() {
vec4 pixColor = texture(texture0, v_texcoord); vec4 pixColor = texture(tex, v_texcoord);
if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) if (discardOpaque == 1 && pixColor[3] * alpha == 1.0)
discard; discard;