[opengl] render a blue screen while waiting for sync

This commit is contained in:
Geoffrey McRae 2018-05-28 15:30:04 +10:00
parent 80581a4aa2
commit a647a602bf
2 changed files with 96 additions and 68 deletions

View file

@ -187,25 +187,20 @@ int renderThread(void * unused)
{ {
while(state.running) while(state.running)
{ {
if (state.started) const uint64_t start = microtime();
if (!state.lgr->render(state.lgrData, state.window))
break;
const uint64_t total = microtime() - start;
if (total < state.fpsSleep)
{ {
const uint64_t start = microtime(); usleep(state.fpsSleep - total);
int64_t delta = (1000000 / params.fpsLimit) - (microtime() - start);
if (!state.lgr->render(state.lgrData, state.window)) state.fpsSleep += delta / 16;
break; if (state.fpsSleep < 0)
state.fpsSleep = 0;
const uint64_t total = microtime() - start;
if (total < state.fpsSleep)
{
usleep(state.fpsSleep - total);
int64_t delta = (1000000 / params.fpsLimit) - (microtime() - start);
state.fpsSleep += delta / 16;
if (state.fpsSleep < 0)
state.fpsSleep = 0;
}
} }
else
usleep(1000000);
} }
return 0; return 0;
@ -898,6 +893,14 @@ int run()
// also send us the current mouse shape since we won't know it yet // also send us the current mouse shape since we won't know it yet
DEBUG_INFO("Waiting for host to signal it's ready..."); DEBUG_INFO("Waiting for host to signal it's ready...");
__sync_or_and_fetch(&state.shm->flags, KVMFR_HEADER_FLAG_RESTART); __sync_or_and_fetch(&state.shm->flags, KVMFR_HEADER_FLAG_RESTART);
// start the renderThread so we don't just display junk
if (!(t_render = SDL_CreateThread(renderThread, "renderThread", NULL)))
{
DEBUG_ERROR("render create thread failed");
break;
}
while(state.running && (state.shm->flags & KVMFR_HEADER_FLAG_RESTART)) while(state.running && (state.shm->flags & KVMFR_HEADER_FLAG_RESTART))
{ {
SDL_Event event; SDL_Event event;
@ -905,13 +908,16 @@ int run()
{ {
if (event.type == SDL_QUIT) if (event.type == SDL_QUIT)
{ {
if (!params.ignoreQuit) state.running = false;
state.running = false;
break; break;
} }
} }
usleep(1000); usleep(1000);
} }
if (!state.running)
break;
DEBUG_INFO("Host ready, starting session"); DEBUG_INFO("Host ready, starting session");
// check the header's magic and version are valid // check the header's magic and version are valid
@ -941,12 +947,6 @@ int run()
break; break;
} }
if (!(t_render = SDL_CreateThread(renderThread, "renderThread", NULL)))
{
DEBUG_ERROR("render create thread failed");
break;
}
while(state.running) while(state.running)
{ {
SDL_Event event; SDL_Event event;

View file

@ -62,10 +62,10 @@ struct Inst
struct Options opt; struct Options opt;
bool amdPinnedMemSupport; bool amdPinnedMemSupport;
bool preConfigured;
bool configured; bool configured;
bool reconfigure; bool reconfigure;
SDL_GLContext glContext; SDL_GLContext glContext;
bool doneInfo;
SDL_Point window; SDL_Point window;
bool resizeWindow; bool resizeWindow;
@ -84,6 +84,7 @@ struct Inst
GLuint vboID[BUFFER_COUNT]; GLuint vboID[BUFFER_COUNT];
uint8_t * texPixels[BUFFER_COUNT]; uint8_t * texPixels[BUFFER_COUNT];
LG_Lock syncLock; LG_Lock syncLock;
bool texReady;
int texIndex; int texIndex;
int texList; int texList;
int fpsList; int fpsList;
@ -123,10 +124,12 @@ static bool _check_gl_error(unsigned int line, const char * name);
#define check_gl_error(name) _check_gl_error(__LINE__, name) #define check_gl_error(name) _check_gl_error(__LINE__, name)
static void deconfigure(struct Inst * this); 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 bool configure(struct Inst * this, SDL_Window *window);
static void update_mouse_shape(struct Inst * this, bool * newShape); static void update_mouse_shape(struct Inst * this, bool * newShape);
static bool draw_frame(struct Inst * this); static bool draw_frame(struct Inst * this);
static void draw_mouse(struct Inst * this); static void draw_mouse(struct Inst * this);
static void render_wait();
const char * opengl_get_name() const char * opengl_get_name()
{ {
@ -291,7 +294,7 @@ bool opengl_render(void * opaque, SDL_Window * window)
if (!this) if (!this)
return false; return false;
if (!configure(this, window)) if (!pre_configure(this, window))
return false; return false;
if (this->resizeWindow) if (this->resizeWindow)
@ -314,6 +317,23 @@ bool opengl_render(void * opaque, SDL_Window * window)
this->resizeWindow = false; this->resizeWindow = false;
} }
if (!configure(this, window))
{
render_wait();
SDL_GL_SwapWindow(window);
return true;
}
if (!draw_frame(this))
return false;
if (!this->texReady)
{
render_wait();
SDL_GL_SwapWindow(window);
return true;
}
if (this->params.showFPS && this->renderTime > 1e9) if (this->params.showFPS && this->renderTime > 1e9)
{ {
char str[128]; char str[128];
@ -392,14 +412,11 @@ bool opengl_render(void * opaque, SDL_Window * window)
glEndList(); glEndList();
} }
if (!draw_frame(this))
return false;
bool newShape; bool newShape;
update_mouse_shape(this, &newShape); update_mouse_shape(this, &newShape);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
glCallList(this->texList + this->texIndex); glCallList(this->texList + this->texIndex);
draw_mouse(this); draw_mouse(this);
if (this->fpsTexture) if (this->fpsTexture)
@ -423,6 +440,12 @@ bool opengl_render(void * opaque, SDL_Window * window)
return true; return true;
} }
static void render_wait()
{
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
static void handle_opt_mipmap(void * opaque, const char *value) static void handle_opt_mipmap(void * opaque, const char *value)
{ {
struct Inst * this = (struct Inst *)opaque; struct Inst * this = (struct Inst *)opaque;
@ -514,6 +537,45 @@ static bool _check_gl_error(unsigned int line, const char * name)
return true; 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;
}
}
SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0);
this->preConfigured = true;
return true;
}
static bool configure(struct Inst * this, SDL_Window *window) static bool configure(struct Inst * this, SDL_Window *window)
{ {
LG_LOCK(this->formatLock); LG_LOCK(this->formatLock);
@ -526,43 +588,6 @@ static bool configure(struct Inst * this, SDL_Window *window)
if (this->configured) if (this->configured)
deconfigure(this); deconfigure(this);
this->glContext = SDL_GL_CreateContext(window);
if (!this->glContext)
{
DEBUG_ERROR("Failed to create the OpenGL context");
LG_UNLOCK(this->formatLock);
return false;
}
if (!this->doneInfo)
{
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;
}
}
this->doneInfo = true;
}
SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0);
switch(this->format.comp) switch(this->format.comp)
{ {
case LG_COMPRESSION_NONE: case LG_COMPRESSION_NONE:
@ -635,12 +660,14 @@ static bool configure(struct Inst * this, SDL_Window *window)
{ {
const int pagesize = getpagesize(); const int pagesize = getpagesize();
this->texPixels[0] = memalign(pagesize, this->texSize * BUFFER_COUNT); this->texPixels[0] = memalign(pagesize, this->texSize * BUFFER_COUNT);
memset(this->texPixels[0], 0, this->texSize * BUFFER_COUNT);
for(int i = 1; i < BUFFER_COUNT; ++i) for(int i = 1; i < BUFFER_COUNT; ++i)
this->texPixels[i] = this->texPixels[0] + this->texSize; this->texPixels[i] = this->texPixels[0] + this->texSize;
for(int i = 0; i < BUFFER_COUNT; ++i) for(int i = 0; i < BUFFER_COUNT; ++i)
{ {
glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, this->vboID[i]); glBindBuffer(GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD, this->vboID[i]);
if (check_gl_error("glBindBuffer")) if (check_gl_error("glBindBuffer"))
{ {
LG_UNLOCK(this->formatLock); LG_UNLOCK(this->formatLock);
@ -1122,6 +1149,7 @@ static bool draw_frame(struct Inst * this)
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
LG_UNLOCK(this->formatLock); LG_UNLOCK(this->formatLock);
this->texReady = true;
return true; return true;
} }