From 2ff9a129c06f7f23ea8e324a919cba3a8d6768f6 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 3 Sep 2021 14:03:59 +0200 Subject: [PATCH 1/3] Reduce CPU usage --- sunshine/platform/linux/kmsgrab.cpp | 2 ++ sunshine/stream.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sunshine/platform/linux/kmsgrab.cpp b/sunshine/platform/linux/kmsgrab.cpp index fb3f0517..e067c3f5 100644 --- a/sunshine/platform/linux/kmsgrab.cpp +++ b/sunshine/platform/linux/kmsgrab.cpp @@ -649,6 +649,7 @@ public: std::this_thread::sleep_for((next_frame - now) / 3 * 2); } while(next_frame > now) { + std::this_thread::sleep_for(1ns); now = std::chrono::steady_clock::now(); } next_frame = now + delay; @@ -769,6 +770,7 @@ public: std::this_thread::sleep_for((next_frame - now) / 3 * 2); } while(next_frame > now) { + std::this_thread::sleep_for(1ns); now = std::chrono::steady_clock::now(); } next_frame = now + delay; diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index 3ae10cd9..6c0a7e42 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -763,7 +763,7 @@ void controlBroadcastThread(control_server_t *server) { break; } - server->iterate(50ms); + server->iterate(500ms); } // Let all remaining connections know the server is shutting down From ea9ada8d20244b48db9c974b7833e06e52c01e88 Mon Sep 17 00:00:00 2001 From: loki-47-6F-64 Date: Sat, 4 Sep 2021 12:09:12 +0200 Subject: [PATCH 2/3] Trade slightly higher rumble latency for lower cpu usage --- sunshine/stream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sunshine/stream.cpp b/sunshine/stream.cpp index 6c0a7e42..dd14e829 100644 --- a/sunshine/stream.cpp +++ b/sunshine/stream.cpp @@ -763,7 +763,7 @@ void controlBroadcastThread(control_server_t *server) { break; } - server->iterate(500ms); + server->iterate(150ms); } // Let all remaining connections know the server is shutting down From d73a4a38e5838ee1a2d386d66cebe66a92f5a373 Mon Sep 17 00:00:00 2001 From: loki Date: Sat, 4 Sep 2021 18:16:36 +0200 Subject: [PATCH 3/3] Fix multi-monitor setup with KMSgrab --- sunshine/platform/linux/graphics.cpp | 42 +++++++++++++++++++++------- sunshine/platform/linux/graphics.h | 8 +++++- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/sunshine/platform/linux/graphics.cpp b/sunshine/platform/linux/graphics.cpp index 0dd53f0c..a0b8d3af 100644 --- a/sunshine/platform/linux/graphics.cpp +++ b/sunshine/platform/linux/graphics.cpp @@ -69,6 +69,13 @@ frame_buf_t frame_buf_t::make(std::size_t count) { return frame_buf; } +void frame_buf_t::copy(int id, int texture, int offset_x, int offset_y, int width, int height) { + gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, (*this)[id]); + gl::ctx.ReadBuffer(GL_COLOR_ATTACHMENT0 + id); + gl::ctx.BindTexture(GL_TEXTURE_2D, texture); + gl::ctx.CopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, offset_x, offset_y, width, height); +} + std::string shader_t::err_str() { int length; ctx.GetShaderiv(handle(), GL_INFO_LOG_LENGTH, &length); @@ -730,18 +737,36 @@ void sws_t::load_ram(platf::img_t &img) { gl::ctx.TexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, img.width, img.height, GL_BGRA, GL_UNSIGNED_BYTE, img.data); } -void sws_t::load_vram(cursor_t &img, int offset_x, int offset_y, int texture) { +void sws_t::load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture) { + // When only a sub-part of the image must be encoded... + const bool copy = offset_x || offset_y || img.sd.width != in_width || img.sd.height != in_height; + if(copy) { + auto framebuf = gl::frame_buf_t::make(1); + framebuf.bind(&texture, &texture + 1); + + loaded_texture = tex[0]; + framebuf.copy(0, loaded_texture, offset_x, offset_y, in_width, in_height); + } + else { + loaded_texture = texture; + } + if(img.data) { - loaded_texture = tex[0]; GLenum attachment = GL_COLOR_ATTACHMENT0; - gl::ctx.BindTexture(GL_TEXTURE_2D, texture); gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, cursor_framebuffer[0]); - gl::ctx.DrawBuffers(1, &attachment); - gl::ctx.UseProgram(program[2].handle()); - gl::ctx.Viewport(offset_x, offset_y, in_width, in_height); - gl::ctx.DrawArrays(GL_TRIANGLES, 0, 3); + + // When a copy has already been made... + if(!copy) { + gl::ctx.BindTexture(GL_TEXTURE_2D, texture); + gl::ctx.DrawBuffers(1, &attachment); + + gl::ctx.Viewport(0, 0, in_width, in_height); + gl::ctx.DrawArrays(GL_TRIANGLES, 0, 3); + + loaded_texture = tex[0]; + } gl::ctx.BindTexture(GL_TEXTURE_2D, tex[1]); if(serial != img.serial) { @@ -770,9 +795,6 @@ void sws_t::load_vram(cursor_t &img, int offset_x, int offset_y, int texture) { gl::ctx.BindTexture(GL_TEXTURE_2D, 0); gl::ctx.BindFramebuffer(GL_FRAMEBUFFER, 0); } - else { - loaded_texture = texture; - } } int sws_t::convert(nv12_t &nv12) { diff --git a/sunshine/platform/linux/graphics.h b/sunshine/platform/linux/graphics.h index 78c66708..127077e4 100644 --- a/sunshine/platform/linux/graphics.h +++ b/sunshine/platform/linux/graphics.h @@ -80,6 +80,11 @@ public: ++x; }); } + + /** + * Copies a part of the framebuffer to texture + */ + void copy(int id, int texture, int offset_x, int offset_y, int width, int height); }; class shader_t { @@ -275,7 +280,7 @@ public: int convert(nv12_t &nv12); void load_ram(platf::img_t &img); - void load_vram(cursor_t &img, int offset_x, int offset_y, int texture); + void load_vram(img_descriptor_t &img, int offset_x, int offset_y, int texture); void set_colorspace(std::uint32_t colorspace, std::uint32_t color_range); @@ -285,6 +290,7 @@ public: // The cursor image will be blended into this framebuffer gl::frame_buf_t cursor_framebuffer; + gl::frame_buf_t copy_framebuffer; // Y - shader, UV - shader, Cursor - shader gl::program_t program[3];