From f9977332a6017e56c98a9711dd7745cac4ed0564 Mon Sep 17 00:00:00 2001 From: Quantum Date: Mon, 2 Aug 2021 20:45:47 -0400 Subject: [PATCH] [client] egl: convert desktop to use desktop_rects --- client/renderers/EGL/desktop.c | 44 +++++++++++--------- client/renderers/EGL/desktop.h | 5 ++- client/renderers/EGL/desktop_rects.c | 39 +++++++++++++++++ client/renderers/EGL/desktop_rects.h | 6 +++ client/renderers/EGL/egl.c | 4 +- client/renderers/EGL/shader/desktop.vert | 19 +++------ client/renderers/EGL/shader/desktop_rgb.frag | 26 +----------- 7 files changed, 83 insertions(+), 60 deletions(-) diff --git a/client/renderers/EGL/desktop.c b/client/renderers/EGL/desktop.c index b414cb55..5986c9e3 100644 --- a/client/renderers/EGL/desktop.c +++ b/client/renderers/EGL/desktop.c @@ -26,7 +26,7 @@ #include "app.h" #include "texture.h" #include "shader.h" -#include "model.h" +#include "desktop_rects.h" #include #include @@ -39,9 +39,9 @@ struct DesktopShader { EGL_Shader * shader; - GLint uDesktopPos; + GLint uTransform; + GLint uUVScale; GLint uDesktopSize; - GLint uRotate; GLint uScaleAlgo; GLint uNV, uNVGain; GLint uCBMode; @@ -53,7 +53,7 @@ struct EGL_Desktop EGL_Texture * texture; struct DesktopShader * shader; // the active shader - EGL_Model * model; + EGL_DesktopRects * mesh; // internals int width, height; @@ -93,9 +93,11 @@ static bool egl_init_desktop_shader( return false; } - shader->uDesktopPos = egl_shader_get_uniform_location(shader->shader, "position" ); + egl_shader_associate_textures(shader->shader, 1); + + shader->uTransform = egl_shader_get_uniform_location(shader->shader, "transform"); + shader->uUVScale = egl_shader_get_uniform_location(shader->shader, "uvScale" ); shader->uDesktopSize = egl_shader_get_uniform_location(shader->shader, "size" ); - shader->uRotate = egl_shader_get_uniform_location(shader->shader, "rotate" ); shader->uScaleAlgo = egl_shader_get_uniform_location(shader->shader, "scaleAlgo"); shader->uNV = egl_shader_get_uniform_location(shader->shader, "nv" ); shader->uNVGain = egl_shader_get_uniform_location(shader->shader, "nvGain" ); @@ -104,7 +106,7 @@ static bool egl_init_desktop_shader( return true; } -bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA) +bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA, int maxRects) { *desktop = (EGL_Desktop *)malloc(sizeof(EGL_Desktop)); if (!*desktop) @@ -132,15 +134,12 @@ bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA) return false; } - if (!egl_model_init(&(*desktop)->model)) + if (!egl_desktopRectsInit(&(*desktop)->mesh, maxRects)) { - DEBUG_ERROR("Failed to initialize the desktop model"); + DEBUG_ERROR("Failed to initialize the desktop mesh"); return false; } - egl_model_set_default((*desktop)->model); - egl_model_set_texture((*desktop)->model, (*desktop)->texture); - app_registerKeybind(KEY_N, egl_desktop_toggle_nv, *desktop, "Toggle night vision mode"); app_registerKeybind(KEY_S, egl_desktop_toggle_scale_algo, *desktop, "Toggle scale algorithm"); @@ -202,9 +201,9 @@ void egl_desktop_free(EGL_Desktop ** desktop) if (!*desktop) return; - egl_texture_free(&(*desktop)->texture ); - egl_shader_free (&(*desktop)->shader_generic.shader); - egl_model_free (&(*desktop)->model ); + egl_texture_free (&(*desktop)->texture ); + egl_shader_free (&(*desktop)->shader_generic.shader); + egl_desktopRectsFree(&(*desktop)->mesh ); free(*desktop); *desktop = NULL; @@ -276,7 +275,7 @@ bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dm bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType, - LG_RendererRotate rotate) + LG_RendererRotate rotate, const struct DamageRects * rects) { if (!desktop->shader) return false; @@ -310,12 +309,16 @@ bool egl_desktop_render(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_desktopRectsUpdate(desktop->mesh, rects, desktop->width, desktop->height); + const struct DesktopShader * shader = desktop->shader; egl_shader_use(shader->shader); - glUniform4f(shader->uDesktopPos , x, y, scaleX, scaleY); - glUniform1i(shader->uRotate , rotate); 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) { @@ -326,6 +329,9 @@ bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, glUniform1i(shader->uNV, 0); glUniform1i(shader->uCBMode, desktop->cbMode); - egl_model_render(desktop->model); + + egl_texture_bind(desktop->texture); + egl_desktopRectsRender(desktop->mesh); + glBindTexture(GL_TEXTURE_2D, 0); return true; } diff --git a/client/renderers/EGL/desktop.h b/client/renderers/EGL/desktop.h index 8fbf0dff..28d6fc0c 100644 --- a/client/renderers/EGL/desktop.h +++ b/client/renderers/EGL/desktop.h @@ -23,6 +23,7 @@ #include #include "interface/renderer.h" +#include "desktop_rects.h" typedef struct EGL_Desktop EGL_Desktop; @@ -36,11 +37,11 @@ enum EGL_DesktopScaleType struct Option; bool egl_desktop_scale_validate(struct Option * opt, const char ** error); -bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA); +bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display, bool useDMA, int maxRects); void egl_desktop_free(EGL_Desktop ** desktop); bool egl_desktop_setup (EGL_Desktop * desktop, const LG_RendererFormat format); bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame, int dmaFd); bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType, - LG_RendererRotate rotate); + LG_RendererRotate rotate, const struct DamageRects * rects); diff --git a/client/renderers/EGL/desktop_rects.c b/client/renderers/EGL/desktop_rects.c index e58f0264..494c68e0 100644 --- a/client/renderers/EGL/desktop_rects.c +++ b/client/renderers/EGL/desktop_rects.c @@ -219,6 +219,45 @@ struct Rect egl_desktopToScreen(const double matrix[6], const struct FrameDamage }; } +void egl_screenToDesktopMatrix(double matrix[6], int frameWidth, int frameHeight, + double translateX, double translateY, double scaleX, double scaleY, LG_RendererRotate rotate, + double windowWidth, double windowHeight) +{ + double inverted[6] = {0}; + egl_desktopToScreenMatrix(inverted, frameWidth, frameHeight, translateX, translateY, + scaleX, scaleY, rotate, windowWidth, windowHeight); + + double det = inverted[0] * inverted[3] - inverted[1] * inverted[2]; + matrix[0] = inverted[3] / det; + matrix[1] = -inverted[1] / det; + matrix[2] = -inverted[2] / det; + matrix[3] = inverted[0] / det; + matrix[4] = (inverted[2] * inverted[5] - inverted[3] * inverted[4]) / det; + matrix[5] = (inverted[1] * inverted[4] - inverted[0] * inverted[5]) / det; +} + +bool egl_screenToDesktop(struct FrameDamageRect * output, const double matrix[6], + const struct Rect * rect, int width, int height) +{ + double x1, y1, x2, y2; + matrixMultiply(matrix, &x1, &y1, rect->x, rect->y); + matrixMultiply(matrix, &x2, &y2, rect->x + rect->w, rect->y + rect->h); + + int x3 = min(x1, x2); + int y3 = min(y1, y2); + int x4 = ceil(max(x1, x2)); + int y4 = ceil(max(y1, y2)); + + if (x4 < 0 || y4 < 0 || x3 >= width || y3 >= height) + return false; + + output->x = max(x3, 0); + output->y = max(y3, 0); + output->width = min(width, x4) - output->x; + output->height = min(height, y4) - output->y; + return true; +} + void egl_desktopRectsRender(EGL_DesktopRects * rects) { if (!rects->count) diff --git a/client/renderers/EGL/desktop_rects.h b/client/renderers/EGL/desktop_rects.h index 7ee38009..f3b6ea96 100644 --- a/client/renderers/EGL/desktop_rects.h +++ b/client/renderers/EGL/desktop_rects.h @@ -42,6 +42,12 @@ void egl_desktopToScreenMatrix(double matrix[6], int frameWidth, int frameHeight double windowWidth, double windowHeight); struct Rect egl_desktopToScreen(const double matrix[6], const struct FrameDamageRect * rect); +void egl_screenToDesktopMatrix(double matrix[6], int frameWidth, int frameHeight, + double translateX, double translateY, double scaleX, double scaleY, LG_RendererRotate rotate, + double windowWidth, double windowHeight); +bool egl_screenToDesktop(struct FrameDamageRect * output, const double matrix[6], + const struct Rect * rect, int width, int height); + void egl_desktopRectsUpdate(EGL_DesktopRects * rects, const struct DamageRects * data, int width, int height); void egl_desktopRectsRender(EGL_DesktopRects * rects); \ No newline at end of file diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index 3ea043d6..890303fe 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -771,7 +771,7 @@ static bool egl_render_startup(void * opaque, bool useDMA) eglSwapInterval(this->display, this->opt.vsync ? 1 : 0); - if (!egl_desktop_init(&this->desktop, this->display, useDMA)) + if (!egl_desktop_init(&this->desktop, this->display, useDMA, 1)) { DEBUG_ERROR("Failed to initialize the desktop"); return false; @@ -833,7 +833,7 @@ static bool egl_render(void * opaque, LG_RendererRotate rotate, const bool newFr if (egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX , this->scaleY , - this->scaleType , rotate)) + this->scaleType , rotate, NULL)) { if (!this->waitFadeTime) { diff --git a/client/renderers/EGL/shader/desktop.vert b/client/renderers/EGL/shader/desktop.vert index 3472a22b..10f13171 100644 --- a/client/renderers/EGL/shader/desktop.vert +++ b/client/renderers/EGL/shader/desktop.vert @@ -1,20 +1,13 @@ #version 300 es -layout(location = 0) in vec3 vertexPosition_modelspace; -layout(location = 1) in vec2 vertexUV; - -uniform vec4 position; - +layout(location = 0) in vec2 vertex; out highp vec2 uv; +uniform highp vec2 uvScale; +uniform mat3x2 transform; + void main() { - gl_Position.xyz = vertexPosition_modelspace; - gl_Position.w = 1.0; - gl_Position.x -= position.x; - gl_Position.y -= position.y; - gl_Position.x *= position.z; - gl_Position.y *= position.w; - - uv = vertexUV; + gl_Position = vec4(transform * vec3(vertex, 1.0), 0.0, 1.0); + uv = vertex * uvScale; } diff --git a/client/renderers/EGL/shader/desktop_rgb.frag b/client/renderers/EGL/shader/desktop_rgb.frag index 51d6db62..c0e7be29 100644 --- a/client/renderers/EGL/shader/desktop_rgb.frag +++ b/client/renderers/EGL/shader/desktop_rgb.frag @@ -12,7 +12,6 @@ uniform sampler2D sampler1; uniform int scaleAlgo; uniform highp vec2 size; -uniform int rotate; uniform int nv; uniform highp float nvGain; @@ -20,35 +19,14 @@ uniform int cbMode; void main() { - highp vec2 ruv; - if (rotate == 0) // 0 - { - ruv = uv; - } - else if (rotate == 1) // 90 - { - ruv.x = uv.y; - ruv.y = -uv.x + 1.0f; - } - else if (rotate == 2) // 180 - { - ruv.x = -uv.x + 1.0f; - ruv.y = -uv.y + 1.0f; - } - else if (rotate == 3) // 270 - { - ruv.x = -uv.y + 1.0f; - ruv.y = uv.x; - } - switch (scaleAlgo) { case EGL_SCALE_NEAREST: - color = texelFetch(sampler1, ivec2(ruv * size), 0); + color = texelFetch(sampler1, ivec2(uv * size), 0); break; case EGL_SCALE_LINEAR: - color = texture(sampler1, ruv); + color = texture(sampler1, uv); break; }