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) {