[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

@ -93,7 +93,8 @@ 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 bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame);
typedef void (* LG_RendererOnAlert )(void * opaque, const LG_MsgAlert alert, const char * message, bool ** closeFlag); 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 bool (* LG_RendererRender )(void * opaque, SDL_Window *window);
typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS); typedef void (* LG_RendererUpdateFPS )(void * opaque, const float avgUPS, const float avgFPS);
@ -110,7 +111,8 @@ typedef struct LG_Renderer
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_RendererOnFrame on_frame;
LG_RendererOnAlert on_alert; LG_RendererOnAlert on_alert;
LG_RendererRender render_startup; LG_RendererRender render_startup;
LG_RendererRender render; LG_RendererRender render;

View File

@ -175,9 +175,7 @@ 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; enum EGL_PixelFormat pixFmt;
switch(format.type) switch(format.type)
@ -227,8 +225,12 @@ bool egl_desktop_update(EGL_Desktop * desktop, const bool sourceChanged, const L
DEBUG_ERROR("Failed to setup the desktop texture"); DEBUG_ERROR("Failed to setup the desktop texture");
return false; 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;

View File

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

View File

@ -308,21 +308,11 @@ 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 = (
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)); 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;
@ -623,7 +621,8 @@ struct LG_Renderer LGR_EGL =
.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_frame = egl_on_frame,
.on_alert = egl_on_alert, .on_alert = egl_on_alert,
.render_startup = egl_render_startup, .render_startup = egl_render_startup,
.render = egl_render, .render = egl_render,

View File

@ -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)
{
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)); memcpy(&this->format, &format, sizeof(LG_RendererFormat));
this->reconfigure = true; this->reconfigure = true;
LG_UNLOCK(this->formatLock); LG_UNLOCK(this->formatLock);
return true; return true;
} }
LG_UNLOCK(this->formatLock);
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;
@ -839,7 +823,8 @@ const LG_Renderer LGR_OpenGL =
.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_frame = opengl_on_frame,
.on_alert = opengl_on_alert, .on_alert = opengl_on_alert,
.render_startup = opengl_render_startup, .render_startup = opengl_render_startup,
.render = opengl_render, .render = opengl_render,

View File

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

View File

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

View File

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