Merge branch 'bugfix/VNC-127-kasm-vnc-low-frame-rate-on-master' into 'master'

VNC-127 Threading performance increases

Closes VNC-127

See merge request kasm-technologies/internal/KasmVNC!179
This commit is contained in:
Matthew McClaskey 2025-05-13 16:35:12 +00:00
commit b26ec0bf3d
25 changed files with 173 additions and 52 deletions

View File

@ -73,8 +73,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -73,8 +73,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -73,8 +73,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -73,8 +73,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -28,8 +28,7 @@ RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libav
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

View File

@ -31,8 +31,7 @@ RUN CMAKE_URL="https://cmake.org/files/v3.22/cmake-3.22.0" && \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

View File

@ -17,8 +17,7 @@ RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libav
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

View File

@ -78,8 +78,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -79,8 +79,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -78,8 +78,7 @@ RUN \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd RUN useradd -m docker && echo "docker:docker" | chpasswd

View File

@ -19,8 +19,7 @@ RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libav
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

View File

@ -9,7 +9,6 @@ RUN zypper install -ny \
bdftopcf \ bdftopcf \
bigreqsproto-devel \ bigreqsproto-devel \
ninja \ ninja \
cmake \
nasm \ nasm \
curl \ curl \
ffmpeg-4-libavcodec-devel \ ffmpeg-4-libavcodec-devel \
@ -49,10 +48,6 @@ RUN zypper install -ny \
xorg-x11-util-devel \ xorg-x11-util-devel \
zlib-devel zlib-devel
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-14 140 \
--slave /usr/bin/g++ g++ /usr/bin/g++-14 \
--slave /usr/bin/gcov gcov /usr/bin/gcov-14
RUN useradd -u 1000 docker && \ RUN useradd -u 1000 docker && \
groupadd -g 1000 docker && \ groupadd -g 1000 docker && \
usermod -a -G docker docker usermod -a -G docker docker
@ -71,8 +66,11 @@ RUN ARCH=$(arch) && \
rm cmake.sh rm cmake.sh
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
ENV CC=/usr/bin/gcc-14
ENV CXX=/usr/bin/g++-14
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp && $SCRIPTS_DIR/build-libjpeg-turbo RUN $SCRIPTS_DIR/build-deps.sh
COPY --chown=docker:docker . /src/ COPY --chown=docker:docker . /src/

View File

@ -41,7 +41,6 @@ RUN dnf install -y --nogpgcheck https://mirrors.rpmfusion.org/free/el/rpmfusion-
# Install from new repos # Install from new repos
RUN dnf install -y \ RUN dnf install -y \
tbb-devel \
ffmpeg-devel \ ffmpeg-devel \
giflib-devel \ giflib-devel \
lbzip2 \ lbzip2 \
@ -58,7 +57,7 @@ RUN dnf install -y \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN echo "source /opt/rh/gcc-toolset-14/enable" > /etc/profile.d/gcc-toolset.sh && \ RUN echo "source /opt/rh/gcc-toolset-14/enable" > /etc/profile.d/gcc-toolset.sh && \
$SCRIPTS_DIR/build-webp && $SCRIPTS_DIR/build-libjpeg-turbo && \ $SCRIPTS_DIR/build-deps.sh && \
useradd -m docker && echo "docker:docker" | chpasswd useradd -m docker && echo "docker:docker" | chpasswd
COPY --chown=docker:docker . /src/ COPY --chown=docker:docker . /src/

View File

@ -57,7 +57,7 @@ RUN dnf install -y \
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN echo "source /opt/rh/gcc-toolset-14/enable" > /etc/profile.d/gcc-toolset.sh && \ RUN echo "source /opt/rh/gcc-toolset-14/enable" > /etc/profile.d/gcc-toolset.sh && \
$SCRIPTS_DIR/build-webp && $SCRIPTS_DIR/build-libjpeg-turbo && \ $SCRIPTS_DIR/build-deps.sh && \
useradd -m docker && echo "docker:docker" | chpasswd useradd -m docker && echo "docker:docker" | chpasswd
COPY --chown=docker:docker . /src/ COPY --chown=docker:docker . /src/

