From 973806dd9c7af3d2b85c7636a775471391c6ab76 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 27 Jan 2021 21:27:26 +1100 Subject: [PATCH] [client] opengl: implement & fix opengl support --- client/displayservers/SDL/sdl.c | 71 ++++++++++++++++++----- client/displayservers/X11/CMakeLists.txt | 2 + client/displayservers/X11/x11.c | 74 ++++++++++++++++++++++-- client/include/app.h | 4 ++ client/include/interface/displayserver.h | 11 ++++ client/renderers/OpenGL/opengl.c | 26 ++------- client/src/app.c | 20 +++++++ client/src/main.c | 7 +++ 8 files changed, 175 insertions(+), 40 deletions(-) diff --git a/client/displayservers/SDL/sdl.c b/client/displayservers/SDL/sdl.c index 6dcbbbe1..d1135053 100644 --- a/client/displayservers/SDL/sdl.c +++ b/client/displayservers/SDL/sdl.c @@ -22,7 +22,9 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include +#ifdef ENABLE_EGL #include +#endif #if defined(SDL_VIDEO_DRIVER_WAYLAND) #include @@ -58,6 +60,13 @@ static bool sdlProbe(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. SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); @@ -67,12 +76,15 @@ static bool sdlEarlyInit(void) return false; } - return true; -} - -static bool sdlInit(const LG_DSInitParams params) -{ - memset(&sdl, 0, sizeof(sdl)); + if (params.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); + } sdl.window = SDL_CreateWindow( params.title, @@ -84,14 +96,15 @@ static bool sdlInit(const LG_DSInitParams params) SDL_WINDOW_HIDDEN | (params.resizable ? SDL_WINDOW_RESIZABLE : 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) { 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}; @@ -115,6 +128,10 @@ static bool sdlInit(const LG_DSInitParams params) SDL_SetEventFilter(sdlEventFilter, NULL); return true; + +fail_init: + SDL_Quit(); + return false; } static void sdlStartup(void) @@ -123,11 +140,12 @@ static void sdlStartup(void) static void sdlShutdown(void) { - SDL_DestroyWindow(sdl.window); } static void sdlFree(void) { + SDL_DestroyWindow(sdl.window); + if (sdl.cursor) SDL_FreeCursor(sdl.cursor); @@ -234,9 +252,29 @@ static void sdlEGLSwapBuffers(EGLDisplay display, EGLSurface 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); } @@ -334,8 +372,9 @@ static int sdlEventFilter(void * userdata, SDL_Event * event) &border.bottom, &border.right ); - - app_handleResizeEvent(event->window.data1, event->window.data2, + app_handleResizeEvent( + event->window.data1, + event->window.data2, border); break; } @@ -478,7 +517,11 @@ struct LG_DisplayServerOps LGDS_SDL = .eglSwapBuffers = sdlEGLSwapBuffers, #endif - .glSwapBuffers = sdlSwapBuffers, + .glCreateContext = sdlGLCreateContext, + .glDeleteContext = sdlGLDeleteContext, + .glMakeCurrent = sdlGLMakeCurrent, + .glSetSwapInterval = sdlGLSetSwapInterval, + .glSwapBuffers = sdlGLSwapBuffers, .showPointer = sdlShowPointer, .grabPointer = sdlGrabPointer, diff --git a/client/displayservers/X11/CMakeLists.txt b/client/displayservers/X11/CMakeLists.txt index c88f4408..80a9edf6 100644 --- a/client/displayservers/X11/CMakeLists.txt +++ b/client/displayservers/X11/CMakeLists.txt @@ -14,6 +14,8 @@ add_library(displayserver_X11 STATIC x11.c ) +add_definitions(-D GLX_GLXEXT_PROTOTYPES) + target_link_libraries(displayserver_X11 ${DISPLAYSERVER_X11_PKGCONFIG_LIBRARIES} lg_common diff --git a/client/displayservers/X11/x11.c b/client/displayservers/X11/x11.c index 87e39ec2..323db306 100644 --- a/client/displayservers/X11/x11.c +++ b/client/displayservers/X11/x11.c @@ -31,10 +31,14 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #include +#include + +#ifdef ENABLE_EGL #include +#include "egl_dynprocs.h" +#endif #include "app.h" -#include "egl_dynprocs.h" #include "common/debug.h" #include "common/thread.h" @@ -44,9 +48,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA struct X11DSState { - Display * display; - Window window; - int xinputOp; + Display * display; + Window window; + XVisualInfo * visual; + int xinputOp; LGThread * eventThread; @@ -137,6 +142,36 @@ static bool x11Init(const LG_DSInitParams params) PropertyChangeMask | 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.display, @@ -144,8 +179,10 @@ static bool x11Init(const LG_DSInitParams params) params.x, params.y, params.w, params.h, 0, - CopyFromParent, InputOutput, - CopyFromParent, CWEventMask, + x11.visual ? x11.visual->depth : CopyFromParent, + InputOutput, + x11.visual ? x11.visual->visual : CopyFromParent, + swaMask, &swa); if (!x11.window) @@ -835,6 +872,27 @@ static void x11EGLSwapBuffers(EGLDisplay display, EGLSurface surface) } #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) { glXSwapBuffers(x11.display, x11.window); @@ -1391,6 +1449,10 @@ struct LG_DisplayServerOps LGDS_X11 = .getEGLNativeWindow = x11GetEGLNativeWindow, .eglSwapBuffers = x11EGLSwapBuffers, #endif + .glCreateContext = x11GLCreateContext, + .glDeleteContext = x11GLDeleteContext, + .glMakeCurrent = x11GLMakeCurrent, + .glSetSwapInterval = x11GLSetSwapInterval, .glSwapBuffers = x11GLSwapBuffers, .showPointer = x11ShowPointer, .grabPointer = x11GrabPointer, diff --git a/client/include/app.h b/client/include/app.h index c683b4f4..4bb57ab5 100644 --- a/client/include/app.h +++ b/client/include/app.h @@ -64,6 +64,10 @@ EGLNativeWindowType app_getEGLNativeWindow(void); void app_eglSwapBuffers(EGLDisplay display, EGLSurface surface); #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_clipboardRelease(void); diff --git a/client/include/interface/displayserver.h b/client/include/interface/displayserver.h index 1b99dc1b..f7ffbf0b 100644 --- a/client/include/interface/displayserver.h +++ b/client/include/interface/displayserver.h @@ -72,6 +72,9 @@ LG_DSInitParams; typedef void (* LG_ClipboardReplyFn)(void * opaque, const LG_ClipboardData type, uint8_t * data, uint32_t size); +typedef struct LG_DSGLContext + * LG_DSGLContext; + struct LG_DisplayServerOps { /* return true if the selected ds is valid for the current platform */ @@ -107,6 +110,10 @@ struct LG_DisplayServerOps #endif /* 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); /* dm specific cursor implementations */ @@ -163,6 +170,10 @@ struct LG_DisplayServerOps ASSERT_EGL_FN((x)->getEGLDisplay ); \ ASSERT_EGL_FN((x)->getEGLNativeWindow ); \ ASSERT_EGL_FN((x)->eglSwapBuffers ); \ + assert((x)->glCreateContext ); \ + assert((x)->glDeleteContext ); \ + assert((x)->glMakeCurrent ); \ + assert((x)->glSetSwapInterval ); \ assert((x)->glSwapBuffers ); \ assert((x)->showPointer ); \ assert((x)->grabPointer ); \ diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 47322122..b2e3ed1e 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -108,7 +108,7 @@ struct Inst bool renderStarted; bool configured; bool reconfigure; - SDL_GLContext glContext; + LG_DSGLContext glContext; SDL_Point window; bool frameUpdate; @@ -246,17 +246,6 @@ bool opengl_initialize(void * opaque) this->waiting = true; this->waitDone = false; 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) @@ -279,7 +268,7 @@ void opengl_deinitialize(void * opaque) if (this->glContext) { - SDL_GL_DeleteContext(this->glContext); + app_glDeleteContext(this->glContext); this->glContext = NULL; } @@ -499,16 +488,14 @@ void bitmap_to_texture(LG_FontBitmap * bitmap, GLuint texture) bool opengl_render_startup(void * opaque) { - //FIXME - return false; -#if 0 - struct Inst * this = (struct Inst *)opaque; - this->glContext = app_getGLContext(); + this->glContext = app_glCreateContext(); if (!this->glContext) return false; + app_glMakeCurrent(this->glContext); + DEBUG_INFO("Vendor : %s", glGetString(GL_VENDOR )); DEBUG_INFO("Renderer: %s", glGetString(GL_RENDERER)); DEBUG_INFO("Version : %s", glGetString(GL_VERSION )); @@ -552,10 +539,9 @@ bool opengl_render_startup(void * opaque) } this->hasTextures = true; - SDL_GL_SetSwapInterval(this->opt.vsync ? 1 : 0); + app_glSetSwapInterval(this->opt.vsync ? 1 : 0); this->renderStarted = true; return true; -#endif } bool opengl_render(void * opaque, LG_RendererRotate rotate) diff --git a/client/src/app.c b/client/src/app.c index 42f7dc88..42c8b7d8 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -583,6 +583,26 @@ void app_eglSwapBuffers(EGLDisplay display, EGLSurface surface) } #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) { g_state.ds->glSwapBuffers(); diff --git a/client/src/main.c b/client/src/main.c index 4cc9febd..9e3eff88 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -722,6 +722,13 @@ static int lg_run(void) 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 = { .title = g_params.windowTitle,