[client] opengl: implement & fix opengl support

This commit is contained in:
Geoffrey McRae 2021-01-27 21:27:26 +11:00
parent 740dad943b
commit 973806dd9c
8 changed files with 175 additions and 40 deletions

View File

@ -22,7 +22,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h> #include <SDL2/SDL_syswm.h>
#ifdef ENABLE_EGL
#include <EGL/eglext.h> #include <EGL/eglext.h>
#endif
#if defined(SDL_VIDEO_DRIVER_WAYLAND) #if defined(SDL_VIDEO_DRIVER_WAYLAND)
#include <wayland-egl.h> #include <wayland-egl.h>
@ -58,6 +60,13 @@ static bool sdlProbe(void)
static bool sdlEarlyInit(void) static bool sdlEarlyInit(void)
{ {
return true;
}
static bool sdlInit(const LG_DSInitParams params)
{
memset(&sdl, 0, sizeof(sdl));
// Allow screensavers for now: we will enable and disable as needed. // Allow screensavers for now: we will enable and disable as needed.
SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
@ -67,12 +76,15 @@ static bool sdlEarlyInit(void)
return false; return false;
} }
return true; if (params.opengl)
} {
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER , 1);
static bool sdlInit(const LG_DSInitParams params) SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
{ SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
memset(&sdl, 0, sizeof(sdl)); SDL_GL_SetAttribute(SDL_GL_RED_SIZE , 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE , 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8);
}
sdl.window = SDL_CreateWindow( sdl.window = SDL_CreateWindow(
params.title, params.title,
@ -84,14 +96,15 @@ static bool sdlInit(const LG_DSInitParams params)
SDL_WINDOW_HIDDEN | SDL_WINDOW_HIDDEN |
(params.resizable ? SDL_WINDOW_RESIZABLE : 0) | (params.resizable ? SDL_WINDOW_RESIZABLE : 0) |
(params.borderless ? SDL_WINDOW_BORDERLESS : 0) | (params.borderless ? SDL_WINDOW_BORDERLESS : 0) |
(params.maximize ? SDL_WINDOW_MAXIMIZED : 0) (params.maximize ? SDL_WINDOW_MAXIMIZED : 0) |
(params.opengl ? SDL_WINDOW_OPENGL : 0)
) )
); );
if (sdl.window == NULL) if (sdl.window == NULL)
{ {
DEBUG_ERROR("Could not create an SDL window: %s\n", SDL_GetError()); DEBUG_ERROR("Could not create an SDL window: %s\n", SDL_GetError());
return 1; goto fail_init;
} }
const uint8_t data[4] = {0xf, 0x9, 0x9, 0xf}; const uint8_t data[4] = {0xf, 0x9, 0x9, 0xf};
@ -115,6 +128,10 @@ static bool sdlInit(const LG_DSInitParams params)
SDL_SetEventFilter(sdlEventFilter, NULL); SDL_SetEventFilter(sdlEventFilter, NULL);
return true; return true;
fail_init:
SDL_Quit();
return false;
} }
static void sdlStartup(void) static void sdlStartup(void)
@ -123,11 +140,12 @@ static void sdlStartup(void)
static void sdlShutdown(void) static void sdlShutdown(void)
{ {
SDL_DestroyWindow(sdl.window);
} }
static void sdlFree(void) static void sdlFree(void)
{ {
SDL_DestroyWindow(sdl.window);
if (sdl.cursor) if (sdl.cursor)
SDL_FreeCursor(sdl.cursor); SDL_FreeCursor(sdl.cursor);
@ -234,9 +252,29 @@ static void sdlEGLSwapBuffers(EGLDisplay display, EGLSurface surface)
{ {
eglSwapBuffers(display, surface); eglSwapBuffers(display, surface);
} }
#endif #endif //ENABLE_EGL
static void sdlSwapBuffers(void) static LG_DSGLContext sdlGLCreateContext(void)
{
return (LG_DSGLContext)SDL_GL_CreateContext(sdl.window);
}
static void sdlGLDeleteContext(LG_DSGLContext context)
{
SDL_GL_DeleteContext((SDL_GLContext)context);
}
static void sdlGLMakeCurrent(LG_DSGLContext context)
{
SDL_GL_MakeCurrent(sdl.window, (SDL_GLContext)context);
}
static void sdlGLSetSwapInterval(int interval)
{
SDL_GL_SetSwapInterval(interval);
}
static void sdlGLSwapBuffers(void)
{ {
SDL_GL_SwapWindow(sdl.window); SDL_GL_SwapWindow(sdl.window);
} }
@ -334,8 +372,9 @@ static int sdlEventFilter(void * userdata, SDL_Event * event)
&border.bottom, &border.bottom,
&border.right &border.right
); );
app_handleResizeEvent(
app_handleResizeEvent(event->window.data1, event->window.data2, event->window.data1,
event->window.data2,
border); border);
break; break;
} }
@ -478,7 +517,11 @@ struct LG_DisplayServerOps LGDS_SDL =
.eglSwapBuffers = sdlEGLSwapBuffers, .eglSwapBuffers = sdlEGLSwapBuffers,
#endif #endif
.glSwapBuffers = sdlSwapBuffers, .glCreateContext = sdlGLCreateContext,
.glDeleteContext = sdlGLDeleteContext,
.glMakeCurrent = sdlGLMakeCurrent,
.glSetSwapInterval = sdlGLSetSwapInterval,
.glSwapBuffers = sdlGLSwapBuffers,
.showPointer = sdlShowPointer, .showPointer = sdlShowPointer,
.grabPointer = sdlGrabPointer, .grabPointer = sdlGrabPointer,

