mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-10 08:38:20 +00:00
[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
This commit is contained in:
parent
13cd50f92c
commit
83592f7e4a
@ -35,6 +35,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
(x)->on_mouse_shape && \
|
(x)->on_mouse_shape && \
|
||||||
(x)->on_mouse_event && \
|
(x)->on_mouse_event && \
|
||||||
(x)->on_alert && \
|
(x)->on_alert && \
|
||||||
|
(x)->render_startup && \
|
||||||
(x)->render)
|
(x)->render)
|
||||||
|
|
||||||
#define LGR_OPTION_COUNT(x) (sizeof(x) / sizeof(LG_RendererOpt))
|
#define LGR_OPTION_COUNT(x) (sizeof(x) / sizeof(LG_RendererOpt))
|
||||||
@ -129,6 +130,7 @@ typedef struct LG_Renderer
|
|||||||
LG_RendererOnMouseEvent on_mouse_event;
|
LG_RendererOnMouseEvent on_mouse_event;
|
||||||
LG_RendererOnFrameEvent on_frame_event;
|
LG_RendererOnFrameEvent on_frame_event;
|
||||||
LG_RendererOnAlert on_alert;
|
LG_RendererOnAlert on_alert;
|
||||||
|
LG_RendererRender render_startup;
|
||||||
LG_RendererRender render;
|
LG_RendererRender render;
|
||||||
}
|
}
|
||||||
LG_Renderer;
|
LG_Renderer;
|
||||||
|
@ -54,6 +54,7 @@ struct AppState
|
|||||||
TTF_Font * font;
|
TTF_Font * font;
|
||||||
TTF_Font * alertFont;
|
TTF_Font * alertFont;
|
||||||
bool haveSrcSize;
|
bool haveSrcSize;
|
||||||
|
int windowW, windowH;
|
||||||
SDL_Point srcSize;
|
SDL_Point srcSize;
|
||||||
LG_RendererRect dstRect;
|
LG_RendererRect dstRect;
|
||||||
SDL_Point cursor;
|
SDL_Point cursor;
|
||||||
@ -64,6 +65,7 @@ struct AppState
|
|||||||
|
|
||||||
const LG_Renderer * lgr ;
|
const LG_Renderer * lgr ;
|
||||||
void * lgrData;
|
void * lgrData;
|
||||||
|
bool lgrResize;
|
||||||
|
|
||||||
SDL_Window * window;
|
SDL_Window * window;
|
||||||
int shmFD;
|
int shmFD;
|
||||||
@ -144,36 +146,35 @@ struct AppParams params =
|
|||||||
|
|
||||||
static inline void updatePositionInfo()
|
static inline void updatePositionInfo()
|
||||||
{
|
{
|
||||||
int w, h;
|
SDL_GetWindowSize(state.window, &state.windowW, &state.windowH);
|
||||||
SDL_GetWindowSize(state.window, &w, &h);
|
|
||||||
|
|
||||||
if (state.haveSrcSize)
|
if (state.haveSrcSize)
|
||||||
{
|
{
|
||||||
if (params.keepAspect)
|
if (params.keepAspect)
|
||||||
{
|
{
|
||||||
const float srcAspect = (float)state.srcSize.y / (float)state.srcSize.x;
|
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)
|
if (wndAspect < srcAspect)
|
||||||
{
|
{
|
||||||
state.dstRect.w = (float)h / srcAspect;
|
state.dstRect.w = (float)state.windowH / srcAspect;
|
||||||
state.dstRect.h = h;
|
state.dstRect.h = state.windowH;
|
||||||
state.dstRect.x = (w >> 1) - (state.dstRect.w >> 1);
|
state.dstRect.x = (state.windowW >> 1) - (state.dstRect.w >> 1);
|
||||||
state.dstRect.y = 0;
|
state.dstRect.y = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.dstRect.w = w;
|
state.dstRect.w = state.windowW;
|
||||||
state.dstRect.h = (float)w * srcAspect;
|
state.dstRect.h = (float)state.windowW * srcAspect;
|
||||||
state.dstRect.x = 0;
|
state.dstRect.x = 0;
|
||||||
state.dstRect.y = (h >> 1) - (state.dstRect.h >> 1);
|
state.dstRect.y = (state.windowH >> 1) - (state.dstRect.h >> 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.dstRect.x = 0;
|
state.dstRect.x = 0;
|
||||||
state.dstRect.y = 0;
|
state.dstRect.y = 0;
|
||||||
state.dstRect.w = w;
|
state.dstRect.w = state.windowW;
|
||||||
state.dstRect.h = h;
|
state.dstRect.h = state.windowH;
|
||||||
}
|
}
|
||||||
state.dstRect.valid = true;
|
state.dstRect.valid = true;
|
||||||
|
|
||||||
@ -181,14 +182,23 @@ static inline void updatePositionInfo()
|
|||||||
state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w;
|
state.scaleY = (float)state.srcSize.x / (float)state.dstRect.w;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.lgr)
|
state.lgrResize = true;
|
||||||
state.lgr->on_resize(state.lgrData, w, h, state.dstRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int renderThread(void * unused)
|
int renderThread(void * unused)
|
||||||
{
|
{
|
||||||
|
if (!state.lgr->render_startup(state.lgrData, state.window))
|
||||||
|
return 1;
|
||||||
|
|
||||||
while(state.running)
|
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();
|
const uint64_t start = microtime();
|
||||||
|
|
||||||
if (!state.lgr->render(state.lgrData, state.window))
|
if (!state.lgr->render(state.lgrData, state.window))
|
||||||
|
@ -80,13 +80,12 @@ struct Inst
|
|||||||
struct Options opt;
|
struct Options opt;
|
||||||
|
|
||||||
bool amdPinnedMemSupport;
|
bool amdPinnedMemSupport;
|
||||||
bool preConfigured;
|
bool renderStarted;
|
||||||
bool configured;
|
bool configured;
|
||||||
bool reconfigure;
|
bool reconfigure;
|
||||||
SDL_GLContext glContext;
|
SDL_GLContext glContext;
|
||||||
|
|
||||||
SDL_Point window;
|
SDL_Point window;
|
||||||
bool resizeWindow;
|
|
||||||
bool frameUpdate;
|
bool frameUpdate;
|
||||||
|
|
||||||
LG_Lock formatLock;
|
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)
|
#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);
|
||||||
@ -205,7 +203,7 @@ void opengl_deinitialize(void * opaque)
|
|||||||
if (!this)
|
if (!this)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this->preConfigured)
|
if (this->renderStarted)
|
||||||
{
|
{
|
||||||
glDeleteLists(this->texList , BUFFER_COUNT);
|
glDeleteLists(this->texList , BUFFER_COUNT);
|
||||||
glDeleteLists(this->mouseList, 1);
|
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)
|
void opengl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
if (!this)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this->window.x = width;
|
this->window.x = width;
|
||||||
this->window.y = height;
|
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)
|
if (destRect.valid)
|
||||||
memcpy(&this->destRect, &destRect, sizeof(LG_RendererRect));
|
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)
|
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);
|
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)
|
bool opengl_render(void * opaque, SDL_Window * window)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
if (!this)
|
if (!this)
|
||||||
return false;
|
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 (configure(this, window))
|
||||||
if (!draw_frame(this))
|
if (!draw_frame(this))
|
||||||
return false;
|
return false;
|
||||||
@ -800,6 +845,7 @@ const LG_Renderer LGR_OpenGL =
|
|||||||
.on_mouse_event = opengl_on_mouse_event,
|
.on_mouse_event = opengl_on_mouse_event,
|
||||||
.on_frame_event = opengl_on_frame_event,
|
.on_frame_event = opengl_on_frame_event,
|
||||||
.on_alert = opengl_on_alert,
|
.on_alert = opengl_on_alert,
|
||||||
|
.render_startup = opengl_render_startup,
|
||||||
.render = opengl_render
|
.render = opengl_render
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -814,66 +860,6 @@ 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
static bool configure(struct Inst * this, SDL_Window *window)
|
||||||
{
|
{
|
||||||
LG_LOCK(this->formatLock);
|
LG_LOCK(this->formatLock);
|
||||||
@ -1085,9 +1071,7 @@ static bool configure(struct Inst * this, SDL_Window *window)
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||||
|
|
||||||
this->resizeWindow = true;
|
|
||||||
this->drawStart = nanotime();
|
this->drawStart = nanotime();
|
||||||
|
|
||||||
this->configured = true;
|
this->configured = true;
|
||||||
this->reconfigure = false;
|
this->reconfigure = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user