mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 14:03:40 +00:00
[client] egl: migrate cursor code into seperate unit
This commit is contained in:
parent
50c460df5a
commit
c23bf6a0c4
@ -63,6 +63,7 @@ set(SOURCES
|
||||
renderers/egl/shader.c
|
||||
renderers/egl/texture.c
|
||||
renderers/egl/model.c
|
||||
renderers/egl/cursor.c
|
||||
fonts/sdl.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;
|
||||
|
@ -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\
|
||||
\
|
||||
|
Loading…
Reference in New Issue
Block a user