View File

@ -13,7 +13,7 @@ RUN apt-get update && \
RUN apt-get update && apt-get install -y --no-install-recommends tzdata RUN apt-get update && apt-get install -y --no-install-recommends tzdata
RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev RUN apt-get update && apt-get -y build-dep xorg-server libxfont-dev
RUN apt-get update && apt-get -y install ninja-build nasm git vim wget curl RUN apt-get update && apt-get -y install ninja-build nasm git vim wget curl
RUN apt-get update && apt-get -y install libtbb-dev libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev \ RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libavcodec-dev libssl-dev libxrandr-dev \
libxcursor-dev libavformat-dev libswscale-dev libxcursor-dev libavformat-dev libswscale-dev
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
@ -34,8 +34,7 @@ RUN ARCH=$(arch) && \
(echo y; echo n) | bash cmake.sh --prefix=/usr/local --skip-license && \ (echo y; echo n) | bash cmake.sh --prefix=/usr/local --skip-license && \
rm cmake.sh rm cmake.sh
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
COPY --chown=docker:docker . /src/ COPY --chown=docker:docker . /src/

View File

@ -3,7 +3,7 @@ FROM ubuntu:focal
ENV DEBIAN_FRONTEND noninteractive ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \ RUN apt-get update && \
apt-get -y install vim build-essential devscripts equivs libtbb-dev apt-get -y install vim build-essential devscripts equivs
# Install build-deps for the package. # Install build-deps for the package.
COPY ./debian/control /tmp COPY ./debian/control /tmp

View File

@ -18,8 +18,7 @@ RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libav
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

View File

@ -53,18 +53,16 @@ RUN sed -i 's$# deb-src$deb-src$' /etc/apt/sources.list && \
libxkbfile-dev \ libxkbfile-dev \
x11proto-dev \ x11proto-dev \
libgbm-dev \ libgbm-dev \
htop \
inotify-tools && \ inotify-tools && \
echo "kasm-user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers echo "kasm-user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - RUN curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
RUN apt install -y nodejs nginx RUN apt install -y nodejs nginx
COPY builder/scripts/build-webp /tmp ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts/build-libjpeg-turbo /tmp COPY builder/scripts $SCRIPTS_DIR
COPY builder/common.sh /tmp RUN $SCRIPTS_DIR/build-deps.sh
RUN chmod +x /tmp/build-webp && /tmp/build-webp
RUN chmod +x /tmp/build-libjpeg-turbo && /tmp/build-libjpeg-turbo
USER 1000 USER 1000

View File

@ -18,8 +18,7 @@ RUN apt-get update && apt-get -y install libpng-dev libtiff-dev libgif-dev libav
ENV SCRIPTS_DIR=/tmp/scripts ENV SCRIPTS_DIR=/tmp/scripts
COPY builder/scripts $SCRIPTS_DIR COPY builder/scripts $SCRIPTS_DIR
RUN $SCRIPTS_DIR/build-webp RUN $SCRIPTS_DIR/build-deps.sh
RUN $SCRIPTS_DIR/build-libjpeg-turbo
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo

8
builder/scripts/build-deps.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
source_dir=$(dirname "$0")
"${source_dir}"/build-libjpeg-turbo
"${source_dir}"/build-webp
"${source_dir}"/build-tbb

63
builder/scripts/build-tbb Executable file
View File

