[client] egl: implement pixel perfect upscaling

This commit is contained in:
Geoffrey McRae 2019-04-19 11:23:51 +10:00
parent 6f77ba8aea
commit ba50fbdc3e
6 changed files with 51 additions and 17 deletions

View file

@ -1 +1 @@
a12-157-g972ff93e6c+1 a12-158-g6f77ba8aea+1

View file

@ -47,6 +47,8 @@ struct EGL_Desktop
// uniforms // uniforms
GLint uDesktopPos; GLint uDesktopPos;
GLint uDesktopSize;
GLint uNearest;
GLint uNV, uNVGain; GLint uNV, uNVGain;
// internals // internals
@ -201,6 +203,8 @@ bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
if (desktop->shader) if (desktop->shader)
{ {
desktop->uDesktopPos = egl_shader_get_uniform_location(desktop->shader, "position"); desktop->uDesktopPos = egl_shader_get_uniform_location(desktop->shader, "position");
desktop->uDesktopSize = egl_shader_get_uniform_location(desktop->shader, "size" );
desktop->uNearest = egl_shader_get_uniform_location(desktop->shader, "nearest" );
desktop->uNV = egl_shader_get_uniform_location(desktop->shader, "nv" ); desktop->uNV = egl_shader_get_uniform_location(desktop->shader, "nv" );
desktop->uNVGain = egl_shader_get_uniform_location(desktop->shader, "nvGain" ); desktop->uNVGain = egl_shader_get_uniform_location(desktop->shader, "nvGain" );
} }
@ -232,13 +236,16 @@ bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged)
return true; return true;
} }
void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY) void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest)
{ {
if (!desktop->shader) if (!desktop->shader)
return; return;
egl_shader_use(desktop->shader); egl_shader_use(desktop->shader);
glUniform4f(desktop->uDesktopPos , x, y, scaleX, scaleY); glUniform4f(desktop->uDesktopPos , x, y, scaleX, scaleY);
glUniform1i(desktop->uNearest , nearest ? 1 : 0);
glUniform2f(desktop->uDesktopSize, desktop->width, desktop->height);
if (desktop->nvGain) if (desktop->nvGain)
{ {
glUniform1i(desktop->uNV, 1); glUniform1i(desktop->uNV, 1);

View file

@ -30,4 +30,4 @@ void egl_desktop_free(EGL_Desktop ** desktop);
bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged, const LG_RendererFormat format, const uint8_t * data); bool egl_desktop_prepare_update(EGL_Desktop * desktop, const bool sourceChanged, const LG_RendererFormat format, const uint8_t * data);
bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged); bool egl_desktop_perform_update(EGL_Desktop * desktop, const bool sourceChanged);
void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY); void egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest);

View file

@ -86,6 +86,7 @@ struct Inst
float scaleX , scaleY; float scaleX , scaleY;
float splashRatio; float splashRatio;
float screenScaleX, screenScaleY; float screenScaleX, screenScaleY;
bool useNearest;
float mouseWidth , mouseHeight; float mouseWidth , mouseHeight;
float mouseScaleX, mouseScaleY; float mouseScaleX, mouseScaleY;
@ -239,6 +240,8 @@ bool egl_on_frame_event(void * opaque, const LG_RendererFormat format, const uin
if (this->sourceChanged) if (this->sourceChanged)
memcpy(&this->format, &format, sizeof(LG_RendererFormat)); memcpy(&this->format, &format, sizeof(LG_RendererFormat));
this->useNearest = this->width < format.width || this->height < format.height;
if (!egl_desktop_prepare_update(this->desktop, this->sourceChanged, format, data)) if (!egl_desktop_prepare_update(this->desktop, this->sourceChanged, format, data))
{ {
DEBUG_INFO("Failed to prepare to update the desktop"); DEBUG_INFO("Failed to prepare to update the desktop");
@ -420,7 +423,7 @@ bool egl_render(void * opaque, SDL_Window * window)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX, this->scaleY); egl_desktop_render(this->desktop, this->translateX, this->translateY, this->scaleX, this->scaleY, this->useNearest);
egl_cursor_render(this->cursor); egl_cursor_render(this->cursor);
if (!this->waitDone) if (!this->waitDone)

View file

@ -4,12 +4,19 @@ in highp vec2 uv;
out highp vec4 color; out highp vec4 color;
uniform sampler2D sampler1; uniform sampler2D sampler1;
uniform int nearest;
uniform highp vec2 size;
uniform int nv; uniform int nv;
uniform highp float nvGain; uniform highp float nvGain;
void main() void main()
{ {
if(nearest == 1)
color = texture(sampler1, uv); color = texture(sampler1, uv);
else
color = texelFetch(sampler1, ivec2(uv * size), 0);
if (nv == 1) if (nv == 1)
{ {

View file

@ -3,6 +3,9 @@
in highp vec2 uv; in highp vec2 uv;
out highp vec4 color; out highp vec4 color;
uniform int nearest;
uniform highp vec2 size;
uniform int nv; uniform int nv;
uniform highp float nvGain; uniform highp float nvGain;
@ -12,12 +15,26 @@ uniform sampler2D sampler3;
void main() void main()
{ {
highp vec4 yuv = vec4( highp vec4 yuv;
if(nearest == 1)
{
yuv = vec4(
texture(sampler1, uv).r, texture(sampler1, uv).r,
texture(sampler2, uv).r, texture(sampler2, uv).r,
texture(sampler3, uv).r, texture(sampler3, uv).r,
1.0 1.0
); );
}
else
{
highp ivec2 px = ivec2(uv * size);
yuv = vec4(
texelFetch(sampler1, px, 0).r,
texelFetch(sampler2, px, 0).r,
texelFetch(sampler3, px, 0).r,
1.0
);
}
highp mat4 yuv_to_rgb = mat4( highp mat4 yuv_to_rgb = mat4(
1.0, 0.0 , 1.402, -0.701, 1.0, 0.0 , 1.402, -0.701,