View File

@ -14,6 +14,8 @@ add_library(displayserver_X11 STATIC
x11.c x11.c
) )
add_definitions(-D GLX_GLXEXT_PROTOTYPES)
target_link_libraries(displayserver_X11 target_link_libraries(displayserver_X11
${DISPLAYSERVER_X11_PKGCONFIG_LIBRARIES} ${DISPLAYSERVER_X11_PKGCONFIG_LIBRARIES}
lg_common lg_common

View File

@ -31,10 +31,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#include <GL/glx.h> #include <GL/glx.h>
#include <GL/glxext.h>
#ifdef ENABLE_EGL
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include "egl_dynprocs.h"
#endif
#include "app.h" #include "app.h"
#include "egl_dynprocs.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/thread.h" #include "common/thread.h"
@ -44,9 +48,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA
struct X11DSState struct X11DSState
{ {
Display * display; Display * display;
Window window; Window window;
int xinputOp; XVisualInfo * visual;
int xinputOp;
LGThread * eventThread; LGThread * eventThread;
@ -137,6 +142,36 @@ static bool x11Init(const LG_DSInitParams params)
PropertyChangeMask | PropertyChangeMask |
ExposureMask ExposureMask
}; };
unsigned long swaMask = CWEventMask;
if (params.opengl)
{
GLint glXAttribs[] =
{
GLX_RGBA,
GLX_DEPTH_SIZE , 24,
GLX_STENCIL_SIZE , 0,
GLX_RED_SIZE , 8,
GLX_GREEN_SIZE , 8,
GLX_BLUE_SIZE , 8,
GLX_SAMPLE_BUFFERS, 0,
GLX_SAMPLES , 0,
None
};
x11.visual = glXChooseVisual(x11.display,
XDefaultScreen(x11.display), glXAttribs);
if (!x11.visual)
{
DEBUG_ERROR("glXChooseVisual failed");
goto fail_display;
}
swa.colormap = XCreateColormap(x11.display, XDefaultRootWindow(x11.display),
x11.visual->visual, AllocNone);
swaMask |= CWColormap;
}
x11.window = XCreateWindow( x11.window = XCreateWindow(
x11.display, x11.display,
@ -144,8 +179,10 @@ static bool x11Init(const LG_DSInitParams params)
params.x, params.y, params.x, params.y,
params.w, params.h, params.w, params.h,
0, 0,
CopyFromParent, InputOutput, x11.visual ? x11.visual->depth : CopyFromParent,
CopyFromParent, CWEventMask, InputOutput,
x11.visual ? x11.visual->visual : CopyFromParent,
swaMask,
&swa); &swa);
if (!x11.window) if (!x11.window)
@ -835,6 +872,27 @@ static void x11EGLSwapBuffers(EGLDisplay display, EGLSurface surface)
} }
#endif #endif
static LG_DSGLContext x11GLCreateContext(void)
{
return (LG_DSGLContext)
glXCreateContext(x11.display, x11.visual, NULL, GL_TRUE);
}
static void x11GLDeleteContext(LG_DSGLContext context)
{
glXDestroyContext(x11.display, (GLXContext)context);
}
static void x11GLMakeCurrent(LG_DSGLContext context)
{
glXMakeCurrent(x11.display, x11.window, (GLXContext)context);
}
static void x11GLSetSwapInterval(int interval)
{
glXSwapIntervalEXT(x11.display, x11.window, interval);
}
static void x11GLSwapBuffers(void) static void x11GLSwapBuffers(void)
{ {
glXSwapBuffers(x11.display, x11.window); glXSwapBuffers(x11.display, x11.window);
@ -1391,6 +1449,10 @@ struct LG_DisplayServerOps LGDS_X11 =
.getEGLNativeWindow = x11GetEGLNativeWindow, .getEGLNativeWindow = x11GetEGLNativeWindow,
.eglSwapBuffers = x11EGLSwapBuffers, .eglSwapBuffers = x11EGLSwapBuffers,
#endif #endif
.glCreateContext = x11GLCreateContext,
.glDeleteContext = x11GLDeleteContext,
.glMakeCurrent = x11GLMakeCurrent,
.glSetSwapInterval = x11GLSetSwapInterval,
.glSwapBuffers = x11GLSwapBuffers, .glSwapBuffers = x11GLSwapBuffers,
.showPointer = x11ShowPointer, .showPointer = x11ShowPointer,
.grabPointer = x11GrabPointer, .grabPointer = x11GrabPointer,

View File

@ -64,6 +64,10 @@ EGLNativeWindowType app_getEGLNativeWindow(void);
void app_eglSwapBuffers(EGLDisplay display, EGLSurface surface); void app_eglSwapBuffers(EGLDisplay display, EGLSurface surface);
#endif #endif
LG_DSGLContext app_glCreateContext(void);
void app_glDeleteContext(LG_DSGLContext context);
void app_glMakeCurrent(LG_DSGLContext context);
void app_glSetSwapInterval(int interval);
void app_glSwapBuffers(void); void app_glSwapBuffers(void);
void app_clipboardRelease(void); void app_clipboardRelease(void);

View File

@ -72,6 +72,9 @@ LG_DSInitParams;
typedef void (* LG_ClipboardReplyFn)(void * opaque, const LG_ClipboardData type, typedef void (* LG_ClipboardReplyFn)(void * opaque, const LG_ClipboardData type,
uint8_t * data, uint32_t size); uint8_t * data, uint32_t size);
typedef struct LG_DSGLContext
* LG_DSGLContext;
struct LG_DisplayServerOps struct LG_DisplayServerOps
{ {
/* return true if the selected ds is valid for the current platform */ /* return true if the selected ds is valid for the current platform */
@ -107,6 +110,10 @@ struct LG_DisplayServerOps
#endif #endif
/* opengl platform specific methods */ /* opengl platform specific methods */
LG_DSGLContext (*glCreateContext)(void);
void (*glDeleteContext)(LG_DSGLContext context);
void (*glMakeCurrent)(LG_DSGLContext context);
void (*glSetSwapInterval)(int interval);
void (*glSwapBuffers)(void); void (*glSwapBuffers)(void);
/* dm specific cursor implementations */ /* dm specific cursor implementations */
@ -163,6 +170,10 @@ struct LG_DisplayServerOps
ASSERT_EGL_FN((x)->getEGLDisplay ); \ ASSERT_EGL_FN((x)->getEGLDisplay ); \
ASSERT_EGL_FN((x)->getEGLNativeWindow ); \ ASSERT_EGL_FN((x)->getEGLNativeWindow ); \
ASSERT_EGL_FN((x)->eglSwapBuffers ); \ ASSERT_EGL_FN((x)->eglSwapBuffers ); \
assert((x)->glCreateContext ); \
assert((x)->glDeleteContext ); \
assert((x)->glMakeCurrent ); \
assert((x)->glSetSwapInterval ); \
assert((x)->glSwapBuffers ); \ assert((x)->glSwapBuffers ); \
assert((x)->showPointer ); \ assert((x)->showPointer ); \
assert((x)->grabPointer ); \ assert((x)->grabPointer ); \

View File

@ -108,7 +108,7 @@ struct Inst
bool renderStarted; bool renderStarted;
bool configured; bool configured;
bool reconfigure; bool reconfigure;
SDL_GLContext glContext; LG_DSGLContext glContext;
SDL_Point window; SDL_Point window;
bool frameUpdate; bool frameUpdate;
@ -246,17 +246,6 @@ bool opengl_initialize(void * opaque)
this->waiting = true; this->waiting = true;
this->waitDone = false; this->waitDone = false;
return true; return true;
#if 0
*sdlFlags = SDL_WINDOW_OPENGL;
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER , 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE , 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE , 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE , 8);
return true;
#endif
} }
void opengl_deinitialize(void * opaque) void opengl_deinitialize(void * opaque)
@ -279,7 +268,7 @@ void opengl_deinitialize(void * opaque)
if (this->glContext) if (this->glContext)
{ {
SDL_GL_DeleteContext(this->glContext); app_glDeleteContext(this->glContext);
this->glContext = NULL; this->glContext = NULL;
} }
@ -499,16 +488,14 @@ void bitmap_to_texture(LG_FontBitmap * bitmap, GLuint texture)
bool opengl_render_startup(void * opaque) bool opengl_render_startup(void * opaque)
{ {
//FIXME
return false;
#if 0
struct Inst * this = (struct Inst *)opaque; struct Inst * this = (struct Inst *)opaque;
this->glContext = app_getGLContext(); this->glContext = app_glCreateContext();
if (!this->glContext) if (!this->glContext)
return false; return false;
app_glMakeCurrent(this->glContext);
DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR )); DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR ));
DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER)); DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER));
DEBUG_INFO("Version : %s", glGetString(GL_VERSION )); DEBUG_INFO("Version : %s", glGetString(GL_VERSION ));
@ -552,10 +539,9 @@ bool opengl_render_startup(void * opaque)
} }
this->hasTextures = true; this->hasTextures = true;
SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0); app_glSetSwapInterval(this->opt.vsync ? 1 : 0);
this->renderStarted = true; this->renderStarted = true;
return true; return true;
#endif
} }
bool opengl_render(void * opaque, LG_RendererRotate rotate) bool opengl_render(void * opaque, LG_RendererRotate rotate)

View File

@ -583,6 +583,26 @@ void app_eglSwapBuffers(EGLDisplay display, EGLSurface surface)
} }
#endif #endif
LG_DSGLContext app_glCreateContext(void)
{
return g_state.ds->glCreateContext();
}
void app_glDeleteContext(LG_DSGLContext context)
{
g_state.ds->glDeleteContext(context);
}
void app_glMakeCurrent(LG_DSGLContext context)
{
g_state.ds->glMakeCurrent(context);
}
void app_glSetSwapInterval(int interval)
{
g_state.ds->glSetSwapInterval(interval);
}
void app_glSwapBuffers(void) void app_glSwapBuffers(void)
{ {
g_state.ds->glSwapBuffers(); g_state.ds->glSwapBuffers();

View File

@ -722,6 +722,13 @@ static int lg_run(void)
return -1; return -1;
} }
// initialize the window dimensions at init for renderers
g_state.windowW = g_params.w;
g_state.windowH = g_params.h;
g_state.windowCX = g_params.w / 2;
g_state.windowCY = g_params.h / 2;
core_updatePositionInfo();
const LG_DSInitParams params = const LG_DSInitParams params =
{ {
.title = g_params.windowTitle, .title = g_params.windowTitle,