@ -0,0 +1,63 @@
#!/usr/bin/env bash
set -euo pipefail
build_and_install() {
if [ $older_release -eq 1 ]; then
make extra_inc=big_iron.inc work_dir="$PWD"/ tbb_root="$PWD"
if [ -d /usr/lib/x86_64-linux-gnu ]; then
LIBS=lib/x86_64-linux-gnu
elif [ -d /usr/lib/aarch64-linux-gnu ]; then
LIBS=lib/aarch64-linux-gnu
elif [ -d /usr/lib/arm-linux-gnueabihf ]; then
LIBS=lib/arm-linux-gnu
fi
PC_FILE=/usr/${LIBS}/pkgconfig/tbb.pc
echo "prefix=/usr" > "${PC_FILE}"
echo "exec_prefix=\${prefix}" >> "${PC_FILE}"
echo "libdir=\${exec_prefix}/lib/${LIBS}" >> "${PC_FILE}"
echo "includedir=\${prefix}/include" >> "${PC_FILE}"
echo "Name: Threading Building Blocks" >> "${PC_FILE}"
echo "Description: Intel's parallelism library for C++" >> "${PC_FILE}"
echo "URL: http://www.threadingbuildingblocks.org/" >> "${PC_FILE}"
echo "Version: v2020.3.3" >> "${PC_FILE}"
echo "Libs: -ltbb -latomic" >> "${PC_FILE}"
echo "Cflags: -I\${includedir}" >> "${PC_FILE}"
cp _release/*.a /usr/"${LIBS}"/
cp -r include/* /usr/include/
else
cmake -B build -DCMAKE_INSTALL_PREFIX=/usr/local \
-DTBB_TEST=OFF -DBUILD_SHARED_LIBS=OFF -GNinja .
ninja -C build install
fi
}
prepare_source() {
DIR=tbb
cd /tmp
[ -d ./${DIR} ] && rm -rf ./${DIR}
mkdir ${DIR}
if [ $older_release -eq 1 ]; then
TBB_RELEASE="v2020.3.3"
else
TBB_RELEASE=$(curl -sL "https://api.github.com/repos/uxlfoundation/oneTBB/releases/latest" \
| grep '"tag_name":' | sed -E 's/.*"tag_name": "([^"]+)".*/\1/')
fi
curl -Ls "https://github.com/uxlfoundation/oneTBB/archive/${TBB_RELEASE}.tar.gz" | \
tar xzvf - -C ${DIR}/ --strip-components=1
cd ${DIR}
}
older_release=0
if grep -q 'Ubuntu 20.04\|Debian GNU/Linux 11' /etc/os-release 2>/dev/null; then
older_release=1
fi
prepare_source
build_and_install

54
builder/test_build_containers Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
#set -e
script_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
current_dir="$(pwd)"
images_list=()
for file in "$script_dir"/dockerfile.*.build; do
if [[ "$file" == *deb* ]] || [[ "$file" == *apk* ]] || [[ "$file" == *rpm* ]] || [[ "$file" == *www* ]]; then
continue
fi
[ -e "$file" ] || continue
filename="$(basename "$file")"
image_name=$(echo "$filename" | sed -E 's/^(dockerfile\.|Dockerfile\.)(.*)\.build$/\2/')
if [ -e builder/build/kasmvnc."$image_name".tar.gz ]; then
continue
fi
echo "Building docker image: $image_name using file: $file"
docker build -f "$file" -t "$image_name" "$current_dir"
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo "Build failed for $filename"
break
fi
rm -rf .cmake CMakeFiles build.ninja cmake_install.cmake cmake_uninstall.cmake CMakeCache.txt config.h
echo "Running container from image '$image_name'"
# Run the container and capture the exit code
docker run -it -v "$current_dir":/src -v "$current_dir/builder/build":/build "$image_name"
exit_code=$?
echo "Container for image '$image_name' "
if [ $exit_code -ne 0 ]; then
echo "exited with error (exit code $exit_code)."
break
else
echo "finished successfully."
images_list+=("$image_name")
fi
done
echo "Removing all built docker images..."
for img in "${images_list[@]}"; do
echo "Removing docker image: $img"
docker rmi -f "$img"
done

View File

