From 83592f7e4a8fb16e9a4759d6092af290053ce72f Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Sat, 28 Jul 2018 14:49:37 +1000 Subject: [PATCH] [client] cleanup of renderer API for better usage * Added new on_render_start for render initialization * Changed on_resize to execute inside the render thread --- client/lg-renderer.h | 2 + client/main.c | 36 +++++--- client/renderers/opengl.c | 178 +++++++++++++++++--------------------- 3 files changed, 106 insertions(+), 110 deletions(-) diff --git a/client/lg-renderer.h b/client/lg-renderer.h index c940e017..66e8b78a 100644 --- a/client/lg-renderer.h +++ b/client/lg-renderer.h @@ -35,6 +35,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA (x)->on_mouse_shape && \ (x)->on_mouse_event && \ (x)->on_alert && \ + (x)->render_startup && \ (x)->render) #define LGR_OPTION_COUNT(x) (sizeof(x) / sizeof(LG_RendererOpt)) @@ -129,6 +130,7 @@ typedef struct LG_Renderer LG_RendererOnMouseEvent on_mouse_event; LG_RendererOnFrameEvent on_frame_event; LG_RendererOnAlert on_alert; + LG_RendererRender render_startup; LG_RendererRender render; } LG_Renderer; diff --git a/client/main.c b/client/main.c index 19d4eaeb..a28f204e 100644 --- a/client/main.c +++ b/client/main.c @@ -54,6 +54,7 @@ struct AppState TTF_Font * font; TTF_Font * alertFont; bool haveSrcSize; + int windowW, windowH; SDL_Point srcSize; LG_RendererRect dstRect; SDL_Point cursor; @@ -64,6 +65,7 @@ struct AppState const LG_Renderer * lgr ; void * lgrData; + bool lgrResize; SDL_Window * window; int shmFD; @@ -144,36 +146,35 @@ struct AppParams params = static inline void updatePositionInfo() { - int w, h; - SDL_GetWindowSize(state.window, &w, &h); + SDL_GetWindowSize(state.window, &state.windowW, &state.windowH); if (state.haveSrcSize) { if (params.keepAspect) { const float srcAspect = (float)state.srcSize.y / (float)state.srcSize.x; - const float wndAspect = (float)h / (float)w; + const float wndAspect = (float)state.windowH / (float)state.windowW; if (wndAspect < srcAspect) { - state.dstRect.w = (float)h / srcAspect; - state.dstRect.h = h; - state.dstRect.x = (w >> 1) - (state.dstRect.w >> 1); + state.dstRect.w = (float)state.windowH / srcAspect; + state.dstRect.h = state.windowH; + state.dstRect.x = (state.windowW >> 1) - (state.dstRect.w >> 1); state.dstRect.y = 0; } else { - state.dstRect.w = w; - state.dstRect.h = (float)w * srcAspect; + state.dstRect.w = state.windowW; + state.dstRect.h = (float)state.windowW * srcAspect; state.dstRect.x = 0; - state.dstRect.y = (h >> 1) - (state.dstRect.h >> 1); + state.dstRect.y = (state.windowH >> 1) - (state.dstRect.h >> 1); } } else { state.dstRect.x = 0; state.dstRect.y = 0; - state.dstRect.w = w; - state.dstRect.h = h; + state.dstRect.w = state.windowW; + state.dstRect.h = state.windowH; } state.dstRect.valid = true; @@ -181,14 +182,23 @@ static inline void updatePositionInfo() state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w; } - if (state.lgr) - state.lgr->on_resize(state.lgrData, w, h, state.dstRect); + state.lgrResize = true; } int renderThread(void * unused) { + if (!state.lgr->render_startup(state.lgrData, state.window)) + return 1; + while(state.running) { + if (state.lgrResize) + { + if (state.lgr) + state.lgr->on_resize(state.lgrData, state.windowW, state.windowH, state.dstRect); + state.lgrResize = false; + } + const uint64_t start = microtime(); if (!state.lgr->render(state.lgrData, state.window)) diff --git a/client/renderers/opengl.c b/client/renderers/opengl.c index 30f56772..47773c3d 100644 --- a/client/renderers/opengl.c +++ b/client/renderers/opengl.c @@ -80,13 +80,12 @@ struct Inst struct Options opt; bool amdPinnedMemSupport; - bool preConfigured; + bool renderStarted; bool configured; bool reconfigure; SDL_GLContext glContext; SDL_Point window; - bool resizeWindow; bool frameUpdate; LG_Lock formatLock; @@ -148,7 +147,6 @@ static bool _check_gl_error(unsigned int line, const char * name); #define check_gl_error(name) _check_gl_error(__LINE__, name) static void deconfigure(struct Inst * this); -static bool pre_configure(struct Inst * this, SDL_Window *window); static bool configure(struct Inst * this, SDL_Window *window); static void update_mouse_shape(struct Inst * this, bool * newShape); static bool draw_frame(struct Inst * this); @@ -205,7 +203,7 @@ void opengl_deinitialize(void * opaque) if (!this) return; - if (this->preConfigured) + if (this->renderStarted) { glDeleteLists(this->texList , BUFFER_COUNT); glDeleteLists(this->mouseList, 1); @@ -242,8 +240,6 @@ void opengl_deinitialize(void * opaque) void opengl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect) { struct Inst * this = (struct Inst *)opaque; - if (!this) - return; this->window.x = width; this->window.y = height; @@ -251,7 +247,24 @@ void opengl_on_resize(void * opaque, const int width, const int height, const LG if (destRect.valid) memcpy(&this->destRect, &destRect, sizeof(LG_RendererRect)); - this->resizeWindow = true; + // setup the projection matrix + glViewport(0, 0, this->window.x, this->window.y); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, this->window.x, this->window.y, 0); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + if (this->destRect.valid) + { + glTranslatef(this->destRect.x, this->destRect.y, 0.0f); + glScalef( + (float)this->destRect.w / (float)this->format.width, + (float)this->destRect.h / (float)this->format.height, + 1.0f + ); + } } bool opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data) @@ -428,39 +441,71 @@ void surface_to_texture(SDL_Surface * surface, GLuint texture) glBindTexture(GL_TEXTURE_2D, 0); } +bool opengl_render_startup(void * opaque, SDL_Window * window) +{ + struct Inst * this = (struct Inst *)opaque; + + this->glContext = SDL_GL_CreateContext(window); + if (!this->glContext) + { + DEBUG_ERROR("Failed to create the OpenGL context"); + return false; + } + + DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR )); + DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER)); + DEBUG_INFO("Version : %s", glGetString(GL_VERSION )); + + GLint n; + glGetIntegerv(GL_NUM_EXTENSIONS, &n); + for(GLint i = 0; i < n; ++i) + { + const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i); + if (strcmp((const char *)ext, "GL_AMD_pinned_memory") == 0) + { + if (this->opt.amdPinnedMem) + { + this->amdPinnedMemSupport = true; + DEBUG_INFO("Using GL_AMD_pinned_memory"); + } + else + DEBUG_INFO("GL_AMD_pinned_memory is available but not in use"); + break; + } + } + + glEnable(GL_TEXTURE_2D); + glEnable(GL_COLOR_MATERIAL); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendEquation(GL_FUNC_ADD); + glEnable(GL_MULTISAMPLE); + + // generate lists for drawing + this->texList = glGenLists(BUFFER_COUNT); + this->mouseList = glGenLists(1); + this->fpsList = glGenLists(1); + this->alertList = glGenLists(1); + + // create the overlay textures + glGenTextures(TEXTURE_COUNT, this->textures); + if (check_gl_error("glGenTextures")) + { + LG_UNLOCK(this->formatLock); + return false; + } + this->hasTextures = true; + + SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0); + this->renderStarted = true; + return true; +} + bool opengl_render(void * opaque, SDL_Window * window) { struct Inst * this = (struct Inst *)opaque; if (!this) return false; - if (!pre_configure(this, window)) - return false; - - if (this->resizeWindow) - { - // setup the projection matrix - glViewport(0, 0, this->window.x, this->window.y); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluOrtho2D(0, this->window.x, this->window.y, 0); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - if (this->destRect.valid) - { - glTranslatef(this->destRect.x, this->destRect.y, 0.0f); - glScalef( - (float)this->destRect.w / (float)this->format.width, - (float)this->destRect.h / (float)this->format.height, - 1.0f - ); - } - - this->resizeWindow = false; - } - if (configure(this, window)) if (!draw_frame(this)) return false; @@ -800,6 +845,7 @@ const LG_Renderer LGR_OpenGL = .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 }; @@ -814,66 +860,6 @@ static bool _check_gl_error(unsigned int line, const char * name) return true; } -static bool pre_configure(struct Inst * this, SDL_Window *window) -{ - if (this->preConfigured) - return true; - - this->glContext = SDL_GL_CreateContext(window); - if (!this->glContext) - { - DEBUG_ERROR("Failed to create the OpenGL context"); - return false; - } - - DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR )); - DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER)); - DEBUG_INFO("Version : %s", glGetString(GL_VERSION )); - - GLint n; - glGetIntegerv(GL_NUM_EXTENSIONS, &n); - for(GLint i = 0; i < n; ++i) - { - const GLubyte *ext = glGetStringi(GL_EXTENSIONS, i); - if (strcmp((const char *)ext, "GL_AMD_pinned_memory") == 0) - { - if (this->opt.amdPinnedMem) - { - this->amdPinnedMemSupport = true; - DEBUG_INFO("Using GL_AMD_pinned_memory"); - } - else - DEBUG_INFO("GL_AMD_pinned_memory is available but not in use"); - break; - } - } - - glEnable(GL_TEXTURE_2D); - glEnable(GL_COLOR_MATERIAL); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendEquation(GL_FUNC_ADD); - glEnable(GL_MULTISAMPLE); - - // generate lists for drawing - this->texList = glGenLists(BUFFER_COUNT); - this->mouseList = glGenLists(1); - this->fpsList = glGenLists(1); - this->alertList = glGenLists(1); - - // create the overlay textures - glGenTextures(TEXTURE_COUNT, this->textures); - if (check_gl_error("glGenTextures")) - { - LG_UNLOCK(this->formatLock); - return false; - } - this->hasTextures = true; - - SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0); - this->preConfigured = true; - return true; -} - static bool configure(struct Inst * this, SDL_Window *window) { LG_LOCK(this->formatLock); @@ -1085,9 +1071,7 @@ static bool configure(struct Inst * this, SDL_Window *window) glBindTexture(GL_TEXTURE_2D, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - this->resizeWindow = true; - this->drawStart = nanotime(); - + this->drawStart = nanotime(); this->configured = true; this->reconfigure = false;