mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 13:33:40 +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
|
||||
typedef void (* LG_RendererSetup)();
|
||||
|
||||
typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
||||
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
||||
typedef void (* LG_RendererDeInitialize)(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 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_RendererOnFrameEvent)(void * opaque, const LG_RendererFormat format, const FrameBuffer * frame);
|
||||
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
||||
typedef bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
|
||||
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
|
||||
typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params);
|
||||
typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags);
|
||||
typedef void (* LG_RendererDeInitialize )(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 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_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format);
|
||||
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame);
|
||||
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag);
|
||||
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
|
||||
{
|
||||
LG_RendererGetName get_name;
|
||||
LG_RendererSetup setup;
|
||||
|
||||
LG_RendererCreate create;
|
||||
LG_RendererInitialize initialize;
|
||||
LG_RendererDeInitialize deinitialize;
|
||||
LG_RendererOnRestart on_restart;
|
||||
LG_RendererOnResize on_resize;
|
||||
LG_RendererOnMouseShape on_mouse_shape;
|
||||
LG_RendererOnMouseEvent on_mouse_event;
|
||||
LG_RendererOnFrameEvent on_frame_event;
|
||||
LG_RendererOnAlert on_alert;
|
||||
LG_RendererRender render_startup;
|
||||
LG_RendererRender render;
|
||||
LG_RendererUpdateFPS update_fps;
|
||||
LG_RendererCreate create;
|
||||
LG_RendererInitialize initialize;
|
||||
LG_RendererDeInitialize deinitialize;
|
||||
LG_RendererOnRestart on_restart;
|
||||
LG_RendererOnResize on_resize;
|
||||
LG_RendererOnMouseShape on_mouse_shape;
|
||||
LG_RendererOnMouseEvent on_mouse_event;
|
||||
LG_RendererOnFrameFormat on_frame_format;
|
||||
LG_RendererOnFrame on_frame;
|
||||
LG_RendererOnAlert on_alert;
|
||||
LG_RendererRender render_startup;
|
||||
LG_RendererRender render;
|
||||
LG_RendererUpdateFPS update_fps;
|
||||
}
|
||||
LG_Renderer;
|
||||
|
@ -175,60 +175,62 @@ void egl_desktop_free(EGL_Desktop ** desktop)
|
||||
*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;
|
||||
switch(format.type)
|
||||
{
|
||||
case FRAME_TYPE_BGRA:
|
||||
pixFmt = EGL_PF_BGRA;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
case FRAME_TYPE_BGRA:
|
||||
pixFmt = EGL_PF_BGRA;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
|
||||
case FRAME_TYPE_RGBA:
|
||||
pixFmt = EGL_PF_RGBA;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
case FRAME_TYPE_RGBA:
|
||||
pixFmt = EGL_PF_RGBA;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
|
||||
case FRAME_TYPE_RGBA10:
|
||||
pixFmt = EGL_PF_RGBA10;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
case FRAME_TYPE_RGBA10:
|
||||
pixFmt = EGL_PF_RGBA10;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
|
||||
case FRAME_TYPE_RGBA16F:
|
||||
pixFmt = EGL_PF_RGBA16F;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
case FRAME_TYPE_RGBA16F:
|
||||
pixFmt = EGL_PF_RGBA16F;
|
||||
desktop->shader = &desktop->shader_generic;
|
||||
break;
|
||||
|
||||
case FRAME_TYPE_YUV420:
|
||||
pixFmt = EGL_PF_YUV420;
|
||||
desktop->shader = &desktop->shader_yuv;
|
||||
break;
|
||||
case FRAME_TYPE_YUV420:
|
||||
pixFmt = EGL_PF_YUV420;
|
||||
desktop->shader = &desktop->shader_yuv;
|
||||
break;
|
||||
|
||||
default:
|
||||
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");
|
||||
default:
|
||||
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 true;
|
||||
}
|
||||
|
||||
bool egl_desktop_update(EGL_Desktop * desktop, const FrameBuffer * frame)
|
||||
{
|
||||
if (!egl_texture_update_from_frame(desktop->texture, frame))
|
||||
return false;
|
||||
|
||||
|
@ -28,5 +28,6 @@ typedef struct EGL_Desktop EGL_Desktop;
|
||||
bool egl_desktop_init(void * egl, 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);
|
||||
|
@ -308,20 +308,10 @@ bool egl_on_mouse_event(void * opaque, const bool visible, const int x, const in
|
||||
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;
|
||||
const bool sourceChanged = (
|
||||
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;
|
||||
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
||||
|
||||
/* this event runs in a second thread so we need to init it here */
|
||||
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");
|
||||
return false;
|
||||
@ -614,18 +612,19 @@ void egl_update_fps(void * opaque, const float avgUPS, const float avgFPS)
|
||||
|
||||
struct LG_Renderer LGR_EGL =
|
||||
{
|
||||
.get_name = egl_get_name,
|
||||
.setup = egl_setup,
|
||||
.create = egl_create,
|
||||
.initialize = egl_initialize,
|
||||
.deinitialize = egl_deinitialize,
|
||||
.on_restart = egl_on_restart,
|
||||
.on_resize = egl_on_resize,
|
||||
.on_mouse_shape = egl_on_mouse_shape,
|
||||
.on_mouse_event = egl_on_mouse_event,
|
||||
.on_frame_event = egl_on_frame_event,
|
||||
.on_alert = egl_on_alert,
|
||||
.render_startup = egl_render_startup,
|
||||
.render = egl_render,
|
||||
.update_fps = egl_update_fps
|
||||
.get_name = egl_get_name,
|
||||
.setup = egl_setup,
|
||||
.create = egl_create,
|
||||
.initialize = egl_initialize,
|
||||
.deinitialize = egl_deinitialize,
|
||||
.on_restart = egl_on_restart,
|
||||
.on_resize = egl_on_resize,
|
||||
.on_mouse_shape = egl_on_mouse_shape,
|
||||
.on_mouse_event = egl_on_mouse_event,
|
||||
.on_frame_format = egl_on_frame_format,
|
||||
.on_frame = egl_on_frame,
|
||||
.on_alert = egl_on_alert,
|
||||
.render_startup = egl_render_startup,
|
||||
.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;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!this)
|
||||
{
|
||||
DEBUG_ERROR("Invalid opaque pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
LG_LOCK(this->formatLock);
|
||||
if (this->reconfigure)
|
||||
{
|
||||
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;
|
||||
}
|
||||
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
||||
this->reconfigure = true;
|
||||
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);
|
||||
this->frame = frame;
|
||||
@ -829,21 +813,22 @@ static void render_wait(struct Inst * this)
|
||||
|
||||
const LG_Renderer LGR_OpenGL =
|
||||
{
|
||||
.get_name = opengl_get_name,
|
||||
.setup = opengl_setup,
|
||||
.get_name = opengl_get_name,
|
||||
.setup = opengl_setup,
|
||||
|
||||
.create = opengl_create,
|
||||
.initialize = opengl_initialize,
|
||||
.deinitialize = opengl_deinitialize,
|
||||
.on_restart = opengl_on_restart,
|
||||
.on_resize = opengl_on_resize,
|
||||
.on_mouse_shape = opengl_on_mouse_shape,
|
||||
.on_mouse_event = opengl_on_mouse_event,
|
||||
.on_frame_event = opengl_on_frame_event,
|
||||
.on_alert = opengl_on_alert,
|
||||
.render_startup = opengl_render_startup,
|
||||
.render = opengl_render,
|
||||
.update_fps = opengl_update_fps
|
||||
.create = opengl_create,
|
||||
.initialize = opengl_initialize,
|
||||
.deinitialize = opengl_deinitialize,
|
||||
.on_restart = opengl_on_restart,
|
||||
.on_resize = opengl_on_resize,
|
||||
.on_mouse_shape = opengl_on_mouse_shape,
|
||||
.on_mouse_event = opengl_on_mouse_event,
|
||||
.on_frame_format = opengl_on_frame_format,
|
||||
.on_frame = opengl_on_frame,
|
||||
.on_alert = opengl_on_alert,
|
||||
.render_startup = opengl_render_startup,
|
||||
.render = opengl_render,
|
||||
.update_fps = opengl_update_fps
|
||||
};
|
||||
|
||||
static bool _check_gl_error(unsigned int line, const char * name)
|
||||
|
@ -471,6 +471,18 @@ static int frameThread(void * unused)
|
||||
|
||||
formatValid = true;
|
||||
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)
|
||||
@ -485,9 +497,10 @@ static int frameThread(void * unused)
|
||||
}
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ set(COMMON_SOURCES
|
||||
src/stringlist.c
|
||||
src/option.c
|
||||
src/framebuffer.c
|
||||
src/KVMFR.c
|
||||
)
|
||||
|
||||
add_library(lg_common STATIC ${COMMON_SOURCES})
|
||||
|
@ -35,6 +35,8 @@ typedef enum FrameType
|
||||
}
|
||||
FrameType;
|
||||
|
||||
extern const char * FrameTypeStr[FRAME_TYPE_MAX];
|
||||
|
||||
enum
|
||||
{
|
||||
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