@ -132,6 +132,13 @@ endif ()
find_package(PkgConfig REQUIRED) find_package(PkgConfig REQUIRED)
pkg_check_modules(FFMPEG REQUIRED libavcodec libavformat libavutil libswscale) pkg_check_modules(FFMPEG REQUIRED libavcodec libavformat libavutil libswscale)
find_package(TBB)
if (TBB_FOUND)
set(RFB_LIBRARIES ${RFB_LIBRARIES} tbb)
else ()
pkg_check_modules(TBB tbb)
set(RFB_LIBRARIES ${RFB_LIBRARIES} ${TBB_LIBRARIES})
endif ()
add_library(rfb STATIC ${RFB_SOURCES}) add_library(rfb STATIC ${RFB_SOURCES})
@ -142,9 +149,10 @@ target_include_directories(rfb PRIVATE
${CMAKE_SOURCE_DIR}/unix/kasmvncpasswd ${CMAKE_SOURCE_DIR}/unix/kasmvncpasswd
${CMAKE_SOURCE_DIR}/third_party/tinyxml2 ${CMAKE_SOURCE_DIR}/third_party/tinyxml2
${FFMPEG_INCLUDE_DIRS} ${FFMPEG_INCLUDE_DIRS}
${TBB_INCLUDE_DIRS}
) )
target_link_libraries(rfb PRIVATE ${RFB_LIBRARIES} tinyxml2_objs) target_link_libraries(rfb PUBLIC ${RFB_LIBRARIES} tinyxml2_objs)
if (UNIX) if (UNIX)
libtool_create_control_file(rfb) libtool_create_control_file(rfb)

View File

@ -44,6 +44,7 @@
#include <rfb/TightWEBPEncoder.h> #include <rfb/TightWEBPEncoder.h>
#include <rfb/TightQOIEncoder.h> #include <rfb/TightQOIEncoder.h>
#include <execution> #include <execution>
#include <tbb/parallel_for.h>
using namespace rfb; using namespace rfb;
@ -210,6 +211,9 @@ EncodeManager::EncodeManager(SConnection* conn_, EncCache *encCache_) : conn(con
dynamicQualityMin = Server::dynamicQualityMin; dynamicQualityMin = Server::dynamicQualityMin;
dynamicQualityOff = Server::dynamicQualityMax - Server::dynamicQualityMin; dynamicQualityOff = Server::dynamicQualityMax - Server::dynamicQualityMin;
} }
const auto num_cores = tbb::this_task_arena::max_concurrency() / 2;
arena.initialize(num_cores);
} }
EncodeManager::~EncodeManager() EncodeManager::~EncodeManager()
@ -1237,13 +1241,14 @@ void EncodeManager::writeRects(const Region& changed, const PixelBuffer* pb,
} }
scalingTime = msSince(&scalestart); scalingTime = msSince(&scalestart);
std::for_each(std::execution::par_unseq, std::begin(indices), std::end(indices), [&](size_t i) arena.execute([&] {
{ tbb::parallel_for(static_cast<size_t>(0), subrects_size, [&](size_t i) {
encoderTypes[i] = getEncoderType(subrects[i], pb, &palettes[i], compresseds[i], encoderTypes[i] = getEncoderType(subrects[i], pb, &palettes[i], compresseds[i],
&isWebp[i], &fromCache[i], &isWebp[i], &fromCache[i],
scaledpb, scaledrects[i], ms[i]); scaledpb, scaledrects[i], ms[i]);
checkWebpFallback(start); checkWebpFallback(start);
}); });
});
for (uint32_t i = 0; i < subrects_size; ++i) { for (uint32_t i = 0; i < subrects_size; ++i) {
if (encoderTypes[i] == encoderFullColour) { if (encoderTypes[i] == encoderFullColour) {

View File

@ -32,6 +32,7 @@
#include <stdint.h> #include <stdint.h>
#include <atomic> #include <atomic>
#include <tbb/task_arena.h>
#include <sys/time.h> #include <sys/time.h>
namespace rfb { namespace rfb {
@ -167,6 +168,7 @@ namespace rfb {
protected: protected:
SConnection *conn; SConnection *conn;
tbb::task_arena arena;
std::vector<Encoder*> encoders; std::vector<Encoder*> encoders;
std::vector<int> activeEncoders; std::vector<int> activeEncoders;