From c38e38d43db293d4b3492c68842132540abb900a Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 19 Dec 2017 10:19:12 +1100 Subject: [PATCH] [client] opengl: add splitmouse option This feature was previously hardcoded enabled, it is now optional as some hardware pipelines stall with the excessive flushes resulting in a jumpy cursor. Default is disabled and may be re-enabled with `-o opengl:splitmouse=1` or `-o opengl-basic:splitmouse=1` depending on the renderer selected. --- client/renderers/opengl-basic.c | 66 +++++++++++++++++++++----------- client/renderers/opengl.c | 67 +++++++++++++++++++++------------ 2 files changed, 86 insertions(+), 47 deletions(-) diff --git a/client/renderers/opengl-basic.c b/client/renderers/opengl-basic.c index a92c24b4..cbd438c3 100644 --- a/client/renderers/opengl-basic.c +++ b/client/renderers/opengl-basic.c @@ -45,12 +45,14 @@ struct Options { bool mipmap; bool vsync; + bool splitMouse; }; static struct Options defaultOptions = { - .mipmap = true, - .vsync = true + .mipmap = true, + .vsync = true, + .splitMouse = false }; struct LGR_OpenGLBasic @@ -659,31 +661,34 @@ bool lgr_opengl_basic_render(void * opaque) } - if (!this->frameUpdate) + if (this->opt.splitMouse) { - if (!this->mouseUpdate) - return true; - - if (!this->newShape) + if (!this->frameUpdate) { - // don't update the mouse too fast - const uint64_t delta = nanotime() - this->lastMouseDraw; - if (delta < 5e6) + if (!this->mouseUpdate) return true; + + if (!this->newShape) + { + // don't update the mouse too fast + const uint64_t delta = nanotime() - this->lastMouseDraw; + if (delta < 5e6) + return true; + } + this->newShape = false; + + glDrawBuffer(GL_FRONT); + glCallList(this->texList); + lgr_opengl_basic_draw_mouse(this); + if (this->fpsTexture) + glCallList(this->fpsList); + glDrawBuffer(GL_BACK); + glFlush(); + + this->mouseUpdate = false; + this->lastMouseDraw = nanotime(); + return true; } - this->newShape = false; - - glDrawBuffer(GL_FRONT); - glCallList(this->texList); - lgr_opengl_basic_draw_mouse(this); - if (this->fpsTexture) - glCallList(this->fpsList); - glDrawBuffer(GL_BACK); - glFlush(); - - this->mouseUpdate = false; - this->lastMouseDraw = nanotime(); - return true; } glDisable(GL_SCISSOR_TEST); @@ -733,6 +738,15 @@ static void handle_opt_vsync(void * opaque, const char *value) this->opt.vsync = LG_RendererValueToBool(value); } +static void handle_opt_split_mouse(void * opaque, const char *value) +{ + struct LGR_OpenGLBasic * this = (struct LGR_OpenGLBasic *)opaque; + if (!this) + return; + + this->opt.splitMouse = LG_RendererValueToBool(value); +} + static LG_RendererOpt lgr_opengl_basic_options[] = { { @@ -746,6 +760,12 @@ static LG_RendererOpt lgr_opengl_basic_options[] = .desc ="Enable or disable vsync [default: enabled]", .validator = LG_RendererValidatorBool, .handler = handle_opt_vsync + }, + { + .name = "splitMouse", + .desc = "Draw mouse updates directly to the front buffer [default: disabled]", + .validator = LG_RendererValidatorBool, + .handler = handle_opt_split_mouse } }; diff --git a/client/renderers/opengl.c b/client/renderers/opengl.c index 022669a7..a476b1a0 100644 --- a/client/renderers/opengl.c +++ b/client/renderers/opengl.c @@ -47,12 +47,14 @@ struct Options { bool mipmap; bool vsync; + bool splitMouse; }; static struct Options defaultOptions = { - .mipmap = true, - .vsync = true + .mipmap = true, + .vsync = true, + .splitMouse = false }; struct LGR_OpenGL @@ -723,32 +725,34 @@ bool lgr_opengl_render(void * opaque) this->resizeWindow = false; } - - if (!this->frameUpdate) + if (this->opt.splitMouse) { - if (!this->mouseUpdate) - return true; - - if (!this->newShape) + if (!this->frameUpdate) { - // don't update the mouse too fast - const uint64_t delta = nanotime() - this->lastMouseDraw; - if (delta < 5e6) + if (!this->mouseUpdate) return true; + + if (!this->newShape) + { + // don't update the mouse too fast + const uint64_t delta = nanotime() - this->lastMouseDraw; + if (delta < 5e6) + return true; + } + this->newShape = false; + + glDrawBuffer(GL_FRONT); + glCallList(this->texList + this->texIndex); + lgr_opengl_draw_mouse(this); + if (this->fpsTexture) + glCallList(this->fpsList); + glDrawBuffer(GL_BACK); + glFlush(); + + this->mouseUpdate = false; + this->lastMouseDraw = nanotime(); + return true; } - this->newShape = false; - - glDrawBuffer(GL_FRONT); - glCallList(this->texList + this->texIndex); - lgr_opengl_draw_mouse(this); - if (this->fpsTexture) - glCallList(this->fpsList); - glDrawBuffer(GL_BACK); - glFlush(); - - this->mouseUpdate = false; - this->lastMouseDraw = nanotime(); - return true; } glDisable(GL_SCISSOR_TEST); @@ -798,6 +802,15 @@ static void handle_opt_vsync(void * opaque, const char *value) this->opt.vsync = LG_RendererValueToBool(value); } +static void handle_opt_split_mouse(void * opaque, const char *value) +{ + struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque; + if (!this) + return; + + this->opt.splitMouse = LG_RendererValueToBool(value); +} + static LG_RendererOpt lgr_opengl_options[] = { { @@ -811,6 +824,12 @@ static LG_RendererOpt lgr_opengl_options[] = .desc ="Enable or disable vsync [default: enabled]", .validator = LG_RendererValidatorBool, .handler = handle_opt_vsync + }, + { + .name = "splitMouse", + .desc = "Draw mouse updates directly to the front buffer [default: disabled]", + .validator = LG_RendererValidatorBool, + .handler = handle_opt_split_mouse } };