From 40b03ab0dca7d948051a40d68db7602a652b8351 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Sat, 8 Apr 2023 02:40:00 +0200 Subject: Enable use on amd/intel --- README.md | 8 ++-- TODO | 3 +- com.dec05eba.gpu_screen_recorder.appdata.xml | 7 +++- src/config.hpp | 4 +- src/main.cpp | 55 ++++++++++++++++++++++------ 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index fc5b4cd..9faf5c9 100644 --- a/README.md +++ b/README.md @@ -9,22 +9,24 @@ where only the last few seconds are saved. More info at [gpu-screen-recorder](https://git.dec05eba.com/gpu-screen-recorder/about/). ## Note -This software works only on x11 and with an nvidia gpu.\ +This software works only on X11 (Wayland with Xwayland is NOT supported).\ Recording a window doesn't work when using picom in glx mode. However it works in xrender mode or when recording the a monitor/screen (which uses NvFBC).\ For screen capture to work with PRIME (laptops with a nvidia gpu), you must set the primary GPU to use your dedicated nvidia graphics card. You can do this by selecting "NVIDIA (Performance Mode) in nvidia settings:\ ![](https://dec05eba.com/images/nvidia-settings-prime.png)\ and then rebooting your laptop. # Performance +On a system with a i5 4690k CPU and a GTX 1080 GPU:\ When recording Legend of Zelda Breath of the Wild at 4k, fps drops from 30 to 7 when using OBS Studio + nvenc, however when using this screen recorder the fps remains at 30.\ When recording GTA V at 4k on highest settings, fps drops from 60 to 23 when using obs-nvfbc + nvenc, however when using this screen recorder the fps only drops to 58. The quality is also much better when using gpu-screen-recorder.\ -It is recommended to save the video to a SSD because of the large file size, which a slow HDD might not be fast enough to handle. +It is recommended to save the video to a SSD because of the large file size, which a slow HDD might not be fast enough to handle.\ +Note that if you have a very powerful CPU and a not so powerful GPU and play a game that is bottlenecked by your GPU and barely uses your CPU then a CPU based screen recording (such as OBS with libx264 instead of nvenc) might perform slightly better than GPU Screen Recorder. At least on NVIDIA. ## Note about optimal performance on NVIDIA NVIDIA driver has a "feature" (read: bug) where it will downclock memory transfer rate when a program uses cuda, such as GPU Screen Recorder. See https://git.dec05eba.com/gpu-screen-recorder/about/ for more information and how to overcome this. ## Installation This program depends on [gpu-screen-recorder](https://git.dec05eba.com/gpu-screen-recorder/) which needs to be installed first.\ -Run `./install.sh` as root or if you are running Arch Linux, then you can find gpu screen recorder gtk on aur under the name gpu-screen-recorder-gtk-git (`yay -S gpu-screen-recorder-gtk-git`).\ +Run `sudo ./install.sh` or if you are running Arch Linux, then you can find gpu screen recorder gtk on aur under the name gpu-screen-recorder-gtk-git (`yay -S gpu-screen-recorder-gtk-git`).\ Dependencies needed when building using `build.sh` or `install.sh`: `gtk3 libx11 libxrandr libpulse`.\ You can also install gpu screen recorder (the gtk gui version) from [flathub](https://flathub.org/apps/details/com.dec05eba.gpu_screen_recorder). This flatpak includes gpu-screen-recorder so no need to install that first.\ Note that if you use the flatpak version then you wont be able to use overclocking unless you set "Coolbits" NVIDIA X setting. See https://git.dec05eba.com/gpu-screen-recorder/about/ for more information and how to overcome this. diff --git a/TODO b/TODO index 7c7c218..d71a5e3 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,5 @@ Capture stderr (ignore fps: 250) and show that in notification on error. Make sure the resolution is allowed for streaming. Add list of windows to select from. This makes it easier to select another window that is not in the view to be clickable. -Detect switchable graphics, to give proper error if cuda is not installed. \ No newline at end of file +Detect switchable graphics, to give proper error if cuda is not installed. +Disable overclocking and show some kind of sign that overclocking is not possible (if coolbits not set). \ No newline at end of file diff --git a/com.dec05eba.gpu_screen_recorder.appdata.xml b/com.dec05eba.gpu_screen_recorder.appdata.xml index 2b21541..5b5b498 100644 --- a/com.dec05eba.gpu_screen_recorder.appdata.xml +++ b/com.dec05eba.gpu_screen_recorder.appdata.xml @@ -18,7 +18,7 @@

- This is a screen recorder that has minimal impact on system performance by recording a window using the GPU only, similar to shadowplay on windows. This is the fastest screen recording tool for Linux. It's currently limited to NVIDIA GPUs and X11 (Wayland with Xwayland does NOT work). + This is a screen recorder that has minimal impact on system performance by recording a window using the GPU only, similar to shadowplay on windows. This is the fastest screen recording tool for Linux. This screen recorder only works on X11 (Wayland with Xwayland is NOT supported).

This screen recorder can be used for recording your desktop offline, for live streaming and for nvidia-like instant replay, where only the last few seconds are saved. @@ -38,6 +38,11 @@ + + +

Add experimental support for AMD/Intel. Quality might not be well tuned yet and the video is in variable framerate mode, which might cause issues with some out of date video editing software or video players

+
+

Show error when using wayland (because wayland is not supported)

diff --git a/src/config.hpp b/src/config.hpp index 275f9f9..7257a4a 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -138,8 +138,8 @@ static bool file_get_content(const char *filepath, std::string &file_content) { } struct StringView { - const char *str; - size_t size; + const char *str = nullptr; + size_t size = 0; bool operator == (const char *other) const { int len = strlen(other); diff --git a/src/main.cpp b/src/main.cpp index 4ce1f8f..d5b9313 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1500,6 +1500,28 @@ static bool is_cuda_installed() { return lib != nullptr; } +static bool is_program_installed(const StringView program_name) { + const char *path = getenv("PATH"); + if(!path) + return false; + + bool program_installed = false; + char full_program_path[PATH_MAX]; + string_split_char(path, ':', [&](StringView line) -> bool { + snprintf(full_program_path, sizeof(full_program_path), "%.*s/%.*s", (int)line.size, line.str, (int)program_name.size, program_name.str); + if(access(full_program_path, F_OK) == 0) { + program_installed = true; + return false; + } + return true; + }); + return program_installed; +} + +static bool is_pkexec_installed() { + return is_program_installed({ "pkexec", 6 }); +} + typedef gboolean (*KeyPressHandler)(GtkButton *button, gpointer userdata); static void keypress_toggle_recording(bool recording_state, GtkButton *record_button, KeyPressHandler keypress_handler, GtkApplication *app) { if(!gtk_widget_get_sensitive(GTK_WIDGET(record_button))) @@ -2416,6 +2438,15 @@ static bool is_xwayland() { return xwayland_found; } +static const char* gpu_vendor_to_name(gpu_vendor vendor) { + switch(vendor) { + case GPU_VENDOR_AMD: return "AMD"; + case GPU_VENDOR_INTEL: return "Intel"; + case GPU_VENDOR_NVIDIA: return "NVIDIA"; + } + return ""; +} + static void activate(GtkApplication *app, gpointer userdata) { nvfbc_installed = is_nv_fbc_installed(); @@ -2438,16 +2469,6 @@ static void activate(GtkApplication *app, gpointer userdata) { return; } - // TODO: Remove once gpu screen recorder supports amd and intel properly - if(gpu_inf.vendor != GPU_VENDOR_NVIDIA) { - GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, - "GPU Screen Recorder does currently only support NVIDIA GPUs. If you are using a laptop with a NVIDIA GPU then make sure you are using your NVIDIA GPU for all applications, everything. You can do this by switching to NVIDIA performance mode in nvidia settings and then rebooting. Make sure you have done this PROPERLY. You can verify this by using this command:\nglxinfo | grep 'client glx'\nand see if it says NVIDIA Corporation.\nNote: using prime-run won't fix this as it only runs one application on the NVIDIA GPU. All applications, everything needs to run on the NVIDIA GPU for screen capture to work."); - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - g_application_quit(G_APPLICATION(app)); - return; - } - if(gpu_inf.vendor == GPU_VENDOR_NVIDIA) { if(!is_cuda_installed()) { GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, @@ -2466,11 +2487,23 @@ static void activate(GtkApplication *app, gpointer userdata) { g_application_quit(G_APPLICATION(app)); return; } + } else { + if(!is_pkexec_installed()) { + GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + "pkexec needs to be installed to record a monitor on systems with AMD/Intel GPU. Please install polkit which provides pkexec."); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + g_application_quit(G_APPLICATION(app)); + return; + } } + std::string window_title = "GPU Screen Recorder | Running on "; + window_title += gpu_vendor_to_name(gpu_inf.vendor); + window = gtk_application_window_new(app); g_signal_connect(window, "destroy", G_CALLBACK(on_destroy_window), nullptr); - gtk_window_set_title(GTK_WINDOW(window), "GPU Screen Recorder"); + gtk_window_set_title(GTK_WINDOW(window), window_title.c_str()); gtk_window_set_resizable(GTK_WINDOW(window), false); select_window_userdata.app = app; -- cgit v1.2.3