[client] egl: rework egl to accomodate post-processing filtering

This commit is contained in:
Geoffrey McRae
2021-08-09 14:08:10 +10:00
parent 30ad28ffd1
commit 86d6b67337
21 changed files with 793 additions and 183 deletions

View File

@@ -22,6 +22,7 @@
#include "common/debug.h"
#include "common/option.h"
#include "common/locking.h"
#include "common/array.h"
#include "app.h"
#include "texture.h"
@@ -33,6 +34,8 @@
#include <string.h>
// these headers are auto generated by cmake
#include "null.vert.h"
#include "null.frag.h"
#include "desktop.vert.h"
#include "desktop_rgb.frag.h"
#include "desktop_rgb.def.h"
@@ -41,28 +44,26 @@ struct DesktopShader
{
EGL_Shader * shader;
GLint uTransform;
GLint uUVScale;
GLint uDesktopSize;
GLint uScaleAlgo;
GLint uNV, uNVGain;
GLint uNVGain;
GLint uCBMode;
};
struct EGL_Desktop
{
EGL * egl;
EGLDisplay * display;
EGL_Texture * texture;
struct DesktopShader * shader; // the active shader
struct DesktopShader shader;
EGL_DesktopRects * mesh;
CountedBuffer * matrix;
// internals
int width, height;
LG_RendererRotate rotate;
// shader instances
struct DesktopShader shader_generic;
// scale algorithm
int scaleAlgo;
@@ -80,7 +81,7 @@ struct EGL_Desktop
// forwards
void egl_desktop_toggle_nv(int key, void * opaque);
static bool egl_init_desktop_shader(
static bool egl_initDesktopShader(
struct DesktopShader * shader,
const char * vertex_code , size_t vertex_size,
const char * fragment_code, size_t fragment_size
@@ -96,40 +97,37 @@ static bool egl_init_desktop_shader(
return false;
}
egl_shaderAssocTextures(shader->shader, 1);
shader->uTransform = egl_shaderGetUniform(shader->shader, "transform");
shader->uUVScale = egl_shaderGetUniform(shader->shader, "uvScale" );
shader->uDesktopSize = egl_shaderGetUniform(shader->shader, "size" );
shader->uScaleAlgo = egl_shaderGetUniform(shader->shader, "scaleAlgo");
shader->uNV = egl_shaderGetUniform(shader->shader, "nv" );
shader->uNVGain = egl_shaderGetUniform(shader->shader, "nvGain" );
shader->uCBMode = egl_shaderGetUniform(shader->shader, "cbMode" );
return true;
}
bool egl_desktopInit(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA, int maxRects)
bool egl_desktopInit(EGL * egl, EGL_Desktop ** desktop, EGLDisplay * display,
bool useDMA, int maxRects)
{
*desktop = (EGL_Desktop *)malloc(sizeof(EGL_Desktop));
*desktop = (EGL_Desktop *)calloc(1, sizeof(EGL_Desktop));
if (!*desktop)
{
DEBUG_ERROR("Failed to malloc EGL_Desktop");
return false;
}
memset(*desktop, 0, sizeof(EGL_Desktop));
(*desktop)->egl = egl;
(*desktop)->display = display;
if (!egl_textureInit(&(*desktop)->texture, display,
if (!egl_textureInit(egl, &(*desktop)->texture, display,
useDMA ? EGL_TEXTYPE_DMABUF : EGL_TEXTYPE_FRAMEBUFFER, true))
{
DEBUG_ERROR("Failed to initialize the desktop texture");
return false;
}
if (!egl_init_desktop_shader(
&(*desktop)->shader_generic,
if (!egl_initDesktopShader(
&(*desktop)->shader,
b_shader_desktop_vert , b_shader_desktop_vert_size,
b_shader_desktop_rgb_frag, b_shader_desktop_rgb_frag_size))
{
@@ -143,6 +141,13 @@ bool egl_desktopInit(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA,
return false;
}
(*desktop)->matrix = countedBufferNew(6 * sizeof(GLfloat));
if (!(*desktop)->matrix)
{
DEBUG_ERROR("Failed to allocate the desktop matrix buffer");
return false;
}
app_registerKeybind(KEY_N, egl_desktop_toggle_nv, *desktop, "Toggle night vision mode");
(*desktop)->nvMax = option_get_int("egl", "nvGainMax");
@@ -181,9 +186,10 @@ void egl_desktopFree(EGL_Desktop ** desktop)
if (!*desktop)
return;
egl_textureFree (&(*desktop)->texture );
egl_shaderFree (&(*desktop)->shader_generic.shader);
egl_desktopRectsFree(&(*desktop)->mesh );
egl_textureFree (&(*desktop)->texture );
egl_shaderFree (&(*desktop)->shader.shader);
egl_desktopRectsFree(&(*desktop)->mesh );
countedBufferRelease(&(*desktop)->matrix );
free(*desktop);
*desktop = NULL;
@@ -237,22 +243,18 @@ bool egl_desktopSetup(EGL_Desktop * desktop, const LG_RendererFormat format)
{
case FRAME_TYPE_BGRA:
pixFmt = EGL_PF_BGRA;
desktop->shader = &desktop->shader_generic;
break;
case FRAME_TYPE_RGBA:
pixFmt = EGL_PF_RGBA;
desktop->shader = &desktop->shader_generic;
break;
case FRAME_TYPE_RGBA10:
pixFmt = EGL_PF_RGBA10;
desktop->shader = &desktop->shader_generic;
break;
case FRAME_TYPE_RGBA16F:
pixFmt = EGL_PF_RGBA16F;
desktop->shader = &desktop->shader_generic;
break;
default:
@@ -290,7 +292,8 @@ bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dm
desktop->useDMA = false;
egl_textureFree(&desktop->texture);
if (!egl_textureInit(&desktop->texture, desktop->display, EGL_TEXTYPE_FRAMEBUFFER, true))
if (!egl_textureInit(desktop->egl, &desktop->texture, desktop->display,
EGL_TEXTYPE_FRAMEBUFFER, true))
{
DEBUG_ERROR("Failed to initialize the desktop texture");
return false;
@@ -307,9 +310,6 @@ bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType,
LG_RendererRotate rotate, const struct DamageRects * rects)
{
if (!desktop->shader)
return false;
enum EGL_TexStatus status;
if ((status = egl_textureProcess(desktop->texture)) != EGL_TEX_STATUS_OK)
{
@@ -339,28 +339,45 @@ bool egl_desktopRender(EGL_Desktop * desktop, const float x, const float y,
scaleAlgo = desktop->scaleAlgo;
}
float matrix[6];
egl_desktopRectsMatrix(matrix, desktop->width, desktop->height, x, y, scaleX, scaleY, rotate);
egl_desktopRectsMatrix((float *)desktop->matrix->data,
desktop->width, desktop->height, x, y, scaleX, scaleY, rotate);
egl_desktopRectsUpdate(desktop->mesh, rects, desktop->width, desktop->height);
const struct DesktopShader * shader = desktop->shader;
egl_shaderUse(shader->shader);
glUniform1i(shader->uScaleAlgo , scaleAlgo);
glUniform2f(shader->uDesktopSize, desktop->width, desktop->height);
glUniform2f(shader->uUVScale , 1.0f / desktop->width, 1.0f / desktop->height);
glUniformMatrix3x2fv(shader->uTransform, 1, GL_FALSE, matrix);
if (desktop->nvGain)
{
glUniform1i(shader->uNV, 1);
glUniform1f(shader->uNVGain, (float)desktop->nvGain);
}
else
glUniform1i(shader->uNV, 0);
glUniform1i(shader->uCBMode, desktop->cbMode);
egl_textureBind(desktop->texture);
const struct DesktopShader * shader = &desktop->shader;
EGL_Uniform uniforms[] =
{
{
.type = EGL_UNIFORM_TYPE_1I,
.location = shader->uScaleAlgo,
.i = { scaleAlgo },
},
{
.type = EGL_UNIFORM_TYPE_2F,
.location = shader->uDesktopSize,
.f = { desktop->width, desktop->height },
},
{
.type = EGL_UNIFORM_TYPE_M3x2FV,
.location = shader->uTransform,
.m.transpose = GL_FALSE,
.m.v = desktop->matrix
},
{
.type = EGL_UNIFORM_TYPE_1F,
.location = shader->uNVGain,
.f = { (float)desktop->nvGain }
},
{
.type = EGL_UNIFORM_TYPE_1I,
.location = shader->uCBMode,
.f = { desktop->cbMode }
}
};
egl_shaderSetUniforms(shader->shader, uniforms, ARRAY_LENGTH(uniforms));
egl_shaderUse(shader->shader);
egl_desktopRectsRender(desktop->mesh);
glBindTexture(GL_TEXTURE_2D, 0);
return true;