mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-22 05:27:20 +00:00
[client] updates for new protocol and vsync disable method
This commit is contained in:
parent
818164da7f
commit
301d394f50
242
client/main.c
242
client/main.c
@ -145,15 +145,15 @@ int renderThread(void * unused)
|
|||||||
{
|
{
|
||||||
bool error = false;
|
bool error = false;
|
||||||
struct KVMFRHeader header;
|
struct KVMFRHeader header;
|
||||||
volatile uint64_t * dataPos = &state.shm->dataPos;
|
volatile int32_t * updateCount = &state.shm->updateCount - 1;
|
||||||
|
|
||||||
while(state.running)
|
while(state.running)
|
||||||
{
|
{
|
||||||
// if the next frame isn't aready available
|
// if the next frame isn't aready available
|
||||||
if (header.dataPos == *dataPos)
|
if (header.updateCount == *updateCount)
|
||||||
{
|
{
|
||||||
// poll until we have a new frame, or we time out
|
// poll until we have a new frame, or we time out
|
||||||
while(header.dataPos == *dataPos && state.running) {
|
while(header.updateCount == *updateCount && state.running) {
|
||||||
const struct timespec s = {
|
const struct timespec s = {
|
||||||
.tv_sec = 0,
|
.tv_sec = 0,
|
||||||
.tv_nsec = 1000
|
.tv_nsec = 1000
|
||||||
@ -174,133 +174,140 @@ int renderThread(void * unused)
|
|||||||
// check the header's magic and version are valid
|
// check the header's magic and version are valid
|
||||||
if (
|
if (
|
||||||
memcmp(header.magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC)) != 0 ||
|
memcmp(header.magic, KVMFR_HEADER_MAGIC, sizeof(KVMFR_HEADER_MAGIC)) != 0 ||
|
||||||
header.version != KVMFR_HEADER_VERSION ||
|
header.version != KVMFR_HEADER_VERSION
|
||||||
(
|
){
|
||||||
header.dataPos == 0 ||
|
|
||||||
header.width == 0 ||
|
|
||||||
header.height == 0 ||
|
|
||||||
header.stride == 0 ||
|
|
||||||
header.frameType >= FRAME_TYPE_MAX
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup the renderer format with the frame format details
|
if(header.flags & KVMFR_HEADER_FLAG_FRAME)
|
||||||
LG_RendererFormat lgrFormat;
|
|
||||||
lgrFormat.width = header.width;
|
|
||||||
lgrFormat.height = header.height;
|
|
||||||
lgrFormat.stride = header.stride;
|
|
||||||
|
|
||||||
switch(header.frameType)
|
|
||||||
{
|
{
|
||||||
case FRAME_TYPE_ARGB:
|
if (
|
||||||
lgrFormat.pitch = header.stride * 4;
|
header.frame.type >= FRAME_TYPE_MAX ||
|
||||||
lgrFormat.bpp = 32;
|
header.frame.width == 0 ||
|
||||||
break;
|
header.frame.height == 0 ||
|
||||||
|
header.frame.stride == 0 ||
|
||||||
case FRAME_TYPE_RGB:
|
header.frame.dataPos == 0 ||
|
||||||
lgrFormat.pitch = header.stride * 3;
|
header.frame.dataPos > state.shmSize
|
||||||
lgrFormat.bpp = 24;
|
){
|
||||||
break;
|
usleep(1000);
|
||||||
|
continue;
|
||||||
default:
|
|
||||||
DEBUG_ERROR("Unsupported frameType");
|
|
||||||
error = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// check the header's dataPos is sane
|
|
||||||
const size_t dataSize = lgrFormat.height * lgrFormat.pitch;
|
|
||||||
if (header.dataPos + dataSize > state.shmSize)
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("The guest sent an invalid dataPos");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if we have a compatible renderer
|
|
||||||
if (!state.lgr || !state.lgr->is_compatible(state.lgrData, lgrFormat))
|
|
||||||
{
|
|
||||||
int width, height;
|
|
||||||
SDL_GetWindowSize(state.window, &width, &height);
|
|
||||||
|
|
||||||
LG_RendererParams lgrParams;
|
|
||||||
lgrParams.window = state.window;
|
|
||||||
lgrParams.font = state.font;
|
|
||||||
lgrParams.showFPS = params.showFPS;
|
|
||||||
lgrParams.vsync = params.vsync;
|
|
||||||
lgrParams.width = width;
|
|
||||||
lgrParams.height = height;
|
|
||||||
|
|
||||||
DEBUG_INFO("Data Format: w=%u, h=%u, s=%u, p=%u, bpp=%u",
|
|
||||||
lgrFormat.width, lgrFormat.height, lgrFormat.stride, lgrFormat.pitch, lgrFormat.bpp);
|
|
||||||
|
|
||||||
// first try to reinitialize any existing renderer
|
|
||||||
if (state.lgr)
|
|
||||||
{
|
|
||||||
state.lgr->deinitialize(state.lgrData);
|
|
||||||
if (state.lgr->initialize(&state.lgrData, lgrParams, lgrFormat))
|
|
||||||
{
|
|
||||||
DEBUG_INFO("Reinitialized %s", state.lgr->get_name());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to reinitialize %s, trying other renderers", state.lgr->get_name());
|
|
||||||
state.lgr->deinitialize(state.lgrData);
|
|
||||||
state.lgr = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.lgr)
|
// setup the renderer format with the frame format details
|
||||||
|
LG_RendererFormat lgrFormat;
|
||||||
|
lgrFormat.width = header.frame.width;
|
||||||
|
lgrFormat.height = header.frame.height;
|
||||||
|
lgrFormat.stride = header.frame.stride;
|
||||||
|
|
||||||
|
switch(header.frame.type)
|
||||||
{
|
{
|
||||||
// probe for a a suitable renderer
|
case FRAME_TYPE_ARGB:
|
||||||
for(const LG_Renderer **r = &LG_Renderers[0]; *r; ++r)
|
lgrFormat.pitch = header.frame.stride * 4;
|
||||||
{
|
lgrFormat.bpp = 32;
|
||||||
if (!IS_LG_RENDERER_VALID(*r))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("FIXME: Renderer %d is invalid, skipping", (int)(r - &LG_Renderers[0]));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.lgrData = NULL;
|
|
||||||
if (!(*r)->initialize(&state.lgrData, lgrParams, lgrFormat))
|
|
||||||
{
|
|
||||||
(*r)->deinitialize(state.lgrData);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.lgr = *r;
|
|
||||||
DEBUG_INFO("Initialized %s", (*r)->get_name());
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FRAME_TYPE_RGB:
|
||||||
|
lgrFormat.pitch = header.frame.stride * 3;
|
||||||
|
lgrFormat.bpp = 24;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG_ERROR("Unsupported frameType");
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// check the header's dataPos is sane
|
||||||
|
const size_t dataSize = lgrFormat.height * lgrFormat.pitch;
|
||||||
|
if (header.frame.dataPos + dataSize > state.shmSize)
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("The guest sent an invalid dataPos");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if we have a compatible renderer
|
||||||
|
if (!state.lgr || !state.lgr->is_compatible(state.lgrData, lgrFormat))
|
||||||
|
{
|
||||||
|
int width, height;
|
||||||
|
SDL_GetWindowSize(state.window, &width, &height);
|
||||||
|
|
||||||
|
LG_RendererParams lgrParams;
|
||||||
|
lgrParams.window = state.window;
|
||||||
|
lgrParams.font = state.font;
|
||||||
|
lgrParams.showFPS = params.showFPS;
|
||||||
|
lgrParams.vsync = params.vsync;
|
||||||
|
lgrParams.width = width;
|
||||||
|
lgrParams.height = height;
|
||||||
|
|
||||||
|
DEBUG_INFO("Data Format: w=%u, h=%u, s=%u, p=%u, bpp=%u",
|
||||||
|
lgrFormat.width, lgrFormat.height, lgrFormat.stride, lgrFormat.pitch, lgrFormat.bpp);
|
||||||
|
|
||||||
|
// first try to reinitialize any existing renderer
|
||||||
|
if (state.lgr)
|
||||||
|
{
|
||||||
|
state.lgr->deinitialize(state.lgrData);
|
||||||
|
if (state.lgr->initialize(&state.lgrData, lgrParams, lgrFormat))
|
||||||
|
{
|
||||||
|
DEBUG_INFO("Reinitialized %s", state.lgr->get_name());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("Failed to reinitialize %s, trying other renderers", state.lgr->get_name());
|
||||||
|
state.lgr->deinitialize(state.lgrData);
|
||||||
|
state.lgr = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.lgr)
|
if (!state.lgr)
|
||||||
{
|
{
|
||||||
DEBUG_INFO("Unable to find a suitable renderer");
|
// probe for a a suitable renderer
|
||||||
return -1;
|
for(const LG_Renderer **r = &LG_Renderers[0]; *r; ++r)
|
||||||
|
{
|
||||||
|
if (!IS_LG_RENDERER_VALID(*r))
|
||||||
|
{
|
||||||
|
DEBUG_ERROR("FIXME: Renderer %d is invalid, skipping", (int)(r - &LG_Renderers[0]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.lgrData = NULL;
|
||||||
|
if (!(*r)->initialize(&state.lgrData, lgrParams, lgrFormat))
|
||||||
|
{
|
||||||
|
(*r)->deinitialize(state.lgrData);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.lgr = *r;
|
||||||
|
DEBUG_INFO("Initialized %s", (*r)->get_name());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!state.lgr)
|
||||||
|
{
|
||||||
|
DEBUG_INFO("Unable to find a suitable renderer");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state.srcSize.x = header.frame.width;
|
||||||
|
state.srcSize.y = header.frame.height;
|
||||||
|
if (params.autoResize)
|
||||||
|
SDL_SetWindowSize(state.window, header.frame.width, header.frame.height);
|
||||||
|
updatePositionInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
state.srcSize.x = header.width;
|
if (!state.lgr->render(
|
||||||
state.srcSize.y = header.height;
|
state.lgrData,
|
||||||
if (params.autoResize)
|
(uint8_t *)state.shm + header.frame.dataPos,
|
||||||
SDL_SetWindowSize(state.window, header.width, header.height);
|
params.useMipmap
|
||||||
updatePositionInfo();
|
))
|
||||||
}
|
{
|
||||||
|
DEBUG_ERROR("Failed to render the frame");
|
||||||
if (!state.lgr->render(
|
break;
|
||||||
state.lgrData,
|
}
|
||||||
(uint8_t *)state.shm + header.dataPos,
|
|
||||||
params.useMipmap
|
|
||||||
))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR("Failed to render the frame");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -477,8 +484,8 @@ int eventThread(void * arg)
|
|||||||
x = (float)x * state.scaleX;
|
x = (float)x * state.scaleX;
|
||||||
y = (float)y * state.scaleY;
|
y = (float)y * state.scaleY;
|
||||||
}
|
}
|
||||||
x -= state.shm->mouseX;
|
x -= state.shm->cursor.x;
|
||||||
y -= state.shm->mouseY;
|
y -= state.shm->cursor.y;
|
||||||
realignGuest = false;
|
realignGuest = false;
|
||||||
|
|
||||||
if (!spice_mouse_motion(x, y))
|
if (!spice_mouse_motion(x, y))
|
||||||
@ -605,6 +612,9 @@ int run()
|
|||||||
FcPatternDestroy(pat);
|
FcPatternDestroy(pat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!params.vsync)
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
|
||||||
|
|
||||||
state.window = SDL_CreateWindow(
|
state.window = SDL_CreateWindow(
|
||||||
"Looking Glass (Client)",
|
"Looking Glass (Client)",
|
||||||
params.center ? SDL_WINDOWPOS_CENTERED : params.x,
|
params.center ? SDL_WINDOWPOS_CENTERED : params.x,
|
||||||
|
Loading…
Reference in New Issue
Block a user