[client] treat buffers correctly

This commit is contained in:
Geoffrey McRae 2017-12-14 10:06:22 +11:00
parent 2374b1a9fb
commit 9d29b1195d
3 changed files with 41 additions and 37 deletions

View File

@ -39,6 +39,7 @@ typedef struct LG_RendererParams
SDL_Window * window; SDL_Window * window;
TTF_Font * font; TTF_Font * font;
bool showFPS; bool showFPS;
bool resample;
int width; int width;
int height; 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 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 uint8_t * data, bool resample); typedef bool (* LG_RendererOnFrameEvent )(void * opaque, const uint8_t * data);
typedef bool (* LG_RendererRender )(void * opaque); typedef bool (* LG_RendererRender )(void * opaque);
typedef struct LG_Renderer typedef struct LG_Renderer

View File

@ -235,11 +235,12 @@ int renderThread(void * unused)
SDL_GetWindowSize(state.window, &width, &height); SDL_GetWindowSize(state.window, &width, &height);
LG_RendererParams lgrParams; LG_RendererParams lgrParams;
lgrParams.window = state.window; lgrParams.window = state.window;
lgrParams.font = state.font; lgrParams.font = state.font;
lgrParams.showFPS = params.showFPS; lgrParams.resample = params.useMipmap;
lgrParams.width = width; lgrParams.showFPS = params.showFPS;
lgrParams.height = height; lgrParams.width = width;
lgrParams.height = height;
DEBUG_INFO("Data Format: w=%u, h=%u, s=%u, p=%u, bpp=%u", DEBUG_INFO("Data Format: w=%u, h=%u, s=%u, p=%u, bpp=%u",
lgrFormat.width, lgrFormat.height, lgrFormat.stride, lgrFormat.pitch, lgrFormat.bpp); 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; 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"); DEBUG_ERROR("Failed to render the frame");
break; break;

View File

@ -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 // check if the GPU supports GL_ARB_buffer_storage first
// there is no advantage to this renderer if it is not present. // 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, this->texSize * BUFFER_COUNT,
NULL, NULL,
GL_MAP_WRITE_BIT | GL_MAP_WRITE_BIT |
GL_MAP_PERSISTENT_BIT | GL_MAP_PERSISTENT_BIT
GL_MAP_COHERENT_BIT
); );
if (lgr_opengl_check_error("glBufferStorage")) if (lgr_opengl_check_error("glBufferStorage"))
return false; return false;
@ -188,7 +188,7 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const
this->texSize * BUFFER_COUNT, this->texSize * BUFFER_COUNT,
GL_MAP_WRITE_BIT | GL_MAP_WRITE_BIT |
GL_MAP_PERSISTENT_BIT | GL_MAP_PERSISTENT_BIT |
GL_MAP_COHERENT_BIT GL_MAP_FLUSH_EXPLICIT_BIT
); );
if (lgr_opengl_check_error("glMapBufferRange")) 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; 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; struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
if (!this || !this->initialized) if (!this || !this->initialized)
return false; return false;
int texIndex = this->texIndex + 1;
if (texIndex == BUFFER_COUNT)
texIndex = 0;
if (this->params.showFPS && this->renderTime > 1e9) if (this->params.showFPS && this->renderTime > 1e9)
{ {
char str[128]; char str[128];
@ -526,33 +522,38 @@ bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data, bool resampl
glEndList(); glEndList();
} }
// copy the buffer to the texture
memcpySSE(this->texPixels[texIndex], data, this->texSize);
// bind the texture and update it // bind the texture and update it
glBindTexture(GL_TEXTURE_2D , this->textures[FRAME_TEXTURE]); glBindTexture(GL_TEXTURE_2D , this->textures[FRAME_TEXTURE]);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[0] ); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, this->vboID[0] );
glPixelStorei(GL_UNPACK_ALIGNMENT , 4 ); glPixelStorei(GL_UNPACK_ALIGNMENT , 4 );
glPixelStorei(GL_UNPACK_ROW_LENGTH , this->format.width ); 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 // update the texture
glTexSubImage2D( glTexSubImage2D(
GL_TEXTURE_2D, GL_TEXTURE_2D,
0, 0,
0, 0,
texIndex * this->format.height, this->texIndex * this->format.height,
this->format.width , this->format.width ,
this->format.height, this->format.height,
this->vboFormat, this->vboFormat,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
(void*)(texIndex * this->texSize) (void*)(this->texIndex * this->texSize)
); );
lgr_opengl_check_error("glTexSubImage2D"); lgr_opengl_check_error("glTexSubImage2D");
// unbind the buffer // unbind the buffer
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
const bool mipmap = resample && ( const bool mipmap = this->params.resample && (
(this->format.width > this->destRect.w) || (this->format.width > this->destRect.w) ||
(this->format.height > this->destRect.h)); (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); glBindTexture(GL_TEXTURE_2D, 0);
if (++this->texIndex == BUFFER_COUNT)
this->texIndex = 0;
this->frameUpdate = true; this->frameUpdate = true;
this->texIndex = texIndex;
return true; return true;
} }
@ -616,9 +619,6 @@ bool lgr_opengl_render(void * opaque)
); );
this->resizeWindow = false; 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; const uint64_t delta = nanotime() - this->lastMouseDraw;
if (delta < 1e7) if (delta < 1e7)
return true; 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); glCallList(this->texList + this->texIndex);
lgr_opengl_draw_mouse(this); lgr_opengl_draw_mouse(this);
if (this->fpsTexture) if (this->fpsTexture)
glCallList(this->fpsList); glCallList(this->fpsList);
SDL_GL_SwapWindow(this->params.window);
glFlush();
++this->frameCount; ++this->frameCount;
const uint64_t t = nanotime(); const uint64_t t = nanotime();