summaryrefslogtreecommitdiffstats
path: root/platform/linuxbsd
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linuxbsd')
-rw-r--r--platform/linuxbsd/wayland/detect_prime_egl.cpp28
-rw-r--r--platform/linuxbsd/wayland/detect_prime_egl.h28
-rw-r--r--platform/linuxbsd/wayland/display_server_wayland.cpp6
-rw-r--r--platform/linuxbsd/x11/display_server_x11.cpp31
-rw-r--r--platform/linuxbsd/x11/display_server_x11.h1
-rw-r--r--platform/linuxbsd/x11/gl_manager_x11.cpp2
6 files changed, 74 insertions, 22 deletions
diff --git a/platform/linuxbsd/wayland/detect_prime_egl.cpp b/platform/linuxbsd/wayland/detect_prime_egl.cpp
index 4c97a80039..e24c03c869 100644
--- a/platform/linuxbsd/wayland/detect_prime_egl.cpp
+++ b/platform/linuxbsd/wayland/detect_prime_egl.cpp
@@ -38,15 +38,6 @@
#include <stdlib.h>
-#ifdef GLAD_ENABLED
-#include "thirdparty/glad/glad/egl.h"
-#include "thirdparty/glad/glad/gl.h"
-#else
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GL/glcorearb.h>
-#endif // GLAD_ENABLED
-
#include <cstring>
#include <sys/types.h>
@@ -57,7 +48,7 @@
#undef glGetString
// Runs inside a child. Exiting will not quit the engine.
-void DetectPrimeEGL::create_context() {
+void DetectPrimeEGL::create_context(EGLenum p_platform_enum) {
#if defined(GLAD_ENABLED)
if (!gladLoaderLoadEGL(nullptr)) {
print_verbose("Unable to load EGL, GPU detection skipped.");
@@ -65,7 +56,18 @@ void DetectPrimeEGL::create_context() {
}
#endif
- EGLDisplay egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ EGLDisplay egl_display = EGL_NO_DISPLAY;
+
+ if (GLAD_EGL_VERSION_1_5) {
+ egl_display = eglGetPlatformDisplay(p_platform_enum, nullptr, nullptr);
+ } else if (GLAD_EGL_EXT_platform_base) {
+#ifdef EGL_EXT_platform_base
+ egl_display = eglGetPlatformDisplayEXT(p_platform_enum, nullptr, nullptr);
+#endif
+ } else {
+ egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ }
+
EGLConfig egl_config;
EGLContext egl_context = EGL_NO_CONTEXT;
@@ -110,7 +112,7 @@ void DetectPrimeEGL::create_context() {
eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context);
}
-int DetectPrimeEGL::detect_prime() {
+int DetectPrimeEGL::detect_prime(EGLenum p_platform_enum) {
pid_t p;
int priorities[4] = {};
String vendors[4];
@@ -168,7 +170,7 @@ int DetectPrimeEGL::detect_prime() {
setenv("DRI_PRIME", itos(i).utf8().ptr(), 1);
- create_context();
+ create_context(p_platform_enum);
PFNGLGETSTRINGPROC glGetString = (PFNGLGETSTRINGPROC)eglGetProcAddress("glGetString");
const char *vendor = (const char *)glGetString(GL_VENDOR);
diff --git a/platform/linuxbsd/wayland/detect_prime_egl.h b/platform/linuxbsd/wayland/detect_prime_egl.h
index 26351b0dce..3391e020d8 100644
--- a/platform/linuxbsd/wayland/detect_prime_egl.h
+++ b/platform/linuxbsd/wayland/detect_prime_egl.h
@@ -34,6 +34,30 @@
#ifdef GLES3_ENABLED
#ifdef EGL_ENABLED
+#ifdef GLAD_ENABLED
+#include "thirdparty/glad/glad/egl.h"
+#include "thirdparty/glad/glad/gl.h"
+#else
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GL/glcorearb.h>
+
+#define GLAD_EGL_VERSION_1_5 1
+
+#ifdef EGL_EXT_platform_base
+#define GLAD_EGL_EXT_platform_base 1
+#endif
+
+#define KHRONOS_STATIC 1
+extern "C" EGLAPI EGLDisplay EGLAPIENTRY eglGetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list);
+#undef KHRONOS_STATIC
+
+#endif // GLAD_ENABLED
+
+#ifndef EGL_EXT_platform_base
+#define GLAD_EGL_EXT_platform_base 0
+#endif
+
class DetectPrimeEGL {
private:
struct Vendor {
@@ -53,10 +77,10 @@ private:
{ nullptr, 0 }
};
- static void create_context();
+ static void create_context(EGLenum p_platform_enum);
public:
- static int detect_prime();
+ static int detect_prime(EGLenum p_platform_enum);
};
#endif // GLES3_ENABLED
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp
index cad843561f..3fad8c2987 100644
--- a/platform/linuxbsd/wayland/display_server_wayland.cpp
+++ b/platform/linuxbsd/wayland/display_server_wayland.cpp
@@ -1384,7 +1384,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
if (prime_idx == -1) {
print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
- prime_idx = DetectPrimeEGL::detect_prime();
+ prime_idx = DetectPrimeEGL::detect_prime(EGL_PLATFORM_WAYLAND_KHR);
}
if (prime_idx) {
@@ -1397,7 +1397,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
if (rendering_driver == "opengl3") {
egl_manager = memnew(EGLManagerWayland);
- if (egl_manager->initialize() != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) {
+ if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) {
memdelete(egl_manager);
egl_manager = nullptr;
@@ -1417,7 +1417,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win
if (rendering_driver == "opengl3_es") {
egl_manager = memnew(EGLManagerWaylandGLES);
- if (egl_manager->initialize() != OK) {
+ if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK) {
memdelete(egl_manager);
egl_manager = nullptr;
r_error = ERR_CANT_CREATE;
diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp
index 0e4c723a87..a605e664ce 100644
--- a/platform/linuxbsd/x11/display_server_x11.cpp
+++ b/platform/linuxbsd/x11/display_server_x11.cpp
@@ -139,8 +139,9 @@ bool DisplayServerX11::has_feature(Feature p_feature) const {
#endif
case FEATURE_CLIPBOARD_PRIMARY:
case FEATURE_TEXT_TO_SPEECH:
- case FEATURE_SCREEN_CAPTURE:
return true;
+ case FEATURE_SCREEN_CAPTURE:
+ return !xwayland;
default: {
}
}
@@ -1494,9 +1495,20 @@ int DisplayServerX11::screen_get_dpi(int p_screen) const {
return 96;
}
+int get_image_errorhandler(Display *dpy, XErrorEvent *ev) {
+ return 0;
+}
+
Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const {
Point2i pos = p_position;
+ if (xwayland) {
+ return Color();
+ }
+
+ int (*old_handler)(Display *, XErrorEvent *) = XSetErrorHandler(&get_image_errorhandler);
+
+ Color color;
int number_of_screens = XScreenCount(x11_display);
for (int i = 0; i < number_of_screens; i++) {
Window root = XRootWindow(x11_display, i);
@@ -1509,12 +1521,15 @@ Color DisplayServerX11::screen_get_pixel(const Point2i &p_position) const {
c.pixel = XGetPixel(image, 0, 0);
XFree(image);
XQueryColor(x11_display, XDefaultColormap(x11_display, i), &c);
- return Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0);
+ color = Color(float(c.red) / 65535.0, float(c.green) / 65535.0, float(c.blue) / 65535.0, 1.0);
+ break;
}
}
}
- return Color();
+ XSetErrorHandler(old_handler);
+
+ return color;
}
Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
@@ -1533,6 +1548,12 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
ERR_FAIL_COND_V(p_screen < 0, Ref<Image>());
+ if (xwayland) {
+ return Ref<Image>();
+ }
+
+ int (*old_handler)(Display *, XErrorEvent *) = XSetErrorHandler(&get_image_errorhandler);
+
XImage *image = nullptr;
bool found = false;
@@ -1575,6 +1596,8 @@ Ref<Image> DisplayServerX11::screen_get_image(int p_screen) const {
}
}
+ XSetErrorHandler(old_handler);
+
Ref<Image> img;
if (image) {
int width = image->width;
@@ -5815,6 +5838,8 @@ static ::XIMStyle _get_best_xim_style(const ::XIMStyle &p_style_a, const ::XIMSt
DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
KeyMappingX11::initialize();
+ xwayland = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").to_lower() == "wayland";
+
native_menu = memnew(NativeMenu);
context = p_context;
diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h
index f0b1811986..341ba5f079 100644
--- a/platform/linuxbsd/x11/display_server_x11.h
+++ b/platform/linuxbsd/x11/display_server_x11.h
@@ -330,6 +330,7 @@ class DisplayServerX11 : public DisplayServer {
bool xrandr_ext_ok = true;
bool xinerama_ext_ok = true;
bool xshaped_ext_ok = true;
+ bool xwayland = false;
struct Property {
unsigned char *data;
diff --git a/platform/linuxbsd/x11/gl_manager_x11.cpp b/platform/linuxbsd/x11/gl_manager_x11.cpp
index febb7ae584..738ebffa02 100644
--- a/platform/linuxbsd/x11/gl_manager_x11.cpp
+++ b/platform/linuxbsd/x11/gl_manager_x11.cpp
@@ -357,7 +357,7 @@ void GLManager_X11::set_use_vsync(bool p_use) {
GLXDrawable drawable = glXGetCurrentDrawable();
glXSwapIntervalEXT(disp.x11_display, drawable, val);
} else {
- WARN_PRINT("Could not set V-Sync mode. V-Sync is not supported.");
+ WARN_PRINT_ONCE("Could not set V-Sync mode, as changing V-Sync mode is not supported by the graphics driver.");
return;
}
use_vsync = p_use;