From ba6f26393f75ecd3cc8d37c7a52726addde9763f Mon Sep 17 00:00:00 2001 From: Quantum Date: Sat, 20 Feb 2021 19:50:59 -0500 Subject: [PATCH] [client] egl: add framework for multiple scaling algorithms This commit fixes the issues with the meaning of useNearest being flipped by removing the variable and use enumerations. We define an enumeration EGL_DesktopScaleType to express the type of scaling needed to be performed: no scaling, upscaling, or downscaling. This is updated when either the frame size or the viewport size changes. Previously, we only updated the useNearest when the frame size changes. The desktop shader can now support an enumeration of scaling algorithms, although only nearest and linear are currently implemented. Like before, nearest is used when not scaling or upscaling, and linear is used when downscaling. --- client/renderers/EGL/desktop.c | 47 ++++++++++---------- client/renderers/EGL/desktop.h | 9 +++- client/renderers/EGL/egl.c | 47 ++++++++++++++++---- client/renderers/EGL/shader/desktop_rgb.frag | 19 +++++--- 4 files changed, 85 insertions(+), 37 deletions(-) diff --git a/client/renderers/EGL/desktop.c b/client/renderers/EGL/desktop.c index 97b4a325..f240bb88 100644 --- a/client/renderers/EGL/desktop.c +++ b/client/renderers/EGL/desktop.c @@ -34,13 +34,16 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "desktop.vert.h" #include "desktop_rgb.frag.h" +#define LG_SCALE_NEAREST 0 +#define LG_SCALE_LINEAR 1 + struct DesktopShader { EGL_Shader * shader; GLint uDesktopPos; GLint uDesktopSize; GLint uRotate; - GLint uNearest; + GLint uScaleAlgo; GLint uNV, uNVGain; GLint uCBMode; }; @@ -87,13 +90,13 @@ static bool egl_init_desktop_shader( return false; } - shader->uDesktopPos = egl_shader_get_uniform_location(shader->shader, "position"); - shader->uDesktopSize = egl_shader_get_uniform_location(shader->shader, "size" ); - shader->uRotate = egl_shader_get_uniform_location(shader->shader, "rotate" ); - shader->uNearest = egl_shader_get_uniform_location(shader->shader, "nearest" ); - shader->uNV = egl_shader_get_uniform_location(shader->shader, "nv" ); - shader->uNVGain = egl_shader_get_uniform_location(shader->shader, "nvGain" ); - shader->uCBMode = egl_shader_get_uniform_location(shader->shader, "cbMode" ); + shader->uDesktopPos = egl_shader_get_uniform_location(shader->shader, "position" ); + 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" ); + shader->uCBMode = egl_shader_get_uniform_location(shader->shader, "cbMode" ); return true; } @@ -241,33 +244,31 @@ 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, const bool nearest, + const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType, LG_RendererRotate rotate) { if (!desktop->shader) return false; - bool useNearest = nearest; - if (!nearest) - { - switch(rotate) - { - case LG_ROTATE_90: - case LG_ROTATE_270: - if (scaleX < 1.0f || scaleY < 1.0f) - useNearest = true; - break; + int scaleAlgo; - default: - break; - } + switch (scaleType) + { + case EGL_DESKTOP_NOSCALE: + case EGL_DESKTOP_UPSCALE: + scaleAlgo = LG_SCALE_NEAREST; + break; + + case EGL_DESKTOP_DOWNSCALE: + scaleAlgo = LG_SCALE_LINEAR; + break; } const struct DesktopShader * shader = desktop->shader; egl_shader_use(shader->shader); glUniform4f(shader->uDesktopPos , x, y, scaleX, scaleY); glUniform1i(shader->uRotate , rotate); - glUniform1i(shader->uNearest , useNearest ? 1 : 0); + glUniform1i(shader->uScaleAlgo , scaleAlgo); glUniform2f(shader->uDesktopSize, desktop->width, desktop->height); if (desktop->nvGain) diff --git a/client/renderers/EGL/desktop.h b/client/renderers/EGL/desktop.h index b603a6cd..d367406b 100644 --- a/client/renderers/EGL/desktop.h +++ b/client/renderers/EGL/desktop.h @@ -25,11 +25,18 @@ Place, Suite 330, Boston, MA 02111-1307 USA typedef struct EGL_Desktop EGL_Desktop; +enum EGL_DesktopScaleType +{ + EGL_DESKTOP_NOSCALE, + EGL_DESKTOP_UPSCALE, + EGL_DESKTOP_DOWNSCALE, +}; + bool egl_desktop_init(EGL_Desktop ** desktop, EGLDisplay * display); void egl_desktop_free(EGL_Desktop ** desktop); bool egl_desktop_setup (EGL_Desktop * desktop, const LG_RendererFormat format, bool useDMA); 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, const bool nearest, + const float scaleX, const float scaleY, enum EGL_DesktopScaleType scaleType, LG_RendererRotate rotate); diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index e1d1e7b9..ca2288bc 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -90,7 +90,9 @@ struct Inst float scaleX , scaleY; float splashRatio; float screenScaleX, screenScaleY; - bool useNearest; + + int viewportWidth, viewportHeight; + enum EGL_DesktopScaleType scaleType; bool cursorVisible; int cursorX , cursorY; @@ -350,6 +352,33 @@ static void egl_calc_mouse_state(struct Inst * this) } } +static void egl_update_scale_type(struct Inst * this) +{ + int width, height; + + switch (this->rotate) + { + case LG_ROTATE_0: + case LG_ROTATE_180: + width = this->format.width; + height = this->format.height; + break; + + case LG_ROTATE_90: + case LG_ROTATE_270: + width = this->format.height; + height = this->format.width; + break; + } + + if (width == this->viewportWidth || height == this->viewportHeight) + this->scaleType = EGL_DESKTOP_NOSCALE; + else if (width > this->viewportWidth || height > this->viewportHeight) + this->scaleType = EGL_DESKTOP_DOWNSCALE; + else + this->scaleType = EGL_DESKTOP_UPSCALE; +} + void egl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect, LG_RendererRotate rotate) { @@ -365,12 +394,15 @@ void egl_on_resize(void * opaque, const int width, const int height, if (destRect.valid) { - this->translateX = 1.0f - (((destRect.w / 2) + destRect.x) * 2) / (float)width; - this->translateY = 1.0f - (((destRect.h / 2) + destRect.y) * 2) / (float)height; - this->scaleX = (float)destRect.w / (float)width; - this->scaleY = (float)destRect.h / (float)height; + this->translateX = 1.0f - (((destRect.w / 2) + destRect.x) * 2) / (float)width; + this->translateY = 1.0f - (((destRect.h / 2) + destRect.y) * 2) / (float)height; + this->scaleX = (float)destRect.w / (float)width; + this->scaleY = (float)destRect.h / (float)height; + this->viewportWidth = destRect.w; + this->viewportHeight = destRect.h; } + egl_update_scale_type(this); egl_calc_mouse_size(this); this->splashRatio = (float)width / (float)height; @@ -436,7 +468,7 @@ bool egl_on_frame_format(void * opaque, const LG_RendererFormat format, bool use } } - this->useNearest = this->width < format.width || this->height < format.height; + egl_update_scale_type(this); return egl_desktop_setup(this->desktop, format, useDMA); } @@ -676,8 +708,7 @@ bool egl_render(void * opaque, LG_RendererRotate rotate) if (this->start && egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX , this->scaleY , - this->useNearest, - rotate)) + this->scaleType , rotate)) { if (!this->waitFadeTime) { diff --git a/client/renderers/EGL/shader/desktop_rgb.frag b/client/renderers/EGL/shader/desktop_rgb.frag index 2fba4a91..45abb8b1 100644 --- a/client/renderers/EGL/shader/desktop_rgb.frag +++ b/client/renderers/EGL/shader/desktop_rgb.frag @@ -1,11 +1,14 @@ #version 300 es +#define LG_SCALE_NEAREST 0 +#define LG_SCALE_LINEAR 1 + in highp vec2 uv; out highp vec4 color; uniform sampler2D sampler1; -uniform int nearest; +uniform int scaleAlgo; uniform highp vec2 size; uniform int rotate; @@ -36,10 +39,16 @@ void main() ruv.y = uv.x; } - if(nearest == 1) - color = texture(sampler1, ruv); - else - color = texelFetch(sampler1, ivec2(ruv * size), 0); + switch (scaleAlgo) + { + case LG_SCALE_NEAREST: + color = texelFetch(sampler1, ivec2(ruv * size), 0); + break; + + case LG_SCALE_LINEAR: + color = texture(sampler1, ruv); + break; + } if (cbMode > 0) {