mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-12 20:27:53 +00:00
[client] egl: RGB24 improvements
This patch performs several changes. * Alters the fourcc codes to types that ignore the alpha channel where possible to allow the gpu to internally use 24-bit formats. * Attempts to use DRM_FORMAT_RGB888 first as some GPUs may support this * If DMABUF is not in use the data is now imported directly as RGB24 without the post-processing shader
This commit is contained in:
parent
8d27d9e2e2
commit
43a3fb0db3
11 changed files with 129 additions and 58 deletions
|
@ -346,11 +346,6 @@ bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format)
|
|||
|
||||
case FRAME_TYPE_RGB_24:
|
||||
pixFmt = EGL_PF_RGB_24;
|
||||
// the data width is correct per the format, but we are going to use a
|
||||
// 32-bit texture to load the data, so we need to alter the width for the
|
||||
// different bpp
|
||||
desktop->format.dataWidth =
|
||||
desktop->format.pitch / 4;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -39,7 +39,8 @@ typedef enum EGL_PixelFormat
|
|||
EGL_PF_RGBA10,
|
||||
EGL_PF_RGBA16F,
|
||||
EGL_PF_BGR_32,
|
||||
EGL_PF_RGB_24
|
||||
EGL_PF_RGB_24,
|
||||
EGL_PF_RGB_24_32
|
||||
}
|
||||
EGL_PixelFormat;
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ static bool egl_filter24bitSetup(EGL_Filter * filter,
|
|||
{
|
||||
EGL_Filter24bit * this = UPCAST(EGL_Filter24bit, filter);
|
||||
|
||||
if (pixFmt != EGL_PF_BGR_32 && pixFmt != EGL_PF_RGB_24)
|
||||
if (pixFmt != EGL_PF_BGR_32 && pixFmt != EGL_PF_RGB_24_32)
|
||||
return false;
|
||||
|
||||
if (this->useDMA != useDMA || this->format != pixFmt)
|
||||
|
|
|
@ -72,7 +72,7 @@ bool egl_framebufferSetup(EGL_Framebuffer * this, enum EGL_PixelFormat pixFmt,
|
|||
}
|
||||
|
||||
GLuint tex;
|
||||
egl_textureGet(this->tex, &tex, NULL, NULL);
|
||||
egl_textureGet(this->tex, &tex, NULL, NULL, NULL);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
|
|
@ -642,7 +642,9 @@ bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
|||
|
||||
//TODO: clean this up
|
||||
GLuint _unused;
|
||||
if (egl_textureGet(tex, &_unused, &sizeX, &sizeY) != EGL_TEX_STATUS_OK)
|
||||
EGL_PixelFormat pixFmt;
|
||||
if (egl_textureGet(tex, &_unused,
|
||||
&sizeX, &sizeY, &pixFmt) != EGL_TEX_STATUS_OK)
|
||||
return false;
|
||||
|
||||
if (atomic_exchange(&this->modified, false))
|
||||
|
@ -677,7 +679,7 @@ bool egl_postProcessRun(EGL_PostProcess * this, EGL_Texture * tex,
|
|||
{
|
||||
egl_filterSetOutputResHint(filter, targetX, targetY);
|
||||
|
||||
if (!egl_filterSetup(filter, tex->format.pixFmt, sizeX, sizeY,
|
||||
if (!egl_filterSetup(filter, pixFmt, sizeX, sizeY,
|
||||
desktopWidth, desktopHeight, useDMA) ||
|
||||
!egl_filterPrepare(filter))
|
||||
continue;
|
||||
|
|
|
@ -92,7 +92,8 @@ typedef struct EGL_TextureOps
|
|||
enum EGL_TexStatus (*process)(EGL_Texture * texture);
|
||||
|
||||
/* get the texture for use */
|
||||
enum EGL_TexStatus (*get)(EGL_Texture * texture, GLuint * tex);
|
||||
enum EGL_TexStatus (*get)(EGL_Texture * texture, GLuint * tex,
|
||||
EGL_PixelFormat * fmt);
|
||||
|
||||
/* bind the texture for use */
|
||||
enum EGL_TexStatus (*bind)(EGL_Texture * texture);
|
||||
|
@ -132,13 +133,15 @@ bool egl_textureUpdateFromDMA(EGL_Texture * texture,
|
|||
enum EGL_TexStatus egl_textureProcess(EGL_Texture * texture);
|
||||
|
||||
static inline EGL_TexStatus egl_textureGet(EGL_Texture * texture, GLuint * tex,
|
||||
unsigned int * sizeX, unsigned int * sizeY)
|
||||
unsigned int * sizeX, unsigned int * sizeY, EGL_PixelFormat * fmt)
|
||||
{
|
||||
if (sizeX)
|
||||
*sizeX = texture->format.width;
|
||||
if (sizeY)
|
||||
*sizeY = texture->format.height;
|
||||
return texture->ops.get(texture, tex);
|
||||
if (fmt)
|
||||
*fmt = texture->format.pixFmt;
|
||||
return texture->ops.get(texture, tex, fmt);
|
||||
}
|
||||
|
||||
enum EGL_TexStatus egl_textureBind(EGL_Texture * texture);
|
||||
|
|
|
@ -132,7 +132,8 @@ EGL_TexStatus egl_texBufferProcess(EGL_Texture * texture)
|
|||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture, GLuint * tex)
|
||||
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture, GLuint * tex,
|
||||
EGL_PixelFormat * fmt)
|
||||
{
|
||||
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||
*tex = this->tex[0];
|
||||
|
@ -260,7 +261,8 @@ EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture)
|
|||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture, GLuint * tex)
|
||||
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture, GLuint * tex,
|
||||
EGL_PixelFormat * fmt)
|
||||
{
|
||||
TextureBuffer * this = UPCAST(TextureBuffer, texture);
|
||||
|
||||
|
@ -298,7 +300,7 @@ EGL_TexStatus egl_texBufferBind(EGL_Texture * texture)
|
|||
GLuint tex;
|
||||
EGL_TexStatus status;
|
||||
|
||||
if ((status = texture->ops.get(texture, &tex)) != EGL_TEX_STATUS_OK)
|
||||
if ((status = texture->ops.get(texture, &tex, NULL)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
|
|
@ -47,7 +47,8 @@ bool egl_texBufferInit(EGL_Texture ** texture_, EGL_TexType type,
|
|||
void egl_texBufferFree(EGL_Texture * texture_);
|
||||
bool egl_texBufferSetup(EGL_Texture * texture_, const EGL_TexSetup * setup);
|
||||
EGL_TexStatus egl_texBufferProcess(EGL_Texture * texture_);
|
||||
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture_, GLuint * tex);
|
||||
EGL_TexStatus egl_texBufferGet(EGL_Texture * texture_, GLuint * tex,
|
||||
EGL_PixelFormat * fmt);
|
||||
EGL_TexStatus egl_texBufferBind(EGL_Texture * texture_);
|
||||
|
||||
bool egl_texBufferStreamInit(EGL_Texture ** texture_, EGL_TexType type,
|
||||
|
@ -55,4 +56,5 @@ bool egl_texBufferStreamInit(EGL_Texture ** texture_, EGL_TexType type,
|
|||
bool egl_texBufferStreamSetup(EGL_Texture * texture_,
|
||||
const EGL_TexSetup * setup);
|
||||
EGL_TexStatus egl_texBufferStreamProcess(EGL_Texture * texture_);
|
||||
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture_, GLuint * tex);
|
||||
EGL_TexStatus egl_texBufferStreamGet(EGL_Texture * texture_, GLuint * tex,
|
||||
EGL_PixelFormat * fmt);
|
||||
|
|
|
@ -37,13 +37,21 @@ typedef struct TexDMABUF
|
|||
TextureBuffer base;
|
||||
|
||||
EGLDisplay display;
|
||||
bool hasImportModifiers;
|
||||
Vector images;
|
||||
|
||||
EGL_PixelFormat pixFmt;
|
||||
unsigned fourcc;
|
||||
unsigned width;
|
||||
GLuint format;
|
||||
}
|
||||
TexDMABUF;
|
||||
|
||||
EGL_TextureOps EGL_TextureDMABUF;
|
||||
|
||||
static bool initDone = false;
|
||||
static bool has24BitSupport = true;
|
||||
static bool hasImportModifiers = true;
|
||||
|
||||
// internal functions
|
||||
|
||||
static void egl_texDMABUFCleanup(EGL_Texture * texture)
|
||||
|
@ -94,9 +102,13 @@ static bool egl_texDMABUFInit(EGL_Texture ** texture, EGL_TexType type,
|
|||
|
||||
this->display = display;
|
||||
|
||||
const char * client_exts = eglQueryString(this->display, EGL_EXTENSIONS);
|
||||
this->hasImportModifiers =
|
||||
util_hasGLExt(client_exts, "EGL_EXT_image_dma_buf_import_modifiers");
|
||||
if (!initDone)
|
||||
{
|
||||
const char * client_exts = eglQueryString(this->display, EGL_EXTENSIONS);
|
||||
hasImportModifiers =
|
||||
util_hasGLExt(client_exts, "EGL_EXT_image_dma_buf_import_modifiers");
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -113,9 +125,18 @@ static void egl_texDMABUFFree(EGL_Texture * texture)
|
|||
free(this);
|
||||
}
|
||||
|
||||
static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup)
|
||||
static bool texDMABUFSetup(EGL_Texture * texture)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
if (texture->format.pixFmt == EGL_PF_RGB_24 && !has24BitSupport)
|
||||
{
|
||||
this->pixFmt = EGL_PF_RGB_24_32;
|
||||
this->width = texture->format.pitch / 4;
|
||||
this->fourcc = DRM_FORMAT_ARGB8888;
|
||||
this->format = GL_BGRA_EXT;
|
||||
}
|
||||
|
||||
egl_texDMABUFCleanup(texture);
|
||||
|
||||
|
@ -126,10 +147,10 @@ static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup
|
|||
glTexImage2D(GL_TEXTURE_EXTERNAL_OES,
|
||||
0,
|
||||
texture->format.intFormat,
|
||||
texture->format.width,
|
||||
this->width,
|
||||
texture->format.height,
|
||||
0,
|
||||
texture->format.format,
|
||||
this->format,
|
||||
texture->format.dataType,
|
||||
NULL);
|
||||
}
|
||||
|
@ -139,6 +160,50 @@ static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool egl_texDMABUFSetup(EGL_Texture * texture, const EGL_TexSetup * setup)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
this->pixFmt = texture->format.pixFmt;
|
||||
this->width = texture->format.width;
|
||||
this->fourcc = texture->format.fourcc;
|
||||
this->format = texture->format.format;
|
||||
|
||||
return texDMABUFSetup(texture);
|
||||
}
|
||||
|
||||
static EGLImage createImage(EGL_Texture * texture, int fd)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
const uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
EGLAttrib attribs[] =
|
||||
{
|
||||
EGL_WIDTH , this->width ,
|
||||
EGL_HEIGHT , texture->format.height,
|
||||
EGL_LINUX_DRM_FOURCC_EXT , this->fourcc,
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT , fd,
|
||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT , 0,
|
||||
EGL_DMA_BUF_PLANE0_PITCH_EXT , texture->format.pitch,
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, (modifier & 0xffffffff),
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, (modifier >> 32),
|
||||
EGL_NONE , EGL_NONE
|
||||
};
|
||||
|
||||
if (!hasImportModifiers)
|
||||
attribs[12] = attribs[13] =
|
||||
attribs[14] = attribs[15] = EGL_NONE;
|
||||
|
||||
return g_egl_dynProcs.eglCreateImage(
|
||||
this->display,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_LINUX_DMA_BUF_EXT,
|
||||
(EGLClientBuffer)NULL,
|
||||
attribs);
|
||||
}
|
||||
|
||||
static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
||||
const EGL_TexUpdate * update)
|
||||
{
|
||||
|
@ -159,30 +224,23 @@ static bool egl_texDMABUFUpdate(EGL_Texture * texture,
|
|||
|
||||
if (unlikely(image == EGL_NO_IMAGE))
|
||||
{
|
||||
const uint64_t modifier = DRM_FORMAT_MOD_LINEAR;
|
||||
EGLAttrib attribs[] =
|
||||
bool setup = false;
|
||||
if (texture->format.pixFmt == EGL_PF_RGB_24 && has24BitSupport)
|
||||
{
|
||||
EGL_WIDTH , texture->format.width ,
|
||||
EGL_HEIGHT , texture->format.height,
|
||||
EGL_LINUX_DRM_FOURCC_EXT , texture->format.fourcc,
|
||||
EGL_DMA_BUF_PLANE0_FD_EXT , update->dmaFD,
|
||||
EGL_DMA_BUF_PLANE0_OFFSET_EXT , 0,
|
||||
EGL_DMA_BUF_PLANE0_PITCH_EXT , texture->format.pitch,
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, (modifier & 0xffffffff),
|
||||
EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, (modifier >> 32),
|
||||
EGL_NONE , EGL_NONE
|
||||
};
|
||||
image = createImage(texture, update->dmaFD);
|
||||
if (image == EGL_NO_IMAGE)
|
||||
{
|
||||
DEBUG_INFO("Using 24-bit in 32-bit for DMA");
|
||||
has24BitSupport = false;
|
||||
setup = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!this->hasImportModifiers)
|
||||
attribs[12] = attribs[13] =
|
||||
attribs[14] = attribs[15] = EGL_NONE;
|
||||
if (!has24BitSupport && setup)
|
||||
texDMABUFSetup(texture);
|
||||
|
||||
image = g_egl_dynProcs.eglCreateImage(
|
||||
this->display,
|
||||
EGL_NO_CONTEXT,
|
||||
EGL_LINUX_DMA_BUF_EXT,
|
||||
(EGLClientBuffer)NULL,
|
||||
attribs);
|
||||
if (image == EGL_NO_IMAGE)
|
||||
image = createImage(texture, update->dmaFD);
|
||||
|
||||
if (unlikely(image == EGL_NO_IMAGE))
|
||||
{
|
||||
|
@ -220,9 +278,12 @@ static EGL_TexStatus egl_texDMABUFProcess(EGL_Texture * texture)
|
|||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex)
|
||||
static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex,
|
||||
EGL_PixelFormat * fmt)
|
||||
{
|
||||
TextureBuffer * parent = UPCAST(TextureBuffer, texture);
|
||||
TexDMABUF * this = UPCAST(TexDMABUF , parent);
|
||||
|
||||
GLsync sync = 0;
|
||||
|
||||
INTERLOCKED_SECTION(parent->copyLock,
|
||||
|
@ -265,6 +326,10 @@ static EGL_TexStatus egl_texDMABUFGet(EGL_Texture * texture, GLuint * tex)
|
|||
}
|
||||
|
||||
*tex = parent->tex[parent->rIndex];
|
||||
|
||||
if (fmt)
|
||||
*fmt = this->pixFmt;
|
||||
|
||||
return EGL_TEX_STATUS_OK;
|
||||
}
|
||||
|
||||
|
@ -273,7 +338,7 @@ static EGL_TexStatus egl_texDMABUFBind(EGL_Texture * texture)
|
|||
GLuint tex;
|
||||
EGL_TexStatus status;
|
||||
|
||||
if ((status = egl_texDMABUFGet(texture, &tex)) != EGL_TEX_STATUS_OK)
|
||||
if ((status = egl_texDMABUFGet(texture, &tex, NULL)) != EGL_TEX_STATUS_OK)
|
||||
return status;
|
||||
|
||||
glBindTexture(GL_TEXTURE_EXTERNAL_OES, tex);
|
||||
|
|
|
@ -48,7 +48,7 @@ bool egl_texUtilGetFormat(const EGL_TexSetup * setup, EGL_TexFormat * fmt)
|
|||
fmt->format = GL_BGRA_EXT;
|
||||
fmt->intFormat = GL_BGRA_EXT;
|
||||
fmt->dataType = GL_UNSIGNED_BYTE;
|
||||
fmt->fourcc = DRM_FORMAT_ARGB8888;
|
||||
fmt->fourcc = DRM_FORMAT_XRGB8888;
|
||||
break;
|
||||
|
||||
case EGL_PF_RGBA:
|
||||
|
@ -56,7 +56,7 @@ bool egl_texUtilGetFormat(const EGL_TexSetup * setup, EGL_TexFormat * fmt)
|
|||
fmt->format = GL_RGBA;
|
||||
fmt->intFormat = GL_RGBA;
|
||||
fmt->dataType = GL_UNSIGNED_BYTE;
|
||||
fmt->fourcc = DRM_FORMAT_ABGR8888;
|
||||
fmt->fourcc = DRM_FORMAT_XBGR8888;
|
||||
break;
|
||||
|
||||
case EGL_PF_RGBA10:
|
||||
|
@ -64,7 +64,7 @@ bool egl_texUtilGetFormat(const EGL_TexSetup * setup, EGL_TexFormat * fmt)
|
|||
fmt->format = GL_RGBA;
|
||||
fmt->intFormat = GL_RGB10_A2;
|
||||
fmt->dataType = GL_UNSIGNED_INT_2_10_10_10_REV;
|
||||
fmt->fourcc = DRM_FORMAT_ABGR2101010;
|
||||
fmt->fourcc = DRM_FORMAT_XBGR2101010;
|
||||
break;
|
||||
|
||||
case EGL_PF_RGBA16F:
|
||||
|
@ -72,16 +72,15 @@ bool egl_texUtilGetFormat(const EGL_TexSetup * setup, EGL_TexFormat * fmt)
|
|||
fmt->format = GL_RGBA;
|
||||
fmt->intFormat = GL_RGBA16F;
|
||||
fmt->dataType = GL_HALF_FLOAT;
|
||||
fmt->fourcc = DRM_FORMAT_ABGR16161616F;
|
||||
fmt->fourcc = DRM_FORMAT_XBGR16161616F;
|
||||
break;
|
||||
|
||||
case EGL_PF_RGB_24:
|
||||
fmt->bpp = 3;
|
||||
fmt->format = GL_BGRA_EXT;
|
||||
fmt->format = GL_RGB;
|
||||
fmt->intFormat = GL_BGRA_EXT;
|
||||
fmt->dataType = GL_UNSIGNED_BYTE;
|
||||
fmt->fourcc = DRM_FORMAT_ARGB8888;
|
||||
fmt->stride = fmt->pitch / 4;
|
||||
fmt->fourcc = DRM_FORMAT_RGB888;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -63,10 +63,12 @@ void egl_texUtilUnmapBuffer(EGL_TexBuffer * buffer);
|
|||
#define fourcc_code(a, b, c, d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
|
||||
((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
|
||||
|
||||
#define DRM_FORMAT_RGB888 fourcc_code('R', 'G', '2', '4')
|
||||
#define DRM_FORMAT_ARGB8888 fourcc_code('A', 'R', '2', '4')
|
||||
#define DRM_FORMAT_ABGR8888 fourcc_code('A', 'B', '2', '4')
|
||||
#define DRM_FORMAT_ABGR2101010 fourcc_code('A', 'B', '3', '0')
|
||||
#define DRM_FORMAT_ABGR16161616F fourcc_code('A', 'B', '4', 'H')
|
||||
#define DRM_FORMAT_XRGB8888 fourcc_code('X', 'R', '2', '4')
|
||||
#define DRM_FORMAT_XBGR8888 fourcc_code('X', 'B', '2', '4')
|
||||
#define DRM_FORMAT_XBGR2101010 fourcc_code('X', 'B', '3', '0')
|
||||
#define DRM_FORMAT_XBGR16161616F fourcc_code('X', 'B', '4', 'H')
|
||||
|
||||
#define DRM_FORMAT_MOD_VENDOR_NONE 0
|
||||
#define fourcc_mod_code(vendor, val) \
|
||||
|
|
Loading…
Reference in a new issue