From 9d29b1195d73610eb8637c02793809b3ae67fafa Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Thu, 14 Dec 2017 10:06:22 +1100 Subject: [PATCH] [client] treat buffers correctly --- client/lg-renderer.h | 3 +- client/main.c | 13 ++++---- client/renderers/opengl.c | 62 ++++++++++++++++++++------------------- 3 files changed, 41 insertions(+), 37 deletions(-) diff --git a/client/lg-renderer.h b/client/lg-renderer.h index 7aa3f213..c2b5159f 100644 --- a/client/lg-renderer.h +++ b/client/lg-renderer.h @@ -39,6 +39,7 @@ typedef struct LG_RendererParams SDL_Window * window; TTF_Font * font; bool showFPS; + bool resample; int width; int height; } @@ -78,7 +79,7 @@ typedef bool (* LG_RendererIsCompatible )(void * opaque, const LG_Rende 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 uint8_t * data, bool resample); +typedef bool (* LG_RendererOnFrameEvent )(void * opaque, const uint8_t * data); typedef bool (* LG_RendererRender )(void * opaque); typedef struct LG_Renderer diff --git a/client/main.c b/client/main.c index ec43b6aa..427286a0 100644 --- a/client/main.c +++ b/client/main.c @@ -235,11 +235,12 @@ int renderThread(void * unused) SDL_GetWindowSize(state.window, &width, &height); LG_RendererParams lgrParams; - lgrParams.window = state.window; - lgrParams.font = state.font; - lgrParams.showFPS = params.showFPS; - lgrParams.width = width; - lgrParams.height = height; + lgrParams.window = state.window; + lgrParams.font = state.font; + lgrParams.resample = params.useMipmap; + lgrParams.showFPS = params.showFPS; + 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); @@ -298,7 +299,7 @@ int renderThread(void * unused) } const uint8_t * data = (const uint8_t *)state.shm + header.frame.dataPos; - if (!state.lgr->on_frame_event(state.lgrData, data, params.useMipmap)) + if (!state.lgr->on_frame_event(state.lgrData, data)) { DEBUG_ERROR("Failed to render the frame"); break; diff --git a/client/renderers/opengl.c b/client/renderers/opengl.c index bff1804e..d31747a4 100644 --- a/client/renderers/opengl.c +++ b/client/renderers/opengl.c @@ -124,7 +124,8 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const } } - SDL_GL_SetSwapInterval(1); + SDL_GL_SetSwapInterval(0); + glDrawBuffer(GL_FRONT); // check if the GPU supports GL_ARB_buffer_storage first // there is no advantage to this renderer if it is not present. @@ -176,8 +177,7 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const this->texSize * BUFFER_COUNT, NULL, GL_MAP_WRITE_BIT | - GL_MAP_PERSISTENT_BIT | - GL_MAP_COHERENT_BIT + GL_MAP_PERSISTENT_BIT ); if (lgr_opengl_check_error("glBufferStorage")) return false; @@ -188,7 +188,7 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const this->texSize * BUFFER_COUNT, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | - GL_MAP_COHERENT_BIT + GL_MAP_FLUSH_EXPLICIT_BIT ); if (lgr_opengl_check_error("glMapBufferRange")) @@ -446,16 +446,12 @@ bool lgr_opengl_on_mouse_event(void * opaque, const bool visible, const int x, c return false; } -bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data, bool resample) +bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data) { struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque; if (!this || !this->initialized) return false; - int texIndex = this->texIndex + 1; - if (texIndex == BUFFER_COUNT) - texIndex = 0; - if (this->params.showFPS && this->renderTime > 1e9) { char str[128]; @@ -526,33 +522,38 @@ bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data, bool resampl glEndList(); } - // copy the buffer to the texture - memcpySSE(this->texPixels[texIndex], data, this->texSize); - // bind the texture and update it glBindTexture(GL_TEXTURE_2D , this->textures[FRAME_TEXTURE]); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[0] ); glPixelStorei(GL_UNPACK_ALIGNMENT , 4 ); glPixelStorei(GL_UNPACK_ROW_LENGTH , this->format.width ); + // copy the buffer to the texture + memcpySSE(this->texPixels[this->texIndex], data, this->texSize); + glFlushMappedBufferRange( + GL_PIXEL_UNPACK_BUFFER, + this->texSize * this->texIndex, + this->texSize + ); + // update the texture glTexSubImage2D( GL_TEXTURE_2D, 0, 0, - texIndex * this->format.height, + this->texIndex * this->format.height, this->format.width , this->format.height, this->vboFormat, GL_UNSIGNED_BYTE, - (void*)(texIndex * this->texSize) + (void*)(this->texIndex * this->texSize) ); lgr_opengl_check_error("glTexSubImage2D"); // unbind the buffer glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); - const bool mipmap = resample && ( + const bool mipmap = this->params.resample && ( (this->format.width > this->destRect.w) || (this->format.height > this->destRect.h)); @@ -568,8 +569,10 @@ bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data, bool resampl glBindTexture(GL_TEXTURE_2D, 0); + if (++this->texIndex == BUFFER_COUNT) + this->texIndex = 0; + this->frameUpdate = true; - this->texIndex = texIndex; return true; } @@ -616,9 +619,6 @@ bool lgr_opengl_render(void * opaque) ); this->resizeWindow = false; - glDisable(GL_SCISSOR_TEST); - glClear(GL_COLOR_BUFFER_BIT); - glEnable(GL_SCISSOR_TEST); } @@ -631,23 +631,25 @@ bool lgr_opengl_render(void * opaque) const uint64_t delta = nanotime() - this->lastMouseDraw; if (delta < 1e7) return true; - - glDrawBuffer(GL_FRONT); - glCallList(this->texList + this->texIndex); - lgr_opengl_draw_mouse(this); - glFlush(); - - this->mouseUpdate = false; - this->lastMouseDraw = nanotime(); - return true; } - glDrawBuffer(GL_BACK); + // wait for vsync + unsigned int count; + glXGetVideoSyncSGI(&count); + if (count == this->gpuFrameCount) + glXWaitVideoSyncSGI(1, 0, &count); + glXGetVideoSyncSGI(&this->gpuFrameCount); + + glDisable(GL_SCISSOR_TEST); + glClear(GL_COLOR_BUFFER_BIT); + glEnable(GL_SCISSOR_TEST); + glCallList(this->texList + this->texIndex); lgr_opengl_draw_mouse(this); if (this->fpsTexture) glCallList(this->fpsList); - SDL_GL_SwapWindow(this->params.window); + + glFlush(); ++this->frameCount; const uint64_t t = nanotime();