slint-ui / slint

Slint is a declarative GUI toolkit to build native user interfaces for Rust, C++, or JavaScript apps.
https://slint.dev
Other
17.55k stars 603 forks source link

Text rendering artifacts when running on imx6 / wayland #2855

Open kkettinger opened 1 year ago

kkettinger commented 1 year ago

I'm trying out slint ui for embedded and i'm experience text rendering issues on a toradex apalis imx6 target. The target is running a custom yocto linux with weston as wayland compositor in kiosk mode (shell=kiosk-shell.so). The output is a HDMI display.

I'm using slint 1.0.2.

rendering issue

When the text changes, the artifacts change also. Everything else like images, rectangles and backgrounds are looking good.

I appreciate any help on this issue, thank you.

kkettinger commented 1 year ago

Here is a minimal example: https://github.com/kkettinger/slint-text-rendering-artifact-demo

Here is a video showing the issue: https://github.com/slint-ui/slint/assets/83078716/eead49ba-62b6-4a97-ac51-e350f9c0814b

Changing the default font did not solve the problem.

Update: When running the demo with the software renderer the text artifacts are gone: SLINT_BACKEND=winit-software ./slint-text-rendering-artifact-demo

So it seems there is some issue with the femtovg renderer.

ogoffart commented 1 year ago

Looks similar to https://github.com/slint-ui/slint/issues/2314

tronical commented 1 year ago

This is rather bizarre. If these artefacts change as the text changes, then that's rather worrying - I wonder if we're triggering some vivante driver bug.

I've got an i.mx6 in the office, I'll try to get hold of that to reproduce it.

Meanwhile, would building with with Skia be an option for you?

kkettinger commented 1 year ago

I've tried building it for my target in yocto, but the skia-bindings don't compile:

| error: failed to run custom build command for `skia-bindings v0.60.0`                                                                                                                                                                           |
| Caused by:
|   process didn't exit successfully: `/home/devel/workspace/build/tmp/work/armv7at2hf-neon-imx-tdx-linux-gnueabi/slint-text-rendering-artifact-demo/0.1.0.AUTOINC+c61cdf779d-r0/build/target/release/bui
ld/skia-bindings-dee2b0b51f422bc0/build-script-build` (exit status: 101)
|   --- stdout                                                                                                                                                                                                                                    |   cargo:rerun-if-env-changed=DOCS_RS                                                                                                                                                                                                            |   cargo:rerun-if-env-changed=SKIA_DEBUG                                                                                                                                                                                                         |   HOST: x86_64-linux
|   cargo:rerun-if-env-changed=SKIA_SOURCE_DIR
|   cargo:rerun-if-env-changed=FORCE_SKIA_BUILD
|   cargo:rerun-if-env-changed=FORCE_SKIA_BINARIES_DOWNLOAD
|   TRYING TO DOWNLOAD AND INSTALL SKIA BINARIES: 0.60.0/b56faf27dc794236290a-arm-tdx-linux-gnueabi-gl-textlayout                                                                                                                                 |   cargo:rerun-if-env-changed=SKIA_BINARIES_URL                                                                                                                                                                                                  |     FROM: https://github.com/rust-skia/skia-binaries/releases/download/0.60.0/skia-binaries-b56faf27dc794236290a-arm-tdx-linux-gnueabi-gl-textlayout.tar.gz                                                                                     |   DOWNLOAD AND INSTALL FAILED: https://github.com/rust-skia/skia-binaries/releases/download/0.60.0/skia-binaries-b56faf27dc794236290a-arm-tdx-linux-gnueabi-gl-textlayout.tar.gz: status code 404
|   STARTING A FULL BUILD
|   cargo:rerun-if-env-changed=CLANGCC
|   cargo:rerun-if-env-changed=CC
|   cargo:rerun-if-env-changed=CLANGCXX
|   cargo:rerun-if-env-changed=CXX
|   HOST: x86_64-linux
|   cargo:rerun-if-env-changed=OPT_LEVEL
|   cargo:rerun-if-env-changed=SKIA_USE_SYSTEM_LIBRARIES
|   cargo:rerun-if-env-changed=SDKTARGETSYSROOT                                                                                                                                                                                                   |   cargo:rerun-if-env-changed=SDKROOT
|   HOST: x86_64-linux
|   cargo:rerun-if-env-changed=SKIA_NINJA_COMMAND
|   cargo:rerun-if-env-changed=SKIA_GN_COMMAND
|   Probing 'python'
|   Probing 'python3'
|   Python 3 found: "python3"
|   Synchronizing Skia dependencies
|   Skipping "bin".
|   skia/third_party/externals/brotli
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/d3d12allocator
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/expat
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/icu
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/harfbuzz
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/freetype
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/libjpeg-turbo
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/libpng
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/libwebp
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/vulkanmemoryallocator
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/piex
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/spirv-cross
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/wuffs
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   skia/third_party/externals/zlib
|     IS NOT TOP-LEVEL GIT DIRECTORY.
|   Skia args: is_official_build=true is_debug=false skia_enable_svg=false skia_enable_gpu=true skia_enable_skottie=false skia_enable_pdf=true skia_use_gl=true skia_use_egl=false skia_use_x11=false skia_use_system_libpng=false skia_use_libweb
p_encode=false skia_use_libwebp_decode=false skia_use_system_zlib=false skia_use_xps=false skia_use_dng_sdk=false cc="/home/devel/workspace/build/tmp/work/armv7at2hf-neon-imx-tdx-linux-gnueabi/slint-te
xt-rendering-artifact-demo/0.1.0.AUTOINC+c61cdf779d-r0/wrapper/target-rust-cc" cxx="/home/devel/workspace/build/tmp/work/armv7at2hf-neon-imx-tdx-linux-gnueabi/slint-text-rendering-artifact-demo/0.1.0.A
UTOINC+c61cdf779d-r0/wrapper/target-rust-cxx" skia_enable_skshaper=true skia_use_icu=true skia_use_system_icu=false skia_use_harfbuzz=true skia_pdf_subset_harfbuzz=true skia_use_system_harfbuzz=false skia_use_sfntly=false skia_enable_skparagraph=true skia_use_system_libjpeg_turbo=false skia_use_expat=true skia_use_system_expat=false target_os="linux" target_cpu="arm" extra_cflags=["-O3","--target=arm-tdx-linux-gnueabi"] extra_asmflags=["--target=arm-tdx-linux-gnueabi"]           |   Done. Made 90 targets from 47 files in 292ms                                                                                                                                                                                                  |   ninja: Entering directory `/home/devel/workspace/build/tmp/work/armv7at2hf-neon-imx-tdx-linux-gnueabi/slint-text-rendering-artifact-demo/0.1.0.AUTOINC+c61cdf779d-r0/build/target/arm-tdx-linux-gnuea
bi/release/build/skia-bindings-ac0ab10dcf92ec7f/out/skia'
|   [1/1424] compile ../../../../../../../../cargo_home/bitbake/skia-bindings-0.60.0/skia/src/gpu/ganesh/GrProxyProvider.cpp
|   FAILED: obj/src/gpu/ganesh/gpu.GrProxyProvider.o
|   /home/devel/workspace/build/tmp/work/armv7at2hf-neon-imx-tdx-linux-gnueabi/slint-text-rendering-artifact-demo/0.1.0.AUTOINC+c61cdf779d-r0/wrapper/target-rust-cxx -MD -MF obj/src/gpu/ganesh/gpu.GrProxyProvider.o.d -DNDEBUG -DSK_R32_SHIFT=16 -DSK_ENABLE_SKSL -DSK_ENABLE_PRECOMPILE -DSK_USE_PERFETTO -DSK_GAMMA_APPLY_TO_A8 -DSKIA_IMPLEMENTATION=1 -DSK_GL -DSK_SUPPORT_GPU=1 -I../../../../../../../../cargo_home/bitbake/skia-bindings-0.60.0/skia -Wno-attributes -fstrict-aliasing -fPIC -fvisibility=hidden -march=armv7-a -mfpu=neon -mthumb -O3 -fdata-sections -ffunction-sections -O3 --target=arm-tdx-linux-gnueabi -std=c++17 -fvisibility-inlines-hidden -fno-exceptions -fno-rtti -c ../../../../../../../../cargo_home/bitbake/skia-bindings-0.60.0/skia/src/gpu/ganesh/GrProxyProvider.cpp -o obj/src/gpu/ganesh/gpu.GrProxyProvider.o
|   arm-tdx-linux-gnueabi-g++: error: unrecognized command-line option '--target=arm-tdx-linux-gnueabi'

