diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 7576d6c9..c90b85d3 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -62,7 +62,8 @@ set(SOURCES renderers/egl.c renderers/egl/shader.c renderers/egl/texture.c - renderers/egl/model.c + renderers/egl/model.c + renderers/egl/cursor.c fonts/sdl.c ) diff --git a/client/renderers/egl.c b/client/renderers/egl.c index 6967a2ae..01f00eb2 100644 --- a/client/renderers/egl.c +++ b/client/renderers/egl.c @@ -29,6 +29,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "egl/model.h" #include "egl/shader.h" #include "egl/progs.h" +#include "egl/cursor.h" struct Options { @@ -43,7 +44,6 @@ static struct Options defaultOptions = struct Models { struct EGL_Model * desktop; - struct EGL_Model * mouse; struct EGL_Model * fps; }; @@ -52,18 +52,12 @@ struct Shaders struct EGL_Shader * rgba; struct EGL_Shader * bgra; struct EGL_Shader * yuv; - - struct EGL_Shader * mouse; - struct EGL_Shader * mouse_mono; - struct EGL_Shader * fps; }; struct Textures { struct EGL_Texture * desktop; - struct EGL_Texture * mouse; - struct EGL_Texture * mouse_mono; struct EGL_Texture * fps; }; @@ -79,6 +73,8 @@ struct Inst EGLSurface surface; EGLContext context; + EGL_Cursor * cursor; // the mouse cursor + struct Models models; struct Shaders shaders; struct Textures textures; @@ -98,19 +94,8 @@ struct Inst float scaleX , scaleY; GLint uDesktopPos; - bool mouseVisible; - float mouseX, mouseY, mouseW, mouseH; + float mouseWidth , mouseHeight; float mouseScaleX, mouseScaleY; - GLint uMousePos, uMousePosMono; - - LG_Lock mouseLock; - LG_RendererCursor mouseCursor; - int mouseWidth; - int mouseHeight; - int mousePitch; - uint8_t * mouseData; - size_t mouseDataSize; - bool mouseUpdate; const LG_Font * font; LG_FontObj fontObj; @@ -144,7 +129,6 @@ bool egl_create(void ** opaque, const LG_RendererParams params) memcpy(&this->params, ¶ms , sizeof(LG_RendererParams)); memcpy(&this->opt , &defaultOptions, sizeof(struct Options )); - LG_LOCK_INIT(this->mouseLock); this->translateX = 0; this->translateY = 0; this->scaleX = 1.0f; @@ -167,6 +151,7 @@ bool egl_initialize(void * opaque, Uint32 * sdlFlags) SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS , 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES , 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + return true; } @@ -177,24 +162,17 @@ void egl_deinitialize(void * opaque) if (this->font && this->fontObj) this->font->destroy(this->fontObj); + egl_cursor_free(&this->cursor); + egl_model_free (&this->models .desktop ); - egl_model_free (&this->models .mouse ); egl_model_free (&this->models .fps ); egl_shader_free (&this->shaders .rgba ); egl_shader_free (&this->shaders .bgra ); egl_shader_free (&this->shaders .yuv ); - egl_shader_free (&this->shaders .mouse ); - egl_shader_free (&this->shaders .mouse_mono); egl_shader_free (&this->shaders .fps ); egl_texture_free(&this->textures.desktop ); - egl_texture_free(&this->textures.mouse ); - egl_texture_free(&this->textures.mouse_mono); egl_texture_free(&this->textures.fps ); - LG_LOCK_FREE(this->mouseLock); - if (this->mouseData) - free(this->mouseData); - free(this); } @@ -218,35 +196,27 @@ void egl_on_resize(void * opaque, const int width, const int height, const LG_Re this->mouseScaleX = 2.0f / this->format.width ; this->mouseScaleY = 2.0f / this->format.height; - this->mouseW = (this->mouseWidth * (1.0f / this->format.width )) * this->scaleX; - this->mouseH = (this->mouseHeight * (1.0f / this->format.height)) * this->scaleY; + egl_cursor_set_size(this->cursor, + (this->mouseWidth * (1.0f / this->format.width )) * this->scaleX, + (this->mouseHeight * (1.0f / this->format.height)) * this->scaleY + ); } bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data) { struct Inst * this = (struct Inst *)opaque; - - LG_LOCK(this->mouseLock); - this->mouseCursor = cursor; - this->mouseWidth = width; - this->mouseHeight = (cursor == LG_CURSOR_MONOCHROME ? height / 2 : height); - this->mousePitch = pitch; - - this->mouseW = (this->mouseWidth * (1.0f / this->format.width )) * this->scaleX; - this->mouseH = (this->mouseHeight * (1.0f / this->format.height)) * this->scaleY; - - const size_t size = height * pitch; - if (size > this->mouseDataSize) + if (!egl_cursor_set_shape(this->cursor, cursor, width, height, pitch, data)) { - if (this->mouseData) - free(this->mouseData); - this->mouseData = (uint8_t *)malloc(size); - this->mouseDataSize = size; + DEBUG_ERROR("Failed to update the cursor shape"); + return false; } - memcpy(this->mouseData, data, size); - this->mouseUpdate = true; - LG_UNLOCK(this->mouseLock); + this->mouseWidth = width; + this->mouseHeight = height; + egl_cursor_set_size(this->cursor, + (this->mouseWidth * (1.0f / this->format.width )) * this->scaleX, + (this->mouseHeight * (1.0f / this->format.height)) * this->scaleY + ); return true; } @@ -254,9 +224,14 @@ bool egl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int bool egl_on_mouse_event(void * opaque, const bool visible , const int x, const int y) { struct Inst * this = (struct Inst *)opaque; - this->mouseVisible = visible; - this->mouseX = (((float)x * this->mouseScaleX) - 1.0f) * this->scaleX; - this->mouseY = (((float)y * this->mouseScaleY) - 1.0f) * this->scaleY; + + egl_cursor_set_state( + this->cursor, + visible, + (((float)x * this->mouseScaleX) - 1.0f) * this->scaleX, + (((float)y * this->mouseScaleY) - 1.0f) * this->scaleY + ); + return true; } @@ -413,12 +388,6 @@ bool egl_render_startup(void * opaque, SDL_Window * window) if (!egl_shader_init(&this->shaders.yuv)) return false; - if (!egl_shader_init(&this->shaders.mouse)) - return false; - - if (!egl_shader_init(&this->shaders.mouse_mono)) - return false; - if (!egl_shader_init(&this->shaders.fps)) return false; @@ -431,38 +400,21 @@ bool egl_render_startup(void * opaque, SDL_Window * window) if (!egl_shader_compile(this->shaders.yuv, egl_vertex_shader_desktop, sizeof(egl_vertex_shader_desktop), egl_fragment_shader_yuv, sizeof(egl_fragment_shader_yuv))) return false; - if (!egl_shader_compile(this->shaders.mouse, egl_vertex_shader_mouse, sizeof(egl_vertex_shader_mouse), egl_fragment_shader_rgba, sizeof(egl_fragment_shader_rgba))) - return false; - - if (!egl_shader_compile(this->shaders.mouse_mono, egl_vertex_shader_mouse, sizeof(egl_vertex_shader_mouse), egl_fragment_shader_mouse_mono, sizeof(egl_fragment_shader_mouse_mono))) - return false; - if (!egl_shader_compile(this->shaders.fps, egl_vertex_shader_fps, sizeof(egl_vertex_shader_fps), egl_fragment_shader_fps, sizeof(egl_fragment_shader_fps))) return false; - this->uMousePos = egl_shader_get_uniform_location(this->shaders.mouse , "mouse" ); - this->uMousePosMono = egl_shader_get_uniform_location(this->shaders.mouse_mono, "mouse" ); this->uFPSSize = egl_shader_get_uniform_location(this->shaders.fps , "size" ); this->uFPSScreen = egl_shader_get_uniform_location(this->shaders.fps , "screen" ); if (!egl_texture_init(&this->textures.desktop)) return false; - if (!egl_texture_init(&this->textures.mouse)) - return false; - - if (!egl_texture_init(&this->textures.mouse_mono)) - return false; - if (!egl_texture_init(&this->textures.fps)) return false; if (!egl_model_init(&this->models.desktop)) return false; - if (!egl_model_init(&this->models.mouse)) - return false; - if (!egl_model_init(&this->models.fps)) return false; @@ -471,15 +423,18 @@ bool egl_render_startup(void * opaque, SDL_Window * window) egl_model_set_uvs (this->models.desktop, uvs , sizeof(uvs ) / sizeof(GLfloat)); egl_model_set_texture (this->models.desktop, this->textures.desktop); - egl_model_set_verticies(this->models.mouse, square, sizeof(square) / sizeof(GLfloat)); - egl_model_set_uvs (this->models.mouse, uvs , sizeof(uvs ) / sizeof(GLfloat)); - egl_model_set_verticies(this->models.fps, square, sizeof(square) / sizeof(GLfloat)); egl_model_set_uvs (this->models.fps, uvs , sizeof(uvs ) / sizeof(GLfloat)); egl_model_set_texture (this->models.fps, this->textures.fps); eglSwapInterval(this->display, this->opt.vsync ? 1 : 0); + if (!egl_cursor_init(&this->cursor)) + { + DEBUG_ERROR("Failed to initialize the cursor"); + return false; + } + return true; } @@ -487,9 +442,6 @@ bool egl_render(void * opaque, SDL_Window * window) { struct Inst * this = (struct Inst *)opaque; - if (this->mouseUpdate) - update_mouse_shape(this); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -500,32 +452,7 @@ bool egl_render(void * opaque, SDL_Window * window) egl_model_render(this->models.desktop); } - if (this->mouseVisible) - { - egl_shader_use(this->shaders.mouse); - glUniform4f(this->uMousePos, this->mouseX, this->mouseY, this->mouseW, this->mouseH); - if (this->mouseCursor == LG_CURSOR_MONOCHROME) - { - glEnable(GL_BLEND); - glBlendFunc(GL_ZERO, GL_SRC_COLOR); - egl_model_set_texture(this->models.mouse, this->textures.mouse); - egl_model_render(this->models.mouse); - - egl_shader_use(this->shaders.mouse_mono); - glUniform4f(this->uMousePosMono, this->mouseX, this->mouseY, this->mouseW, this->mouseH); - glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO); - egl_model_set_texture(this->models.mouse, this->textures.mouse_mono); - egl_model_render(this->models.mouse); - glDisable(GL_BLEND); - } - else - { - glEnable(GL_BLEND); - glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA); - egl_model_render(this->models.mouse); - glDisable(GL_BLEND); - } - } + egl_cursor_render(this->cursor); if (this->fpsReady) { @@ -606,73 +533,6 @@ void egl_update_fps(void * opaque, const float avgFPS, const float renderFPS) this->font->release(this->fontObj, bmp); } -void update_mouse_shape(struct Inst * this) -{ - LG_LOCK(this->mouseLock); - this->mouseUpdate = false; - - LG_RendererCursor cursor = this->mouseCursor; - int width = this->mouseWidth; - int height = this->mouseHeight; - int pitch = this->mousePitch; - const uint8_t * data = this->mouseData; - - // tmp buffer for masked colour - uint32_t tmp[width * height]; - - switch(cursor) - { - case LG_CURSOR_MASKED_COLOR: - { - for(int i = 0; i < width * height; ++i) - { - const uint32_t c = ((uint32_t *)data)[i]; - tmp[i] = (c & ~0xFF000000) | (c & 0xFF000000 ? 0x0 : 0xFF000000); - } - data = (uint8_t *)tmp; - // fall through to LG_CURSOR_COLOR - // - // technically we should also create an XOR texture from the data but this - // usage seems very rare in modern software. - } - - case LG_CURSOR_COLOR: - { - egl_texture_setup(this->textures.mouse, EGL_PF_BGRA, width, height, width * height * 4, false); - egl_texture_update(this->textures.mouse, data); - egl_model_set_texture(this->models.mouse, this->textures.mouse); - break; - } - - case LG_CURSOR_MONOCHROME: - { - uint32_t and[width * height]; - uint32_t xor[width * height]; - - for(int y = 0; y < height; ++y) - for(int x = 0; x < width; ++x) - { - const uint8_t * srcAnd = data + (pitch * y) + (x / 8); - const uint8_t * srcXor = srcAnd + pitch * height; - const uint8_t mask = 0x80 >> (x % 8); - const uint32_t andMask = (*srcAnd & mask) ? 0xFFFFFFFF : 0xFF000000; - const uint32_t xorMask = (*srcXor & mask) ? 0x00FFFFFF : 0x00000000; - - and[y * width + x] = andMask; - xor[y * width + x] = xorMask; - } - - egl_texture_setup(this->textures.mouse , EGL_PF_BGRA, width, height, width * height * 4, false); - egl_texture_setup(this->textures.mouse_mono, EGL_PF_BGRA, width, height, width * height * 4, false); - egl_texture_update(this->textures.mouse , (uint8_t *)and); - egl_texture_update(this->textures.mouse_mono, (uint8_t *)xor); - break; - } - } - - LG_UNLOCK(this->mouseLock); -} - static void handle_opt_vsync(void * opaque, const char *value) { struct Inst * this = (struct Inst *)opaque; diff --git a/client/renderers/egl/progs.h b/client/renderers/egl/progs.h index a433ad3a..cf0835a9 100644 --- a/client/renderers/egl/progs.h +++ b/client/renderers/egl/progs.h @@ -43,51 +43,6 @@ void main()\ }\ "; -static const char egl_vertex_shader_mouse[] = "\ -#version 300 es\n\ -\ -layout(location = 0) in vec3 vertexPosition_modelspace;\ -layout(location = 1) in vec2 vertexUV;\ -\ -uniform vec4 mouse;\ -\ -out highp vec2 uv;\ -\ -void main()\ -{\ - gl_Position.xyz = vertexPosition_modelspace;\ - gl_Position.w = 1.0;\ - \ - gl_Position.x += 1.0f;\ - gl_Position.y -= 1.0f;\ - \ - gl_Position.x *= mouse.z;\ - gl_Position.y *= mouse.w;\ - \ - gl_Position.x += mouse.x;\ - gl_Position.y -= mouse.y;\ - \ - uv = vertexUV;\ -}\ -"; - -static const char egl_fragment_shader_mouse_mono[] = "\ -#version 300 es\n\ -\ -in highp vec2 uv;\ -out highp vec4 color;\ -\ -uniform sampler2D sampler1;\ - \ -void main()\ -{\ - highp vec4 tmp = texture(sampler1, uv);\ - if (tmp.rgb == vec3(0.0, 0.0, 0.0))\ - discard;\ - color = tmp;\ -}\ -"; - static const char egl_fragment_shader_rgba[] = "\ #version 300 es\n\ \