mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 23:07:18 +00:00
[client] adjusted renderer interface to allow for APIs such as Vulkan
This commit is contained in:
parent
7280f305e0
commit
8ec4abc544
@ -27,6 +27,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#define IS_LG_RENDERER_VALID(x) \
|
||||
((x)->get_name && \
|
||||
(x)->initialize && \
|
||||
(x)->configure && \
|
||||
(x)->deconfigure && \
|
||||
(x)->deinitialize && \
|
||||
(x)->is_compatible && \
|
||||
(x)->on_resize && \
|
||||
@ -36,12 +38,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
typedef struct LG_RendererParams
|
||||
{
|
||||
SDL_Window * window;
|
||||
TTF_Font * font;
|
||||
bool showFPS;
|
||||
bool resample;
|
||||
int width;
|
||||
int height;
|
||||
TTF_Font * font;
|
||||
bool showFPS;
|
||||
bool resample;
|
||||
}
|
||||
LG_RendererParams;
|
||||
|
||||
@ -73,7 +72,9 @@ typedef enum LG_RendererCursor
|
||||
LG_RendererCursor;
|
||||
|
||||
typedef const char * (* LG_RendererGetName )();
|
||||
typedef bool (* LG_RendererInitialize )(void ** opaque, const LG_RendererParams params, const LG_RendererFormat format);
|
||||
typedef bool (* LG_RendererInitialize )(void ** opaque, const LG_RendererParams params, Uint32 * sdlFlags);
|
||||
typedef bool (* LG_RendererConfigure )(void * opaque, SDL_Window *window, const LG_RendererFormat format);
|
||||
typedef void (* LG_RendererDeConfigure )(void * opaque);
|
||||
typedef void (* LG_RendererDeInitialize )(void * opaque);
|
||||
typedef bool (* LG_RendererIsCompatible )(void * opaque, const LG_RendererFormat format);
|
||||
typedef void (* LG_RendererOnResize )(void * opaque, const int width, const int height, const LG_RendererRect destRect);
|
||||
@ -86,6 +87,8 @@ typedef struct LG_Renderer
|
||||
{
|
||||
LG_RendererGetName get_name;
|
||||
LG_RendererInitialize initialize;
|
||||
LG_RendererConfigure configure;
|
||||
LG_RendererDeConfigure deconfigure;
|
||||
LG_RendererDeInitialize deinitialize;
|
||||
LG_RendererIsCompatible is_compatible;
|
||||
LG_RendererOnResize on_resize;
|
||||
|
112
client/main.c
112
client/main.c
@ -228,67 +228,17 @@ int renderThread(void * unused)
|
||||
break;
|
||||
}
|
||||
|
||||
// check if we have a compatible renderer
|
||||
if (!state.lgr || !state.lgr->is_compatible(state.lgrData, lgrFormat))
|
||||
// check if the renderer needs reconfiguration
|
||||
if (!state.lgr->is_compatible(state.lgrData, lgrFormat))
|
||||
{
|
||||
int width, height;
|
||||
SDL_GetWindowSize(state.window, &width, &height);
|
||||
|
||||
LG_RendererParams lgrParams;
|
||||
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);
|
||||
|
||||
// first try to reinitialize any existing renderer
|
||||
if (state.lgr)
|
||||
state.lgr->deconfigure(state.lgrData);
|
||||
if (!state.lgr->configure(state.lgrData, state.window, lgrFormat))
|
||||
{
|
||||
state.lgr->deinitialize(state.lgrData);
|
||||
if (state.lgr->initialize(&state.lgrData, lgrParams, lgrFormat))
|
||||
{
|
||||
DEBUG_INFO("Reinitialized %s", state.lgr->get_name());
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_ERROR("Failed to reinitialize %s, trying other renderers", state.lgr->get_name());
|
||||
state.lgr->deinitialize(state.lgrData);
|
||||
state.lgr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!state.lgr)
|
||||
{
|
||||
// probe for a a suitable renderer
|
||||
for(const LG_Renderer **r = &LG_Renderers[0]; *r; ++r)
|
||||
{
|
||||
if (!IS_LG_RENDERER_VALID(*r))
|
||||
{
|
||||
DEBUG_ERROR("FIXME: Renderer %d is invalid, skipping", (int)(r - &LG_Renderers[0]));
|
||||
continue;
|
||||
}
|
||||
|
||||
state.lgrData = NULL;
|
||||
if (!(*r)->initialize(&state.lgrData, lgrParams, lgrFormat))
|
||||
{
|
||||
(*r)->deinitialize(state.lgrData);
|
||||
continue;
|
||||
}
|
||||
|
||||
state.lgr = *r;
|
||||
DEBUG_INFO("Initialized %s", (*r)->get_name());
|
||||
break;
|
||||
}
|
||||
|
||||
if (!state.lgr)
|
||||
{
|
||||
DEBUG_INFO("Unable to find a suitable renderer");
|
||||
return -1;
|
||||
}
|
||||
DEBUG_ERROR("Failed to reconfigure %s", state.lgr->get_name());
|
||||
break;
|
||||
}
|
||||
|
||||
state.srcSize.x = header.frame.width;
|
||||
@ -361,9 +311,6 @@ int renderThread(void * unused)
|
||||
state.lgr->render(state.lgrData);
|
||||
}
|
||||
|
||||
if (state.lgr)
|
||||
state.lgr->deinitialize(state.lgrData);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -661,7 +608,39 @@ int run()
|
||||
FcPatternDestroy(pat);
|
||||
}
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
|
||||
LG_RendererParams lgrParams;
|
||||
lgrParams.font = state.font;
|
||||
lgrParams.resample = params.useMipmap;
|
||||
lgrParams.showFPS = params.showFPS;
|
||||
Uint32 sdlFlags;
|
||||
|
||||
// probe for a a suitable renderer
|
||||
for(const LG_Renderer **r = &LG_Renderers[0]; *r; ++r)
|
||||
{
|
||||
if (!IS_LG_RENDERER_VALID(*r))
|
||||
{
|
||||
DEBUG_ERROR("FIXME: Renderer %d is invalid, skipping", (int)(r - &LG_Renderers[0]));
|
||||
continue;
|
||||
}
|
||||
|
||||
state.lgrData = NULL;
|
||||
sdlFlags = 0;
|
||||
if (!(*r)->initialize(&state.lgrData, lgrParams, &sdlFlags))
|
||||
{
|
||||
(*r)->deinitialize(state.lgrData);
|
||||
continue;
|
||||
}
|
||||
|
||||
state.lgr = *r;
|
||||
DEBUG_INFO("Initialized %s", (*r)->get_name());
|
||||
break;
|
||||
}
|
||||
|
||||
if (!state.lgr)
|
||||
{
|
||||
DEBUG_INFO("Unable to find a suitable renderer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
state.window = SDL_CreateWindow(
|
||||
"Looking Glass (Client)",
|
||||
@ -670,10 +649,10 @@ int run()
|
||||
params.w,
|
||||
params.h,
|
||||
(
|
||||
SDL_WINDOW_SHOWN |
|
||||
SDL_WINDOW_OPENGL |
|
||||
SDL_WINDOW_SHOWN |
|
||||
(params.allowResize ? SDL_WINDOW_RESIZABLE : 0) |
|
||||
(params.borderless ? SDL_WINDOW_BORDERLESS : 0)
|
||||
(params.borderless ? SDL_WINDOW_BORDERLESS : 0) |
|
||||
sdlFlags
|
||||
)
|
||||
);
|
||||
|
||||
@ -785,9 +764,7 @@ int run()
|
||||
usleep(1000);
|
||||
DEBUG_INFO("Host ready, starting session");
|
||||
|
||||
while(state.running)
|
||||
renderThread(NULL);
|
||||
|
||||
renderThread(NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -805,6 +782,9 @@ int run()
|
||||
if (t_spice)
|
||||
SDL_WaitThread(t_spice, NULL);
|
||||
|
||||
if (state.lgr)
|
||||
state.lgr->deinitialize(state.lgrData);
|
||||
|
||||
if (state.window)
|
||||
SDL_DestroyWindow(state.window);
|
||||
|
||||
|
@ -27,8 +27,11 @@ static PFNGLXWAITVIDEOSYNCSGIPROC glXWaitVideoSyncSGI = NULL;
|
||||
struct LGR_OpenGL
|
||||
{
|
||||
LG_RendererParams params;
|
||||
bool initialized;
|
||||
bool configured;
|
||||
SDL_GLContext glContext;
|
||||
bool doneInfo;
|
||||
|
||||
SDL_Point window;
|
||||
bool resizeWindow;
|
||||
bool frameUpdate;
|
||||
|
||||
@ -81,7 +84,7 @@ const char * lgr_opengl_get_name()
|
||||
return "OpenGL";
|
||||
}
|
||||
|
||||
bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const LG_RendererFormat format)
|
||||
bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, Uint32 * sdlFlags)
|
||||
{
|
||||
// create our local storage
|
||||
*opaque = malloc(sizeof(struct LGR_OpenGL));
|
||||
@ -91,26 +94,10 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const
|
||||
return false;
|
||||
}
|
||||
memset(*opaque, 0, sizeof(struct LGR_OpenGL));
|
||||
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)*opaque;
|
||||
memcpy(&this->params, ¶ms, sizeof(LG_RendererParams));
|
||||
|
||||
this->glContext = SDL_GL_CreateContext(params.window);
|
||||
if (!this->glContext)
|
||||
{
|
||||
DEBUG_ERROR("Failed to create the OpenGL context");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SDL_GL_MakeCurrent(params.window, this->glContext) != 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to make the GL context current");
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR ));
|
||||
DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER));
|
||||
DEBUG_INFO("Version : %s", glGetString(GL_VERSION ));
|
||||
|
||||
if (!glXGetVideoSyncSGI)
|
||||
{
|
||||
glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC )glXGetProcAddress((const GLubyte *)"glXGetVideoSyncSGI" );
|
||||
@ -124,6 +111,44 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const
|
||||
}
|
||||
}
|
||||
|
||||
*sdlFlags = SDL_WINDOW_OPENGL;
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool lgr_opengl_configure(void * opaque, SDL_Window *window, const LG_RendererFormat format)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this)
|
||||
return false;
|
||||
|
||||
if (this->configured)
|
||||
{
|
||||
DEBUG_ERROR("Renderer already configured, call deconfigure first");
|
||||
return false;
|
||||
}
|
||||
|
||||
this->glContext = SDL_GL_CreateContext(window);
|
||||
if (!this->glContext)
|
||||
{
|
||||
DEBUG_ERROR("Failed to create the OpenGL context");
|
||||
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 ));
|
||||
this->doneInfo = true;
|
||||
}
|
||||
|
||||
if (SDL_GL_MakeCurrent(window, this->glContext) != 0)
|
||||
{
|
||||
DEBUG_ERROR("Failed to make the GL context current");
|
||||
return false;
|
||||
}
|
||||
|
||||
SDL_GL_SetSwapInterval(0);
|
||||
|
||||
// check if the GPU supports GL_ARB_buffer_storage first
|
||||
@ -260,24 +285,45 @@ bool lgr_opengl_initialize(void ** opaque, const LG_RendererParams params, const
|
||||
|
||||
// copy the format into the local storage
|
||||
memcpy(&this->format, &format, sizeof(LG_RendererFormat));
|
||||
this->initialized = true;
|
||||
this->configured = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void lgr_opengl_deconfigure(void * opaque)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->configured)
|
||||
return;
|
||||
|
||||
if (this->hasTextures)
|
||||
{
|
||||
glDeleteTextures(TEXTURE_COUNT, this->textures);
|
||||
this->hasTextures = false;
|
||||
}
|
||||
|
||||
if (this->hasBuffers)
|
||||
{
|
||||
glDeleteBuffers(1, this->vboID);
|
||||
this->hasBuffers = false;
|
||||
}
|
||||
|
||||
if (this->glContext)
|
||||
{
|
||||
SDL_GL_DeleteContext(this->glContext);
|
||||
this->glContext = NULL;
|
||||
}
|
||||
|
||||
this->configured = false;
|
||||
}
|
||||
|
||||
void lgr_opengl_deinitialize(void * opaque)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this)
|
||||
return;
|
||||
|
||||
if (this->hasTextures)
|
||||
glDeleteTextures(TEXTURE_COUNT, this->textures);
|
||||
|
||||
if (this->hasBuffers)
|
||||
glDeleteBuffers(1, this->vboID);
|
||||
|
||||
if (this->glContext)
|
||||
SDL_GL_DeleteContext(this->glContext);
|
||||
if (this->configured)
|
||||
lgr_opengl_deconfigure(opaque);
|
||||
|
||||
free(this);
|
||||
}
|
||||
@ -285,7 +331,7 @@ void lgr_opengl_deinitialize(void * opaque)
|
||||
bool lgr_opengl_is_compatible(void * opaque, const LG_RendererFormat format)
|
||||
{
|
||||
const struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->initialized)
|
||||
if (!this || !this->configured)
|
||||
return false;
|
||||
|
||||
return (memcmp(&this->format, &format, sizeof(LG_RendererFormat)) == 0);
|
||||
@ -294,11 +340,11 @@ bool lgr_opengl_is_compatible(void * opaque, const LG_RendererFormat format)
|
||||
void lgr_opengl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->initialized)
|
||||
if (!this || !this->configured)
|
||||
return;
|
||||
|
||||
this->params.width = width;
|
||||
this->params.height = height;
|
||||
this->window.x = width;
|
||||
this->window.y = height;
|
||||
memcpy(&this->destRect, &destRect, sizeof(LG_RendererRect));
|
||||
|
||||
this->resizeWindow = true;
|
||||
@ -307,7 +353,7 @@ void lgr_opengl_on_resize(void * opaque, const int width, const int height, cons
|
||||
bool lgr_opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->initialized)
|
||||
if (!this || !this->configured)
|
||||
return false;
|
||||
|
||||
this->mouseType = cursor;
|
||||
@ -432,7 +478,7 @@ bool lgr_opengl_on_mouse_shape(void * opaque, const LG_RendererCursor cursor, co
|
||||
bool lgr_opengl_on_mouse_event(void * opaque, const bool visible, const int x, const int y)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->initialized)
|
||||
if (!this || !this->configured)
|
||||
return false;
|
||||
|
||||
if (this->mousePos.x == x && this->mousePos.y == y && this->mouseVisible == visible)
|
||||
@ -448,8 +494,17 @@ bool lgr_opengl_on_mouse_event(void * opaque, const bool visible, const int x, c
|
||||
bool lgr_opengl_on_frame_event(void * opaque, const uint8_t * data)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->initialized)
|
||||
if (!this)
|
||||
{
|
||||
DEBUG_ERROR("Invalid opaque pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this->configured)
|
||||
{
|
||||
DEBUG_ERROR("Not configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->params.showFPS && this->renderTime > 1e9)
|
||||
{
|
||||
@ -589,16 +644,16 @@ static inline void lgr_opengl_draw_mouse(struct LGR_OpenGL * this)
|
||||
bool lgr_opengl_render(void * opaque)
|
||||
{
|
||||
struct LGR_OpenGL * this = (struct LGR_OpenGL *)opaque;
|
||||
if (!this || !this->initialized)
|
||||
if (!this || !this->configured)
|
||||
return false;
|
||||
|
||||
if (this->resizeWindow)
|
||||
{
|
||||
// setup the projection matrix
|
||||
glViewport(0, 0, this->params.width, this->params.height);
|
||||
glViewport(0, 0, this->window.x, this->window.y);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, this->params.width, this->params.height, 0);
|
||||
gluOrtho2D(0, this->window.x, this->window.y, 0);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
@ -661,6 +716,8 @@ const LG_Renderer LGR_OpenGL =
|
||||
{
|
||||
.get_name = lgr_opengl_get_name,
|
||||
.initialize = lgr_opengl_initialize,
|
||||
.configure = lgr_opengl_configure,
|
||||
.deconfigure = lgr_opengl_deconfigure,
|
||||
.deinitialize = lgr_opengl_deinitialize,
|
||||
.is_compatible = lgr_opengl_is_compatible,
|
||||
.on_resize = lgr_opengl_on_resize,
|
||||
|
Loading…
Reference in New Issue
Block a user