diff --git a/client/renderers/egl.c b/client/renderers/egl.c index 236e4733..bd693ef5 100644 --- a/client/renderers/egl.c +++ b/client/renderers/egl.c @@ -25,13 +25,16 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "egl_model.h" #include "egl_shader.h" +#include "egl_shader_progs.h" struct Options { + bool vsync; }; static struct Options defaultOptions = { + .vsync = true }; struct Models @@ -226,14 +229,22 @@ bool egl_render_startup(void * opaque, SDL_Window * window) 1.0f, 0.0f }; - if (!egl_shader_init(&this->shaders.desktop) ) return false; - if (!egl_shader_load(this->shaders.desktop, "test.vs", "test.fs")) return false; - if (!egl_model_init(&this->models.desktop) ) return false; + if (!egl_shader_init(&this->shaders.desktop)) + return false; + if (!egl_shader_compile(this->shaders.desktop, + egl_vertex_shader_basic, sizeof(egl_vertex_shader_basic), + egl_fragment_shader_bgra, sizeof(egl_fragment_shader_bgra) + )) + return false; + + if (!egl_model_init(&this->models.desktop)) + return false; egl_model_set_verticies(this->models.desktop, desktop, sizeof(desktop) / sizeof(GLfloat)); egl_model_set_uvs (this->models.desktop, uvs , sizeof(uvs ) / sizeof(GLfloat)); egl_model_set_shader (this->models.desktop, this->shaders.desktop); + eglSwapInterval(this->display, this->opt.vsync ? 1 : 0); return true; } @@ -269,8 +280,23 @@ bool egl_render(void * opaque, SDL_Window * window) return true; } +static void handle_opt_vsync(void * opaque, const char *value) +{ + struct Inst * this = (struct Inst *)opaque; + if (!this) + return; + + this->opt.vsync = LG_RendererValueToBool(value); +} + static LG_RendererOpt egl_options[] = { + { + .name = "vsync", + .desc ="Enable or disable vsync [default: enabled]", + .validator = LG_RendererValidatorBool, + .handler = handle_opt_vsync + } }; struct LG_Renderer LGR_EGL = diff --git a/client/renderers/egl_model.c b/client/renderers/egl_model.c index ab7850cf..926e1fab 100644 --- a/client/renderers/egl_model.c +++ b/client/renderers/egl_model.c @@ -42,7 +42,7 @@ struct EGL_Model bool hasTexture; GLuint texture; - bool hasPBO, pboUpdate; + bool hasPBO; GLuint pbo[2]; int pboIndex; size_t pboWidth, pboHeight; @@ -105,7 +105,7 @@ bool egl_model_init_streaming(EGL_Model * model, size_t width, size_t height, si GL_PIXEL_UNPACK_BUFFER, bufferSize, NULL, - GL_STREAM_DRAW + GL_DYNAMIC_DRAW ); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } @@ -124,24 +124,14 @@ bool egl_model_stream_buffer(EGL_Model * model, const uint8_t * buffer, size_t b if (++model->pboIndex == 2) model->pboIndex = 0; - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, model->pbo[model->pboIndex]); - glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, 0, GL_STREAM_DRAW); - GLubyte * ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); - if (!ptr) - { - DEBUG_ERROR("Failed to map the buffer"); - glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D, egl_model_get_texture_id(model)); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, model->pbo[model->pboIndex]); + glBufferData(GL_PIXEL_UNPACK_BUFFER, bufferSize, 0, GL_DYNAMIC_DRAW); + glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, bufferSize, buffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, model->pboWidth, model->pboHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - return false; - } - - memcpy(ptr, buffer, bufferSize); - - glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); glBindTexture(GL_TEXTURE_2D, 0); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - model->pboUpdate = true; return true; } @@ -210,14 +200,6 @@ void egl_model_render(EGL_Model * model) if (model->shader) glUseProgram(0); - - if (model->pboUpdate) - { - glBindTexture(GL_TEXTURE_2D, egl_model_get_texture_id(model)); - glBindBuffer(GL_PIXEL_UNPACK_BUFFER, model->pbo[model->pboIndex]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, model->pboWidth, model->pboHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0); - model->pboUpdate = false; - } } void egl_model_set_shader(EGL_Model * model, EGL_Shader * shader) diff --git a/client/renderers/egl_shader_progs.h b/client/renderers/egl_shader_progs.h new file mode 100644 index 00000000..fb46385d --- /dev/null +++ b/client/renderers/egl_shader_progs.h @@ -0,0 +1,71 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef _EGL_SHADER_PROGS_H +#define _EGL_SHADER_PROGS_H + +static const char egl_vertex_shader_basic[] = "\ +#version 300 es\n\ +\ +layout(location = 0) in vec3 vertexPosition_modelspace;\ +layout(location = 1) in vec2 vertexUV;\ +\ +out highp vec2 uv;\ +\ +void main()\ +{\ + gl_Position.xyz = vertexPosition_modelspace;\ + gl_Position.w = 1.0;\ +\ + uv = vertexUV;\ +}\ +"; + +static const char egl_fragment_shader_rgba[] = "\ +#version 300 es\ +\ +in highp vec2 uv;\ +out highp vec3 color;\ +\ +uniform sampler2D sampler;\ + \ +void main()\ +{\ + color = texture(sampler, uv).rgb;\ +}\ +"; + +static const char egl_fragment_shader_bgra[] = "\ +#version 300 es\n\ +\ +in highp vec2 uv;\ +out highp vec3 color;\ +\ +uniform sampler2D sampler;\ +\ +void main()\ +{\ + highp vec3 tmp = texture(sampler, uv).rgb;\ + color.r = tmp.b;\ + color.g = tmp.g;\ + color.b = tmp.r;\ +}\ +"; + +#endif \ No newline at end of file