mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 13:37:22 +00:00
[client] seperate frame setup and data events
This commit is contained in:
parent
7a49f75d95
commit
58ba76a27f
@ -86,34 +86,36 @@ typedef const char * (* LG_RendererGetName)();
|
|||||||
// called pre-creation to allow the renderer to register any options it might have
|
// called pre-creation to allow the renderer to register any options it might have
|
||||||
typedef void (* LG_RendererSetup)();
|
typedef void (* LG_RendererSetup)();
|
||||||
|
|
||||||
typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
||||||
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
||||||
typedef void (* LG_RendererDeInitialize)(void * opaque);
|
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
||||||
typedef void (* LG_RendererOnRestart )(void * opaque);
|
typedef void (* LG_RendererOnRestart )(void * opaque);
|
||||||
typedef void (* LG_RendererOnResize )(void * opaque, const int width, const int height, const LG_RendererRect destRect);
|
typedef void (* LG_RendererOnResize )(void * opaque, const int width, const int height, const LG_RendererRect destRect);
|
||||||
typedef bool (* LG_RendererOnMouseShape)(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data);
|
typedef bool (* LG_RendererOnMouseShape )(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data);
|
||||||
typedef bool (* LG_RendererOnMouseEvent)(void * opaque, const bool visible , const int x, const int y);
|
typedef bool (* LG_RendererOnMouseEvent )(void * opaque, const bool visible , const int x, const int y);
|
||||||
typedef bool (* LG_RendererOnFrameEvent)(void * opaque, const LG_RendererFormat format, const FrameBuffer * frame);
|
typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format);
|
||||||
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame);
|
||||||
typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
|
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
||||||
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
|
typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
|
||||||
|
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
|
||||||
|
|
||||||
typedef struct LG_Renderer
|
typedef struct LG_Renderer
|
||||||
{
|
{
|
||||||
LG_RendererGetName get_name;
|
LG_RendererGetName get_name;
|
||||||
LG_RendererSetup setup;
|
LG_RendererSetup setup;
|
||||||
|
|
||||||
LG_RendererCreate create;
|
LG_RendererCreate create;
|
||||||
LG_RendererInitialize initialize;
|
LG_RendererInitialize initialize;
|
||||||
LG_RendererDeInitialize deinitialize;
|
LG_RendererDeInitialize deinitialize;
|
||||||
LG_RendererOnRestart on_restart;
|
LG_RendererOnRestart on_restart;
|
||||||
LG_RendererOnResize on_resize;
|
LG_RendererOnResize on_resize;
|
||||||
LG_RendererOnMouseShape on_mouse_shape;
|
LG_RendererOnMouseShape on_mouse_shape;
|
||||||
LG_RendererOnMouseEvent on_mouse_event;
|
LG_RendererOnMouseEvent on_mouse_event;
|
||||||
LG_RendererOnFrameEvent on_frame_event;
|
LG_RendererOnFrameFormat on_frame_format;
|
||||||
LG_RendererOnAlert on_alert;
|
LG_RendererOnFrame on_frame;
|
||||||
LG_RendererRender render_startup;
|
LG_RendererOnAlert on_alert;
|
||||||
LG_RendererRender render;
|
LG_RendererRender render_startup;
|
||||||
LG_RendererUpdateFPS update_fps;
|
LG_RendererRender render;
|
||||||
|
LG_RendererUpdateFPS update_fps;
|
||||||
}
|
}
|
||||||
LG_Renderer;
|
LG_Renderer;
|
||||||
|
@ -175,60 +175,62 @@ void egl_desktop_free(EGL_Desktop ** desktop)
|
|||||||
*desktop = NULL;
|
*desktop = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_desktop_update(EGL_Desktop * desktop, const bool sourceChanged, const LG_RendererFormat format, const FrameBuffer * frame)
|
bool egl_desktop_setup(EGL_Desktop * desktop, const LG_RendererFormat format)
|
||||||
{
|
{
|
||||||
if (sourceChanged)
|
enum EGL_PixelFormat pixFmt;
|
||||||
|
switch(format.type)
|
||||||
{
|
{
|
||||||
enum EGL_PixelFormat pixFmt;
|
case FRAME_TYPE_BGRA:
|
||||||
switch(format.type)
|
pixFmt = EGL_PF_BGRA;
|
||||||
{
|
desktop->shader = &desktop->shader_generic;
|
||||||
case FRAME_TYPE_BGRA:
|
break;
|
||||||
pixFmt = EGL_PF_BGRA;
|
|
||||||
desktop->shader = &desktop->shader_generic;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA:
|
case FRAME_TYPE_RGBA:
|
||||||
pixFmt = EGL_PF_RGBA;
|
pixFmt = EGL_PF_RGBA;
|
||||||
desktop->shader = &desktop->shader_generic;
|
desktop->shader = &desktop->shader_generic;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA10:
|
case FRAME_TYPE_RGBA10:
|
||||||
pixFmt = EGL_PF_RGBA10;
|
pixFmt = EGL_PF_RGBA10;
|
||||||
desktop->shader = &desktop->shader_generic;
|
desktop->shader = &desktop->shader_generic;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAME_TYPE_RGBA16F:
|
case FRAME_TYPE_RGBA16F:
|
||||||
pixFmt = EGL_PF_RGBA16F;
|
pixFmt = EGL_PF_RGBA16F;
|
||||||
desktop->shader = &desktop->shader_generic;
|
desktop->shader = &desktop->shader_generic;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FRAME_TYPE_YUV420:
|
case FRAME_TYPE_YUV420:
|
||||||
pixFmt = EGL_PF_YUV420;
|
pixFmt = EGL_PF_YUV420;
|
||||||
desktop->shader = &desktop->shader_yuv;
|
desktop->shader = &desktop->shader_yuv;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG_ERROR("Unsupported frame format");
|
DEBUG_ERROR("Unsupported frame format");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
desktop->width = format.width;
|
|
||||||
desktop->height = format.height;
|
|
||||||
|
|
||||||
if (!egl_texture_setup(
|
|
||||||
desktop->texture,
|
|
||||||
pixFmt,
|
|
||||||
format.width,
|
|
||||||
format.height,
|
|
||||||
format.pitch,
|
|
||||||
true // streaming texture
|
|
||||||
))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to setup the desktop texture");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
desktop->width = format.width;
|
||||||
|
desktop->height = format.height;
|
||||||
|
|
||||||
|
if (!egl_texture_setup(
|
||||||
|
desktop->texture,
|
||||||
|
pixFmt,
|
||||||
|
format.width,
|
||||||
|
format.height,
|
||||||
|
format.pitch,
|
||||||
|
true // streaming texture
|
||||||
|
))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to setup the desktop texture");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame)
|
||||||
|
{
|
||||||
if (!egl_texture_update_from_frame(desktop->texture, frame))
|
if (!egl_texture_update_from_frame(desktop->texture, frame))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -28,5 +28,6 @@ typedef struct EGL_Desktop EGL_Desktop;
|
|||||||
bool egl_desktop_init(void * egl, EGL_Desktop ** desktop);
|
bool egl_desktop_init(void * egl, EGL_Desktop ** desktop);
|
||||||
void egl_desktop_free(EGL_Desktop ** desktop);
|
void egl_desktop_free(EGL_Desktop ** desktop);
|
||||||
|
|
||||||
bool egl_desktop_update(EGL_Desktop * desktop, const bool sourceChanged, const LG_RendererFormat format, const FrameBuffer * frame);
|
bool egl_desktop_setup (EGL_Desktop * desktop, const LG_RendererFormat format);
|
||||||
|
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame);
|
||||||
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest);
|
bool egl_desktop_render(EGL_Desktop * desktop, const float x, const float y, const float scaleX, const float scaleY, const bool nearest);
|
||||||
|
@ -308,20 +308,10 @@ bool egl_on_mouse_event(void * opaque, const bool visible, const int x, const in
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_on_frame_event(void * opaque, const LG_RendererFormat format, const FrameBuffer * frame)
|
bool egl_on_frame_format(void * opaque, const LG_RendererFormat format)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
const bool sourceChanged = (
|
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
||||||
this->format.type != format.type ||
|
|
||||||
this->format.width != format.width ||
|
|
||||||
this->format.height != format.height ||
|
|
||||||
this->format.pitch != format.pitch
|
|
||||||
);
|
|
||||||
|
|
||||||
if (sourceChanged)
|
|
||||||
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
|
||||||
|
|
||||||
this->useNearest = this->width < format.width || this->height < format.height;
|
|
||||||
|
|
||||||
/* this event runs in a second thread so we need to init it here */
|
/* this event runs in a second thread so we need to init it here */
|
||||||
if (!this->frameContext)
|
if (!this->frameContext)
|
||||||
@ -344,7 +334,15 @@ bool egl_on_frame_event(void * opaque, const LG_RendererFormat format, const Fra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!egl_desktop_update(this->desktop, sourceChanged, format, frame))
|
this->useNearest = this->width < format.width || this->height < format.height;
|
||||||
|
return egl_desktop_setup(this->desktop, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool egl_on_frame(void * opaque, const FrameBuffer * frame)
|
||||||
|
{
|
||||||
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
|
if (!egl_desktop_update(this->desktop, frame))
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Failed to to update the desktop");
|
DEBUG_INFO("Failed to to update the desktop");
|
||||||
return false;
|
return false;
|
||||||
@ -614,18 +612,19 @@ void egl_update_fps(void * opaque, const float avgUPS, const float avgFPS)
|
|||||||
|
|
||||||
struct LG_Renderer LGR_EGL =
|
struct LG_Renderer LGR_EGL =
|
||||||
{
|
{
|
||||||
.get_name = egl_get_name,
|
.get_name = egl_get_name,
|
||||||
.setup = egl_setup,
|
.setup = egl_setup,
|
||||||
.create = egl_create,
|
.create = egl_create,
|
||||||
.initialize = egl_initialize,
|
.initialize = egl_initialize,
|
||||||
.deinitialize = egl_deinitialize,
|
.deinitialize = egl_deinitialize,
|
||||||
.on_restart = egl_on_restart,
|
.on_restart = egl_on_restart,
|
||||||
.on_resize = egl_on_resize,
|
.on_resize = egl_on_resize,
|
||||||
.on_mouse_shape = egl_on_mouse_shape,
|
.on_mouse_shape = egl_on_mouse_shape,
|
||||||
.on_mouse_event = egl_on_mouse_event,
|
.on_mouse_event = egl_on_mouse_event,
|
||||||
.on_frame_event = egl_on_frame_event,
|
.on_frame_format = egl_on_frame_format,
|
||||||
.on_alert = egl_on_alert,
|
.on_frame = egl_on_frame,
|
||||||
.render_startup = egl_render_startup,
|
.on_alert = egl_on_alert,
|
||||||
.render = egl_render,
|
.render_startup = egl_render_startup,
|
||||||
.update_fps = egl_update_fps
|
.render = egl_render,
|
||||||
|
.update_fps = egl_update_fps
|
||||||
};
|
};
|
||||||
|
@ -375,36 +375,20 @@ bool opengl_on_mouse_event(void * opaque, const bool visible, const int x, const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opengl_on_frame_event(void * opaque, const LG_RendererFormat format, const FrameBuffer * frame)
|
bool opengl_on_frame_format(void * opaque, const LG_RendererFormat format)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
if (!this)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Invalid opaque pointer");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
LG_LOCK(this->formatLock);
|
LG_LOCK(this->formatLock);
|
||||||
if (this->reconfigure)
|
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
||||||
{
|
this->reconfigure = true;
|
||||||
LG_UNLOCK(this->formatLock);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this->configured ||
|
|
||||||
this->format.type != format.type ||
|
|
||||||
this->format.width != format.width ||
|
|
||||||
this->format.height != format.height ||
|
|
||||||
this->format.stride != format.stride ||
|
|
||||||
this->format.bpp != format.bpp
|
|
||||||
)
|
|
||||||
{
|
|
||||||
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
|
||||||
this->reconfigure = true;
|
|
||||||
LG_UNLOCK(this->formatLock);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
LG_UNLOCK(this->formatLock);
|
LG_UNLOCK(this->formatLock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool opengl_on_frame(void * opaque, const FrameBuffer * frame)
|
||||||
|
{
|
||||||
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
LG_LOCK(this->syncLock);
|
LG_LOCK(this->syncLock);
|
||||||
this->frame = frame;
|
this->frame = frame;
|
||||||
@ -829,21 +813,22 @@ static void render_wait(struct Inst * this)
|
|||||||
|
|
||||||
const LG_Renderer LGR_OpenGL =
|
const LG_Renderer LGR_OpenGL =
|
||||||
{
|
{
|
||||||
.get_name = opengl_get_name,
|
.get_name = opengl_get_name,
|
||||||
.setup = opengl_setup,
|
.setup = opengl_setup,
|
||||||
|
|
||||||
.create = opengl_create,
|
.create = opengl_create,
|
||||||
.initialize = opengl_initialize,
|
.initialize = opengl_initialize,
|
||||||
.deinitialize = opengl_deinitialize,
|
.deinitialize = opengl_deinitialize,
|
||||||
.on_restart = opengl_on_restart,
|
.on_restart = opengl_on_restart,
|
||||||
.on_resize = opengl_on_resize,
|
.on_resize = opengl_on_resize,
|
||||||
.on_mouse_shape = opengl_on_mouse_shape,
|
.on_mouse_shape = opengl_on_mouse_shape,
|
||||||
.on_mouse_event = opengl_on_mouse_event,
|
.on_mouse_event = opengl_on_mouse_event,
|
||||||
.on_frame_event = opengl_on_frame_event,
|
.on_frame_format = opengl_on_frame_format,
|
||||||
.on_alert = opengl_on_alert,
|
.on_frame = opengl_on_frame,
|
||||||
.render_startup = opengl_render_startup,
|
.on_alert = opengl_on_alert,
|
||||||
.render = opengl_render,
|
.render_startup = opengl_render_startup,
|
||||||
.update_fps = opengl_update_fps
|
.render = opengl_render,
|
||||||
|
.update_fps = opengl_update_fps
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool _check_gl_error(unsigned int line, const char * name)
|
static bool _check_gl_error(unsigned int line, const char * name)
|
||||||
|
@ -471,6 +471,18 @@ static int frameThread(void * unused)
|
|||||||
|
|
||||||
formatValid = true;
|
formatValid = true;
|
||||||
formatVer = frame->formatVer;
|
formatVer = frame->formatVer;
|
||||||
|
|
||||||
|
DEBUG_INFO("Format: %s %ux%u %u %u",
|
||||||
|
FrameTypeStr[frame->type],
|
||||||
|
frame->width, frame->height,
|
||||||
|
frame->stride, frame->pitch);
|
||||||
|
|
||||||
|
if (!state.lgr->on_frame_format(state.lgrData, lgrFormat))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("renderer failed to configure format");
|
||||||
|
state.state = APP_STATE_SHUTDOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lgrFormat.width != state.srcSize.x || lgrFormat.height != state.srcSize.y)
|
if (lgrFormat.width != state.srcSize.x || lgrFormat.height != state.srcSize.y)
|
||||||
@ -485,9 +497,10 @@ static int frameThread(void * unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
|
FrameBuffer * fb = (FrameBuffer *)(((uint8_t*)frame) + frame->offset);
|
||||||
if (!state.lgr->on_frame_event(state.lgrData, lgrFormat, fb))
|
if (!state.lgr->on_frame(state.lgrData, fb))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("renderer on frame event returned failure");
|
lgmpClientMessageDone(queue);
|
||||||
|
DEBUG_ERROR("renderer on frame returned failure");
|
||||||
state.state = APP_STATE_SHUTDOWN;
|
state.state = APP_STATE_SHUTDOWN;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ set(COMMON_SOURCES
|
|||||||
src/stringlist.c
|
src/stringlist.c
|
||||||
src/option.c
|
src/option.c
|
||||||
src/framebuffer.c
|
src/framebuffer.c
|
||||||
|
src/KVMFR.c
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(lg_common STATIC ${COMMON_SOURCES})
|
add_library(lg_common STATIC ${COMMON_SOURCES})
|
||||||
|
@ -35,6 +35,8 @@ typedef enum FrameType
|
|||||||
}
|
}
|
||||||
FrameType;
|
FrameType;
|
||||||
|
|
||||||
|
extern const char * FrameTypeStr[FRAME_TYPE_MAX];
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
CURSOR_FLAG_POSITION = 0x1,
|
CURSOR_FLAG_POSITION = 0x1,
|
||||||
|
30
common/src/KVMFR.c
Normal file
30
common/src/KVMFR.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
KVMGFX Client - A KVM Client for VGA Passthrough
|
||||||
|
Copyright (C) 2017-2020 Geoffrey McRae <geoff@hostfission.com>
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/KVMFR.h"
|
||||||
|
|
||||||
|
const char * FrameTypeStr[FRAME_TYPE_MAX] =
|
||||||
|
{
|
||||||
|
"FRAME_TYPE_INVALID",
|
||||||
|
"FRAME_TYPE_BGRA",
|
||||||
|
"FRAME_TYPE_RGBA",
|
||||||
|
"FRAME_TYPE_RGBA10",
|
||||||
|
"FRAME_TYPE_RGBA16F",
|
||||||
|
"FRAME_TYPE_YUV420"
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user