This might be relevant: https://github.com/rust-skia/rust-skia/commit/ab8bc4dfa8fc85713027e092a1c1e4ed8a1a7aa6

The above changes are merged in skia 0.63.0, in slint 1.0.2 skia-bindings are locked to 0.60.0.

When trying to generate a yocto recipe for the slint master branch, cargo bitbake fails. As soon as this issue is fixed, i will try to build the skia renderer. Here is the ticket to the cargo-bitbake issue: https://github.com/meta-rust/cargo-bitbake/issues/69

kkettinger commented 1 year ago

I was able to build the minimal example with the latest slint version from master, but skia still doesn't compile.

When then trying out the femtovg renderer (now with v0.7.1), the artifacts still exist.

tronical commented 1 year ago

The skia yocto fixes went into the 0.58 release.

For building against a Yocto sdk maybe this helps: https://github.com/rust-skia/rust-skia/tree/master/skia-bindings#cross-compiling-for-linux

for building inside Yocto you could perhaps try our demos recipe and see if the binaries work for you without Artefacts: https://github.com/slint-ui/meta-slint/tree/main/recipes-example/slint-demos

tronical commented 1 year ago

The compiler error looks like the build is invoking gcc when it should be running clang. Can you try setting CLANGCC/CLANGCXX?

If you’re inside a recipe you might need this trick: https://github.com/slint-ui/meta-slint/blob/69feb7f0f40cc8dc4ca52777cf87a4c879d4b953/recipes-slint/slint/slint-cpp.inc#L76

kkettinger commented 1 year ago

Thanks for meta-slint, I never stumbled across this layer which makes things a bit easier. I was always building my recipe with cargo-bitbake, which is a bit of a hassle when you are in early development and i couldn't get it work without it.

For both recipes (slint-hello-world and slint-demos) I had to update the LICENSE md5 hash, but then the recipe started compiling. The slint-hello-world example didn't compile:

...
/home/devel/workspace/build/tmp/work/armv7at2hf-neon-tdx-linux-gnueabi/slint-hello-world/slint-hello-world-AUTOINC+5b1f76496a-r0/recipe-sysroot/usr/include/slint/slint_interpreter_internal.h:194:56: error: 'ValueOpaque' was not declared in this scope
  194 |                                                  Slice<ValueOpaque> args,
      |                                                        ^~~~~~~~~~~
/home/devel/workspace/build/tmp/work/armv7at2hf-neon-tdx-linux-gnueabi/slint-hello-world/slint-hello-world-AUTOINC+5b1f76496a-r0/recipe-sysroot/usr/include/slint/slint_interpreter_internal.h:194:67: error: template argument 1 is invalid
  194 |                                                  Slice<ValueOpaque> args,
      |                                                                   ^
...                                         ^~~~~~~~~~~

The slint-demos recipe compiled without problems, but with femtovg the same issue exists: printerdemo-femtovg

For the slint-demos recipe, the feature for the skia-renderer was not enabled.

For my minimal recipe i've copying these lines from the slint-cpp.inc file (without do_configure/do_install) and it compiled! And the skia renderer does work without artifacts :slightly_smiling_face:

SLINT_BACKEND=winit-skia XDG_RUNTIME_DIR=/run/user/0 slint-text-rendering-artifact-demo

renderer-skia

For completness sake, here is my full recipe with working skia renderer:

inherit cargo

SRC_URI += "git://git@github.com/kkettinger/slint-text-rendering-artifact-demo.git;protocol=ssh;branch=main"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git"

CARGO_DISABLE_BITBAKE_VENDORING = "1"

do_configure[network] = "1"
do_compile[network] = "1"

LIC_FILES_CHKSUM = " \
    "

BBCLASSEXTEND = "native"

SUMMARY = "slint-text-rendering-artifact-demo"
HOMEPAGE = "https://github.com/kkettinger/slint-text-rendering-artifact-demo.git"
LICENSE = "CLOSED"

do_compile:prepend() {
    export RUST_FONTCONFIG_DLOPEN=on
    oe_cargo_fix_env
    export RUSTFLAGS="${RUSTFLAGS}"
    export RUST_TARGET_PATH="${RUST_TARGET_PATH}"
    # Make sure that Skia's invocation of clang to generate bindings.rs for the Skia headers
    # passes the right flags, in particular float abi selection
    export BINDGEN_EXTRA_CLANG_ARGS="${HOST_CC_ARCH} ${TOOLCHAIN_OPTIONS} ${TARGET_CFLAGS}"
}

