[client] seperate frame setup and data events

This commit is contained in:
Geoffrey McRae 2020-10-12 19:43:29 +11:00
parent 7a49f75d95
commit 58ba76a27f
9 changed files with 171 additions and 136 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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
};

View File

@ -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)

View File

@ -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;
}

View File

@ -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})

View File

@ -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
View 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"
};