Initial commit
Signed-off-by: Antoine Damhet <antoine.damhet@lse.epita.fr>
This commit is contained in:
commit
fd61839bc1
16 changed files with 6032 additions and 0 deletions
71
.SRCINFO
Normal file
71
.SRCINFO
Normal file
|
@ -0,0 +1,71 @@
|
|||
pkgbase = obs-studio-wayland
|
||||
pkgdesc = Free, open source software for live streaming and recording (with wayland patches)
|
||||
pkgver = 25.0.8
|
||||
pkgrel = 1
|
||||
url = https://obsproject.com
|
||||
arch = x86_64
|
||||
license = GPL2
|
||||
makedepends = cmake
|
||||
makedepends = libfdk-aac
|
||||
makedepends = libxcomposite
|
||||
makedepends = x264
|
||||
makedepends = vlc
|
||||
makedepends = swig
|
||||
makedepends = python
|
||||
makedepends = luajit
|
||||
depends = ffmpeg
|
||||
depends = jansson
|
||||
depends = libxinerama
|
||||
depends = libxkbcommon-x11
|
||||
depends = mbedtls
|
||||
depends = qt5-svg
|
||||
depends = qt5-x11extras
|
||||
depends = curl
|
||||
depends = jack
|
||||
depends = gtk-update-icon-cache
|
||||
optdepends = libfdk-aac: FDK AAC codec support
|
||||
optdepends = libxcomposite: XComposite capture support
|
||||
optdepends = libva-intel-driver: hardware encoding
|
||||
optdepends = libva-mesa-driver: hardware encoding
|
||||
optdepends = luajit: scripting support
|
||||
optdepends = python: scripting support
|
||||
optdepends = vlc: VLC Media Source support
|
||||
optdepends = obs-xdg-portal-git: screen capture with xdg-desktop-portal interface
|
||||
optdepends = xdg-desktop-portal-wlr: screen capture on wlroots compositors
|
||||
provides = obs-studio
|
||||
conflicts = obs-studio
|
||||
source = obs-studio-25.0.8.tar.gz::https://github.com/jp9000/obs-studio/archive/25.0.8.tar.gz
|
||||
source = https://github.com/obsproject/obs-studio/commit/8a1429e29ebd6bf31ad6ae63c6992e2c03893767.patch
|
||||
source = 0001-deps-glad-Add-EGL.patch
|
||||
source = 0002-libobs-opengl-Rename-gl-x11.c-to-gl-x11-glx.c.patch
|
||||
source = 0003-libobs-opengl-Factor-out-GLX-winsys.patch
|
||||
source = 0004-libobs-opengl-Introduce-the-X11-EGL-winsys.patch
|
||||
source = 0005-deps-glad-Make-X11-required-as-well.patch
|
||||
source = 0006-ci-Install-qtbase5-private-dev-on-Linux.patch
|
||||
source = 0007-libobs-nix-Move-X11-specific-code-to-obs-nix-x11.c.patch
|
||||
source = 0008-libobs-Introduce-the-concept-of-a-Unix-platform.patch
|
||||
source = 0009-UI-Set-the-Unix-platform-on-startup.patch
|
||||
source = 0010-linux-capture-Fail-to-load-when-running-on-EGL.patch
|
||||
source = 0011-libobs-Add-a-Wayland-platform.patch
|
||||
source = 0012-libobs-opengl-Try-to-use-the-platform-display-if-ava.patch
|
||||
source = 0013-libobs-opengl-Introduce-an-EGL-Wayland-renderer.patch
|
||||
source = 0014-UI-Retrieve-Wayland-surface-from-QWindow.patch
|
||||
sha512sums = a97c03dc218a4e03e48f6a7dc82b4a59ebeee2039f17be66bb847681ce9ff3d25e6e015be4af78fe44739f6fad5089b6e683d7657c2e4fde8e547df9a2594a08
|
||||
sha512sums = 1ff0e088eed61554268009f3d8c5a23c0888bfbe860d6cb288ddf348108446c152fd87e2cb8f54613a88378d8474550632c90f924005d5e0343bf1a801339ccc
|
||||
sha512sums = bfe2b0e6da69ffdca95229eb4015515148fdda909355add1d2dec71cf97e9fdabdfc832c74f455a890846708f28d5bcbec64589e853904d539a438b2dcbd7a18
|
||||
sha512sums = 5221b6a7a46f99c58cde1c5406f83d50def2d5b3a2e97be7db759d94d74a5be46da092209e6a4122a6de4b704632c3f013535f80b570349b029ea4124151c4f6
|
||||
sha512sums = c9a0660c95bd18a02620fb0b870032563669544e7a721e4d91dafb8aebb96d1735414a9e37ed56355fc5afeb8f437a434b4fd5f147c9658cc6974e8e8bab4463
|
||||
sha512sums = 0b404ff252f94bcdd957d43db26c54c6b47de5a8f810f4febdb0aa5b873c48f23ef2817361e5ce9c09a189e770978cfca24767167604434ece771d759e7c4270
|
||||
sha512sums = 47f5bffb469ece2b961000cd2d8656b82cba8ac0fa09fa7703c662e0cee2e48744d5b8aa93a4b4508436ea5edfe3038fa7aa88a3b43466f88c7504e6a8ba51ed
|
||||
sha512sums = d15c21968a3024888ce4c8e884d861f147358e95a42c1de557251a4c2fccbdddf9cf5a285deedbf73cffbd25fdaad44dd972cb10bf9a5b23a0049b239e75961f
|
||||
sha512sums = c1f94ccd836c51ff83735df614bf6d3e2c310c599685e700ae5726ace20434edd04ef0c9be0a8c0f4c458dd164ad1ac817fd32bcbeeefb0107a6ce4cbce9cb08
|
||||
sha512sums = 6ce870404a6d2bfbb25935a6da59a07447307f8592dd1dc1aaebba2b9f959633565ba4cdc7d50ee3c4e5b4c169397298daa5804c3060fc780dba52099f687393
|
||||
sha512sums = 6374229b662949e2989eb372a922fda872d2a08e817690b2262f99dc8a02261a75aeeacfc40da2b68a04228b38cda4aeaca4212068e8605b7532662dc459abb4
|
||||
sha512sums = 16dfa319e9e18ef8e946b9723e27d1ea1f56e4de8656d8112571bc87aa7ade8dbda4293f064c2477cdaf92c60fca4484b2c7ac322835bf402657275933f6ab52
|
||||
sha512sums = c81a421475293d3d5c64a744c10a925dc26975a6dfd46e1b3b2a92931da43c311d0a153548889b4e9831bee61ab8b0f5fc504ad3f0ed7f0628f93287e12ad3d3
|
||||
sha512sums = ea36fee6228d582f5f3b886a3de61ad8b139691c3bf30e24a7b20f1eab2f9e43b0dfbf6f254dcef00e2bfbf6826f223a957d3e78524ebd864c64433529e40441
|
||||
sha512sums = a93f186ed24ee979a4297aa063c435ae541f5f1958b86373f6534a2dd85e2178d6f151f115200c987b5e1d999ebd94d6ce0597ef1e7b3588bcb161c53dd4878e
|
||||
sha512sums = c4e6a23edf080076c27599e02909a068b11094848f733297496e7ea0061df56be4becdb58449ec7a05ff2a659fa4c0f75f4006cb204578477308d24d764fba41
|
||||
|
||||
pkgname = obs-studio-wayland
|
||||
|
545
0001-deps-glad-Add-EGL.patch
Normal file
545
0001-deps-glad-Add-EGL.patch
Normal file
|
@ -0,0 +1,545 @@
|
|||
From b91db14ec87f4f1a2fba7d6cb89c4e6d07a0472f Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 13:10:16 -0300
|
||||
Subject: [PATCH 01/15] deps-glad: Add EGL
|
||||
|
||||
The code is generated by https://glad.dav1d.de/
|
||||
---
|
||||
cmake/Modules/FindEGL.cmake | 53 +++++
|
||||
deps/glad/CMakeLists.txt | 11 +-
|
||||
deps/glad/include/glad/glad_egl.h | 363 ++++++++++++++++++++++++++++++
|
||||
deps/glad/src/glad_egl.c | 48 ++++
|
||||
4 files changed, 473 insertions(+), 2 deletions(-)
|
||||
create mode 100644 cmake/Modules/FindEGL.cmake
|
||||
create mode 100644 deps/glad/include/glad/glad_egl.h
|
||||
create mode 100644 deps/glad/src/glad_egl.c
|
||||
|
||||
diff --git a/cmake/Modules/FindEGL.cmake b/cmake/Modules/FindEGL.cmake
|
||||
new file mode 100644
|
||||
index 00000000..ee27cc90
|
||||
--- /dev/null
|
||||
+++ b/cmake/Modules/FindEGL.cmake
|
||||
@@ -0,0 +1,53 @@
|
||||
+# - Try to Find EGL
|
||||
+# Once done, this will define
|
||||
+#
|
||||
+# EGL_FOUND - system has EGL installed.
|
||||
+# EGL_INCLUDE_DIRS - directories which contain the EGL headers.
|
||||
+# EGL_LIBRARIES - libraries required to link against EGL.
|
||||
+# EGL_DEFINITIONS - Compiler switches required for using EGL.
|
||||
+#
|
||||
+# Copyright (C) 2012 Intel Corporation. All rights reserved.
|
||||
+# 2020 Georges Basile Stavracas Neto
|
||||
+#
|
||||
+# Redistribution and use in source and binary forms, with or without
|
||||
+# modification, are permitted provided that the following conditions
|
||||
+# are met:
|
||||
+# 1. Redistributions of source code must retain the above copyright
|
||||
+# notice, this list of conditions and the following disclaimer.
|
||||
+# 2. Redistributions in binary form must reproduce the above copyright
|
||||
+# notice, this list of conditions and the following disclaimer in the
|
||||
+# documentation and/or other materials provided with the distribution.
|
||||
+#
|
||||
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND ITS CONTRIBUTORS ``AS
|
||||
+# IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR ITS
|
||||
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
+# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
+
|
||||
+
|
||||
+find_package(PkgConfig)
|
||||
+
|
||||
+pkg_check_modules(PC_EGL egl)
|
||||
+
|
||||
+if (PC_EGL_FOUND)
|
||||
+ set(EGL_DEFINITIONS ${PC_EGL_CFLAGS_OTHER})
|
||||
+endif ()
|
||||
+
|
||||
+find_path(EGL_INCLUDE_DIRS NAMES EGL/egl.h
|
||||
+ HINTS ${PC_EGL_INCLUDE_DIR} ${PC_EGL_INCLUDE_DIRS}
|
||||
+)
|
||||
+
|
||||
+find_library(EGL_LIBRARIES NAMES egl EGL
|
||||
+ HINTS ${PC_EGL_LIBRARY_DIRS}
|
||||
+)
|
||||
+
|
||||
+include(FindPackageHandleStandardArgs)
|
||||
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(EGL DEFAULT_MSG EGL_INCLUDE_DIRS EGL_LIBRARIES)
|
||||
+
|
||||
+mark_as_advanced(EGL_INCLUDE_DIRS EGL_LIBRARIES)
|
||||
diff --git a/deps/glad/CMakeLists.txt b/deps/glad/CMakeLists.txt
|
||||
index 2c4cf13a..9cb7e8fd 100644
|
||||
--- a/deps/glad/CMakeLists.txt
|
||||
+++ b/deps/glad/CMakeLists.txt
|
||||
@@ -4,6 +4,7 @@ find_package(OpenGL)
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
find_package(X11)
|
||||
+ find_package(EGL REQUIRED)
|
||||
endif()
|
||||
|
||||
set(glad_SOURCES
|
||||
@@ -19,7 +20,9 @@ if(WIN32)
|
||||
obsglad.rc)
|
||||
elseif(NOT APPLE)
|
||||
set(glad_PLATFORM_SOURCES
|
||||
+ src/glad_egl.c
|
||||
src/glad_glx.c
|
||||
+ include/glad/glad_egl.h
|
||||
include/glad/glad_glx.h)
|
||||
endif()
|
||||
|
||||
@@ -28,7 +31,9 @@ set(glad_include_dirs
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
list (APPEND glad_include_dirs
|
||||
- PRIVATE ${X11_X11_INCLUDE_PATH})
|
||||
+ PRIVATE
|
||||
+ ${X11_X11_INCLUDE_PATH}
|
||||
+ ${EGL_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
add_library(glad SHARED
|
||||
@@ -54,7 +59,9 @@ endif()
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
set(glad_PLATFORM_DEPS
|
||||
- ${X11_X11_LIB})
|
||||
+ ${X11_X11_LIB}
|
||||
+ ${EGL_LIBRARIES})
|
||||
+
|
||||
# only link to libdl on linux
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(glad_PLATFORM_DEPS
|
||||
diff --git a/deps/glad/include/glad/glad_egl.h b/deps/glad/include/glad/glad_egl.h
|
||||
new file mode 100644
|
||||
index 00000000..411729f0
|
||||
--- /dev/null
|
||||
+++ b/deps/glad/include/glad/glad_egl.h
|
||||
@@ -0,0 +1,363 @@
|
||||
+/*
|
||||
+
|
||||
+ EGL loader generated by glad 0.1.33 on Mon Mar 9 17:01:26 2020.
|
||||
+
|
||||
+ Language/Generator: C/C++
|
||||
+ Specification: egl
|
||||
+ APIs: egl=1.5
|
||||
+ Profile: -
|
||||
+ Extensions:
|
||||
+ EGL_EXT_platform_wayland,
|
||||
+ EGL_EXT_platform_x11,
|
||||
+ EGL_KHR_platform_wayland,
|
||||
+ EGL_KHR_platform_x11
|
||||
+ Loader: True
|
||||
+ Local files: False
|
||||
+ Omit khrplatform: False
|
||||
+ Reproducible: False
|
||||
+
|
||||
+ Commandline:
|
||||
+ --api="egl=1.5" --generator="c" --spec="egl" --extensions="EGL_EXT_platform_wayland,EGL_EXT_platform_x11,EGL_KHR_platform_wayland,EGL_KHR_platform_x11"
|
||||
+ Online:
|
||||
+ https://glad.dav1d.de/#language=c&specification=egl&loader=on&api=egl%3D1.5&extensions=EGL_EXT_platform_wayland&extensions=EGL_EXT_platform_x11&extensions=EGL_KHR_platform_wayland&extensions=EGL_KHR_platform_x11
|
||||
+*/
|
||||
+
|
||||
+
|
||||
+#ifndef __glad_egl_h_
|
||||
+
|
||||
+#ifdef __egl_h_
|
||||
+#error EGL header already included, remove this include, glad already provides it
|
||||
+#endif
|
||||
+
|
||||
+#define __glad_egl_h_
|
||||
+#define __egl_h_
|
||||
+
|
||||
+#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
|
||||
+#define APIENTRY __stdcall
|
||||
+#endif
|
||||
+
|
||||
+#ifndef APIENTRY
|
||||
+#define APIENTRY
|
||||
+#endif
|
||||
+#ifndef APIENTRYP
|
||||
+#define APIENTRYP APIENTRY *
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+typedef void* (* GLADloadproc)(const char *name);
|
||||
+
|
||||
+#define GLAD_GLAPI_EXPORT
|
||||
+
|
||||
+#ifndef GLAPI
|
||||
+# if defined(GLAD_GLAPI_EXPORT)
|
||||
+# if defined(WIN32) || defined(__CYGWIN__)
|
||||
+# if defined(GLAD_GLAPI_EXPORT_BUILD)
|
||||
+# if defined(__GNUC__)
|
||||
+# define GLAPI __attribute__ ((dllexport)) extern
|
||||
+# else
|
||||
+# define GLAPI __declspec(dllexport) extern
|
||||
+# endif
|
||||
+# else
|
||||
+# if defined(__GNUC__)
|
||||
+# define GLAPI __attribute__ ((dllimport)) extern
|
||||
+# else
|
||||
+# define GLAPI __declspec(dllimport) extern
|
||||
+# endif
|
||||
+# endif
|
||||
+# elif defined(__GNUC__) && defined(GLAD_GLAPI_EXPORT_BUILD)
|
||||
+# define GLAPI __attribute__ ((visibility ("default"))) extern
|
||||
+# else
|
||||
+# define GLAPI extern
|
||||
+# endif
|
||||
+# else
|
||||
+# define GLAPI extern
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
+GLAPI int gladLoadEGL(void);
|
||||
+GLAPI int gladLoadEGLLoader(GLADloadproc);
|
||||
+
|
||||
+#include <KHR/khrplatform.h>
|
||||
+#include <EGL/eglplatform.h>
|
||||
+struct AHardwareBuffer;
|
||||
+struct wl_buffer;
|
||||
+struct wl_display;
|
||||
+struct wl_resource;
|
||||
+typedef unsigned int EGLBoolean;
|
||||
+typedef unsigned int EGLenum;
|
||||
+typedef intptr_t EGLAttribKHR;
|
||||
+typedef intptr_t EGLAttrib;
|
||||
+typedef void *EGLClientBuffer;
|
||||
+typedef void *EGLConfig;
|
||||
+typedef void *EGLContext;
|
||||
+typedef void *EGLDeviceEXT;
|
||||
+typedef void *EGLDisplay;
|
||||
+typedef void *EGLImage;
|
||||
+typedef void *EGLImageKHR;
|
||||
+typedef void *EGLLabelKHR;
|
||||
+typedef void *EGLObjectKHR;
|
||||
+typedef void *EGLOutputLayerEXT;
|
||||
+typedef void *EGLOutputPortEXT;
|
||||
+typedef void *EGLStreamKHR;
|
||||
+typedef void *EGLSurface;
|
||||
+typedef void *EGLSync;
|
||||
+typedef void *EGLSyncKHR;
|
||||
+typedef void *EGLSyncNV;
|
||||
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
|
||||
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
|
||||
+typedef khronos_utime_nanoseconds_t EGLTime;
|
||||
+typedef khronos_utime_nanoseconds_t EGLTimeNV;
|
||||
+typedef khronos_utime_nanoseconds_t EGLuint64NV;
|
||||
+typedef khronos_uint64_t EGLuint64KHR;
|
||||
+typedef khronos_stime_nanoseconds_t EGLnsecsANDROID;
|
||||
+typedef int EGLNativeFileDescriptorKHR;
|
||||
+typedef khronos_ssize_t EGLsizeiANDROID;
|
||||
+typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize);
|
||||
+typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize);
|
||||
+struct EGLClientPixmapHI {
|
||||
+ void *pData;
|
||||
+ EGLint iWidth;
|
||||
+ EGLint iHeight;
|
||||
+ EGLint iStride;
|
||||
+};
|
||||
+typedef void (APIENTRY *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message);
|
||||
+#define PFNEGLBINDWAYLANDDISPLAYWL PFNEGLBINDWAYLANDDISPLAYWLPROC
|
||||
+#define PFNEGLUNBINDWAYLANDDISPLAYWL PFNEGLUNBINDWAYLANDDISPLAYWLPROC
|
||||
+#define PFNEGLQUERYWAYLANDBUFFERWL PFNEGLQUERYWAYLANDBUFFERWLPROC
|
||||
+#define PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWL PFNEGLCREATEWAYLANDBUFFERFROMIMAGEWLPROC
|
||||
+#define EGL_ALPHA_SIZE 0x3021
|
||||
+#define EGL_BAD_ACCESS 0x3002
|
||||
+#define EGL_BAD_ALLOC 0x3003
|
||||
+#define EGL_BAD_ATTRIBUTE 0x3004
|
||||
+#define EGL_BAD_CONFIG 0x3005
|
||||
+#define EGL_BAD_CONTEXT 0x3006
|
||||
+#define EGL_BAD_CURRENT_SURFACE 0x3007
|
||||
+#define EGL_BAD_DISPLAY 0x3008
|
||||
+#define EGL_BAD_MATCH 0x3009
|
||||
+#define EGL_BAD_NATIVE_PIXMAP 0x300A
|
||||
+#define EGL_BAD_NATIVE_WINDOW 0x300B
|
||||
+#define EGL_BAD_PARAMETER 0x300C
|
||||
+#define EGL_BAD_SURFACE 0x300D
|
||||
+#define EGL_BLUE_SIZE 0x3022
|
||||
+#define EGL_BUFFER_SIZE 0x3020
|
||||
+#define EGL_CONFIG_CAVEAT 0x3027
|
||||
+#define EGL_CONFIG_ID 0x3028
|
||||
+#define EGL_CORE_NATIVE_ENGINE 0x305B
|
||||
+#define EGL_DEPTH_SIZE 0x3025
|
||||
+#define EGL_DONT_CARE EGL_CAST(EGLint,-1)
|
||||
+#define EGL_DRAW 0x3059
|
||||
+#define EGL_EXTENSIONS 0x3055
|
||||
+#define EGL_FALSE 0
|
||||
+#define EGL_GREEN_SIZE 0x3023
|
||||
+#define EGL_HEIGHT 0x3056
|
||||
+#define EGL_LARGEST_PBUFFER 0x3058
|
||||
+#define EGL_LEVEL 0x3029
|
||||
+#define EGL_MAX_PBUFFER_HEIGHT 0x302A
|
||||
+#define EGL_MAX_PBUFFER_PIXELS 0x302B
|
||||
+#define EGL_MAX_PBUFFER_WIDTH 0x302C
|
||||
+#define EGL_NATIVE_RENDERABLE 0x302D
|
||||
+#define EGL_NATIVE_VISUAL_ID 0x302E
|
||||
+#define EGL_NATIVE_VISUAL_TYPE 0x302F
|
||||
+#define EGL_NONE 0x3038
|
||||
+#define EGL_NON_CONFORMANT_CONFIG 0x3051
|
||||
+#define EGL_NOT_INITIALIZED 0x3001
|
||||
+#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0)
|
||||
+#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0)
|
||||
+#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0)
|
||||
+#define EGL_PBUFFER_BIT 0x0001
|
||||
+#define EGL_PIXMAP_BIT 0x0002
|
||||
+#define EGL_READ 0x305A
|
||||
+#define EGL_RED_SIZE 0x3024
|
||||
+#define EGL_SAMPLES 0x3031
|
||||
+#define EGL_SAMPLE_BUFFERS 0x3032
|
||||
+#define EGL_SLOW_CONFIG 0x3050
|
||||
+#define EGL_STENCIL_SIZE 0x3026
|
||||
+#define EGL_SUCCESS 0x3000
|
||||
+#define EGL_SURFACE_TYPE 0x3033
|
||||
+#define EGL_TRANSPARENT_BLUE_VALUE 0x3035
|
||||
+#define EGL_TRANSPARENT_GREEN_VALUE 0x3036
|
||||
+#define EGL_TRANSPARENT_RED_VALUE 0x3037
|
||||
+#define EGL_TRANSPARENT_RGB 0x3052
|
||||
+#define EGL_TRANSPARENT_TYPE 0x3034
|
||||
+#define EGL_TRUE 1
|
||||
+#define EGL_VENDOR 0x3053
|
||||
+#define EGL_VERSION 0x3054
|
||||
+#define EGL_WIDTH 0x3057
|
||||
+#define EGL_WINDOW_BIT 0x0004
|
||||
+#define EGL_BACK_BUFFER 0x3084
|
||||
+#define EGL_BIND_TO_TEXTURE_RGB 0x3039
|
||||
+#define EGL_BIND_TO_TEXTURE_RGBA 0x303A
|
||||
+#define EGL_CONTEXT_LOST 0x300E
|
||||
+#define EGL_MIN_SWAP_INTERVAL 0x303B
|
||||
+#define EGL_MAX_SWAP_INTERVAL 0x303C
|
||||
+#define EGL_MIPMAP_TEXTURE 0x3082
|
||||
+#define EGL_MIPMAP_LEVEL 0x3083
|
||||
+#define EGL_NO_TEXTURE 0x305C
|
||||
+#define EGL_TEXTURE_2D 0x305F
|
||||
+#define EGL_TEXTURE_FORMAT 0x3080
|
||||
+#define EGL_TEXTURE_RGB 0x305D
|
||||
+#define EGL_TEXTURE_RGBA 0x305E
|
||||
+#define EGL_TEXTURE_TARGET 0x3081
|
||||
+#define EGL_ALPHA_FORMAT 0x3088
|
||||
+#define EGL_ALPHA_FORMAT_NONPRE 0x308B
|
||||
+#define EGL_ALPHA_FORMAT_PRE 0x308C
|
||||
+#define EGL_ALPHA_MASK_SIZE 0x303E
|
||||
+#define EGL_BUFFER_PRESERVED 0x3094
|
||||
+#define EGL_BUFFER_DESTROYED 0x3095
|
||||
+#define EGL_CLIENT_APIS 0x308D
|
||||
+#define EGL_COLORSPACE 0x3087
|
||||
+#define EGL_COLORSPACE_sRGB 0x3089
|
||||
+#define EGL_COLORSPACE_LINEAR 0x308A
|
||||
+#define EGL_COLOR_BUFFER_TYPE 0x303F
|
||||
+#define EGL_CONTEXT_CLIENT_TYPE 0x3097
|
||||
+#define EGL_DISPLAY_SCALING 10000
|
||||
+#define EGL_HORIZONTAL_RESOLUTION 0x3090
|
||||
+#define EGL_LUMINANCE_BUFFER 0x308F
|
||||
+#define EGL_LUMINANCE_SIZE 0x303D
|
||||
+#define EGL_OPENGL_ES_BIT 0x0001
|
||||
+#define EGL_OPENVG_BIT 0x0002
|
||||
+#define EGL_OPENGL_ES_API 0x30A0
|
||||
+#define EGL_OPENVG_API 0x30A1
|
||||
+#define EGL_OPENVG_IMAGE 0x3096
|
||||
+#define EGL_PIXEL_ASPECT_RATIO 0x3092
|
||||
+#define EGL_RENDERABLE_TYPE 0x3040
|
||||
+#define EGL_RENDER_BUFFER 0x3086
|
||||
+#define EGL_RGB_BUFFER 0x308E
|
||||
+#define EGL_SINGLE_BUFFER 0x3085
|
||||
+#define EGL_SWAP_BEHAVIOR 0x3093
|
||||
+#define EGL_UNKNOWN EGL_CAST(EGLint,-1)
|
||||
+#define EGL_VERTICAL_RESOLUTION 0x3091
|
||||
+#define EGL_CONFORMANT 0x3042
|
||||
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
|
||||
+#define EGL_MATCH_NATIVE_PIXMAP 0x3041
|
||||
+#define EGL_OPENGL_ES2_BIT 0x0004
|
||||
+#define EGL_VG_ALPHA_FORMAT 0x3088
|
||||
+#define EGL_VG_ALPHA_FORMAT_NONPRE 0x308B
|
||||
+#define EGL_VG_ALPHA_FORMAT_PRE 0x308C
|
||||
+#define EGL_VG_ALPHA_FORMAT_PRE_BIT 0x0040
|
||||
+#define EGL_VG_COLORSPACE 0x3087
|
||||
+#define EGL_VG_COLORSPACE_sRGB 0x3089
|
||||
+#define EGL_VG_COLORSPACE_LINEAR 0x308A
|
||||
+#define EGL_VG_COLORSPACE_LINEAR_BIT 0x0020
|
||||
+#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0)
|
||||
+#define EGL_MULTISAMPLE_RESOLVE_BOX_BIT 0x0200
|
||||
+#define EGL_MULTISAMPLE_RESOLVE 0x3099
|
||||
+#define EGL_MULTISAMPLE_RESOLVE_DEFAULT 0x309A
|
||||
+#define EGL_MULTISAMPLE_RESOLVE_BOX 0x309B
|
||||
+#define EGL_OPENGL_API 0x30A2
|
||||
+#define EGL_OPENGL_BIT 0x0008
|
||||
+#define EGL_SWAP_BEHAVIOR_PRESERVED_BIT 0x0400
|
||||
+#define EGL_CONTEXT_MAJOR_VERSION 0x3098
|
||||
+#define EGL_CONTEXT_MINOR_VERSION 0x30FB
|
||||
+#define EGL_CONTEXT_OPENGL_PROFILE_MASK 0x30FD
|
||||
+#define EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY 0x31BD
|
||||
+#define EGL_NO_RESET_NOTIFICATION 0x31BE
|
||||
+#define EGL_LOSE_CONTEXT_ON_RESET 0x31BF
|
||||
+#define EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT 0x00000001
|
||||
+#define EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||
+#define EGL_CONTEXT_OPENGL_DEBUG 0x31B0
|
||||
+#define EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE 0x31B1
|
||||
+#define EGL_CONTEXT_OPENGL_ROBUST_ACCESS 0x31B2
|
||||
+#define EGL_OPENGL_ES3_BIT 0x00000040
|
||||
+#define EGL_CL_EVENT_HANDLE 0x309C
|
||||
+#define EGL_SYNC_CL_EVENT 0x30FE
|
||||
+#define EGL_SYNC_CL_EVENT_COMPLETE 0x30FF
|
||||
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0
|
||||
+#define EGL_SYNC_TYPE 0x30F7
|
||||
+#define EGL_SYNC_STATUS 0x30F1
|
||||
+#define EGL_SYNC_CONDITION 0x30F8
|
||||
+#define EGL_SIGNALED 0x30F2
|
||||
+#define EGL_UNSIGNALED 0x30F3
|
||||
+#define EGL_SYNC_FLUSH_COMMANDS_BIT 0x0001
|
||||
+#define EGL_FOREVER 0xFFFFFFFFFFFFFFFF
|
||||
+#define EGL_TIMEOUT_EXPIRED 0x30F5
|
||||
+#define EGL_CONDITION_SATISFIED 0x30F6
|
||||
+#define EGL_NO_SYNC EGL_CAST(EGLSync,0)
|
||||
+#define EGL_SYNC_FENCE 0x30F9
|
||||
+#define EGL_GL_COLORSPACE 0x309D
|
||||
+#define EGL_GL_COLORSPACE_SRGB 0x3089
|
||||
+#define EGL_GL_COLORSPACE_LINEAR 0x308A
|
||||
+#define EGL_GL_RENDERBUFFER 0x30B9
|
||||
+#define EGL_GL_TEXTURE_2D 0x30B1
|
||||
+#define EGL_GL_TEXTURE_LEVEL 0x30BC
|
||||
+#define EGL_GL_TEXTURE_3D 0x30B2
|
||||
+#define EGL_GL_TEXTURE_ZOFFSET 0x30BD
|
||||
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3
|
||||
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4
|
||||
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5
|
||||
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6
|
||||
+#define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7
|
||||
+#define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8
|
||||
+#define EGL_IMAGE_PRESERVED 0x30D2
|
||||
+#define EGL_NO_IMAGE EGL_CAST(EGLImage,0)
|
||||
+EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
+EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
|
||||
+EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list);
|
||||
+EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
|
||||
+EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list);
|
||||
+EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
|
||||
+EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx);
|
||||
+EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
|
||||
+EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
|
||||
+EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
|
||||
+EGLDisplay eglGetCurrentDisplay(void);
|
||||
+EGLSurface eglGetCurrentSurface(EGLint readdraw);
|
||||
+EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id);
|
||||
+EGLint eglGetError(void);
|
||||
+__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname);
|
||||
+EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);
|
||||
+EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
|
||||
+EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
|
||||
+const char *eglQueryString(EGLDisplay dpy, EGLint name);
|
||||
+EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
|
||||
+EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
|
||||
+EGLBoolean eglTerminate(EGLDisplay dpy);
|
||||
+EGLBoolean eglWaitGL(void);
|
||||
+EGLBoolean eglWaitNative(EGLint engine);
|
||||
+EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
+EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer);
|
||||
+EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
|
||||
+EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval);
|
||||
+EGLBoolean eglBindAPI(EGLenum api);
|
||||
+EGLenum eglQueryAPI(void);
|
||||
+EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
|
||||
+EGLBoolean eglReleaseThread(void);
|
||||
+EGLBoolean eglWaitClient(void);
|
||||
+EGLContext eglGetCurrentContext(void);
|
||||
+EGLSync eglCreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list);
|
||||
+EGLBoolean eglDestroySync(EGLDisplay dpy, EGLSync sync);
|
||||
+EGLint eglClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout);
|
||||
+EGLBoolean eglGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value);
|
||||
+EGLImage eglCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list);
|
||||
+EGLBoolean eglDestroyImage(EGLDisplay dpy, EGLImage image);
|
||||
+EGLDisplay eglGetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list);
|
||||
+EGLSurface eglCreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list);
|
||||
+EGLSurface eglCreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list);
|
||||
+EGLBoolean eglWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags);
|
||||
+#define EGL_PLATFORM_WAYLAND_EXT 0x31D8
|
||||
+#define EGL_PLATFORM_X11_EXT 0x31D5
|
||||
+#define EGL_PLATFORM_X11_SCREEN_EXT 0x31D6
|
||||
+#define EGL_PLATFORM_WAYLAND_KHR 0x31D8
|
||||
+#define EGL_PLATFORM_X11_KHR 0x31D5
|
||||
+#define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6
|
||||
+#ifndef EGL_EXT_platform_wayland
|
||||
+#define EGL_EXT_platform_wayland 1
|
||||
+#endif
|
||||
+#ifndef EGL_EXT_platform_x11
|
||||
+#define EGL_EXT_platform_x11 1
|
||||
+#endif
|
||||
+#ifndef EGL_KHR_platform_wayland
|
||||
+#define EGL_KHR_platform_wayland 1
|
||||
+#endif
|
||||
+#ifndef EGL_KHR_platform_x11
|
||||
+#define EGL_KHR_platform_x11 1
|
||||
+#endif
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#endif
|
||||
diff --git a/deps/glad/src/glad_egl.c b/deps/glad/src/glad_egl.c
|
||||
new file mode 100644
|
||||
index 00000000..e3cd1fc2
|
||||
--- /dev/null
|
||||
+++ b/deps/glad/src/glad_egl.c
|
||||
@@ -0,0 +1,48 @@
|
||||
+/*
|
||||
+
|
||||
+ EGL loader generated by glad 0.1.33 on Mon Mar 9 17:01:26 2020.
|
||||
+
|
||||
+ Language/Generator: C/C++
|
||||
+ Specification: egl
|
||||
+ APIs: egl=1.5
|
||||
+ Profile: -
|
||||
+ Extensions:
|
||||
+ EGL_EXT_platform_wayland,
|
||||
+ EGL_EXT_platform_x11,
|
||||
+ EGL_KHR_platform_wayland,
|
||||
+ EGL_KHR_platform_x11
|
||||
+ Loader: True
|
||||
+ Local files: False
|
||||
+ Omit khrplatform: False
|
||||
+ Reproducible: False
|
||||
+
|
||||
+ Commandline:
|
||||
+ --api="egl=1.5" --generator="c" --spec="egl" --extensions="EGL_EXT_platform_wayland,EGL_EXT_platform_x11,EGL_KHR_platform_wayland,EGL_KHR_platform_x11"
|
||||
+ Online:
|
||||
+ https://glad.dav1d.de/#language=c&specification=egl&loader=on&api=egl%3D1.5&extensions=EGL_EXT_platform_wayland&extensions=EGL_EXT_platform_x11&extensions=EGL_KHR_platform_wayland&extensions=EGL_KHR_platform_x11
|
||||
+*/
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <glad/glad_egl.h>
|
||||
+
|
||||
+int gladLoadEGL(void) {
|
||||
+ return gladLoadEGLLoader((GLADloadproc)eglGetProcAddress);
|
||||
+}
|
||||
+
|
||||
+static int find_extensionsEGL(void) {
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+static void find_coreEGL(void) {
|
||||
+}
|
||||
+
|
||||
+int gladLoadEGLLoader(GLADloadproc load) {
|
||||
+ (void) load;
|
||||
+ find_coreEGL();
|
||||
+
|
||||
+ if (!find_extensionsEGL()) return 0;
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
--
|
||||
2.28.0
|
||||
|
35
0002-libobs-opengl-Rename-gl-x11.c-to-gl-x11-glx.c.patch
Normal file
35
0002-libobs-opengl-Rename-gl-x11.c-to-gl-x11-glx.c.patch
Normal file
|
@ -0,0 +1,35 @@
|
|||
From 49e7a26b3aa5523662e68401554a1474fa8baf86 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 13:19:31 -0300
|
||||
Subject: [PATCH 02/15] libobs-opengl: Rename gl-x11.c to gl-x11-glx.c
|
||||
|
||||
This is in preparation for the future abstraction layer (gl-x11-*)
|
||||
and also to match the actual name of the windowing system. When
|
||||
running under X11, we can glue OpenGL through GLX or EGL, so the
|
||||
new file name matches that now.
|
||||
---
|
||||
libobs-opengl/CMakeLists.txt | 2 +-
|
||||
libobs-opengl/{gl-x11.c => gl-x11-glx.c} | 0
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
rename libobs-opengl/{gl-x11.c => gl-x11-glx.c} (100%)
|
||||
|
||||
diff --git a/libobs-opengl/CMakeLists.txt b/libobs-opengl/CMakeLists.txt
|
||||
index 1d53d518..776f1330 100644
|
||||
--- a/libobs-opengl/CMakeLists.txt
|
||||
+++ b/libobs-opengl/CMakeLists.txt
|
||||
@@ -49,7 +49,7 @@ else() #This needs to change to be more specific to get ready for Wayland
|
||||
${X11_XCB_LIBRARIES})
|
||||
|
||||
set(libobs-opengl_PLATFORM_SOURCES
|
||||
- gl-x11.c)
|
||||
+ gl-x11-glx.c)
|
||||
endif()
|
||||
|
||||
set(libobs-opengl_SOURCES
|
||||
diff --git a/libobs-opengl/gl-x11.c b/libobs-opengl/gl-x11-glx.c
|
||||
similarity index 100%
|
||||
rename from libobs-opengl/gl-x11.c
|
||||
rename to libobs-opengl/gl-x11-glx.c
|
||||
--
|
||||
2.28.0
|
||||
|
403
0003-libobs-opengl-Factor-out-GLX-winsys.patch
Normal file
403
0003-libobs-opengl-Factor-out-GLX-winsys.patch
Normal file
|
@ -0,0 +1,403 @@
|
|||
From dc135a39d088ead4c603f95b1483c7076da4cea4 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 16:46:37 -0300
|
||||
Subject: [PATCH 03/15] 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>
|
||||
---
|
||||
libobs-opengl/CMakeLists.txt | 1 +
|
||||
libobs-opengl/gl-nix.c | 107 +++++++++++++++++++++++++++++++++++
|
||||
libobs-opengl/gl-nix.h | 53 +++++++++++++++++
|
||||
libobs-opengl/gl-x11-glx.c | 59 +++++++++++++------
|
||||
libobs-opengl/gl-x11-glx.h | 22 +++++++
|
||||
5 files changed, 224 insertions(+), 18 deletions(-)
|
||||
create mode 100644 libobs-opengl/gl-nix.c
|
||||
create mode 100644 libobs-opengl/gl-nix.h
|
||||
create mode 100644 libobs-opengl/gl-x11-glx.h
|
||||
|
||||
diff --git a/libobs-opengl/CMakeLists.txt b/libobs-opengl/CMakeLists.txt
|
||||
index 776f1330..50afb923 100644
|
||||
--- a/libobs-opengl/CMakeLists.txt
|
||||
+++ b/libobs-opengl/CMakeLists.txt
|
||||
@@ -49,6 +49,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()
|
||||
|
||||
diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c
|
||||
new file mode 100644
|
||||
index 00000000..574d4f77
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-nix.c
|
||||
@@ -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);
|
||||
+}
|
||||
diff --git a/libobs-opengl/gl-nix.h b/libobs-opengl/gl-nix.h
|
||||
new file mode 100644
|
||||
index 00000000..209cc308
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-nix.h
|
||||
@@ -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);
|
||||
+};
|
||||
diff --git a/libobs-opengl/gl-x11-glx.c b/libobs-opengl/gl-x11-glx.c
|
||||
index d04115b0..a562b564 100644
|
||||
--- a/libobs-opengl/gl-x11-glx.c
|
||||
+++ b/libobs-opengl/gl-x11-glx.c
|
||||
@@ -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;
|
||||
+}
|
||||
diff --git a/libobs-opengl/gl-x11-glx.h b/libobs-opengl/gl-x11-glx.h
|
||||
new file mode 100644
|
||||
index 00000000..bdedf55c
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-x11-glx.h
|
||||
@@ -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);
|
||||
--
|
||||
2.28.0
|
||||
|
745
0004-libobs-opengl-Introduce-the-X11-EGL-winsys.patch
Normal file
745
0004-libobs-opengl-Introduce-the-X11-EGL-winsys.patch
Normal file
|
@ -0,0 +1,745 @@
|
|||
From 3016893fbe071ce95c20ea24844713a068862c29 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 17:35:49 -0300
|
||||
Subject: [PATCH 04/15] libobs-opengl: Introduce the X11/EGL winsys
|
||||
|
||||
Introduce the EGL/X11 winsys, and use it when the OBS_USE_EGL environment
|
||||
variable is defined. This variable is only temporary, for future commits
|
||||
will add a proper concept of platform.
|
||||
|
||||
All the EGL/X11 code is authored by Ivan Avdeev <me@w23.ru>.
|
||||
---
|
||||
libobs-opengl/CMakeLists.txt | 1 +
|
||||
libobs-opengl/gl-nix.c | 8 +-
|
||||
libobs-opengl/gl-x11-egl.c | 651 +++++++++++++++++++++++++++++++++++
|
||||
libobs-opengl/gl-x11-egl.h | 22 ++
|
||||
4 files changed, 681 insertions(+), 1 deletion(-)
|
||||
create mode 100644 libobs-opengl/gl-x11-egl.c
|
||||
create mode 100644 libobs-opengl/gl-x11-egl.h
|
||||
|
||||
diff --git a/libobs-opengl/CMakeLists.txt b/libobs-opengl/CMakeLists.txt
|
||||
index 50afb923..9c645c3d 100644
|
||||
--- a/libobs-opengl/CMakeLists.txt
|
||||
+++ b/libobs-opengl/CMakeLists.txt
|
||||
@@ -50,6 +50,7 @@ else() #This needs to change to be more specific to get ready for Wayland
|
||||
|
||||
set(libobs-opengl_PLATFORM_SOURCES
|
||||
gl-nix.c
|
||||
+ gl-x11-egl.c
|
||||
gl-x11-glx.c)
|
||||
endif()
|
||||
|
||||
diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c
|
||||
index 574d4f77..4b616ef1 100644
|
||||
--- a/libobs-opengl/gl-nix.c
|
||||
+++ b/libobs-opengl/gl-nix.c
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "gl-nix.h"
|
||||
#include "gl-x11-glx.h"
|
||||
+#include "gl-x11-egl.h"
|
||||
|
||||
static const struct gl_winsys_vtable *gl_vtable = NULL;
|
||||
|
||||
@@ -24,7 +25,12 @@ static void init_winsys(void)
|
||||
{
|
||||
assert(gl_vtable == NULL);
|
||||
|
||||
- gl_vtable = gl_x11_glx_get_winsys_vtable();
|
||||
+ if (getenv("OBS_USE_EGL")) {
|
||||
+ gl_vtable = gl_x11_egl_get_winsys_vtable();
|
||||
+ blog(LOG_INFO, "Using EGL/X11");
|
||||
+ } else {
|
||||
+ gl_vtable = gl_x11_glx_get_winsys_vtable();
|
||||
+ }
|
||||
|
||||
assert(gl_vtable != NULL);
|
||||
}
|
||||
diff --git a/libobs-opengl/gl-x11-egl.c b/libobs-opengl/gl-x11-egl.c
|
||||
new file mode 100644
|
||||
index 00000000..5b413995
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-x11-egl.c
|
||||
@@ -0,0 +1,651 @@
|
||||
+/******************************************************************************
|
||||
+ Copyright (C) 2019 by Ivan Avdeev <me@w23.ru>
|
||||
+
|
||||
+ 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/>.
|
||||
+******************************************************************************/
|
||||
+
|
||||
+/* GL context initialization using EGL instead of GLX
|
||||
+ * Which is essential for improved and more performant screen grabbing and
|
||||
+ * VA-API feeding techniques.
|
||||
+ *
|
||||
+ * Note: most of x11-related functionality was taken from gl-x11.c
|
||||
+ */
|
||||
+
|
||||
+#include <X11/Xlib.h>
|
||||
+#include <X11/Xlib-xcb.h>
|
||||
+
|
||||
+#include <xcb/xcb.h>
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include "gl-x11-egl.h"
|
||||
+
|
||||
+#include <glad/glad_egl.h>
|
||||
+
|
||||
+typedef EGLDisplay(EGLAPIENTRYP PFNEGLGETPLATFORMDISPLAYEXTPROC)(
|
||||
+ EGLenum platform, void *native_display, const EGLint *attrib_list);
|
||||
+
|
||||
+static const int ctx_attribs[] = {
|
||||
+#ifdef _DEBUG
|
||||
+ EGL_CONTEXT_OPENGL_DEBUG,
|
||||
+ EGL_TRUE,
|
||||
+#endif
|
||||
+ EGL_CONTEXT_OPENGL_PROFILE_MASK,
|
||||
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
+ EGL_CONTEXT_MAJOR_VERSION,
|
||||
+ 3,
|
||||
+ EGL_CONTEXT_MINOR_VERSION,
|
||||
+ 3,
|
||||
+ EGL_NONE,
|
||||
+};
|
||||
+
|
||||
+static int ctx_pbuffer_attribs[] = {EGL_WIDTH, 2, EGL_HEIGHT, 2, EGL_NONE};
|
||||
+
|
||||
+static const EGLint ctx_config_attribs[] = {EGL_STENCIL_SIZE,
|
||||
+ 0,
|
||||
+ EGL_DEPTH_SIZE,
|
||||
+ 0,
|
||||
+ EGL_BUFFER_SIZE,
|
||||
+ 32,
|
||||
+ EGL_ALPHA_SIZE,
|
||||
+ 8,
|
||||
+ EGL_RENDERABLE_TYPE,
|
||||
+ EGL_OPENGL_BIT,
|
||||
+ EGL_SURFACE_TYPE,
|
||||
+ EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
|
||||
+ EGL_NONE};
|
||||
+
|
||||
+struct gl_windowinfo {
|
||||
+ EGLConfig config;
|
||||
+
|
||||
+ /* Windows in X11 are defined with integers (XID).
|
||||
+ * xcb_window_t is a define for this... they are
|
||||
+ * compatible with Xlib as well.
|
||||
+ */
|
||||
+ xcb_window_t window;
|
||||
+ EGLSurface surface;
|
||||
+
|
||||
+ /* We can't fetch screen without a request so we cache it. */
|
||||
+ int screen;
|
||||
+};
|
||||
+
|
||||
+struct gl_platform {
|
||||
+ Display *xdisplay;
|
||||
+ EGLDisplay edisplay;
|
||||
+ EGLConfig config;
|
||||
+ EGLContext context;
|
||||
+ EGLSurface pbuffer;
|
||||
+};
|
||||
+
|
||||
+/* The following utility functions are copied verbatim from GLX code. */
|
||||
+
|
||||
+/*
|
||||
+ * Since we cannot take advantage of the asynchronous nature of xcb,
|
||||
+ * all of the helper functions are synchronous but thread-safe.
|
||||
+ *
|
||||
+ * They check for errors and will return 0 on problems
|
||||
+ * with the exception of when 0 is a valid return value... in which case
|
||||
+ * read the specific function comments.
|
||||
+ */
|
||||
+
|
||||
+/* Returns -1 on invalid screen. */
|
||||
+static int get_screen_num_from_xcb_screen(xcb_connection_t *xcb_conn,
|
||||
+ xcb_screen_t *screen)
|
||||
+{
|
||||
+ xcb_screen_iterator_t iter =
|
||||
+ xcb_setup_roots_iterator(xcb_get_setup(xcb_conn));
|
||||
+ int screen_num = 0;
|
||||
+
|
||||
+ for (; iter.rem; xcb_screen_next(&iter), ++screen_num)
|
||||
+ if (iter.data == screen)
|
||||
+ return screen_num;
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
+static xcb_screen_t *get_screen_from_root(xcb_connection_t *xcb_conn,
|
||||
+ xcb_window_t root)
|
||||
+{
|
||||
+ xcb_screen_iterator_t iter =
|
||||
+ xcb_setup_roots_iterator(xcb_get_setup(xcb_conn));
|
||||
+
|
||||
+ while (iter.rem) {
|
||||
+ if (iter.data->root == root)
|
||||
+ return iter.data;
|
||||
+
|
||||
+ xcb_screen_next(&iter);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int get_screen_num_from_root(xcb_connection_t *xcb_conn,
|
||||
+ xcb_window_t root)
|
||||
+{
|
||||
+ xcb_screen_t *screen = get_screen_from_root(xcb_conn, root);
|
||||
+
|
||||
+ if (!screen)
|
||||
+ return -1;
|
||||
+
|
||||
+ return get_screen_num_from_xcb_screen(xcb_conn, screen);
|
||||
+}
|
||||
+
|
||||
+static xcb_get_geometry_reply_t *get_window_geometry(xcb_connection_t *xcb_conn,
|
||||
+ xcb_drawable_t drawable)
|
||||
+{
|
||||
+ xcb_get_geometry_cookie_t cookie;
|
||||
+ xcb_generic_error_t *error;
|
||||
+ xcb_get_geometry_reply_t *reply;
|
||||
+
|
||||
+ cookie = xcb_get_geometry(xcb_conn, drawable);
|
||||
+ reply = xcb_get_geometry_reply(xcb_conn, cookie, &error);
|
||||
+
|
||||
+ if (error) {
|
||||
+ blog(LOG_ERROR, "Failed to fetch parent window geometry!");
|
||||
+ free(error);
|
||||
+ free(reply);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ free(error);
|
||||
+ return reply;
|
||||
+}
|
||||
+
|
||||
+static const char *get_egl_error_string2(const EGLint error)
|
||||
+{
|
||||
+ switch (error) {
|
||||
+#define OBS_EGL_CASE_ERROR(e) \
|
||||
+ case e: \
|
||||
+ return #e;
|
||||
+ OBS_EGL_CASE_ERROR(EGL_SUCCESS)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_NOT_INITIALIZED)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_ACCESS)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_ALLOC)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_ATTRIBUTE)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_CONTEXT)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_CONFIG)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_CURRENT_SURFACE)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_DISPLAY)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_SURFACE)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_MATCH)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_PARAMETER)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_NATIVE_PIXMAP)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_BAD_NATIVE_WINDOW)
|
||||
+ OBS_EGL_CASE_ERROR(EGL_CONTEXT_LOST)
|
||||
+#undef OBS_EGL_CASE_ERROR
|
||||
+ default:
|
||||
+ return "Unknown";
|
||||
+ }
|
||||
+}
|
||||
+static const char *get_egl_error_string()
|
||||
+{
|
||||
+ return get_egl_error_string2(eglGetError());
|
||||
+}
|
||||
+
|
||||
+static EGLDisplay get_egl_display(struct gl_platform *plat)
|
||||
+{
|
||||
+ Display *display = plat->xdisplay;
|
||||
+ EGLDisplay edisplay = EGL_NO_DISPLAY;
|
||||
+ const char *egl_client_extensions = NULL;
|
||||
+
|
||||
+ egl_client_extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||
+
|
||||
+ PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT =
|
||||
+ (PFNEGLGETPLATFORMDISPLAYEXTPROC)(
|
||||
+ strstr(egl_client_extensions, "EGL_EXT_platform_base")
|
||||
+ ? eglGetProcAddress("eglGetPlatformDisplayEXT")
|
||||
+ : NULL);
|
||||
+
|
||||
+ if (eglGetPlatformDisplayEXT) {
|
||||
+ edisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT,
|
||||
+ display, NULL);
|
||||
+ if (EGL_NO_DISPLAY == edisplay)
|
||||
+ blog(LOG_ERROR, "Failed to get EGL/X11 display");
|
||||
+ }
|
||||
+
|
||||
+ if (EGL_NO_DISPLAY == edisplay)
|
||||
+ edisplay = eglGetDisplay(display);
|
||||
+
|
||||
+ return edisplay;
|
||||
+}
|
||||
+
|
||||
+static bool gl_context_create(struct gl_platform *plat)
|
||||
+{
|
||||
+ Display *display = plat->xdisplay;
|
||||
+ int frame_buf_config_count = 0;
|
||||
+ EGLDisplay edisplay = EGL_NO_DISPLAY;
|
||||
+ EGLConfig config = NULL;
|
||||
+ EGLContext context = EGL_NO_CONTEXT;
|
||||
+ int egl_min = 0, egl_maj = 0;
|
||||
+ bool success = false;
|
||||
+
|
||||
+ eglBindAPI(EGL_OPENGL_API);
|
||||
+
|
||||
+ edisplay = get_egl_display(plat);
|
||||
+
|
||||
+ if (EGL_NO_DISPLAY == edisplay) {
|
||||
+ blog(LOG_ERROR,
|
||||
+ "Failed to get EGL display using eglGetDisplay");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (!eglInitialize(edisplay, &egl_maj, &egl_min)) {
|
||||
+ blog(LOG_ERROR, "Failed to initialize EGL: %s",
|
||||
+ get_egl_error_string());
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (!eglChooseConfig(edisplay, ctx_config_attribs, &config, 1,
|
||||
+ &frame_buf_config_count)) {
|
||||
+ blog(LOG_ERROR, "Unable to find suitable EGL config: %s",
|
||||
+ get_egl_error_string());
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ context =
|
||||
+ eglCreateContext(edisplay, config, EGL_NO_CONTEXT, ctx_attribs);
|
||||
+#ifdef _DEBUG
|
||||
+ if (EGL_NO_CONTEXT == context) {
|
||||
+ const EGLint error = eglGetError();
|
||||
+ if (error == EGL_BAD_ATTRIBUTE) {
|
||||
+ /* Sometimes creation fails because debug gl is not supported */
|
||||
+ blog(LOG_ERROR,
|
||||
+ "Unable to create EGL context with DEBUG attrib, trying without");
|
||||
+ context = eglCreateContext(edisplay, config,
|
||||
+ EGL_NO_CONTEXT,
|
||||
+ ctx_attribs + 2);
|
||||
+ } else {
|
||||
+ blog(LOG_ERROR, "Unable to create EGL context: %s",
|
||||
+ get_egl_error_string2(error));
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+ if (EGL_NO_CONTEXT == context) {
|
||||
+ blog(LOG_ERROR, "Unable to create EGL context: %s",
|
||||
+ get_egl_error_string());
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ plat->pbuffer =
|
||||
+ eglCreatePbufferSurface(edisplay, config, ctx_pbuffer_attribs);
|
||||
+ if (EGL_NO_SURFACE == plat->pbuffer) {
|
||||
+ blog(LOG_ERROR, "Failed to create OpenGL pbuffer: %s",
|
||||
+ get_egl_error_string());
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ plat->edisplay = edisplay;
|
||||
+ plat->config = config;
|
||||
+ plat->context = context;
|
||||
+
|
||||
+ success = true;
|
||||
+ blog(LOG_DEBUG, "Created EGLDisplay %p", plat->edisplay);
|
||||
+
|
||||
+error:
|
||||
+ if (!success) {
|
||||
+ if (EGL_NO_CONTEXT != context)
|
||||
+ eglDestroyContext(edisplay, context);
|
||||
+ eglTerminate(edisplay);
|
||||
+ }
|
||||
+
|
||||
+ XSync(display, false);
|
||||
+ return success;
|
||||
+}
|
||||
+
|
||||
+static void gl_context_destroy(struct gl_platform *plat)
|
||||
+{
|
||||
+ eglMakeCurrent(plat->edisplay, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
+ EGL_NO_CONTEXT);
|
||||
+ eglDestroyContext(plat->edisplay, plat->context);
|
||||
+}
|
||||
+
|
||||
+static struct gl_windowinfo *
|
||||
+gl_x11_egl_windowinfo_create(const struct gs_init_data *info)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(info);
|
||||
+ return bmalloc(sizeof(struct gl_windowinfo));
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_windowinfo_destroy(struct gl_windowinfo *info)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(info);
|
||||
+ bfree(info);
|
||||
+}
|
||||
+
|
||||
+static Display *open_windowless_display(void)
|
||||
+{
|
||||
+ Display *display = XOpenDisplay(NULL);
|
||||
+ xcb_connection_t *xcb_conn;
|
||||
+ xcb_screen_iterator_t screen_iterator;
|
||||
+ xcb_screen_t *screen;
|
||||
+ int screen_num;
|
||||
+
|
||||
+ if (!display) {
|
||||
+ blog(LOG_ERROR, "Unable to open new X connection!");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ xcb_conn = XGetXCBConnection(display);
|
||||
+ if (!xcb_conn) {
|
||||
+ blog(LOG_ERROR, "Unable to get XCB connection to main display");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ screen_iterator = xcb_setup_roots_iterator(xcb_get_setup(xcb_conn));
|
||||
+ screen = screen_iterator.data;
|
||||
+ if (!screen) {
|
||||
+ blog(LOG_ERROR, "Unable to get screen root");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ screen_num = get_screen_num_from_root(xcb_conn, screen->root);
|
||||
+ if (screen_num == -1) {
|
||||
+ blog(LOG_ERROR, "Unable to get screen number from root");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (!gladLoadEGL()) {
|
||||
+ blog(LOG_ERROR, "Unable to load EGL entry functions.");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ return display;
|
||||
+
|
||||
+error:
|
||||
+ if (display)
|
||||
+ XCloseDisplay(display);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int x_error_handler(Display *display, XErrorEvent *error)
|
||||
+{
|
||||
+ char str1[512];
|
||||
+ char str2[512];
|
||||
+ char str3[512];
|
||||
+ XGetErrorText(display, error->error_code, str1, sizeof(str1));
|
||||
+ XGetErrorText(display, error->request_code, str2, sizeof(str2));
|
||||
+ XGetErrorText(display, error->minor_code, str3, sizeof(str3));
|
||||
+
|
||||
+ blog(LOG_ERROR,
|
||||
+ "X Error: %s, Major opcode: %s, "
|
||||
+ "Minor opcode: %s, Serial: %lu",
|
||||
+ str1, str2, str3, error->serial);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static struct gl_platform *gl_x11_egl_platform_create(gs_device_t *device,
|
||||
+ uint32_t adapter)
|
||||
+{
|
||||
+ /* There's some trickery here... we're mixing libX11, xcb, and EGL
|
||||
+ For an explanation see here: http://xcb.freedesktop.org/MixingCalls/
|
||||
+ Essentially, EGL requires Xlib. Everything else we use xcb. */
|
||||
+ struct gl_platform *plat = bmalloc(sizeof(struct gl_platform));
|
||||
+ Display *display = open_windowless_display();
|
||||
+
|
||||
+ if (!display) {
|
||||
+ goto fail_display_open;
|
||||
+ }
|
||||
+
|
||||
+ XSetEventQueueOwner(display, XCBOwnsEventQueue);
|
||||
+ XSetErrorHandler(x_error_handler);
|
||||
+
|
||||
+ /* We assume later that cur_swap is already set. */
|
||||
+ device->plat = plat;
|
||||
+
|
||||
+ plat->xdisplay = display;
|
||||
+
|
||||
+ if (!gl_context_create(plat)) {
|
||||
+ blog(LOG_ERROR, "Failed to create context!");
|
||||
+ goto fail_context_create;
|
||||
+ }
|
||||
+
|
||||
+ if (!eglMakeCurrent(plat->edisplay, plat->pbuffer, plat->pbuffer,
|
||||
+ plat->context)) {
|
||||
+ blog(LOG_ERROR, "Failed to make context current: %s",
|
||||
+ get_egl_error_string());
|
||||
+ goto fail_make_current;
|
||||
+ }
|
||||
+
|
||||
+ if (!gladLoadGL()) {
|
||||
+ blog(LOG_ERROR, "Failed to load OpenGL entry functions.");
|
||||
+ goto fail_load_gl;
|
||||
+ }
|
||||
+
|
||||
+ goto success;
|
||||
+
|
||||
+fail_make_current:
|
||||
+ gl_context_destroy(plat);
|
||||
+fail_context_create:
|
||||
+fail_load_gl:
|
||||
+ XCloseDisplay(display);
|
||||
+fail_display_open:
|
||||
+ bfree(plat);
|
||||
+ plat = NULL;
|
||||
+success:
|
||||
+ UNUSED_PARAMETER(adapter);
|
||||
+ return plat;
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_platform_destroy(struct gl_platform *plat)
|
||||
+{
|
||||
+ if (!plat)
|
||||
+ return;
|
||||
+
|
||||
+ gl_context_destroy(plat);
|
||||
+ eglTerminate(plat->edisplay);
|
||||
+ bfree(plat);
|
||||
+}
|
||||
+
|
||||
+static bool gl_x11_egl_platform_init_swapchain(struct gs_swap_chain *swap)
|
||||
+{
|
||||
+ const struct gl_platform *plat = swap->device->plat;
|
||||
+ Display *display = plat->xdisplay;
|
||||
+ xcb_connection_t *xcb_conn = XGetXCBConnection(display);
|
||||
+ xcb_window_t wid = xcb_generate_id(xcb_conn);
|
||||
+ xcb_window_t parent = swap->info.window.id;
|
||||
+ xcb_get_geometry_reply_t *geometry =
|
||||
+ get_window_geometry(xcb_conn, parent);
|
||||
+ bool status = false;
|
||||
+
|
||||
+ int screen_num;
|
||||
+ int visual;
|
||||
+
|
||||
+ if (!geometry)
|
||||
+ goto fail_geometry_request;
|
||||
+
|
||||
+ screen_num = get_screen_num_from_root(xcb_conn, geometry->root);
|
||||
+ if (screen_num == -1) {
|
||||
+ goto fail_screen;
|
||||
+ }
|
||||
+
|
||||
+ {
|
||||
+ if (!eglGetConfigAttrib(plat->edisplay, plat->config,
|
||||
+ EGL_NATIVE_VISUAL_ID,
|
||||
+ (EGLint *)&visual)) {
|
||||
+ blog(LOG_ERROR,
|
||||
+ "Cannot get visual id for EGL context: %s",
|
||||
+ get_egl_error_string());
|
||||
+ goto fail_visual_id;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ xcb_colormap_t colormap = xcb_generate_id(xcb_conn);
|
||||
+ uint32_t mask = XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
|
||||
+ uint32_t mask_values[] = {0, colormap, 0};
|
||||
+
|
||||
+ xcb_create_colormap(xcb_conn, XCB_COLORMAP_ALLOC_NONE, colormap, parent,
|
||||
+ visual);
|
||||
+
|
||||
+ xcb_create_window(xcb_conn, 24 /* Hardcoded? */, wid, parent, 0, 0,
|
||||
+ geometry->width, geometry->height, 0, 0, visual, mask,
|
||||
+ mask_values);
|
||||
+
|
||||
+ const EGLSurface surface =
|
||||
+ eglCreateWindowSurface(plat->edisplay, plat->config, wid, 0);
|
||||
+ if (EGL_NO_SURFACE == surface) {
|
||||
+ blog(LOG_ERROR, "Cannot get window EGL surface: %s",
|
||||
+ get_egl_error_string());
|
||||
+ goto fail_window_surface;
|
||||
+ }
|
||||
+
|
||||
+ swap->wi->config = plat->config;
|
||||
+ swap->wi->window = wid;
|
||||
+ swap->wi->surface = surface;
|
||||
+ swap->wi->screen = screen_num;
|
||||
+
|
||||
+ xcb_map_window(xcb_conn, wid);
|
||||
+
|
||||
+ status = true;
|
||||
+ goto success;
|
||||
+
|
||||
+fail_window_surface:
|
||||
+fail_visual_id:
|
||||
+fail_screen:
|
||||
+fail_geometry_request:
|
||||
+success:
|
||||
+ free(geometry);
|
||||
+ return status;
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_platform_cleanup_swapchain(struct gs_swap_chain *swap)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(swap);
|
||||
+ /* Really nothing to clean up? */
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_device_enter_context(gs_device_t *device)
|
||||
+{
|
||||
+ const EGLContext context = device->plat->context;
|
||||
+ const EGLDisplay display = device->plat->edisplay;
|
||||
+ const EGLSurface surface = (device->cur_swap)
|
||||
+ ? device->cur_swap->wi->surface
|
||||
+ : device->plat->pbuffer;
|
||||
+
|
||||
+ if (!eglMakeCurrent(display, surface, surface, context))
|
||||
+ blog(LOG_ERROR, "Failed to make context current: %s",
|
||||
+ get_egl_error_string());
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_device_leave_context(gs_device_t *device)
|
||||
+{
|
||||
+ const EGLDisplay display = device->plat->edisplay;
|
||||
+
|
||||
+ if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
+ EGL_NO_CONTEXT)) {
|
||||
+ blog(LOG_ERROR, "Failed to reset current context: %s",
|
||||
+ get_egl_error_string());
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void *gl_x11_egl_device_get_device_obj(gs_device_t *device)
|
||||
+{
|
||||
+ return device->plat->context;
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_getclientsize(const struct gs_swap_chain *swap,
|
||||
+ uint32_t *width, uint32_t *height)
|
||||
+{
|
||||
+ xcb_connection_t *xcb_conn =
|
||||
+ XGetXCBConnection(swap->device->plat->xdisplay);
|
||||
+ xcb_window_t window = swap->wi->window;
|
||||
+
|
||||
+ xcb_get_geometry_reply_t *geometry =
|
||||
+ get_window_geometry(xcb_conn, window);
|
||||
+ if (geometry) {
|
||||
+ *width = geometry->width;
|
||||
+ *height = geometry->height;
|
||||
+ }
|
||||
+
|
||||
+ free(geometry);
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_update(gs_device_t *device)
|
||||
+{
|
||||
+ Display *display = device->plat->xdisplay;
|
||||
+ xcb_window_t window = device->cur_swap->wi->window;
|
||||
+
|
||||
+ uint32_t values[] = {device->cur_swap->info.cx,
|
||||
+ device->cur_swap->info.cy};
|
||||
+
|
||||
+ xcb_configure_window(XGetXCBConnection(display), window,
|
||||
+ XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT,
|
||||
+ values);
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_clear_context(gs_device_t *device)
|
||||
+{
|
||||
+ Display *display = device->plat->edisplay;
|
||||
+
|
||||
+ if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
+ EGL_NO_CONTEXT)) {
|
||||
+ blog(LOG_ERROR, "Failed to reset current context.");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void gl_x11_egl_device_load_swapchain(gs_device_t *device,
|
||||
+ gs_swapchain_t *swap)
|
||||
+{
|
||||
+ if (device->cur_swap == swap)
|
||||
+ return;
|
||||
+
|
||||
+ device->cur_swap = swap;
|
||||
+
|
||||
+ device_enter_context(device);
|
||||
+}
|
||||
+
|
||||
+enum swap_type {
|
||||
+ SWAP_TYPE_NORMAL,
|
||||
+ SWAP_TYPE_EXT,
|
||||
+ SWAP_TYPE_MESA,
|
||||
+ SWAP_TYPE_SGI,
|
||||
+};
|
||||
+
|
||||
+static void gl_x11_egl_device_present(gs_device_t *device)
|
||||
+{
|
||||
+ Display *display = device->plat->xdisplay;
|
||||
+
|
||||
+ xcb_connection_t *xcb_conn = XGetXCBConnection(display);
|
||||
+ xcb_generic_event_t *xcb_event;
|
||||
+ while ((xcb_event = xcb_poll_for_event(xcb_conn))) {
|
||||
+ free(xcb_event);
|
||||
+ }
|
||||
+
|
||||
+ if (!eglSwapBuffers(device->plat->edisplay,
|
||||
+ device->cur_swap->wi->surface))
|
||||
+ blog(LOG_ERROR, "Cannot swap EGL buffers: %s",
|
||||
+ get_egl_error_string());
|
||||
+}
|
||||
+
|
||||
+static const struct gl_winsys_vtable egl_x11_winsys_vtable = {
|
||||
+ .windowinfo_create = gl_x11_egl_windowinfo_create,
|
||||
+ .windowinfo_destroy = gl_x11_egl_windowinfo_destroy,
|
||||
+ .platform_create = gl_x11_egl_platform_create,
|
||||
+ .platform_destroy = gl_x11_egl_platform_destroy,
|
||||
+ .platform_init_swapchain = gl_x11_egl_platform_init_swapchain,
|
||||
+ .platform_cleanup_swapchain = gl_x11_egl_platform_cleanup_swapchain,
|
||||
+ .device_enter_context = gl_x11_egl_device_enter_context,
|
||||
+ .device_leave_context = gl_x11_egl_device_leave_context,
|
||||
+ .device_get_device_obj = gl_x11_egl_device_get_device_obj,
|
||||
+ .getclientsize = gl_x11_egl_getclientsize,
|
||||
+ .clear_context = gl_x11_egl_clear_context,
|
||||
+ .update = gl_x11_egl_update,
|
||||
+ .device_load_swapchain = gl_x11_egl_device_load_swapchain,
|
||||
+ .device_present = gl_x11_egl_device_present,
|
||||
+};
|
||||
+
|
||||
+const struct gl_winsys_vtable *gl_x11_egl_get_winsys_vtable(void)
|
||||
+{
|
||||
+ return &egl_x11_winsys_vtable;
|
||||
+}
|
||||
diff --git a/libobs-opengl/gl-x11-egl.h b/libobs-opengl/gl-x11-egl.h
|
||||
new file mode 100644
|
||||
index 00000000..44ab3111
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-x11-egl.h
|
||||
@@ -0,0 +1,22 @@
|
||||
+/******************************************************************************
|
||||
+ Copyright (C) 2019 by Ivan Avdeev <me@w23.ru>
|
||||
+
|
||||
+ 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_egl_get_winsys_vtable(void);
|
||||
--
|
||||
2.28.0
|
||||
|
26
0005-deps-glad-Make-X11-required-as-well.patch
Normal file
26
0005-deps-glad-Make-X11-required-as-well.patch
Normal file
|
@ -0,0 +1,26 @@
|
|||
From 6b71db73fb1aef30ad06e576d2b2377052ed9f56 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Sat, 11 Apr 2020 23:49:05 -0300
|
||||
Subject: [PATCH 05/15] deps/glad: Make X11 required as well
|
||||
|
||||
To keep consistency with the EGL line
|
||||
---
|
||||
deps/glad/CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/deps/glad/CMakeLists.txt b/deps/glad/CMakeLists.txt
|
||||
index 9cb7e8fd..a31a5b91 100644
|
||||
--- a/deps/glad/CMakeLists.txt
|
||||
+++ b/deps/glad/CMakeLists.txt
|
||||
@@ -3,7 +3,7 @@ project(glad)
|
||||
find_package(OpenGL)
|
||||
|
||||
if(NOT WIN32 AND NOT APPLE)
|
||||
- find_package(X11)
|
||||
+ find_package(X11 REQUIRED)
|
||||
find_package(EGL REQUIRED)
|
||||
endif()
|
||||
|
||||
--
|
||||
2.28.0
|
||||
|
24
0006-ci-Install-qtbase5-private-dev-on-Linux.patch
Normal file
24
0006-ci-Install-qtbase5-private-dev-on-Linux.patch
Normal file
|
@ -0,0 +1,24 @@
|
|||
From e3eeda73e23c9b6a22562583eb9b7bf5c8a481df Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Fri, 6 Mar 2020 16:22:01 -0300
|
||||
Subject: [PATCH 06/15] ci: Install qtbase5-private-dev on Linux
|
||||
|
||||
---
|
||||
CI/install-dependencies-linux.sh | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/CI/install-dependencies-linux.sh b/CI/install-dependencies-linux.sh
|
||||
index 0d92fbf9..478f953a 100755
|
||||
--- a/CI/install-dependencies-linux.sh
|
||||
+++ b/CI/install-dependencies-linux.sh
|
||||
@@ -42,6 +42,7 @@ sudo apt-get install -y \
|
||||
pkg-config \
|
||||
python3-dev \
|
||||
qtbase5-dev \
|
||||
+ qtbase5-private-dev \
|
||||
libqt5svg5-dev \
|
||||
swig
|
||||
|
||||
--
|
||||
2.28.0
|
||||
|
2683
0007-libobs-nix-Move-X11-specific-code-to-obs-nix-x11.c.patch
Normal file
2683
0007-libobs-nix-Move-X11-specific-code-to-obs-nix-x11.c.patch
Normal file
File diff suppressed because it is too large
Load diff
258
0008-libobs-Introduce-the-concept-of-a-Unix-platform.patch
Normal file
258
0008-libobs-Introduce-the-concept-of-a-Unix-platform.patch
Normal file
|
@ -0,0 +1,258 @@
|
|||
From 2fe20c5488edf35c0507728d253b373bc1b842ab Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Fri, 6 Mar 2020 17:50:41 -0300
|
||||
Subject: [PATCH 08/15] libobs: Introduce the concept of a Unix platform
|
||||
|
||||
This is a Unix-specific code. The only available platforms
|
||||
at this point are the X11/GLX and X11/EGL platforms.
|
||||
|
||||
The concept of a platform display is also introduced. Again,
|
||||
the only display that is set right now is the X11 display.
|
||||
---
|
||||
UI/obs-app.cpp | 12 +++++++++
|
||||
libobs/CMakeLists.txt | 6 +++++
|
||||
libobs/obs-nix-platform.c | 42 +++++++++++++++++++++++++++++++
|
||||
libobs/obs-nix-platform.h | 52 +++++++++++++++++++++++++++++++++++++++
|
||||
libobs/obs-nix-x11.c | 5 ++--
|
||||
libobs/obs-nix.c | 15 +++++++++--
|
||||
6 files changed, 128 insertions(+), 4 deletions(-)
|
||||
create mode 100644 libobs/obs-nix-platform.c
|
||||
create mode 100644 libobs/obs-nix-platform.h
|
||||
|
||||
diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp
|
||||
index b6f0b7d5..cf9ecabf 100644
|
||||
--- a/UI/obs-app.cpp
|
||||
+++ b/UI/obs-app.cpp
|
||||
@@ -54,6 +54,11 @@
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
+#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
+#include <obs-nix-platform.h>
|
||||
+#include <QX11Info>
|
||||
+#endif
|
||||
+
|
||||
#include <iostream>
|
||||
|
||||
#include "ui-config.h"
|
||||
@@ -1346,6 +1351,13 @@ bool OBSApp::OBSInit()
|
||||
|
||||
qRegisterMetaType<VoidFunc>();
|
||||
|
||||
+#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
+ obs_set_nix_platform(OBS_NIX_PLATFORM_X11_GLX);
|
||||
+ if (QApplication::platformName() == "xcb") {
|
||||
+ obs_set_nix_platform_display(QX11Info::display());
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (!StartupOBS(locale.c_str(), GetProfilerNameStore()))
|
||||
return false;
|
||||
|
||||
diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt
|
||||
index 1625363f..489334c0 100644
|
||||
--- a/libobs/CMakeLists.txt
|
||||
+++ b/libobs/CMakeLists.txt
|
||||
@@ -180,13 +180,18 @@ elseif(APPLE)
|
||||
elseif(UNIX)
|
||||
set(libobs_PLATFORM_SOURCES
|
||||
obs-nix.c
|
||||
+ obs-nix-platform.c
|
||||
obs-nix-x11.c
|
||||
util/threading-posix.c
|
||||
util/pipe-posix.c
|
||||
util/platform-nix.c)
|
||||
|
||||
+ set(libobs_PLATFORM_HEADERS
|
||||
+ obs-nix-platform.h)
|
||||
+
|
||||
if(NEEDS_SIMDE)
|
||||
set(libobs_PLATFORM_HEADERS
|
||||
+ ${libobs_PLATFORM_HEADERS}
|
||||
util/simde/check.h
|
||||
util/simde/hedley.h
|
||||
util/simde/mmx.h
|
||||
@@ -197,6 +202,7 @@ elseif(UNIX)
|
||||
util/threading-posix.h)
|
||||
else()
|
||||
set(libobs_PLATFORM_HEADERS
|
||||
+ ${libobs_PLATFORM_HEADERS}
|
||||
util/threading-posix.h)
|
||||
endif()
|
||||
|
||||
diff --git a/libobs/obs-nix-platform.c b/libobs/obs-nix-platform.c
|
||||
new file mode 100644
|
||||
index 00000000..e07a4d7b
|
||||
--- /dev/null
|
||||
+++ b/libobs/obs-nix-platform.c
|
||||
@@ -0,0 +1,42 @@
|
||||
+/******************************************************************************
|
||||
+ 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 "obs-nix-platform.h"
|
||||
+
|
||||
+static enum obs_nix_platform_type obs_nix_platform = OBS_NIX_PLATFORM_X11_GLX;
|
||||
+
|
||||
+static void *obs_nix_platform_display = NULL;
|
||||
+
|
||||
+void obs_set_nix_platform(enum obs_nix_platform_type platform)
|
||||
+{
|
||||
+ obs_nix_platform = platform;
|
||||
+}
|
||||
+
|
||||
+enum obs_nix_platform_type obs_get_nix_platform(void)
|
||||
+{
|
||||
+ return obs_nix_platform;
|
||||
+}
|
||||
+
|
||||
+void obs_set_nix_platform_display(void *display)
|
||||
+{
|
||||
+ obs_nix_platform_display = display;
|
||||
+}
|
||||
+
|
||||
+void *obs_get_nix_platform_display(void)
|
||||
+{
|
||||
+ return obs_nix_platform_display;
|
||||
+}
|
||||
diff --git a/libobs/obs-nix-platform.h b/libobs/obs-nix-platform.h
|
||||
new file mode 100644
|
||||
index 00000000..4cf9d8cd
|
||||
--- /dev/null
|
||||
+++ b/libobs/obs-nix-platform.h
|
||||
@@ -0,0 +1,52 @@
|
||||
+/******************************************************************************
|
||||
+ 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 "util/c99defs.h"
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+extern "C" {
|
||||
+#endif
|
||||
+
|
||||
+enum obs_nix_platform_type {
|
||||
+ OBS_NIX_PLATFORM_X11_GLX,
|
||||
+ OBS_NIX_PLATFORM_X11_EGL,
|
||||
+};
|
||||
+
|
||||
+/**
|
||||
+ * Sets the Unix platform.
|
||||
+ * @param platform The platform to select.
|
||||
+ */
|
||||
+EXPORT void obs_set_nix_platform(enum obs_nix_platform_type platform);
|
||||
+/**
|
||||
+ * Gets the host platform.
|
||||
+ */
|
||||
+EXPORT enum obs_nix_platform_type obs_get_nix_platform(void);
|
||||
+/**
|
||||
+ * Sets the host platform's display connection.
|
||||
+ * @param display The host display connection.
|
||||
+ */
|
||||
+EXPORT void obs_set_nix_platform_display(void *display);
|
||||
+/**
|
||||
+ * Gets the host platform's display connection.
|
||||
+ */
|
||||
+EXPORT void *obs_get_nix_platform_display(void);
|
||||
+
|
||||
+#ifdef __cplusplus
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/libobs/obs-nix-x11.c b/libobs/obs-nix-x11.c
|
||||
index 29aa3c7f..bb3bc0b7 100644
|
||||
--- a/libobs/obs-nix-x11.c
|
||||
+++ b/libobs/obs-nix-x11.c
|
||||
@@ -18,6 +18,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "obs-internal.h"
|
||||
+#include "obs-nix-platform.h"
|
||||
#include "obs-nix-x11.h"
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
void obs_nix_x11_log_info(void)
|
||||
{
|
||||
- Display *dpy = XOpenDisplay(NULL);
|
||||
+ Display *dpy = obs_get_nix_platform_display();
|
||||
if (!dpy) {
|
||||
blog(LOG_INFO, "Unable to open X display");
|
||||
return;
|
||||
@@ -827,7 +828,7 @@ static inline void registerMouseEvents(struct obs_core_hotkeys *hotkeys)
|
||||
|
||||
static bool obs_nix_x11_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys)
|
||||
{
|
||||
- Display *display = XOpenDisplay(NULL);
|
||||
+ Display *display = obs_get_nix_platform_display();
|
||||
if (!display)
|
||||
return false;
|
||||
|
||||
diff --git a/libobs/obs-nix.c b/libobs/obs-nix.c
|
||||
index df1d99df..9c52279a 100644
|
||||
--- a/libobs/obs-nix.c
|
||||
+++ b/libobs/obs-nix.c
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "obs-internal.h"
|
||||
#include "obs-nix.h"
|
||||
+#include "obs-nix-platform.h"
|
||||
#include "obs-nix-x11.h"
|
||||
#if defined(__FreeBSD__)
|
||||
#define _GNU_SOURCE
|
||||
@@ -289,12 +290,22 @@ void log_system_info(void)
|
||||
#if defined(__linux__)
|
||||
log_distribution_info();
|
||||
#endif
|
||||
- obs_nix_x11_log_info();
|
||||
+ switch (obs_get_nix_platform()) {
|
||||
+ case OBS_NIX_PLATFORM_X11_GLX:
|
||||
+ case OBS_NIX_PLATFORM_X11_EGL:
|
||||
+ obs_nix_x11_log_info();
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
|
||||
bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys)
|
||||
{
|
||||
- hotkeys_vtable = obs_nix_x11_get_hotkeys_vtable();
|
||||
+ switch (obs_get_nix_platform()) {
|
||||
+ case OBS_NIX_PLATFORM_X11_GLX:
|
||||
+ case OBS_NIX_PLATFORM_X11_EGL:
|
||||
+ hotkeys_vtable = obs_nix_x11_get_hotkeys_vtable();
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
return hotkeys_vtable->init(hotkeys);
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
|
67
0009-UI-Set-the-Unix-platform-on-startup.patch
Normal file
67
0009-UI-Set-the-Unix-platform-on-startup.patch
Normal file
|
@ -0,0 +1,67 @@
|
|||
From 25d37ebfbe7d9aa583bd8bd9655892c2d73f13dc Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Tue, 7 Apr 2020 23:17:02 -0300
|
||||
Subject: [PATCH 09/15] UI: Set the Unix platform on startup
|
||||
|
||||
Move the OBS_USE_EGL environment variable check to obs-app.cpp,
|
||||
and set the OBS platform to be either OBS_NIX_PLATFORM_X11_GLX
|
||||
or OBS_NIX_PLATFORM_X11_EGL.
|
||||
---
|
||||
UI/obs-app.cpp | 4 ++++
|
||||
libobs-opengl/gl-nix.c | 10 ++++++----
|
||||
libobs-opengl/gl-nix.h | 2 ++
|
||||
3 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp
|
||||
index cf9ecabf..c62ba1da 100644
|
||||
--- a/UI/obs-app.cpp
|
||||
+++ b/UI/obs-app.cpp
|
||||
@@ -1354,6 +1354,10 @@ bool OBSApp::OBSInit()
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
obs_set_nix_platform(OBS_NIX_PLATFORM_X11_GLX);
|
||||
if (QApplication::platformName() == "xcb") {
|
||||
+ if (getenv("OBS_USE_EGL")) {
|
||||
+ blog(LOG_INFO, "Using EGL/X11");
|
||||
+ obs_set_nix_platform(OBS_NIX_PLATFORM_X11_EGL);
|
||||
+ }
|
||||
obs_set_nix_platform_display(QX11Info::display());
|
||||
}
|
||||
#endif
|
||||
diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c
|
||||
index 4b616ef1..9ed3d198 100644
|
||||
--- a/libobs-opengl/gl-nix.c
|
||||
+++ b/libobs-opengl/gl-nix.c
|
||||
@@ -25,11 +25,13 @@ static void init_winsys(void)
|
||||
{
|
||||
assert(gl_vtable == NULL);
|
||||
|
||||
- if (getenv("OBS_USE_EGL")) {
|
||||
- gl_vtable = gl_x11_egl_get_winsys_vtable();
|
||||
- blog(LOG_INFO, "Using EGL/X11");
|
||||
- } else {
|
||||
+ switch (obs_get_nix_platform()) {
|
||||
+ case OBS_NIX_PLATFORM_X11_GLX:
|
||||
gl_vtable = gl_x11_glx_get_winsys_vtable();
|
||||
+ break;
|
||||
+ case OBS_NIX_PLATFORM_X11_EGL:
|
||||
+ gl_vtable = gl_x11_egl_get_winsys_vtable();
|
||||
+ break;
|
||||
}
|
||||
|
||||
assert(gl_vtable != NULL);
|
||||
diff --git a/libobs-opengl/gl-nix.h b/libobs-opengl/gl-nix.h
|
||||
index 209cc308..f5532719 100644
|
||||
--- a/libobs-opengl/gl-nix.h
|
||||
+++ b/libobs-opengl/gl-nix.h
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
+#include <obs-nix-platform.h>
|
||||
+
|
||||
#include "gl-subsystem.h"
|
||||
|
||||
struct gl_winsys_vtable {
|
||||
--
|
||||
2.28.0
|
||||
|
38
0010-linux-capture-Fail-to-load-when-running-on-EGL.patch
Normal file
38
0010-linux-capture-Fail-to-load-when-running-on-EGL.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
From d07e62894d3aa78430a2ee543443a81c70153067 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Wed, 8 Apr 2020 23:58:43 -0300
|
||||
Subject: [PATCH 10/15] linux-capture: Fail to load when running on EGL
|
||||
|
||||
Right now, linux-capture hard-depends on GLX. Disable it when
|
||||
running under EGL.
|
||||
---
|
||||
plugins/linux-capture/linux-capture.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/plugins/linux-capture/linux-capture.c b/plugins/linux-capture/linux-capture.c
|
||||
index ce49ee72..56ff485c 100644
|
||||
--- a/plugins/linux-capture/linux-capture.c
|
||||
+++ b/plugins/linux-capture/linux-capture.c
|
||||
@@ -15,6 +15,7 @@ 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 <obs-module.h>
|
||||
+#include <obs-nix-platform.h>
|
||||
|
||||
OBS_DECLARE_MODULE()
|
||||
OBS_MODULE_USE_DEFAULT_LOCALE("linux-xshm", "en-US")
|
||||
@@ -30,6 +31,11 @@ extern void xcomposite_unload(void);
|
||||
|
||||
bool obs_module_load(void)
|
||||
{
|
||||
+ if (obs_get_nix_platform() != OBS_NIX_PLATFORM_X11_GLX) {
|
||||
+ blog(LOG_ERROR, "linux-capture cannot run on EGL platforms");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
obs_register_source(&xshm_input);
|
||||
xcomposite_load();
|
||||
return true;
|
||||
--
|
||||
2.28.0
|
||||
|
422
0011-libobs-Add-a-Wayland-platform.patch
Normal file
422
0011-libobs-Add-a-Wayland-platform.patch
Normal file
|
@ -0,0 +1,422 @@
|
|||
From de53eda26763e1aa7ec82803fd231c0cf9c0a6c4 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Fri, 6 Mar 2020 18:53:42 -0300
|
||||
Subject: [PATCH 11/15] libobs: Add a Wayland platform
|
||||
|
||||
Introduce the OBS_NIX_PLATFORM_WAYLAND enum value, and try to detect
|
||||
it when OBS Studio runs by looking into the platform name.
|
||||
---
|
||||
CMakeLists.txt | 2 +
|
||||
UI/CMakeLists.txt | 5 ++
|
||||
UI/obs-app.cpp | 17 +++++++
|
||||
cmake/Modules/FindWayland.cmake | 78 +++++++++++++++++++++++++++++
|
||||
libobs-opengl/CMakeLists.txt | 2 +-
|
||||
libobs-opengl/gl-nix.c | 5 ++
|
||||
libobs/CMakeLists.txt | 15 ++++++
|
||||
libobs/obs-nix-platform.h | 4 ++
|
||||
libobs/obs-nix-wayland.c | 88 +++++++++++++++++++++++++++++++++
|
||||
libobs/obs-nix-wayland.h | 24 +++++++++
|
||||
libobs/obs-nix.c | 14 ++++++
|
||||
libobs/obsconfig.h.in | 2 +
|
||||
12 files changed, 255 insertions(+), 1 deletion(-)
|
||||
create mode 100644 cmake/Modules/FindWayland.cmake
|
||||
create mode 100644 libobs/obs-nix-wayland.c
|
||||
create mode 100644 libobs/obs-nix-wayland.h
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index b56c2bba..9ab530ce 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -189,6 +189,8 @@ if(APPLE)
|
||||
list(APPEND CMAKE_INSTALL_RPATH "@loader_path/" "@executable_path/")
|
||||
elseif(UNIX)
|
||||
option(USE_XDG "Utilize XDG Base Directory Specification" ON)
|
||||
+ option(ENABLE_WAYLAND "Build support for Wayland" ON)
|
||||
+
|
||||
if(USE_XDG)
|
||||
add_definitions(-DUSE_XDG)
|
||||
endif()
|
||||
diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt
|
||||
index a660f326..171efa2b 100644
|
||||
--- a/UI/CMakeLists.txt
|
||||
+++ b/UI/CMakeLists.txt
|
||||
@@ -403,6 +403,11 @@ if (APPLE)
|
||||
set_target_properties(obs PROPERTIES LINK_FLAGS "-pagezero_size 10000 -image_base 100000000")
|
||||
endif()
|
||||
|
||||
+if (ENABLE_WAYLAND)
|
||||
+ find_package(Qt5Gui)
|
||||
+ include_directories(${Qt5Gui_PRIVATE_INCLUDE_DIRS})
|
||||
+endif()
|
||||
+
|
||||
define_graphic_modules(obs)
|
||||
|
||||
install_obs_core(obs)
|
||||
diff --git a/UI/obs-app.cpp b/UI/obs-app.cpp
|
||||
index c62ba1da..8335c2ce 100644
|
||||
--- a/UI/obs-app.cpp
|
||||
+++ b/UI/obs-app.cpp
|
||||
@@ -57,6 +57,11 @@
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
#include <obs-nix-platform.h>
|
||||
#include <QX11Info>
|
||||
+
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+#include <qpa/qplatformnativeinterface.h>
|
||||
+#endif
|
||||
+
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@@ -1360,6 +1365,18 @@ bool OBSApp::OBSInit()
|
||||
}
|
||||
obs_set_nix_platform_display(QX11Info::display());
|
||||
}
|
||||
+
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+ if (QApplication::platformName().contains("wayland")) {
|
||||
+ obs_set_nix_platform(OBS_NIX_PLATFORM_WAYLAND);
|
||||
+ QPlatformNativeInterface *native =
|
||||
+ QGuiApplication::platformNativeInterface();
|
||||
+ obs_set_nix_platform_display(
|
||||
+ native->nativeResourceForIntegration("display"));
|
||||
+
|
||||
+ blog(LOG_INFO, "Platform: Wayland");
|
||||
+ }
|
||||
+#endif
|
||||
#endif
|
||||
|
||||
if (!StartupOBS(locale.c_str(), GetProfilerNameStore()))
|
||||
diff --git a/cmake/Modules/FindWayland.cmake b/cmake/Modules/FindWayland.cmake
|
||||
new file mode 100644
|
||||
index 00000000..377f0545
|
||||
--- /dev/null
|
||||
+++ b/cmake/Modules/FindWayland.cmake
|
||||
@@ -0,0 +1,78 @@
|
||||
+# Try to find Wayland on a Unix system
|
||||
+#
|
||||
+# This will define:
|
||||
+#
|
||||
+# WAYLAND_FOUND - True if Wayland is found
|
||||
+# WAYLAND_LIBRARIES - Link these to use Wayland
|
||||
+# WAYLAND_INCLUDE_DIRS - Include directory for Wayland
|
||||
+# WAYLAND_DEFINITIONS - Compiler flags for using Wayland
|
||||
+#
|
||||
+# In addition the following more fine grained variables will be defined:
|
||||
+#
|
||||
+# Wayland_Client_FOUND WAYLAND_CLIENT_INCLUDE_DIRS WAYLAND_CLIENT_LIBRARIES
|
||||
+# Wayland_Server_FOUND WAYLAND_SERVER_INCLUDE_DIRS WAYLAND_SERVER_LIBRARIES
|
||||
+# Wayland_EGL_FOUND WAYLAND_EGL_INCLUDE_DIRS WAYLAND_EGL_LIBRARIES
|
||||
+# Wayland_Cursor_FOUND WAYLAND_CURSOR_INCLUDE_DIRS WAYLAND_CURSOR_LIBRARIES
|
||||
+#
|
||||
+# Copyright (c) 2013 Martin Gräßlin <mgraesslin@kde.org>
|
||||
+# 2020 Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
+#
|
||||
+# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
+
|
||||
+IF (NOT WIN32)
|
||||
+
|
||||
+ # Use pkg-config to get the directories and then use these values
|
||||
+ # in the find_path() and find_library() calls
|
||||
+ find_package(PkgConfig)
|
||||
+ PKG_CHECK_MODULES(PKG_WAYLAND QUIET wayland-client wayland-server wayland-egl wayland-cursor)
|
||||
+
|
||||
+ set(WAYLAND_DEFINITIONS ${PKG_WAYLAND_CFLAGS})
|
||||
+
|
||||
+ find_path(WAYLAND_CLIENT_INCLUDE_DIRS NAMES wayland-client.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
+ find_library(WAYLAND_CLIENT_LIBRARIES NAMES wayland-client HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
+ if(WAYLAND_CLIENT_INCLUDE_DIRS AND WAYLAND_CLIENT_LIBRARIES)
|
||||
+ set(Wayland_Client_FOUND TRUE)
|
||||
+ else()
|
||||
+ set(Wayland_Client_FOUND FALSE)
|
||||
+ endif()
|
||||
+ mark_as_advanced(WAYLAND_CLIENT_INCLUDE_DIRS WAYLAND_CLIENT_LIBRARIES)
|
||||
+
|
||||
+ find_path(WAYLAND_CURSOR_INCLUDE_DIRS NAMES wayland-cursor.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
+ find_library(WAYLAND_CURSOR_LIBRARIES NAMES wayland-cursor HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
+ if(WAYLAND_CURSOR_INCLUDE_DIRS AND WAYLAND_CURSOR_LIBRARIES)
|
||||
+ set(Wayland_Cursor_FOUND TRUE)
|
||||
+ else()
|
||||
+ set(Wayland_Cursor_FOUND FALSE)
|
||||
+ endif()
|
||||
+ mark_as_advanced(WAYLAND_CURSOR_INCLUDE_DIRS WAYLAND_CURSOR_LIBRARIES)
|
||||
+
|
||||
+ find_path(WAYLAND_EGL_INCLUDE_DIRS NAMES wayland-egl.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
+ find_library(WAYLAND_EGL_LIBRARIES NAMES wayland-egl HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
+ if(WAYLAND_EGL_INCLUDE_DIRS AND WAYLAND_EGL_LIBRARIES)
|
||||
+ set(Wayland_EGL_FOUND TRUE)
|
||||
+ else()
|
||||
+ set(Wayland_EGL_FOUND FALSE)
|
||||
+ endif()
|
||||
+ mark_as_advanced(WAYLAND_EGL_INCLUDE_DIRS WAYLAND_EGL_LIBRARIES)
|
||||
+
|
||||
+ find_path(WAYLAND_SERVER_INCLUDE_DIRS NAMES wayland-server.h HINTS ${PKG_WAYLAND_INCLUDE_DIRS})
|
||||
+ find_library(WAYLAND_SERVER_LIBRARIES NAMES wayland-server HINTS ${PKG_WAYLAND_LIBRARY_DIRS})
|
||||
+ if(WAYLAND_SERVER_INCLUDE_DIRS AND WAYLAND_SERVER_LIBRARIES)
|
||||
+ set(Wayland_Server_FOUND TRUE)
|
||||
+ else()
|
||||
+ set(Wayland_Server_FOUND FALSE)
|
||||
+ endif()
|
||||
+ mark_as_advanced(WAYLAND_SERVER_INCLUDE_DIRS WAYLAND_SERVER_LIBRARIES)
|
||||
+
|
||||
+ set(WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIRS} ${WAYLAND_SERVER_INCLUDE_DIRS} ${WAYLAND_EGL_INCLUDE_DIRS} ${WAYLAND_CURSOR_INCLUDE_DIRS})
|
||||
+ set(WAYLAND_LIBRARIES ${WAYLAND_CLIENT_LIBRARIES} ${WAYLAND_SERVER_LIBRARIES} ${WAYLAND_EGL_LIBRARIES} ${WAYLAND_CURSOR_LIBRARIES})
|
||||
+ mark_as_advanced(WAYLAND_INCLUDE_DIRS WAYLAND_LIBRARIES)
|
||||
+
|
||||
+ list(REMOVE_DUPLICATES WAYLAND_INCLUDE_DIRS)
|
||||
+
|
||||
+ include(FindPackageHandleStandardArgs)
|
||||
+
|
||||
+ find_package_handle_standard_args(Wayland REQUIRED_VARS WAYLAND_LIBRARIES WAYLAND_INCLUDE_DIRS HANDLE_COMPONENTS)
|
||||
+
|
||||
+ENDIF ()
|
||||
diff --git a/libobs-opengl/CMakeLists.txt b/libobs-opengl/CMakeLists.txt
|
||||
index 9c645c3d..f84636cf 100644
|
||||
--- a/libobs-opengl/CMakeLists.txt
|
||||
+++ b/libobs-opengl/CMakeLists.txt
|
||||
@@ -32,7 +32,7 @@ elseif(APPLE)
|
||||
${COCOA}
|
||||
${IOSURF}
|
||||
${OPENGL_gl_LIBRARY})
|
||||
-else() #This needs to change to be more specific to get ready for Wayland
|
||||
+else()
|
||||
find_package(XCB COMPONENTS XCB REQUIRED)
|
||||
find_package(X11_XCB REQUIRED)
|
||||
|
||||
diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c
|
||||
index 9ed3d198..581e16a4 100644
|
||||
--- a/libobs-opengl/gl-nix.c
|
||||
+++ b/libobs-opengl/gl-nix.c
|
||||
@@ -32,6 +32,11 @@ static void init_winsys(void)
|
||||
case OBS_NIX_PLATFORM_X11_EGL:
|
||||
gl_vtable = gl_x11_egl_get_winsys_vtable();
|
||||
break;
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+ case OBS_NIX_PLATFORM_WAYLAND:
|
||||
+ blog(LOG_ERROR, "EGL/Wayland not implemented yet");
|
||||
+ break;
|
||||
+#endif
|
||||
}
|
||||
|
||||
assert(gl_vtable != NULL);
|
||||
diff --git a/libobs/CMakeLists.txt b/libobs/CMakeLists.txt
|
||||
index 489334c0..1cb1583b 100644
|
||||
--- a/libobs/CMakeLists.txt
|
||||
+++ b/libobs/CMakeLists.txt
|
||||
@@ -189,6 +189,21 @@ elseif(UNIX)
|
||||
set(libobs_PLATFORM_HEADERS
|
||||
obs-nix-platform.h)
|
||||
|
||||
+ if(ENABLE_WAYLAND)
|
||||
+ find_package(Wayland COMPONENTS Client REQUIRED)
|
||||
+
|
||||
+ set(libobs_PLATFORM_SOURCES ${libobs_PLATFORM_SOURCES}
|
||||
+ obs-nix-wayland.c)
|
||||
+
|
||||
+ include_directories(
|
||||
+ ${WAYLAND_CLIENT_INCLUDE_DIR})
|
||||
+ add_definitions(
|
||||
+ ${WAYLAND_DEFINITIONS})
|
||||
+ set(libobs_PLATFORM_DEPS
|
||||
+ ${libobs_PLATFORM_DEPS}
|
||||
+ ${WAYLAND_CLIENT_LIBRARIES})
|
||||
+ endif()
|
||||
+
|
||||
if(NEEDS_SIMDE)
|
||||
set(libobs_PLATFORM_HEADERS
|
||||
${libobs_PLATFORM_HEADERS}
|
||||
diff --git a/libobs/obs-nix-platform.h b/libobs/obs-nix-platform.h
|
||||
index 4cf9d8cd..cef700d7 100644
|
||||
--- a/libobs/obs-nix-platform.h
|
||||
+++ b/libobs/obs-nix-platform.h
|
||||
@@ -26,6 +26,10 @@ extern "C" {
|
||||
enum obs_nix_platform_type {
|
||||
OBS_NIX_PLATFORM_X11_GLX,
|
||||
OBS_NIX_PLATFORM_X11_EGL,
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+ OBS_NIX_PLATFORM_WAYLAND,
|
||||
+#endif
|
||||
+
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/libobs/obs-nix-wayland.c b/libobs/obs-nix-wayland.c
|
||||
new file mode 100644
|
||||
index 00000000..b242017f
|
||||
--- /dev/null
|
||||
+++ b/libobs/obs-nix-wayland.c
|
||||
@@ -0,0 +1,88 @@
|
||||
+/******************************************************************************
|
||||
+ 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 "obs-internal.h"
|
||||
+#include "obs-nix-platform.h"
|
||||
+#include "obs-nix-wayland.h"
|
||||
+
|
||||
+#include <wayland-client.h>
|
||||
+
|
||||
+void obs_nix_wayland_log_info(void)
|
||||
+{
|
||||
+ struct wl_display *display = obs_get_nix_platform_display();
|
||||
+ if (display == NULL) {
|
||||
+ blog(LOG_INFO, "Unable to connect to Wayland server");
|
||||
+ return;
|
||||
+ }
|
||||
+ //TODO: query some information about the wayland server if possible
|
||||
+ blog(LOG_INFO, "Connected to Wayland server");
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+obs_nix_wayland_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(hotkeys);
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+obs_nix_wayland_hotkeys_platform_free(struct obs_core_hotkeys *hotkeys)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(hotkeys);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+obs_nix_wayland_hotkeys_platform_is_pressed(obs_hotkeys_platform_t *context,
|
||||
+ obs_key_t key)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(context);
|
||||
+ UNUSED_PARAMETER(key);
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static void obs_nix_wayland_key_to_str(obs_key_t key, struct dstr *dstr)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(key);
|
||||
+ UNUSED_PARAMETER(dstr);
|
||||
+}
|
||||
+
|
||||
+static obs_key_t obs_nix_wayland_key_from_virtual_key(int sym)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(sym);
|
||||
+ return OBS_KEY_NONE;
|
||||
+}
|
||||
+
|
||||
+static int obs_nix_wayland_key_to_virtual_key(obs_key_t key)
|
||||
+{
|
||||
+ UNUSED_PARAMETER(key);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct obs_nix_hotkeys_vtable wayland_hotkeys_vtable = {
|
||||
+ .init = obs_nix_wayland_hotkeys_platform_init,
|
||||
+ .free = obs_nix_wayland_hotkeys_platform_free,
|
||||
+ .is_pressed = obs_nix_wayland_hotkeys_platform_is_pressed,
|
||||
+ .key_to_str = obs_nix_wayland_key_to_str,
|
||||
+ .key_from_virtual_key = obs_nix_wayland_key_from_virtual_key,
|
||||
+ .key_to_virtual_key = obs_nix_wayland_key_to_virtual_key,
|
||||
+
|
||||
+};
|
||||
+
|
||||
+const struct obs_nix_hotkeys_vtable *obs_nix_wayland_get_hotkeys_vtable(void)
|
||||
+{
|
||||
+ return &wayland_hotkeys_vtable;
|
||||
+}
|
||||
diff --git a/libobs/obs-nix-wayland.h b/libobs/obs-nix-wayland.h
|
||||
new file mode 100644
|
||||
index 00000000..d44720c5
|
||||
--- /dev/null
|
||||
+++ b/libobs/obs-nix-wayland.h
|
||||
@@ -0,0 +1,24 @@
|
||||
+/******************************************************************************
|
||||
+ 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 "obs-nix.h"
|
||||
+
|
||||
+void obs_nix_wayland_log_info(void);
|
||||
+
|
||||
+const struct obs_nix_hotkeys_vtable *obs_nix_wayland_get_hotkeys_vtable(void);
|
||||
diff --git a/libobs/obs-nix.c b/libobs/obs-nix.c
|
||||
index 9c52279a..ec7f8e25 100644
|
||||
--- a/libobs/obs-nix.c
|
||||
+++ b/libobs/obs-nix.c
|
||||
@@ -20,6 +20,11 @@
|
||||
#include "obs-nix.h"
|
||||
#include "obs-nix-platform.h"
|
||||
#include "obs-nix-x11.h"
|
||||
+
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+#include "obs-nix-wayland.h"
|
||||
+#endif
|
||||
+
|
||||
#if defined(__FreeBSD__)
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
@@ -295,6 +300,10 @@ void log_system_info(void)
|
||||
case OBS_NIX_PLATFORM_X11_EGL:
|
||||
obs_nix_x11_log_info();
|
||||
break;
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+ case OBS_NIX_PLATFORM_WAYLAND:
|
||||
+ break;
|
||||
+#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,6 +314,11 @@ bool obs_hotkeys_platform_init(struct obs_core_hotkeys *hotkeys)
|
||||
case OBS_NIX_PLATFORM_X11_EGL:
|
||||
hotkeys_vtable = obs_nix_x11_get_hotkeys_vtable();
|
||||
break;
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+ case OBS_NIX_PLATFORM_WAYLAND:
|
||||
+ hotkeys_vtable = obs_nix_wayland_get_hotkeys_vtable();
|
||||
+ break;
|
||||
+#endif
|
||||
}
|
||||
|
||||
return hotkeys_vtable->init(hotkeys);
|
||||
diff --git a/libobs/obsconfig.h.in b/libobs/obsconfig.h.in
|
||||
index 1a09ebea..82d2e3af 100644
|
||||
--- a/libobs/obsconfig.h.in
|
||||
+++ b/libobs/obsconfig.h.in
|
||||
@@ -24,6 +24,8 @@
|
||||
#define LIBOBS_IMAGEMAGICK_DIR_STYLE_7GE 7
|
||||
#define LIBOBS_IMAGEMAGICK_DIR_STYLE @LIBOBS_IMAGEMAGICK_DIR_STYLE@
|
||||
|
||||
+#cmakedefine ENABLE_WAYLAND
|
||||
+
|
||||
/* NOTE: Release candidate version numbers internally are always the previous
|
||||
* main release number! For example, if the current public release is 21.0 and
|
||||
* the build is 22.0 release candidate 1, internally the build number (defined
|
||||
--
|
||||
2.28.0
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
From 5bf0de83d59b4147e91feceba2ec957522d83736 Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Sat, 11 Apr 2020 23:32:16 -0300
|
||||
Subject: [PATCH 12/15] libobs-opengl: Try to use the platform display if
|
||||
available
|
||||
|
||||
We need to ensure we're running all X11 code on the same display.
|
||||
---
|
||||
libobs-opengl/gl-x11-egl.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libobs-opengl/gl-x11-egl.c b/libobs-opengl/gl-x11-egl.c
|
||||
index 5b413995..47b8e420 100644
|
||||
--- a/libobs-opengl/gl-x11-egl.c
|
||||
+++ b/libobs-opengl/gl-x11-egl.c
|
||||
@@ -324,14 +324,19 @@ static void gl_x11_egl_windowinfo_destroy(struct gl_windowinfo *info)
|
||||
bfree(info);
|
||||
}
|
||||
|
||||
-static Display *open_windowless_display(void)
|
||||
+static Display *open_windowless_display(Display *platform_display)
|
||||
{
|
||||
- Display *display = XOpenDisplay(NULL);
|
||||
+ Display *display;
|
||||
xcb_connection_t *xcb_conn;
|
||||
xcb_screen_iterator_t screen_iterator;
|
||||
xcb_screen_t *screen;
|
||||
int screen_num;
|
||||
|
||||
+ if (platform_display)
|
||||
+ display = platform_display;
|
||||
+ else
|
||||
+ display = XOpenDisplay(NULL);
|
||||
+
|
||||
if (!display) {
|
||||
blog(LOG_ERROR, "Unable to open new X connection!");
|
||||
return NULL;
|
||||
@@ -392,7 +397,8 @@ static struct gl_platform *gl_x11_egl_platform_create(gs_device_t *device,
|
||||
For an explanation see here: http://xcb.freedesktop.org/MixingCalls/
|
||||
Essentially, EGL requires Xlib. Everything else we use xcb. */
|
||||
struct gl_platform *plat = bmalloc(sizeof(struct gl_platform));
|
||||
- Display *display = open_windowless_display();
|
||||
+ Display *platform_display = obs_get_nix_platform_display();
|
||||
+ Display *display = open_windowless_display(platform_display);
|
||||
|
||||
if (!display) {
|
||||
goto fail_display_open;
|
||||
--
|
||||
2.28.0
|
||||
|
474
0013-libobs-opengl-Introduce-an-EGL-Wayland-renderer.patch
Normal file
474
0013-libobs-opengl-Introduce-an-EGL-Wayland-renderer.patch
Normal file
|
@ -0,0 +1,474 @@
|
|||
From 7fd9f95fee70ec8d604797db4a0de77e58c6e32d Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 21:09:11 -0300
|
||||
Subject: [PATCH 13/15] libobs-opengl: Introduce an EGL/Wayland renderer
|
||||
|
||||
Introduce a new Wayland/EGL renderer.
|
||||
---
|
||||
libobs-opengl/CMakeLists.txt | 23 +++
|
||||
libobs-opengl/gl-nix.c | 7 +-
|
||||
libobs-opengl/gl-nix.h | 1 +
|
||||
libobs-opengl/gl-wayland-egl.c | 350 +++++++++++++++++++++++++++++++++
|
||||
libobs-opengl/gl-wayland-egl.h | 22 +++
|
||||
5 files changed, 402 insertions(+), 1 deletion(-)
|
||||
create mode 100644 libobs-opengl/gl-wayland-egl.c
|
||||
create mode 100644 libobs-opengl/gl-wayland-egl.h
|
||||
|
||||
diff --git a/libobs-opengl/CMakeLists.txt b/libobs-opengl/CMakeLists.txt
|
||||
index f84636cf..0f694b6c 100644
|
||||
--- a/libobs-opengl/CMakeLists.txt
|
||||
+++ b/libobs-opengl/CMakeLists.txt
|
||||
@@ -52,6 +52,29 @@ else()
|
||||
gl-nix.c
|
||||
gl-x11-egl.c
|
||||
gl-x11-glx.c)
|
||||
+
|
||||
+ if(ENABLE_WAYLAND)
|
||||
+ find_package(EGL REQUIRED)
|
||||
+ find_package(Wayland REQUIRED)
|
||||
+
|
||||
+ include_directories(
|
||||
+ ${WAYLAND_CLIENT_INCLUDE_DIRS}
|
||||
+ ${WAYLAND_EGL_INCLUDE_DIRS}
|
||||
+ ${EGL_INCLUDE_DIRS})
|
||||
+
|
||||
+ add_definitions(
|
||||
+ ${WAYLAND_DEFINITIONS})
|
||||
+
|
||||
+ set(libobs-opengl_PLATFORM_DEPS
|
||||
+ ${libobs-opengl_PLATFORM_DEPS}
|
||||
+ ${WAYLAND_CLIENT_LIBRARIES}
|
||||
+ ${WAYLAND_EGL_LIBRARIES}
|
||||
+ ${EGL_LIBRARIES})
|
||||
+
|
||||
+ set(libobs-opengl_PLATFORM_SOURCES
|
||||
+ ${libobs-opengl_PLATFORM_SOURCES}
|
||||
+ gl-wayland-egl.c)
|
||||
+ endif()
|
||||
endif()
|
||||
|
||||
set(libobs-opengl_SOURCES
|
||||
diff --git a/libobs-opengl/gl-nix.c b/libobs-opengl/gl-nix.c
|
||||
index 581e16a4..6c272c3d 100644
|
||||
--- a/libobs-opengl/gl-nix.c
|
||||
+++ b/libobs-opengl/gl-nix.c
|
||||
@@ -19,6 +19,10 @@
|
||||
#include "gl-x11-glx.h"
|
||||
#include "gl-x11-egl.h"
|
||||
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+#include "gl-wayland-egl.h"
|
||||
+#endif
|
||||
+
|
||||
static const struct gl_winsys_vtable *gl_vtable = NULL;
|
||||
|
||||
static void init_winsys(void)
|
||||
@@ -34,7 +38,8 @@ static void init_winsys(void)
|
||||
break;
|
||||
#ifdef ENABLE_WAYLAND
|
||||
case OBS_NIX_PLATFORM_WAYLAND:
|
||||
- blog(LOG_ERROR, "EGL/Wayland not implemented yet");
|
||||
+ gl_vtable = gl_wayland_egl_get_winsys_vtable();
|
||||
+ blog(LOG_INFO, "Using EGL/Wayland");
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
diff --git a/libobs-opengl/gl-nix.h b/libobs-opengl/gl-nix.h
|
||||
index f5532719..741154da 100644
|
||||
--- a/libobs-opengl/gl-nix.h
|
||||
+++ b/libobs-opengl/gl-nix.h
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
+#include <obs.h>
|
||||
#include <obs-nix-platform.h>
|
||||
|
||||
#include "gl-subsystem.h"
|
||||
diff --git a/libobs-opengl/gl-wayland-egl.c b/libobs-opengl/gl-wayland-egl.c
|
||||
new file mode 100644
|
||||
index 00000000..98bb483f
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-wayland-egl.c
|
||||
@@ -0,0 +1,350 @@
|
||||
+/******************************************************************************
|
||||
+ 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-wayland-egl.h"
|
||||
+
|
||||
+#include <wayland-client.h>
|
||||
+#include <wayland-egl.h>
|
||||
+
|
||||
+#include <EGL/egl.h>
|
||||
+#include <EGL/eglplatform.h>
|
||||
+#include <EGL/eglext.h>
|
||||
+
|
||||
+static const EGLint config_attribs[] = {EGL_SURFACE_TYPE,
|
||||
+ EGL_WINDOW_BIT,
|
||||
+ EGL_RENDERABLE_TYPE,
|
||||
+ EGL_OPENGL_BIT,
|
||||
+ EGL_STENCIL_SIZE,
|
||||
+ 0,
|
||||
+ EGL_DEPTH_SIZE,
|
||||
+ 0,
|
||||
+ EGL_BUFFER_SIZE,
|
||||
+ 32,
|
||||
+ EGL_ALPHA_SIZE,
|
||||
+ 8,
|
||||
+ EGL_NATIVE_RENDERABLE,
|
||||
+ EGL_TRUE,
|
||||
+ EGL_NONE};
|
||||
+
|
||||
+static const EGLint ctx_attribs[] = {
|
||||
+#ifdef _DEBUG
|
||||
+ EGL_CONTEXT_OPENGL_DEBUG,
|
||||
+ EGL_TRUE,
|
||||
+#endif
|
||||
+ EGL_CONTEXT_OPENGL_PROFILE_MASK,
|
||||
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
|
||||
+ EGL_CONTEXT_MAJOR_VERSION,
|
||||
+ 3,
|
||||
+ EGL_CONTEXT_MINOR_VERSION,
|
||||
+ 3,
|
||||
+ EGL_NONE};
|
||||
+
|
||||
+#ifdef EGL_KHR_create_context
|
||||
+static const EGLint khr_ctx_attribs[] = {
|
||||
+#ifdef _DEBUG
|
||||
+ EGL_CONTEXT_FLAGS_KHR,
|
||||
+ EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR,
|
||||
+#endif
|
||||
+ EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR,
|
||||
+ EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR,
|
||||
+ EGL_CONTEXT_MAJOR_VERSION_KHR,
|
||||
+ 3,
|
||||
+ EGL_CONTEXT_MINOR_VERSION_KHR,
|
||||
+ 3,
|
||||
+ EGL_NONE};
|
||||
+#endif
|
||||
+
|
||||
+struct gl_windowinfo {
|
||||
+ struct wl_egl_window *window;
|
||||
+ EGLSurface egl_surface;
|
||||
+};
|
||||
+
|
||||
+struct gl_platform {
|
||||
+ struct wl_display *wl_display;
|
||||
+ EGLDisplay display;
|
||||
+ EGLConfig config;
|
||||
+ EGLContext context;
|
||||
+};
|
||||
+
|
||||
+struct gl_windowinfo *
|
||||
+gl_wayland_egl_windowinfo_create(const struct gs_init_data *info)
|
||||
+{
|
||||
+ struct wl_egl_window *window =
|
||||
+ wl_egl_window_create(info->window.display, info->cx, info->cy);
|
||||
+ if (window == NULL) {
|
||||
+ blog(LOG_ERROR, "wl_egl_window_create failed");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ struct gl_windowinfo *wi = bmalloc(sizeof(struct gl_windowinfo));
|
||||
+ wi->window = window;
|
||||
+ return wi;
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_windowinfo_destroy(struct gl_windowinfo *info)
|
||||
+{
|
||||
+ wl_egl_window_destroy(info->window);
|
||||
+ bfree(info);
|
||||
+}
|
||||
+
|
||||
+static bool egl_make_current(EGLDisplay display, EGLSurface surface,
|
||||
+ EGLContext context)
|
||||
+{
|
||||
+ if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) {
|
||||
+ blog(LOG_ERROR, "eglBindAPI failed");
|
||||
+ }
|
||||
+
|
||||
+ if (!eglMakeCurrent(display, surface, surface, context)) {
|
||||
+ blog(LOG_ERROR, "eglMakeCurrent failed");
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static bool egl_context_create(struct gl_platform *plat, const EGLint *attribs)
|
||||
+{
|
||||
+ bool success = false;
|
||||
+ EGLint num_config;
|
||||
+
|
||||
+ if (eglBindAPI(EGL_OPENGL_API) == EGL_FALSE) {
|
||||
+ blog(LOG_ERROR, "eglBindAPI failed");
|
||||
+ }
|
||||
+
|
||||
+ EGLBoolean result = eglChooseConfig(plat->display, config_attribs,
|
||||
+ &plat->config, 1, &num_config);
|
||||
+ if (result != EGL_TRUE || num_config == 0) {
|
||||
+ blog(LOG_ERROR, "eglChooseConfig failed");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ plat->context = eglCreateContext(plat->display, plat->config,
|
||||
+ EGL_NO_CONTEXT, attribs);
|
||||
+ if (plat->context == EGL_NO_CONTEXT) {
|
||||
+ blog(LOG_ERROR, "eglCreateContext failed");
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ success =
|
||||
+ egl_make_current(plat->display, EGL_NO_SURFACE, plat->context);
|
||||
+
|
||||
+error:
|
||||
+ return success;
|
||||
+}
|
||||
+
|
||||
+static void egl_context_destroy(struct gl_platform *plat)
|
||||
+{
|
||||
+ egl_make_current(plat->display, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
+ eglDestroyContext(plat->display, plat->context);
|
||||
+}
|
||||
+
|
||||
+static bool extension_supported(const char *extensions, const char *search)
|
||||
+{
|
||||
+ const char *result = strstr(extensions, search);
|
||||
+ unsigned long len = strlen(search);
|
||||
+ return result != NULL &&
|
||||
+ (result == extensions || *(result - 1) == ' ') &&
|
||||
+ (result[len] == ' ' || result[len] == '\0');
|
||||
+}
|
||||
+
|
||||
+static struct gl_platform *gl_wayland_egl_platform_create(gs_device_t *device,
|
||||
+ uint32_t adapter)
|
||||
+{
|
||||
+ struct gl_platform *plat = bmalloc(sizeof(struct gl_platform));
|
||||
+
|
||||
+ plat->wl_display = obs_get_nix_platform_display();
|
||||
+
|
||||
+ device->plat = plat;
|
||||
+
|
||||
+ plat->display = eglGetDisplay(plat->wl_display);
|
||||
+ if (plat->display == EGL_NO_DISPLAY) {
|
||||
+ blog(LOG_ERROR, "eglGetDisplay failed");
|
||||
+ goto fail_display_init;
|
||||
+ }
|
||||
+
|
||||
+ EGLint major;
|
||||
+ EGLint minor;
|
||||
+
|
||||
+ if (eglInitialize(plat->display, &major, &minor) == EGL_FALSE) {
|
||||
+ blog(LOG_ERROR, "eglInitialize failed");
|
||||
+ goto fail_display_init;
|
||||
+ }
|
||||
+
|
||||
+ blog(LOG_INFO, "Initialized EGL %d.%d", major, minor);
|
||||
+
|
||||
+ const char *extensions = eglQueryString(plat->display, EGL_EXTENSIONS);
|
||||
+ blog(LOG_DEBUG, "Supported EGL Extensions: %s", extensions);
|
||||
+
|
||||
+ const EGLint *attribs = ctx_attribs;
|
||||
+ if (major == 1 && minor == 4) {
|
||||
+#ifdef EGL_KHR_create_context
|
||||
+ if (extension_supported(extensions, "EGL_KHR_create_context")) {
|
||||
+ attribs = khr_ctx_attribs;
|
||||
+ } else {
|
||||
+#endif
|
||||
+ blog(LOG_ERROR,
|
||||
+ "EGL_KHR_create_context extension is required to use EGL 1.4.");
|
||||
+ goto fail_context_create;
|
||||
+#ifdef EGL_KHR_create_context
|
||||
+ }
|
||||
+#endif
|
||||
+ } else if (major < 1 || (major == 1 && minor < 4)) {
|
||||
+ blog(LOG_ERROR, "EGL 1.4 or higher is required.");
|
||||
+ goto fail_context_create;
|
||||
+ }
|
||||
+
|
||||
+ if (!egl_context_create(plat, attribs)) {
|
||||
+ goto fail_context_create;
|
||||
+ }
|
||||
+
|
||||
+ if (!gladLoadGL()) {
|
||||
+ blog(LOG_ERROR, "Failed to load OpenGL entry functions.");
|
||||
+ goto fail_load_gl;
|
||||
+ }
|
||||
+
|
||||
+ goto success;
|
||||
+
|
||||
+fail_load_gl:
|
||||
+ egl_context_destroy(plat);
|
||||
+fail_context_create:
|
||||
+ eglTerminate(plat->display);
|
||||
+fail_display_init:
|
||||
+ bfree(plat);
|
||||
+ plat = NULL;
|
||||
+success:
|
||||
+ UNUSED_PARAMETER(adapter);
|
||||
+ return plat;
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_platform_destroy(struct gl_platform *plat)
|
||||
+{
|
||||
+ if (plat) {
|
||||
+ egl_context_destroy(plat);
|
||||
+ eglTerminate(plat->display);
|
||||
+ bfree(plat);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static bool gl_wayland_egl_platform_init_swapchain(struct gs_swap_chain *swap)
|
||||
+{
|
||||
+ struct gl_platform *plat = swap->device->plat;
|
||||
+ EGLSurface egl_surface = eglCreateWindowSurface(
|
||||
+ plat->display, plat->config, swap->wi->window, NULL);
|
||||
+ if (egl_surface == EGL_NO_SURFACE) {
|
||||
+ blog(LOG_ERROR, "eglCreateWindowSurface failed");
|
||||
+ return false;
|
||||
+ }
|
||||
+ swap->wi->egl_surface = egl_surface;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+gl_wayland_egl_platform_cleanup_swapchain(struct gs_swap_chain *swap)
|
||||
+{
|
||||
+ struct gl_platform *plat = swap->device->plat;
|
||||
+ eglDestroySurface(plat->display, swap->wi->egl_surface);
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_device_enter_context(gs_device_t *device)
|
||||
+{
|
||||
+ struct gl_platform *plat = device->plat;
|
||||
+ EGLSurface surface = EGL_NO_SURFACE;
|
||||
+ if (device->cur_swap != NULL)
|
||||
+ surface = device->cur_swap->wi->egl_surface;
|
||||
+ egl_make_current(plat->display, surface, plat->context);
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_device_leave_context(gs_device_t *device)
|
||||
+{
|
||||
+ struct gl_platform *plat = device->plat;
|
||||
+ egl_make_current(plat->display, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
+}
|
||||
+
|
||||
+static void *gl_wayland_egl_device_get_device_obj(gs_device_t *device)
|
||||
+{
|
||||
+ return device->plat->context;
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_getclientsize(const struct gs_swap_chain *swap,
|
||||
+ uint32_t *width, uint32_t *height)
|
||||
+{
|
||||
+ wl_egl_window_get_attached_size(swap->wi->window, (void *)width,
|
||||
+ (void *)height);
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_clear_context(gs_device_t *device)
|
||||
+{
|
||||
+ struct gl_platform *plat = device->plat;
|
||||
+ egl_make_current(plat->display, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_update(gs_device_t *device)
|
||||
+{
|
||||
+ wl_egl_window_resize(device->cur_swap->wi->window,
|
||||
+ device->cur_swap->info.cx,
|
||||
+ device->cur_swap->info.cy, 0, 0);
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_device_load_swapchain(gs_device_t *device,
|
||||
+ gs_swapchain_t *swap)
|
||||
+{
|
||||
+ if (device->cur_swap == swap)
|
||||
+ return;
|
||||
+
|
||||
+ device->cur_swap = swap;
|
||||
+
|
||||
+ struct gl_platform *plat = device->plat;
|
||||
+ if (swap == NULL) {
|
||||
+ egl_make_current(plat->display, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
+ } else {
|
||||
+ egl_make_current(plat->display, swap->wi->egl_surface,
|
||||
+ plat->context);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static void gl_wayland_egl_device_present(gs_device_t *device)
|
||||
+{
|
||||
+ struct gl_platform *plat = device->plat;
|
||||
+ struct gl_windowinfo *wi = device->cur_swap->wi;
|
||||
+ if (eglSwapInterval(plat->display, 0) == EGL_FALSE) {
|
||||
+ blog(LOG_ERROR, "eglSwapInterval failed");
|
||||
+ }
|
||||
+ if (eglSwapBuffers(plat->display, wi->egl_surface) == EGL_FALSE) {
|
||||
+ blog(LOG_ERROR, "eglSwapBuffers failed");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static const struct gl_winsys_vtable egl_wayland_winsys_vtable = {
|
||||
+ .windowinfo_create = gl_wayland_egl_windowinfo_create,
|
||||
+ .windowinfo_destroy = gl_wayland_egl_windowinfo_destroy,
|
||||
+ .platform_create = gl_wayland_egl_platform_create,
|
||||
+ .platform_destroy = gl_wayland_egl_platform_destroy,
|
||||
+ .platform_init_swapchain = gl_wayland_egl_platform_init_swapchain,
|
||||
+ .platform_cleanup_swapchain = gl_wayland_egl_platform_cleanup_swapchain,
|
||||
+ .device_enter_context = gl_wayland_egl_device_enter_context,
|
||||
+ .device_leave_context = gl_wayland_egl_device_leave_context,
|
||||
+ .device_get_device_obj = gl_wayland_egl_device_get_device_obj,
|
||||
+ .getclientsize = gl_wayland_egl_getclientsize,
|
||||
+ .clear_context = gl_wayland_egl_clear_context,
|
||||
+ .update = gl_wayland_egl_update,
|
||||
+ .device_load_swapchain = gl_wayland_egl_device_load_swapchain,
|
||||
+ .device_present = gl_wayland_egl_device_present,
|
||||
+};
|
||||
+
|
||||
+const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void)
|
||||
+{
|
||||
+ return &egl_wayland_winsys_vtable;
|
||||
+}
|
||||
diff --git a/libobs-opengl/gl-wayland-egl.h b/libobs-opengl/gl-wayland-egl.h
|
||||
new file mode 100644
|
||||
index 00000000..3384576f
|
||||
--- /dev/null
|
||||
+++ b/libobs-opengl/gl-wayland-egl.h
|
||||
@@ -0,0 +1,22 @@
|
||||
+/******************************************************************************
|
||||
+ 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-nix.h"
|
||||
+
|
||||
+const struct gl_winsys_vtable *gl_wayland_egl_get_winsys_vtable(void);
|
||||
--
|
||||
2.28.0
|
||||
|
107
0014-UI-Retrieve-Wayland-surface-from-QWindow.patch
Normal file
107
0014-UI-Retrieve-Wayland-surface-from-QWindow.patch
Normal file
|
@ -0,0 +1,107 @@
|
|||
From ded1e2a0201d3160ff1b427bab104870f29d516b Mon Sep 17 00:00:00 2001
|
||||
From: Georges Basile Stavracas Neto <georges.stavracas@gmail.com>
|
||||
Date: Mon, 9 Mar 2020 21:23:37 -0300
|
||||
Subject: [PATCH 14/15] UI: Retrieve Wayland surface from QWindow
|
||||
|
||||
On Wayland, we want to query the window's underlying
|
||||
platform for the Wayland surface, instead of foolishly
|
||||
retrieving the X11 display.
|
||||
|
||||
Pass QWindow instead of WId directly, and set the surface
|
||||
as the platform data on Wayland systems.
|
||||
---
|
||||
UI/qt-display.cpp | 2 +-
|
||||
UI/qt-wrappers.cpp | 28 +++++++++++++++++++++++-----
|
||||
UI/qt-wrappers.hpp | 3 ++-
|
||||
3 files changed, 26 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/UI/qt-display.cpp b/UI/qt-display.cpp
|
||||
index 1bb97c7b..685ee6f9 100644
|
||||
--- a/UI/qt-display.cpp
|
||||
+++ b/UI/qt-display.cpp
|
||||
@@ -89,7 +89,7 @@ void OBSQTDisplay::CreateDisplay()
|
||||
info.format = GS_BGRA;
|
||||
info.zsformat = GS_ZS_NONE;
|
||||
|
||||
- QTToGSWindow(winId(), info.window);
|
||||
+ QTToGSWindow(windowHandle(), info.window);
|
||||
|
||||
display = obs_display_create(&info, backgroundColor);
|
||||
|
||||
diff --git a/UI/qt-wrappers.cpp b/UI/qt-wrappers.cpp
|
||||
index e8a51d37..1485a181 100644
|
||||
--- a/UI/qt-wrappers.cpp
|
||||
+++ b/UI/qt-wrappers.cpp
|
||||
@@ -27,9 +27,14 @@
|
||||
#include <QKeyEvent>
|
||||
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
+#include <obs-nix-platform.h>
|
||||
#include <QX11Info>
|
||||
#endif
|
||||
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+#include <qpa/qplatformnativeinterface.h>
|
||||
+#endif
|
||||
+
|
||||
static inline void OBSErrorBoxva(QWidget *parent, const char *msg, va_list args)
|
||||
{
|
||||
char full_message[4096];
|
||||
@@ -105,15 +110,28 @@ void OBSMessageBox::critical(QWidget *parent, const QString &title,
|
||||
mb.exec();
|
||||
}
|
||||
|
||||
-void QTToGSWindow(WId windowId, gs_window &gswindow)
|
||||
+void QTToGSWindow(QWindow *window, gs_window &gswindow)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
- gswindow.hwnd = (HWND)windowId;
|
||||
+ gswindow.hwnd = (HWND)window->winId();
|
||||
#elif __APPLE__
|
||||
- gswindow.view = (id)windowId;
|
||||
+ gswindow.view = (id)window->winId();
|
||||
#else
|
||||
- gswindow.id = windowId;
|
||||
- gswindow.display = QX11Info::display();
|
||||
+ switch (obs_get_nix_platform()) {
|
||||
+ case OBS_NIX_PLATFORM_X11_GLX:
|
||||
+ case OBS_NIX_PLATFORM_X11_EGL:
|
||||
+ gswindow.id = window->winId();
|
||||
+ gswindow.display = obs_get_nix_platform_display();
|
||||
+ break;
|
||||
+#ifdef ENABLE_WAYLAND
|
||||
+ case OBS_NIX_PLATFORM_WAYLAND:
|
||||
+ QPlatformNativeInterface *native =
|
||||
+ QGuiApplication::platformNativeInterface();
|
||||
+ gswindow.display =
|
||||
+ native->nativeResourceForWindow("surface", window);
|
||||
+ break;
|
||||
+#endif
|
||||
+ }
|
||||
#endif
|
||||
}
|
||||
|
||||
diff --git a/UI/qt-wrappers.hpp b/UI/qt-wrappers.hpp
|
||||
index 69996deb..f191f8f9 100644
|
||||
--- a/UI/qt-wrappers.hpp
|
||||
+++ b/UI/qt-wrappers.hpp
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QWidget>
|
||||
+#include <QWindow>
|
||||
#include <QThread>
|
||||
#include <obs.hpp>
|
||||
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
|
||||
void OBSErrorBox(QWidget *parent, const char *msg, ...);
|
||||
|
||||
-void QTToGSWindow(WId windowId, gs_window &gswindow);
|
||||
+void QTToGSWindow(QWindow *window, gs_window &gswindow);
|
||||
|
||||
uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods);
|
||||
|
||||
--
|
||||
2.28.0
|
||||
|
84
PKGBUILD
Normal file
84
PKGBUILD
Normal file
|
@ -0,0 +1,84 @@
|
|||
# Maintainer: Antoine Damhet <xdbob at lse.epita.fr>
|
||||
# Original-Maintainer: Jonathan Steel <jsteel at archlinux.org>
|
||||
# Contributor: Benjamin Klettbach <b.klettbach@gmail.com>
|
||||
|
||||
_pkgname=obs-studio
|
||||
pkgname=$_pkgname-wayland
|
||||
provides=("$_pkgname")
|
||||
conflicts=("$_pkgname")
|
||||
pkgver=25.0.8
|
||||
pkgrel=1
|
||||
pkgdesc="Free, open source software for live streaming and recording (with wayland patches)"
|
||||
arch=('x86_64')
|
||||
url="https://obsproject.com"
|
||||
license=('GPL2')
|
||||
depends=('ffmpeg' 'jansson' 'libxinerama' 'libxkbcommon-x11' 'mbedtls'
|
||||
'qt5-svg' 'qt5-x11extras' 'curl' 'jack' 'gtk-update-icon-cache')
|
||||
makedepends=('cmake' 'libfdk-aac' 'libxcomposite' 'x264' 'vlc' 'swig' 'python' 'luajit')
|
||||
optdepends=('libfdk-aac: FDK AAC codec support'
|
||||
'libxcomposite: XComposite capture support'
|
||||
'libva-intel-driver: hardware encoding'
|
||||
'libva-mesa-driver: hardware encoding'
|
||||
'luajit: scripting support'
|
||||
'python: scripting support'
|
||||
'vlc: VLC Media Source support'
|
||||
'obs-xdg-portal-git: screen capture with xdg-desktop-portal interface'
|
||||
'xdg-desktop-portal-wlr: screen capture on wlroots compositors')
|
||||
source=(
|
||||
$_pkgname-$pkgver.tar.gz::https://github.com/jp9000/obs-studio/archive/$pkgver.tar.gz
|
||||
https://github.com/obsproject/obs-studio/commit/8a1429e29ebd6bf31ad6ae63c6992e2c03893767.patch
|
||||
0001-deps-glad-Add-EGL.patch
|
||||
0002-libobs-opengl-Rename-gl-x11.c-to-gl-x11-glx.c.patch
|
||||
0003-libobs-opengl-Factor-out-GLX-winsys.patch
|
||||
0004-libobs-opengl-Introduce-the-X11-EGL-winsys.patch
|
||||
0005-deps-glad-Make-X11-required-as-well.patch
|
||||
0006-ci-Install-qtbase5-private-dev-on-Linux.patch
|
||||
0007-libobs-nix-Move-X11-specific-code-to-obs-nix-x11.c.patch
|
||||
0008-libobs-Introduce-the-concept-of-a-Unix-platform.patch
|
||||
0009-UI-Set-the-Unix-platform-on-startup.patch
|
||||
0010-linux-capture-Fail-to-load-when-running-on-EGL.patch
|
||||
0011-libobs-Add-a-Wayland-platform.patch
|
||||
0012-libobs-opengl-Try-to-use-the-platform-display-if-ava.patch
|
||||
0013-libobs-opengl-Introduce-an-EGL-Wayland-renderer.patch
|
||||
0014-UI-Retrieve-Wayland-surface-from-QWindow.patch
|
||||
)
|
||||
sha512sums=('a97c03dc218a4e03e48f6a7dc82b4a59ebeee2039f17be66bb847681ce9ff3d25e6e015be4af78fe44739f6fad5089b6e683d7657c2e4fde8e547df9a2594a08'
|
||||
'1ff0e088eed61554268009f3d8c5a23c0888bfbe860d6cb288ddf348108446c152fd87e2cb8f54613a88378d8474550632c90f924005d5e0343bf1a801339ccc'
|
||||
'bfe2b0e6da69ffdca95229eb4015515148fdda909355add1d2dec71cf97e9fdabdfc832c74f455a890846708f28d5bcbec64589e853904d539a438b2dcbd7a18'
|
||||
'5221b6a7a46f99c58cde1c5406f83d50def2d5b3a2e97be7db759d94d74a5be46da092209e6a4122a6de4b704632c3f013535f80b570349b029ea4124151c4f6'
|
||||
'c9a0660c95bd18a02620fb0b870032563669544e7a721e4d91dafb8aebb96d1735414a9e37ed56355fc5afeb8f437a434b4fd5f147c9658cc6974e8e8bab4463'
|
||||
'0b404ff252f94bcdd957d43db26c54c6b47de5a8f810f4febdb0aa5b873c48f23ef2817361e5ce9c09a189e770978cfca24767167604434ece771d759e7c4270'
|
||||
'47f5bffb469ece2b961000cd2d8656b82cba8ac0fa09fa7703c662e0cee2e48744d5b8aa93a4b4508436ea5edfe3038fa7aa88a3b43466f88c7504e6a8ba51ed'
|
||||
'd15c21968a3024888ce4c8e884d861f147358e95a42c1de557251a4c2fccbdddf9cf5a285deedbf73cffbd25fdaad44dd972cb10bf9a5b23a0049b239e75961f'
|
||||
'c1f94ccd836c51ff83735df614bf6d3e2c310c599685e700ae5726ace20434edd04ef0c9be0a8c0f4c458dd164ad1ac817fd32bcbeeefb0107a6ce4cbce9cb08'
|
||||
'6ce870404a6d2bfbb25935a6da59a07447307f8592dd1dc1aaebba2b9f959633565ba4cdc7d50ee3c4e5b4c169397298daa5804c3060fc780dba52099f687393'
|
||||
'6374229b662949e2989eb372a922fda872d2a08e817690b2262f99dc8a02261a75aeeacfc40da2b68a04228b38cda4aeaca4212068e8605b7532662dc459abb4'
|
||||
'16dfa319e9e18ef8e946b9723e27d1ea1f56e4de8656d8112571bc87aa7ade8dbda4293f064c2477cdaf92c60fca4484b2c7ac322835bf402657275933f6ab52'
|
||||
'c81a421475293d3d5c64a744c10a925dc26975a6dfd46e1b3b2a92931da43c311d0a153548889b4e9831bee61ab8b0f5fc504ad3f0ed7f0628f93287e12ad3d3'
|
||||
'ea36fee6228d582f5f3b886a3de61ad8b139691c3bf30e24a7b20f1eab2f9e43b0dfbf6f254dcef00e2bfbf6826f223a957d3e78524ebd864c64433529e40441'
|
||||
'a93f186ed24ee979a4297aa063c435ae541f5f1958b86373f6534a2dd85e2178d6f151f115200c987b5e1d999ebd94d6ce0597ef1e7b3588bcb161c53dd4878e'
|
||||
'c4e6a23edf080076c27599e02909a068b11094848f733297496e7ea0061df56be4becdb58449ec7a05ff2a659fa4c0f75f4006cb204578477308d24d764fba41')
|
||||
prepare() {
|
||||
cd $_pkgname-$pkgver
|
||||
|
||||
for patch in ../*.patch; do
|
||||
patch -Np1 -i "$patch"
|
||||
done
|
||||
}
|
||||
|
||||
build() {
|
||||
cd $_pkgname-$pkgver
|
||||
|
||||
mkdir -p build; cd build
|
||||
|
||||
cmake -DCMAKE_INSTALL_PREFIX="/usr" \
|
||||
-DOBS_VERSION_OVERRIDE="$pkgver-$pkgrel" ..
|
||||
|
||||
make
|
||||
}
|
||||
|
||||
package() {
|
||||
cd $_pkgname-$pkgver/build
|
||||
|
||||
make install DESTDIR="$pkgdir"
|
||||
}
|
Loading…
Reference in a new issue