DEPENDS = "fontconfig libxcb wayland clang-cross-${TARGET_ARCH} virtual/libgl"

# Usually OE_CMAKE_C_COMPILER is just say `arm-poky-linux-gcc`, but we need the original `${CC}` that includes
# options like -mfloat-abi. This is taken into use when compiling Rust Skia's bindings.cpp (the manual part),
# where OECMAKE_CXX_COMPILER becomes CMAKE_CXX_COMPILER, and Corrison turns it into CXX_<triplet>.
OECMAKE_C_COMPILER = "${RUST_TARGET_CC}"
OECMAKE_CXX_COMPILER = "${RUST_TARGET_CXX}"

EXTRA_OECMAKE:append = " -DRust_CARGO_TARGET=${HOST_SYS}"

EXTRA_OECMAKE:append = " -DFETCHCONTENT_FULLY_DISCONNECTED=OFF"
EXTRA_OECMAKE:append = " -DBUILD_TESTING=OFF -DSLINT_BUILD_EXAMPLES=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo"
EXTRA_OECMAKE:append = " -DCMAKE_DISABLE_FIND_PACKAGE_Qt5=true -DSLINT_FEATURE_BACKEND_QT=OFF"
EXTRA_OECMAKE:append = " -DSLINT_FEATURE_BACKEND_WINIT=OFF -DSLINT_FEATURE_BACKEND_WINIT_WAYLAND=ON"
EXTRA_OECMAKE:append = " -DSLINT_FEATURE_RENDERER_WINIT_FEMTOVG=OFF -DSLINT_FEATURE_RENDERER_WINIT_SKIA=ON"

# Emulate what clang-environment.inc does.

export TARGET_CLANGCC_ARCH = "${TARGET_CC_ARCH}"
TARGET_CLANGCC_ARCH:remove = "-mthumb-interwork"
TARGET_CLANGCC_ARCH:remove = "-mmusl"
TARGET_CLANGCC_ARCH:remove = "-muclibc"
TARGET_CLANGCC_ARCH:remove = "-meb"
TARGET_CLANGCC_ARCH:remove = "-mel"
TARGET_CLANGCC_ARCH:append = "${@bb.utils.contains("TUNE_FEATURES", "bigendian", " -mbig-endian", " -mlittle-endian", d)}"
TARGET_CLANGCC_ARCH:remove:powerpc = "-mhard-float"
TARGET_CLANGCC_ARCH:remove:powerpc = "-mno-spe"

# Add -I=/usr/include/freetype2 as skia has hardcoded it to -I/usr/include/freetype2, which
# would locate freetype in the host system, not the sysroot target.
export CLANGCC="${TARGET_PREFIX}clang --target=${TARGET_SYS} ${TARGET_CLANGCC_ARCH} --sysroot=${STAGING_DIR_TARGET}  -I=/usr/include/freetype2"
export CLANGCXX="${TARGET_PREFIX}clang++ --target=${TARGET_SYS} ${TARGET_CLANGCC_ARCH} --sysroot=${STAGING_DIR_TARGET}  -I=/usr/include/freetype2"
export CLANGCPP="${TARGET_PREFIX}clang -E --target=${TARGET_SYS} ${TARGET_CLANGCC_ARCH} --sysroot=${STAGING_DIR_TARGET}  -I=/usr/include/freetype2"
export CLANG_TIDY_EXE="${TARGET_PREFIX}clang-tidy"
export SDKTARGETSYSROOT="${PKG_CONFIG_SYSROOT_DIR}"

I think it makes sense to have a slint.bbclass that one can inherit that include these changes.

Thank you for your help!

tronical commented 1 year ago

I think it makes sense to have a slint.bbclass that one can inherit that include these changes.

That is an excellent idea! Will do that.

tronical commented 1 year ago

Keeping this ticket open as the issue in femtovg still exists.

kkettinger commented 1 year ago

Great, if you need someone to test, just tell me 🙂

tronical commented 1 year ago

I pushed the change to introduce a common bblcass into the meta-slint repo. Built for me locally but YMMV :).

kkettinger commented 1 year ago

Thank you :-) I'll have a look at it.

kkettinger commented 1 year ago

printerdemo with renderer skia now looks good! SLINT_BACKEND=winit-skia printerdemo printerdemo-skia