libobs-opengl: Factor out GLX winsys

Move the GLX-related code to gl-x11-glx, and introduce gl-nix as
a winsys-agnostic abstraction layer. gl-nix serves as the runtime
selector of which winsys going to be used. Only the X11/GLX winsys
is available now, but later commits will introduce the X11/EGL
winsys as well.

The gl-nix code was originally written by Jason Francis <cycl0ps@tuta.io>
master
Georges Basile Stavracas Neto 2020-03-09 16:46:37 -03:00
parent 83ae6f6f43
commit 647415ec4f
5 changed files with 224 additions and 18 deletions

View File

@ -45,6 +45,7 @@ else() #This needs to change to be more specific to get ready for Wayland
${X11_XCB_LIBRARIES})
set(libobs-opengl_PLATFORM_SOURCES
gl-nix.c
gl-x11-glx.c)
endif()

107
libobs-opengl/gl-nix.c Normal file
View File

@ -0,0 +1,107 @@
/******************************************************************************
Copyright (C) 2019 by Jason Francis <cycl0ps@tuta.io>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#include "gl-nix.h"
#include "gl-x11-glx.h"
static const struct gl_winsys_vtable *gl_vtable = NULL;
static void init_winsys(void)
{
assert(gl_vtable == NULL);
gl_vtable = gl_x11_glx_get_winsys_vtable();
assert(gl_vtable != NULL);
}
extern struct gl_windowinfo *
gl_windowinfo_create(const struct gs_init_data *info)
{
return gl_vtable->windowinfo_create(info);
}
extern void gl_windowinfo_destroy(struct gl_windowinfo *info)
{
gl_vtable->windowinfo_destroy(info);
}
extern struct gl_platform *gl_platform_create(gs_device_t *device,
uint32_t adapter)
{
init_winsys();
return gl_vtable->platform_create(device, adapter);
}
extern void gl_platform_destroy(struct gl_platform *plat)
{
gl_vtable->platform_destroy(plat);
gl_vtable = NULL;
}
extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap)
{
return gl_vtable->platform_init_swapchain(swap);
}
extern void gl_platform_cleanup_swapchain(struct gs_swap_chain *swap)
{
gl_vtable->platform_cleanup_swapchain(swap);
}
extern void device_enter_context(gs_device_t *device)
{
gl_vtable->device_enter_context(device);
}
extern void device_leave_context(gs_device_t *device)
{
gl_vtable->device_leave_context(device);
}
extern void *device_get_device_obj(gs_device_t *device)
{
return gl_vtable->device_get_device_obj(device);
}
extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,
uint32_t *height)
{
gl_vtable->getclientsize(swap, width, height);
}
extern void gl_clear_context(gs_device_t *device)
{
gl_vtable->clear_context(device);
}
extern void gl_update(gs_device_t *device)
{
gl_vtable->update(device);
}
extern void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap)
{
gl_vtable->device_load_swapchain(device, swap);
}
extern void device_present(gs_device_t *device)
{
gl_vtable->device_present(device);
}

53
libobs-opengl/gl-nix.h Normal file
View File

@ -0,0 +1,53 @@
/******************************************************************************
Copyright (C) 2019 by Jason Francis <cycl0ps@tuta.io>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#pragma once
#include "gl-subsystem.h"
struct gl_winsys_vtable {
struct gl_windowinfo *(*windowinfo_create)(
const struct gs_init_data *info);
void (*windowinfo_destroy)(struct gl_windowinfo *info);
struct gl_platform *(*platform_create)(gs_device_t *device,
uint32_t adapter);
void (*platform_destroy)(struct gl_platform *plat);
bool (*platform_init_swapchain)(struct gs_swap_chain *swap);
void (*platform_cleanup_swapchain)(struct gs_swap_chain *swap);
void (*device_enter_context)(gs_device_t *device);
void (*device_leave_context)(gs_device_t *device);
void *(*device_get_device_obj)(gs_device_t *device);
void (*getclientsize)(const struct gs_swap_chain *swap, uint32_t *width,
uint32_t *height);
void (*clear_context)(gs_device_t *device);
void (*update)(gs_device_t *device);
void (*device_load_swapchain)(gs_device_t *device,
gs_swapchain_t *swap);
void (*device_present)(gs_device_t *device);
};

View File

@ -36,7 +36,7 @@
#include <stdio.h>
#include "gl-subsystem.h"
#include "gl-nix.h"
#include <glad/glad_glx.h>
@ -221,14 +221,14 @@ static void gl_context_destroy(struct gl_platform *plat)
bfree(plat);
}
extern struct gl_windowinfo *
gl_windowinfo_create(const struct gs_init_data *info)
static struct gl_windowinfo *
gl_x11_glx_windowinfo_create(const struct gs_init_data *info)
{
UNUSED_PARAMETER(info);
return bmalloc(sizeof(struct gl_windowinfo));
}
extern void gl_windowinfo_destroy(struct gl_windowinfo *info)
static void gl_x11_glx_windowinfo_destroy(struct gl_windowinfo *info)
{
bfree(info);
}
@ -294,8 +294,8 @@ static int x_error_handler(Display *display, XErrorEvent *error)
return 0;
}
extern struct gl_platform *gl_platform_create(gs_device_t *device,
uint32_t adapter)
static struct gl_platform *gl_x11_glx_platform_create(gs_device_t *device,
uint32_t adapter)
{
/* There's some trickery here... we're mixing libX11, xcb, and GLX
For an explanation see here: http://xcb.freedesktop.org/MixingCalls/
@ -346,7 +346,7 @@ success:
return plat;
}
extern void gl_platform_destroy(struct gl_platform *plat)
static void gl_x11_glx_platform_destroy(struct gl_platform *plat)
{
if (!plat) /* In what case would platform be invalid here? */
return;
@ -354,7 +354,7 @@ extern void gl_platform_destroy(struct gl_platform *plat)
gl_context_destroy(plat);
}
extern bool gl_platform_init_swapchain(struct gs_swap_chain *swap)
static bool gl_x11_glx_platform_init_swapchain(struct gs_swap_chain *swap)
{
Display *display = swap->device->plat->display;
xcb_connection_t *xcb_conn = XGetXCBConnection(display);
@ -429,13 +429,13 @@ success:
return status;
}
extern void gl_platform_cleanup_swapchain(struct gs_swap_chain *swap)
static void gl_x11_glx_platform_cleanup_swapchain(struct gs_swap_chain *swap)
{
UNUSED_PARAMETER(swap);
/* Really nothing to clean up? */
}
extern void device_enter_context(gs_device_t *device)
static void gl_x11_glx_device_enter_context(gs_device_t *device)
{
GLXContext context = device->plat->context;
Display *display = device->plat->display;
@ -453,7 +453,7 @@ extern void device_enter_context(gs_device_t *device)
}
}
extern void device_leave_context(gs_device_t *device)
static void gl_x11_glx_device_leave_context(gs_device_t *device)
{
Display *display = device->plat->display;
@ -462,13 +462,13 @@ extern void device_leave_context(gs_device_t *device)
}
}
void *device_get_device_obj(gs_device_t *device)
static void *gl_x11_glx_device_get_device_obj(gs_device_t *device)
{
return device->plat->context;
}
extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,
uint32_t *height)
static void gl_x11_glx_getclientsize(const struct gs_swap_chain *swap,
uint32_t *width, uint32_t *height)
{
xcb_connection_t *xcb_conn =
XGetXCBConnection(swap->device->plat->display);
@ -484,7 +484,7 @@ extern void gl_getclientsize(const struct gs_swap_chain *swap, uint32_t *width,
free(geometry);
}
extern void gl_clear_context(gs_device_t *device)
static void gl_x11_glx_clear_context(gs_device_t *device)
{
Display *display = device->plat->display;
@ -493,7 +493,7 @@ extern void gl_clear_context(gs_device_t *device)
}
}
extern void gl_update(gs_device_t *device)
static void gl_x11_glx_update(gs_device_t *device)
{
Display *display = device->plat->display;
xcb_window_t window = device->cur_swap->wi->window;
@ -506,7 +506,8 @@ extern void gl_update(gs_device_t *device)
values);
}
extern void device_load_swapchain(gs_device_t *device, gs_swapchain_t *swap)
static void gl_x11_glx_device_load_swapchain(gs_device_t *device,
gs_swapchain_t *swap)
{
if (device->cur_swap == swap)
return;
@ -536,7 +537,7 @@ enum swap_type {
SWAP_TYPE_SGI,
};
extern void device_present(gs_device_t *device)
static void gl_x11_glx_device_present(gs_device_t *device)
{
static bool initialized = false;
static enum swap_type swap_type = SWAP_TYPE_NORMAL;
@ -577,3 +578,25 @@ extern void device_present(gs_device_t *device)
glXSwapBuffers(display, window);
}
static const struct gl_winsys_vtable glx_winsys_vtable = {
.windowinfo_create = gl_x11_glx_windowinfo_create,
.windowinfo_destroy = gl_x11_glx_windowinfo_destroy,
.platform_create = gl_x11_glx_platform_create,
.platform_destroy = gl_x11_glx_platform_destroy,
.platform_init_swapchain = gl_x11_glx_platform_init_swapchain,
.platform_cleanup_swapchain = gl_x11_glx_platform_cleanup_swapchain,
.device_enter_context = gl_x11_glx_device_enter_context,
.device_leave_context = gl_x11_glx_device_leave_context,
.device_get_device_obj = gl_x11_glx_device_get_device_obj,
.getclientsize = gl_x11_glx_getclientsize,
.clear_context = gl_x11_glx_clear_context,
.update = gl_x11_glx_update,
.device_load_swapchain = gl_x11_glx_device_load_swapchain,
.device_present = gl_x11_glx_device_present,
};
const struct gl_winsys_vtable *gl_x11_glx_get_winsys_vtable(void)
{
return &glx_winsys_vtable;
}

View File

@ -0,0 +1,22 @@
/******************************************************************************
Copyright (C) 2014 by Zachary Lund <admin@computerquip.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
#pragma once
#include "gl-nix.h"
const struct gl_winsys_vtable *gl_x11_glx_get_winsys_vtable(void);