aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-03-10 23:17:44 +0100
committerdec05eba <dec05eba@protonmail.com>2024-03-10 23:17:44 +0100
commit0d25ffb2a97ff7ff51fab72b6780024909f3e1a6 (patch)
treeab9bf059479d2ed29687067785aaddfa3c76ec7c
parent8b3afca0c676aef7e821330e8698220fca79f15c (diff)
Show the correct monitors when using prime-run
-rw-r--r--com.dec05eba.gpu_screen_recorder.appdata.xml9
-rw-r--r--src/egl.c17
-rw-r--r--src/egl.h10
-rw-r--r--src/main.cpp99
4 files changed, 97 insertions, 38 deletions
diff --git a/com.dec05eba.gpu_screen_recorder.appdata.xml b/com.dec05eba.gpu_screen_recorder.appdata.xml
index 1577b5c..0336ecf 100644
--- a/com.dec05eba.gpu_screen_recorder.appdata.xml
+++ b/com.dec05eba.gpu_screen_recorder.appdata.xml
@@ -75,6 +75,15 @@
</screenshots>
<releases>
+ <release version="3.6.0" date="2024-03-10">
+ <description>
+ <ul>
+ <li>Support HDR capture and full color range on nvidia</li>
+ <li>Support cursor capture when recording a single window</li>
+ <li>Show the correct monitors when using prime-run</li>
+ </ul>
+ </description>
+ </release>
<release version="3.5.3" date="2024-02-16">
<description>
<p>Fix minor permissions issue</p>
diff --git a/src/egl.c b/src/egl.c
index 0ad9f13..b574f90 100644
--- a/src/egl.c
+++ b/src/egl.c
@@ -221,6 +221,7 @@ static bool gsr_egl_load_egl(gsr_egl *self, void *library) {
{ (void**)&self->eglDestroyContext, "eglDestroyContext" },
{ (void**)&self->eglDestroySurface, "eglDestroySurface" },
{ (void**)&self->eglBindAPI, "eglBindAPI" },
+ { (void**)&self->eglGetProcAddress, "eglGetProcAddress" },
{ NULL, NULL }
};
@@ -248,6 +249,13 @@ static bool gsr_egl_load_gl(gsr_egl *self, void *library) {
return true;
}
+static bool gsr_egl_proc_load_egl(gsr_egl *self) {
+ self->eglQueryDisplayAttribEXT = (FUNC_eglQueryDisplayAttribEXT)self->eglGetProcAddress("eglQueryDisplayAttribEXT");
+ self->eglQueryDeviceStringEXT = (FUNC_eglQueryDeviceStringEXT)self->eglGetProcAddress("eglQueryDeviceStringEXT");
+
+ return true;
+}
+
bool gsr_egl_load(gsr_egl *self, Display *dpy, bool wayland) {
memset(self, 0, sizeof(gsr_egl));
self->x11.dpy = dpy;
@@ -274,9 +282,18 @@ bool gsr_egl_load(gsr_egl *self, Display *dpy, bool wayland) {
if(!gsr_egl_load_gl(self, gl_lib))
goto fail;
+ if(!gsr_egl_proc_load_egl(self))
+ goto fail;
+
if(!gsr_egl_create_window(self, wayland))
goto fail;
+ if(self->eglQueryDisplayAttribEXT && self->eglQueryDeviceStringEXT) {
+ intptr_t device = 0;
+ if(self->eglQueryDisplayAttribEXT(self->egl_display, EGL_DEVICE_EXT, &device) && device)
+ self->dri_card_path = self->eglQueryDeviceStringEXT((void*)device, EGL_DRM_DEVICE_FILE_EXT);
+ }
+
self->egl_library = egl_lib;
self->gl_library = gl_lib;
return true;
diff --git a/src/egl.h b/src/egl.h
index ab33048..e46a6ab 100644
--- a/src/egl.h
+++ b/src/egl.h
@@ -37,12 +37,17 @@ typedef void* EGLImageKHR;
typedef void *GLeglImageOES;
typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+typedef int (*FUNC_eglQueryDisplayAttribEXT)(EGLDisplay dpy, int32_t attribute, intptr_t *value);
+typedef const char* (*FUNC_eglQueryDeviceStringEXT)(void *device, int32_t name);
+
#define EGL_BUFFER_SIZE 0x3020
#define EGL_RENDERABLE_TYPE 0x3040
#define EGL_OPENGL_BIT 0x0008
#define EGL_OPENGL_API 0x30A2
#define EGL_NONE 0x3038
#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_DEVICE_EXT 0x322C
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
@@ -79,6 +84,7 @@ typedef struct {
EGLDisplay egl_display;
EGLSurface egl_surface;
EGLContext egl_context;
+ const char *dri_card_path;
gsr_x11 x11;
gsr_wayland wayland;
@@ -94,6 +100,10 @@ typedef struct {
unsigned int (*eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
unsigned int (*eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
unsigned int (*eglBindAPI)(unsigned int api);
+ __eglMustCastToProperFunctionPointerType (*eglGetProcAddress)(const char *procname);
+
+ FUNC_eglQueryDisplayAttribEXT eglQueryDisplayAttribEXT;
+ FUNC_eglQueryDeviceStringEXT eglQueryDeviceStringEXT;
const unsigned char* (*glGetString)(unsigned int name);
} gsr_egl;
diff --git a/src/main.cpp b/src/main.cpp
index d676e00..d6615f8 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -825,48 +825,60 @@ static void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_ty
}
}
-/* output should be >= 128 bytes */
-static bool gsr_get_valid_card_path(char *output) {
- for(int i = 0; i < 10; ++i) {
- drmVersion *ver = NULL;
- drmModePlaneResPtr planes = NULL;
- bool found_screen_card = false;
-
- sprintf(output, DRM_DEV_NAME, DRM_DIR_NAME, i);
- int fd = open(output, O_RDONLY);
- if(fd == -1)
- continue;
+static bool try_card_has_valid_plane(const char *card_path) {
+ drmVersion *ver = NULL;
+ drmModePlaneResPtr planes = NULL;
+ bool found_screen_card = false;
- ver = drmGetVersion(fd);
- if(!ver || strstr(ver->name, "nouveau"))
- goto next;
+ int fd = open(card_path, O_RDONLY);
+ if(fd == -1)
+ return false;
- drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ ver = drmGetVersion(fd);
+ if(!ver || strstr(ver->name, "nouveau"))
+ goto next;
- planes = drmModeGetPlaneResources(fd);
- if(!planes)
- goto next;
+ drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
- for(uint32_t i = 0; i < planes->count_planes; ++i) {
- drmModePlanePtr plane = drmModeGetPlane(fd, planes->planes[i]);
- if(!plane)
- continue;
+ planes = drmModeGetPlaneResources(fd);
+ if(!planes)
+ goto next;
- if(plane->fb_id)
- found_screen_card = true;
+ for(uint32_t j = 0; j < planes->count_planes; ++j) {
+ drmModePlanePtr plane = drmModeGetPlane(fd, planes->planes[j]);
+ if(!plane)
+ continue;
- drmModeFreePlane(plane);
- if(found_screen_card)
- break;
- }
+ if(plane->fb_id)
+ found_screen_card = true;
- next:
- if(planes)
- drmModeFreePlaneResources(planes);
- if(ver)
- drmFreeVersion(ver);
- close(fd);
+ drmModeFreePlane(plane);
if(found_screen_card)
+ break;
+ }
+
+ next:
+ if(planes)
+ drmModeFreePlaneResources(planes);
+ if(ver)
+ drmFreeVersion(ver);
+ close(fd);
+ if(found_screen_card)
+ return true;
+
+ return false;
+}
+
+/* output should be >= 128 bytes */
+static bool gsr_get_valid_card_path(gsr_egl *egl, char *output) {
+ if(egl->dri_card_path) {
+ strncpy(output, egl->dri_card_path, 128);
+ return try_card_has_valid_plane(output);
+ }
+
+ for(int i = 0; i < 10; ++i) {
+ snprintf(output, 128, DRM_DEV_NAME, DRM_DIR_NAME, i);
+ if(try_card_has_valid_plane(output))
return true;
}
return false;
@@ -2436,8 +2448,10 @@ static GtkWidget* create_common_settings_page(GtkStack *stack, GtkApplication *a
gtk_combo_box_text_append(video_codec_input_menu, "av1", "AV1");
if(wayland) {
- gtk_combo_box_text_append(video_codec_input_menu, "hevc_hdr", "HEVC (HDR)");
- gtk_combo_box_text_append(video_codec_input_menu, "av1_hdr", "AV1 (HDR)");
+ if(supported_video_codecs.hevc)
+ gtk_combo_box_text_append(video_codec_input_menu, "hevc_hdr", "HEVC (HDR)");
+ if(supported_video_codecs.av1)
+ gtk_combo_box_text_append(video_codec_input_menu, "av1_hdr", "AV1 (HDR)");
}
} else {
gtk_combo_box_text_append(video_codec_input_menu, "h264", "H264");
@@ -3143,6 +3157,15 @@ static void load_config(const gpu_info &gpu_inf) {
return;
}
}
+
+ if(!supported_video_codecs.h264 && !supported_video_codecs.hevc && gpu_inf.vendor == GPU_VENDOR_NVIDIA) {
+ GtkWidget *dialog = gtk_message_dialog_new_with_markup(GTK_WINDOW(window), GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
+ "Failed to find H264/HEVC video codecs. Your NVIDIA GPU may be missing support for H264/HEVC video codecs for video encoding.");
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+ g_application_quit(G_APPLICATION(select_window_userdata.app));
+ return;
+ }
}
static bool gl_get_gpu_info(gsr_egl *egl, gpu_info *info) {
@@ -3250,9 +3273,9 @@ static void activate(GtkApplication *app, gpointer) {
}
if((gpu_inf.vendor != GPU_VENDOR_NVIDIA) || wayland) {
- if(!gsr_get_valid_card_path(egl.card_path)) {
+ if(!gsr_get_valid_card_path(&egl, egl.card_path)) {
GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
- "Failed to find a valid DRM card.");
+ "Failed to find a valid DRM card. If you are using prime-run then run without it.");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
g_application_quit(G_APPLICATION(app));