From e9fca9bd3b0943dcdf959d91a2ce990112769581 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 5 Mar 2025 20:28:10 +0900 Subject: [PATCH 01/21] [Tizen] Cherrypicks from flutter-3.27.1 of flutter-tizen/engine --- DEPS | 2 +- engine/src/flutter/common/config.gni | 4 +-- .../src/flutter/display_list/testing/BUILD.gn | 3 +- engine/src/flutter/impeller/tools/args.gni | 5 ++-- engine/src/flutter/shell/config.gni | 2 +- engine/src/flutter/testing/BUILD.gn | 2 +- engine/src/flutter/tools/gn | 28 +++++++------------ .../src/flutter/txt/src/txt/platform_linux.cc | 3 +- 8 files changed, 19 insertions(+), 30 deletions(-) diff --git a/DEPS b/DEPS index 0139ff7ebda07..a4fe246ccff4c 100644 --- a/DEPS +++ b/DEPS @@ -127,7 +127,7 @@ vars = { "checkout_llvm": False, # Setup Git hooks by default. - 'setup_githooks': True, + 'setup_githooks': False, # When this is true, the Flutter Engine's configuration files and scripts for # RBE will be downloaded from CIPD. This option is only usable by Googlers. diff --git a/engine/src/flutter/common/config.gni b/engine/src/flutter/common/config.gni index 318d305bd37fc..f3b3c15534a2f 100644 --- a/engine/src/flutter/common/config.gni +++ b/engine/src/flutter/common/config.gni @@ -157,6 +157,4 @@ if (flutter_prebuilt_dart_sdk) { # TODO: We can't build the engine artifacts for arm (32-bit) right now; # see https://github.com/flutter/flutter/issues/74322. build_engine_artifacts = - flutter_build_engine_artifacts && !is_android && - (current_toolchain == host_toolchain || - (is_linux && !is_chromeos && current_cpu != "arm") || is_mac || is_win) + flutter_build_engine_artifacts && current_toolchain == host_toolchain diff --git a/engine/src/flutter/display_list/testing/BUILD.gn b/engine/src/flutter/display_list/testing/BUILD.gn index 9a9637184af6f..f3cb22539cf78 100644 --- a/engine/src/flutter/display_list/testing/BUILD.gn +++ b/engine/src/flutter/display_list/testing/BUILD.gn @@ -35,7 +35,8 @@ surface_provider_include_software = !is_android && !is_ios # But, since benchmarks do not run on Windows and rendertests only # runs on SW by default, this restriction currently only limits the # ability to manually cross-check OpenGL on Windows for rendertests -surface_provider_include_gl = !is_fuchsia && !is_ios && !is_win && !is_mac +surface_provider_include_gl = + !is_fuchsia && !is_ios && !is_win && !is_mac && !is_linux # TODO (https://github.com/flutter/flutter/issues/107357): # impeller_enable_vulkan currently requires skia to not use VMA, which in turn diff --git a/engine/src/flutter/impeller/tools/args.gni b/engine/src/flutter/impeller/tools/args.gni index d1b387506a5af..2759a69136c9f 100644 --- a/engine/src/flutter/impeller/tools/args.gni +++ b/engine/src/flutter/impeller/tools/args.gni @@ -18,9 +18,8 @@ declare_args() { enable_unittests) && target_os != "fuchsia" # Whether the Vulkan backend is enabled. - impeller_enable_vulkan = - (is_linux || is_win || is_android || is_mac || is_qnx || - enable_unittests) && target_os != "fuchsia" + impeller_enable_vulkan = (is_win || is_android || is_mac || + enable_unittests) && target_os != "fuchsia" } # Arguments that are combinations of other arguments by default but which can diff --git a/engine/src/flutter/shell/config.gni b/engine/src/flutter/shell/config.gni index 3f498d2c044f7..9ad466439ee2e 100644 --- a/engine/src/flutter/shell/config.gni +++ b/engine/src/flutter/shell/config.gni @@ -17,6 +17,6 @@ declare_args() { test_enable_metal = shell_enable_metal # The Vulkan unittests are combined with the GL unittests. - test_enable_vulkan = is_fuchsia || shell_enable_gl + test_enable_vulkan = is_fuchsia test_enable_software = shell_enable_software } diff --git a/engine/src/flutter/testing/BUILD.gn b/engine/src/flutter/testing/BUILD.gn index 4cf0a3a6b3a63..30bb7bd7620f0 100644 --- a/engine/src/flutter/testing/BUILD.gn +++ b/engine/src/flutter/testing/BUILD.gn @@ -54,7 +54,7 @@ source_set("testing") { if (enable_unittests && is_linux) { # So that we can call gtk_init in main(). - configs += [ "//flutter/shell/platform/linux/config:gtk" ] + # configs += [ "//flutter/shell/platform/linux/config:gtk" ] } public_deps = [ ":testing_lib" ] diff --git a/engine/src/flutter/tools/gn b/engine/src/flutter/tools/gn index 06a3e28989eeb..edd73a4c0f418 100755 --- a/engine/src/flutter/tools/gn +++ b/engine/src/flutter/tools/gn @@ -89,18 +89,7 @@ def to_command_line(gn_args): def is_host_build(args): - # If target_os == None, then this is a host build. - if args.target_os is None: - return True - # For linux arm64 builds, we cross compile from x64 hosts, so the - # target_os='linux' and linux-cpu='arm64' - if args.target_os == 'linux' and args.linux_cpu == 'arm64': - return True - # The Mac and host targets are redundant. Again, necessary to disambiguate - # during cross-compilation. - if args.target_os == 'mac': - return True - return False + return args.target_os is None # Determines whether a prebuilt Dart SDK can be used instead of building one. @@ -542,7 +531,7 @@ def to_gn_args(args): # does not exist. Further, we set the 'host_cpu' so that it shares the # bitwidth of the 32-bit arm target. if sys.platform.startswith( - ('cygwin', 'win')) and args.target_os == 'android' and gn_args['target_cpu'] == 'arm': + ('cygwin', 'win')) and args.target_os != 'win' and gn_args['target_cpu'] == 'arm': gn_args['host_cpu'] = 'x86' gn_args['current_cpu'] = 'x86' @@ -665,7 +654,7 @@ def to_gn_args(args): # Enable Vulkan on all platforms except for iOS. This is just # to save on mobile binary size, as there's no reason the Vulkan embedder # features can't work on these platforms. - if gn_args['target_os'] not in ['ios', 'mac']: + if gn_args['target_os'] not in ['ios', 'mac', 'linux']: gn_args['skia_use_vulkan'] = True gn_args['skia_use_vma'] = False gn_args['shell_enable_vulkan'] = True @@ -773,13 +762,17 @@ def to_gn_args(args): # Enable pointer compression on 64-bit mobile targets. iOS is excluded due to # its inability to allocate address space without allocating memory. - if args.target_os in ['android'] and gn_args['target_cpu'] in ['x64', 'arm64']: + if args.target_os in ['android', 'linux'] and gn_args['target_cpu'] in ['x64', 'arm64']: gn_args['dart_use_compressed_pointers'] = True if args.target_os == 'fuchsia': gn_args['gn_configs_path'] = '//flutter/build/config/fuchsia/gn_configs.gni' gn_args['fuchsia_gn_sdk'] = '//flutter/tools/fuchsia/gn-sdk' + # Don't use the default Linux sysroot when buliding for Linux on macOS. + if sys.platform == 'darwin' and args.target_os == 'linux': + gn_args['use_default_linux_sysroot'] = False + # Flags for Dart features: if args.use_mallinfo2: gn_args['dart_use_mallinfo2'] = args.use_mallinfo2 @@ -805,9 +798,8 @@ def to_gn_args(args): # gen_snapshot, but the build defines otherwise make it look like the build is # for a host Windows build and make GN think we will be building ANGLE. # Angle is not used on Mac hosts as there are no tests for the OpenGL backend. - if is_host_build(args) or (args.target_os == 'android' and get_host_os() == 'win'): - # Don't include git commit information. - gn_args['angle_enable_commit_id'] = False + if (is_host_build(args) and gn_args['host_os'] != 'mac') or (args.target_os == 'linux' and + get_host_os() == 'win'): # Do not build unnecessary parts of the ANGLE tree. gn_args['angle_build_all'] = False gn_args['angle_has_astc_encoder'] = False diff --git a/engine/src/flutter/txt/src/txt/platform_linux.cc b/engine/src/flutter/txt/src/txt/platform_linux.cc index c67f65dbe9829..a20febd4bb6f2 100644 --- a/engine/src/flutter/txt/src/txt/platform_linux.cc +++ b/engine/src/flutter/txt/src/txt/platform_linux.cc @@ -20,8 +20,7 @@ namespace txt { std::vector GetDefaultFontFamilies() { - return {"Ubuntu", "Adwaita Sans", "Cantarell", - "DejaVu Sans", "Liberation Sans", "Arial"}; + return {"TizenDefaultFont", "SamsungOneUI"}; } sk_sp GetDefaultFontManager(uint32_t font_initialization_data) { From a0fce363c6526156d11b570719dd718011e191a9 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 5 Mar 2025 20:50:28 +0900 Subject: [PATCH 02/21] [Tizen] Add CI related files --- .github/workflows/build-docker.yml | 21 ++ .github/workflows/build.yml | 313 ++++++++++++++++++ engine/src/flutter/ci/tizen/.gitignore | 3 + engine/src/flutter/ci/tizen/Dockerfile | 32 ++ engine/src/flutter/ci/tizen/arm.patch | 15 + engine/src/flutter/ci/tizen/build_llvm.sh | 45 +++ .../src/flutter/ci/tizen/generate_sysroot.py | 151 +++++++++ 7 files changed, 580 insertions(+) create mode 100644 .github/workflows/build-docker.yml create mode 100644 .github/workflows/build.yml create mode 100644 engine/src/flutter/ci/tizen/.gitignore create mode 100644 engine/src/flutter/ci/tizen/Dockerfile create mode 100644 engine/src/flutter/ci/tizen/arm.patch create mode 100755 engine/src/flutter/ci/tizen/build_llvm.sh create mode 100755 engine/src/flutter/ci/tizen/generate_sysroot.py diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml new file mode 100644 index 0000000000000..62267c3bbf820 --- /dev/null +++ b/.github/workflows/build-docker.yml @@ -0,0 +1,21 @@ +name: Build Docker + +on: [workflow_dispatch] + +jobs: + builder: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/build-push-action@v5 + with: + context: ci/tizen + file: ci/tizen/Dockerfile + push: true + tags: ghcr.io/${{ github.repository_owner }}/build-engine:latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000000..34d2bdd939119 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,313 @@ +name: Build + +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + container: + image: ghcr.io/flutter-tizen/build-engine:latest + credentials: + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + strategy: + matrix: + arch: [arm, arm64, x86] + mode: [debug, release, profile] + include: + - arch: arm + triple: arm-linux-gnueabi + - arch: arm64 + triple: aarch64-linux-gnu + - arch: x86 + triple: i686-linux-gnu + exclude: + - arch: x86 + mode: release + - arch: x86 + mode: profile + + steps: + - uses: actions/checkout@v4 + with: + path: flutter + fetch-depth: 1 + + - uses: actions/cache@v4 + with: + path: /tizen_tools/sysroot + key: sysroot + + - name: Install depot_tools + run: | + git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git + echo "$PWD/depot_tools" >> $GITHUB_PATH + export PATH="$PWD/depot_tools:$PATH" + # Install ninja + apt install ninja-build + + - name: Run gclient sync + run: | + cd flutter + gclient config --unmanaged https://github.com/flutter-tizen/flutter + sed -i "s/'flutter'/'.'/g" ./.gclient + gclient setdep --var=download_dart_sdk=False --var=download_android_deps=False --var=download_fuchsia_deps=False --deps-file=DEPS + gclient sync -v --no-history --shallow + + - name: Generate sysroot + run: flutter/engine/src/flutter/ci/tizen/generate_sysroot.py --out /tizen_tools/sysroot + + - name: Build + run: | + cd flutter + # Ignore unsupported linker option. + sed -i "/-Wl,--undefined-version/d" engine/src/build/config/compiler/BUILD.gn + + engine/src/flutter/tools/gn \ + --target-os linux \ + --linux-cpu ${{ matrix.arch }} \ + --no-goma \ + --target-toolchain /tizen_tools/toolchains \ + --target-sysroot /tizen_tools/sysroot/${{ matrix.arch }} \ + --target-triple ${{ matrix.triple }} \ + --runtime-mode ${{ matrix.mode }} \ + --enable-fontconfig \ + --disable-desktop-embeddings \ + --target-dir build + cd engine/src + ninja -C out/build flutter_engine_library + cp -f flutter/third_party/icu/flutter/icudtl.dat out/build + + - name: Build gen_snapshot + if: ${{ matrix.mode != 'debug' }} + run: | + cd flutter + ninja -C engine/src/out/build clang_x64/gen_snapshot + + - uses: actions/upload-artifact@v4 + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }} + path: | + flutter/engine/src/out/build/libflutter_engine.so + flutter/engine/src/out/build/icudtl.dat + if-no-files-found: error + + - uses: actions/upload-artifact@v4 + if: ${{ github.event_name == 'push' }} + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_symbols + path: flutter/engine/src/out/build/so.unstripped/libflutter_engine.so + if-no-files-found: error + + - uses: actions/upload-artifact@v4 + if: ${{ matrix.mode != 'debug' }} + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_linux-x64 + path: flutter/engine/src/out/build/clang_x64/gen_snapshot + if-no-files-found: error + + windows-build: + runs-on: windows-latest + + strategy: + matrix: + arch: [arm, arm64] + mode: [release, profile] + + steps: + - name: Run git checkout + run: | + mkdir C:\workspace\flutter + cd C:\workspace\flutter + git config --global core.autocrlf true + git init --quiet + git remote add origin https://github.com/${{ github.repository }} + git fetch --depth 1 origin ${{ github.sha }} + git checkout FETCH_HEAD + + - name: Environment setup + run: | + Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -Force + echo "DEPOT_TOOLS_WIN_TOOLCHAIN=0" >> $Env:GITHUB_ENV + echo "GYP_MSVS_OVERRIDE_PATH=C:\Program Files\Microsoft Visual Studio\2022\Enterprise" >> $Env:GITHUB_ENV + echo "WINDOWSSDKDIR=C:\Program Files (x86)\Windows Kits\10" >> $Env:GITHUB_ENV + + - name: Install depot_tools + run: | + Invoke-WebRequest -Uri https://storage.googleapis.com/chrome-infra/depot_tools.zip -OutFile depot_tools.zip + 7z x -y -o"C:\workspace\depot_tools" .\depot_tools.zip + echo "C:\workspace\depot_tools" >> $Env:GITHUB_PATH + + - name: Run gclient sync + working-directory: C:\workspace\flutter + shell: powershell + run: | + gclient config --unmanaged https://github.com/flutter-tizen/flutter + (Get-Content ".gclient") | ForEach-Object { $_ -replace "'flutter'","'.'" } | Set-Content ".gclient" + # TODO(jsuya) : pipes deprecated in python 3.13. (https://dart-review.googlesource.com/c/sdk/+/307620) + (Get-Content "engine/src/build/vs_toolchain.py") | ForEach-Object { $_ -replace 'import pipes','' } | Set-Content "engine/src/build/vs_toolchain.py" + gclient setdep --var=download_dart_sdk=False --var=download_android_deps=False --var=download_fuchsia_deps=False --deps-file=DEPS + gclient sync -v --no-history --shallow + + - name: Build + working-directory: C:\workspace\flutter\engine\src + run: | + python3 .\flutter\tools\gn ` + --linux ` + --linux-cpu=${{ matrix.arch }} ` + --runtime-mode=${{ matrix.mode }} ` + --no-goma ` + --target-dir build + # TODO(jsuya) : https://github.com/flutter/flutter/issues/163487 + C:\workspace\flutter\engine\src\flutter/third_party/ninja/ninja -C .\out\build gen_snapshot + + - uses: actions/upload-artifact@v4 + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_windows-x64 + path: C:\workspace\flutter\engine\src\out\build\gen_snapshot.exe + if-no-files-found: error + + macos-build: + runs-on: macos-latest + + strategy: + matrix: + arch: [arm, arm64] + mode: [release, profile] + + steps: + - uses: actions/checkout@v4 + with: + path: flutter + fetch-depth: 1 + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install depot_tools + run: | + git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git + echo "$PWD/depot_tools" >> $GITHUB_PATH + + - name: Run gclient sync + run: | + cd flutter + gclient config --unmanaged https://github.com/flutter-tizen/flutter + sed -i '' "s/'flutter'/'.'/g" .gclient + gclient setdep --var=download_dart_sdk=False --var=download_android_deps=False --var=download_fuchsia_deps=False --deps-file=DEPS + gclient sync -v --no-history --shallow + + - name: Build + run: | + cd flutter + # Change host_toolchain to mac/clang_arm64. + sed -i "" "s|//build/toolchain/linux:clang_$host_cpu|//build/toolchain/mac:clang_$host_cpu|g" engine/src/build/config/BUILDCONFIG.gn + + # Pass dummy values to prevent using the default (Linux) toolchain. + engine/src/flutter/tools/gn \ + --linux \ + --linux-cpu=${{ matrix.arch }} \ + --no-goma \ + --target-toolchain _ \ + --target-sysroot _ \ + --target-triple _ \ + --runtime-mode=${{ matrix.mode }} \ + --disable-desktop-embeddings \ + --target-dir build + cd engine/src + # TODO(jsuya) : https://github.com/flutter/flutter/issues/163487 + flutter/third_party/ninja/ninja -C out/build clang_arm64/gen_snapshot + + - uses: actions/upload-artifact@v4 + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_darwin-arm64 + path: flutter/engine/src/out/build/clang_arm64/gen_snapshot + if-no-files-found: error + + macos-intel-build: + runs-on: macos-13 + + strategy: + matrix: + arch: [arm, arm64] + mode: [release, profile] + + steps: + - uses: actions/checkout@v4 + with: + path: flutter + fetch-depth: 1 + + - uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Install depot_tools + run: | + git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git + echo "$PWD/depot_tools" >> $GITHUB_PATH + + - name: Run gclient sync + run: | + cd flutter + gclient config --unmanaged https://github.com/flutter-tizen/flutter + sed -i '' "s/'flutter'/'.'/g" .gclient + gclient setdep --var=download_dart_sdk=False --var=download_android_deps=False --var=download_fuchsia_deps=False --deps-file=DEPS + gclient sync -v --no-history --shallow + + - name: Build + run: | + cd flutter + # Change host_toolchain to mac/clang_x64. + sed -i "" "s|//build/toolchain/linux:clang_$host_cpu|//build/toolchain/mac:clang_$host_cpu|g" engine/src/build/config/BUILDCONFIG.gn + + # Pass dummy values to prevent using the default (Linux) toolchain. + engine/src/flutter/tools/gn \ + --linux \ + --linux-cpu=${{ matrix.arch }} \ + --no-goma \ + --target-toolchain _ \ + --target-sysroot _ \ + --target-triple _ \ + --runtime-mode=${{ matrix.mode }} \ + --disable-desktop-embeddings \ + --target-dir build + cd engine/src + # TODO(jsuya) : https://github.com/flutter/flutter/issues/163487 + flutter/third_party/ninja/ninja -C out/build clang_x64/gen_snapshot + + - uses: actions/upload-artifact@v4 + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_darwin-x64 + path: flutter/engine/src/out/build/clang_x64/gen_snapshot + if-no-files-found: error + + release: + needs: [build] + if: ${{ github.event_name == 'push' }} + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + + - name: Create archives + run: | + for name in tizen-*; do + 7z a $name.zip ./$name/* + done + + - name: Set variables + run: | + echo "SHORT_SHA=$(git rev-parse --short $GITHUB_SHA)" >> $GITHUB_ENV + echo "VERSION=$(echo "${{ github.ref_name }}" | cut -d'-' -f2)" >> $GITHUB_ENV + + - uses: softprops/action-gh-release@v2 + with: + name: ${{ env.VERSION }} (${{ env.SHORT_SHA }}) + tag_name: ${{ env.SHORT_SHA }} + target_commitish: ${{ github.sha }} + files: tizen-*.zip + body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} diff --git a/engine/src/flutter/ci/tizen/.gitignore b/engine/src/flutter/ci/tizen/.gitignore new file mode 100644 index 0000000000000..c23e7e850155f --- /dev/null +++ b/engine/src/flutter/ci/tizen/.gitignore @@ -0,0 +1,3 @@ +/llvm-project*/ +/toolchains*/ +/sysroot/ diff --git a/engine/src/flutter/ci/tizen/Dockerfile b/engine/src/flutter/ci/tizen/Dockerfile new file mode 100644 index 0000000000000..f5d0f1fc5520f --- /dev/null +++ b/engine/src/flutter/ci/tizen/Dockerfile @@ -0,0 +1,32 @@ +############################### +### Stage for building LLVM ### +############################### + +FROM ubuntu:22.04 AS llvm + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y git zip build-essential cmake ninja-build clang-11 && \ + apt-get clean + +COPY build_llvm.sh . + +RUN /build_llvm.sh + + +############################## +### Create a release image ### +############################## + +FROM ubuntu:22.04 + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && \ + apt-get install -y binutils-arm-linux-gnueabi binutils-aarch64-linux-gnu binutils-i686-linux-gnu && \ + apt-get install -y git curl pkg-config ca-certificates python3 python3-pip rpm2cpio cpio && \ + apt-get clean + +# Copy build artifacts from the previous stage. +COPY --from=llvm /toolchains/ /tizen_tools/toolchains/ diff --git a/engine/src/flutter/ci/tizen/arm.patch b/engine/src/flutter/ci/tizen/arm.patch new file mode 100644 index 0000000000000..1dabb3f2803d4 --- /dev/null +++ b/engine/src/flutter/ci/tizen/arm.patch @@ -0,0 +1,15 @@ +diff --git a/usr/include/asm-arm/hwcap.h b/usr/include/asm-arm/hwcap.h +index da85060..adaf619 100644 +--- a/usr/include/asm-arm/hwcap.h ++++ b/usr/include/asm-arm/hwcap.h +@@ -26,5 +26,10 @@ + #define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ + #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) + ++#define HWCAP2_AES (1 << 0) ++#define HWCAP2_PMULL (1 << 1) ++#define HWCAP2_SHA1 (1 << 2) ++#define HWCAP2_SHA2 (1 << 3) ++#define HWCAP2_CRC32 (1 << 4) + + #endif /* __ASMARM_HWCAP_H */ diff --git a/engine/src/flutter/ci/tizen/build_llvm.sh b/engine/src/flutter/ci/tizen/build_llvm.sh new file mode 100755 index 0000000000000..507395cea8363 --- /dev/null +++ b/engine/src/flutter/ci/tizen/build_llvm.sh @@ -0,0 +1,45 @@ +#!/bin/bash +# Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +set -e + +SCRIPT_DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +OUTPUT_DIR="$SCRIPT_DIR/toolchains" +cd "$SCRIPT_DIR" + +# Check out the LLVM project source code. +if [ -d llvm-project ]; then + echo "The directory already exists. Skipping download." + cd llvm-project +else + mkdir llvm-project + cd llvm-project + git init + git remote add origin https://github.com/llvm/llvm-project.git + git fetch --depth=1 origin llvmorg-17.0.6 + git checkout FETCH_HEAD +fi + +# Run the ninja build. +mkdir -p build && cd build +cmake -G Ninja \ + -DCLANG_VENDOR="Tizen" \ + -DLLVM_ENABLE_PROJECTS="clang" \ + -DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" \ + -DCMAKE_C_COMPILER=clang-11 \ + -DCMAKE_CXX_COMPILER=clang++-11 \ + -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX="$OUTPUT_DIR" \ + ../llvm +ninja install -j$(nproc) + +# Create symbolic links to binutils. +# See build/toolchain/custom/BUILD.gn for more information. +cd "$OUTPUT_DIR/bin" +for name in ar readelf nm strip; do + ln -sf llvm-$name arm-linux-gnueabi-$name + ln -sf llvm-$name aarch64-linux-gnu-$name + ln -sf llvm-$name i686-linux-gnu-$name +done diff --git a/engine/src/flutter/ci/tizen/generate_sysroot.py b/engine/src/flutter/ci/tizen/generate_sysroot.py new file mode 100755 index 0000000000000..c4bdc51f347cf --- /dev/null +++ b/engine/src/flutter/ci/tizen/generate_sysroot.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# Copyright 2022 Samsung Electronics Co., Ltd. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import argparse +import os +import re +import shutil +import subprocess +import sys +import urllib.parse +import urllib.request +from pathlib import Path + +base_packages = [ + 'gcc', + 'glibc', + 'glibc-devel', + 'libgcc', + 'libstdc++', + 'linux-glibc-devel', + 'zlib-devel', +] + +unified_packages = [ + 'fontconfig', + 'fontconfig-devel', + 'freetype2-devel', + 'libpng-devel', +] + + +def generate_sysroot(sysroot: Path, api_version: float, arch: str, quiet=False): + if arch == 'arm': + tizen_arch = 'armv7l' + elif arch == 'arm64': + tizen_arch = 'aarch64' + elif arch == 'x86': + tizen_arch = 'i686' + else: + sys.exit('Unknown arch: ' + arch) + + base_repo = 'http://download.tizen.org/snapshots/TIZEN/Tizen-{}/Tizen-{}-Base/latest/repos/standard/packages'.format( + api_version, api_version + ) + unified_repo = 'http://download.tizen.org/snapshots/TIZEN/Tizen-{}/Tizen-{}-Unified/latest/repos/standard/packages'.format( + api_version, api_version + ) + + # Retrieve html documents. + documents = {} + for url in ['{}/{}'.format(base_repo, tizen_arch), '{}/{}'.format(base_repo, 'noarch'), + '{}/{}'.format(unified_repo, tizen_arch), '{}/{}'.format(unified_repo, 'noarch')]: + request = urllib.request.Request(url) + with urllib.request.urlopen(request) as response: + documents[url] = response.read().decode('utf-8') + + # Download packages. + download_path = sysroot / '.rpms' + download_path.mkdir(exist_ok=True) + existing_rpms = [f for f in download_path.iterdir() if f.suffix == '.rpm'] + + for package in base_packages + unified_packages: + quoted = urllib.parse.quote(package) + pattern = re.escape(quoted) + '-\\d+\\.[\\d_\\.]+-[\\d\\.]+\\..+\\.rpm' + + if any([re.match(pattern, rpm.name) for rpm in existing_rpms]): + continue + + for parent, doc in documents.items(): + match = re.search('.+?'.format(pattern), doc) + if match: + rpm_url = '{}/{}'.format(parent, match.group(1)) + break + + if match: + if not quiet: + print('Downloading ' + rpm_url) + urllib.request.urlretrieve(rpm_url, download_path / match.group(1)) + else: + sys.exit('Could not find a package named ' + package) + + # Extract files. + for rpm in [f for f in download_path.iterdir() if f.suffix == '.rpm']: + command = 'rpm2cpio {} | cpio -idum --quiet'.format(rpm) + subprocess.run(command, shell=True, cwd=sysroot, check=True) + + # Create symbolic links. + asm = sysroot / 'usr' / 'include' / 'asm' + if not asm.exists(): + os.symlink('asm-' + arch, asm) + pkgconfig = sysroot / 'usr' / 'lib' / 'pkgconfig' + if arch == 'arm64' and not pkgconfig.exists(): + os.symlink('../lib64/pkgconfig', pkgconfig) + + # Copy objects required by the linker, such as crtbeginS.o and libgcc.a. + if arch == 'arm64': + libpath = sysroot / 'usr' / 'lib64' + else: + libpath = sysroot / 'usr' / 'lib' + subprocess.run('cp gcc/*/*/*.o gcc/*/*/*.a .', shell=True, cwd=libpath, check=True) + + # Apply a patch if applicable. + patch = Path(__file__).parent / '{}.patch'.format(arch) + if patch.is_file(): + command = 'patch -p1 -s -d {} < {}'.format(sysroot, patch) + subprocess.run(command, shell=True, check=True) + + +def main(): + # Check dependencies. + for dep in ['rpm2cpio', 'cpio', 'git']: + if not shutil.which(dep): + sys.exit('{} is not installed. To install, run:\n' + ' sudo apt install {}'.format(dep, dep)) + + # Parse arguments. + parser = argparse.ArgumentParser(description='Tizen sysroot generator') + parser.add_argument('-o', '--out', metavar='PATH', type=str, help='Path to the output directory') + parser.add_argument('-f', '--force', action='store_true', help='Force re-downloading of packages') + parser.add_argument('-q', '--quiet', action='store_true', help='Suppress log output') + parser.add_argument( + '--api-version', + metavar='VER', + default=6.0, + type=float, + help='Target API version (defaults to 6.0)' + ) + args = parser.parse_args() + + if args.out: + outpath = Path(args.out) + else: + outpath = Path(__file__).parent / 'sysroot' + outpath.mkdir(exist_ok=True) + + for arch in ['arm', 'arm64', 'x86']: + sysroot = outpath / arch + if args.force and sysroot.is_dir(): + shutil.rmtree(sysroot) + sysroot.mkdir(exist_ok=True) + + if not args.quiet: + print('Generating sysroot for {}...'.format(arch)) + generate_sysroot(sysroot.resolve(), args.api_version, arch, args.quiet) + + +# Execute only if run as a script. +if __name__ == '__main__': + main() From b6bbae164d853b2c15ec7a1804bf34e3c7496fa4 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 12 Mar 2025 12:56:12 +0900 Subject: [PATCH 03/21] [Tizen][impeller] Disable gles3 compile --- engine/src/flutter/impeller/tools/shaders.gni | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/engine/src/flutter/impeller/tools/shaders.gni b/engine/src/flutter/impeller/tools/shaders.gni index 98aa5a7932170..ddacd814a83bb 100644 --- a/engine/src/flutter/impeller/tools/shaders.gni +++ b/engine/src/flutter/impeller/tools/shaders.gni @@ -122,22 +122,6 @@ template("impeller_shaders") { analyze = analyze } } - - gles3_shaders = "gles3_$target_name" - - impeller_shaders_gles(gles3_shaders) { - name = invoker.name - require_framebuffer_fetch = require_framebuffer_fetch - gles_language_version = 300 - is_300 = true - analyze = false - if (defined(invoker.gles_exclusions)) { - shaders = invoker.shaders - invoker.gles_exclusions - } else { - shaders = invoker.shaders - } - analyze = analyze - } } if (impeller_enable_vulkan) { @@ -171,12 +155,7 @@ template("impeller_shaders") { } if (enable_opengles) { - public_deps += [ ":$gles3_shaders" ] - - # wasm builds only use GLES3, no need to build GLES2 shaders - if (!is_wasm) { - public_deps += [ ":$gles_shaders" ] - } + public_deps += [ ":$gles_shaders" ] } if (impeller_enable_vulkan) { From 81aa8906a57aa946aba19db847e07e5df2e43b7f Mon Sep 17 00:00:00 2001 From: Xiaowei Guan Date: Tue, 18 Mar 2025 15:03:44 +0900 Subject: [PATCH 04/21] [Tizen] Support EmbedderExternalTextureGL for impeller --- .../shell/platform/embedder/embedder.h | 9 ++- .../embedder/embedder_external_texture_gl.cc | 79 ++++++++++++++++--- .../embedder/embedder_external_texture_gl.h | 8 ++ 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index 00900d8f39b08..61bac5028417a 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -407,6 +407,7 @@ typedef struct { } FlutterTransformation; typedef void (*VoidCallback)(void* /* user data */); +typedef bool (*BoolCallback)(void* /* user data */); typedef enum { /// Specifies an OpenGL texture target type. Textures are specified using @@ -514,6 +515,13 @@ typedef struct { uint32_t name; /// The texture format (example GL_RGBA8). uint32_t format; + /// The pixel data buffer. + const uint8_t* buffer; + /// The size of pixel buffer. + size_t buffer_size; + /// Callback invoked that the gpu surface texture start binding. + BoolCallback bind_callback; + /// User data to be returned on the invocation of the destruction callback. void* user_data; /// Callback invoked (on an engine managed thread) that asks the embedder to @@ -607,7 +615,6 @@ typedef struct { uint32_t format; } FlutterOpenGLSurface; -typedef bool (*BoolCallback)(void* /* user data */); typedef FlutterTransformation (*TransformationCallback)(void* /* user data */); typedef uint32_t (*UIntCallback)(void* /* user data */); typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */, diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index fe81731aff0d5..1a627ec864516 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -138,15 +138,73 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( return nullptr; } + if (texture->bind_callback != nullptr) { + return ResolveTextureImpellerSurface(aiks_context, std::move(texture)); + } else { + return ResolveTextureImpellerPixelbuffer(aiks_context, std::move(texture)); + } +} + +sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer( + impeller::AiksContext* aiks_context, + std::unique_ptr texture) { impeller::TextureDescriptor desc; desc.size = impeller::ISize(texture->width, texture->height); + desc.type = impeller::TextureType::kTexture2D; + desc.storage_mode = impeller::StorageMode::kDevicePrivate; + desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + impeller::ContextGLES& context = + impeller::ContextGLES::Cast(*aiks_context->GetContext()); + std::shared_ptr image = + std::make_shared(context.GetReactor(), desc); + + image->MarkContentsInitialized(); + if (!image->SetContents(texture->buffer, texture->buffer_size)) { + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return nullptr; + } + if (!image) { + // In case Skia rejects the image, call the release proc so that + // embedders can perform collection of intermediates. + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + FML_LOG(ERROR) << "Could not create external texture"; + return nullptr; + } + + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + + return impeller::DlImageImpeller::Make(image); +} + +sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerSurface( + impeller::AiksContext* aiks_context, + std::unique_ptr texture) { + impeller::TextureDescriptor desc; + desc.size = impeller::ISize(texture->width, texture->height); + desc.storage_mode = impeller::StorageMode::kDevicePrivate; + desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + desc.type = impeller::TextureType::kTextureExternalOES; impeller::ContextGLES& context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); - impeller::HandleGLES handle = context.GetReactor()->CreateHandle( - impeller::HandleType::kTexture, texture->target); std::shared_ptr image = - impeller::TextureGLES::WrapTexture(context.GetReactor(), desc, handle); + std::make_shared(context.GetReactor(), desc); + image->MarkContentsInitialized(); + image->SetCoordinateSystem( + impeller::TextureCoordinateSystem::kUploadFromHost); + if (!image->Bind()) { + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + FML_LOG(ERROR) << "Could not bind texture"; + return nullptr; + } if (!image) { // In case Skia rejects the image, call the release proc so that @@ -157,15 +215,18 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( FML_LOG(ERROR) << "Could not create external texture"; return nullptr; } - if (texture->destruction_callback && - !context.GetReactor()->RegisterCleanupCallback( - handle, - [callback = texture->destruction_callback, - user_data = texture->user_data]() { callback(user_data); })) { - FML_LOG(ERROR) << "Could not register destruction callback"; + + if (!texture->bind_callback(texture->user_data)) { + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } return nullptr; } + if (texture->destruction_callback) { + texture->destruction_callback(texture->user_data); + } + return impeller::DlImageImpeller::Make(image); } diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h index 7dbc631d56ad1..6ecb6843208d1 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h @@ -39,6 +39,14 @@ class EmbedderExternalTextureGL : public flutter::Texture { impeller::AiksContext* aiks_context, const SkISize& size); + sk_sp ResolveTextureImpellerPixelbuffer( + impeller::AiksContext* aiks_context, + std::unique_ptr texture); + + sk_sp ResolveTextureImpellerSurface( + impeller::AiksContext* aiks_context, + std::unique_ptr texture); + // |flutter::Texture| void Paint(PaintContext& context, const DlRect& bounds, From 065319253760bff92f16dd58fbecc27c2fea60a2 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 23 May 2025 17:47:47 +0900 Subject: [PATCH 05/21] [Tizen] Remove unnecessary CI --- .github/workflows/mirror.yml | 28 ---------------------------- 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/mirror.yml diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml deleted file mode 100644 index a568c78265469..0000000000000 --- a/.github/workflows/mirror.yml +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2013 The Flutter Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Mirror master to main branches in the flutter repository. -on: - push: - branches: - - 'master' - -# Declare default permissions as read only. -permissions: read-all - -jobs: - mirror_job: - permissions: - pull-requests: write - runs-on: ubuntu-latest - if: ${{ github.repository == 'flutter/flutter' }} - name: Mirror master branch to main branch - steps: - - name: Mirror action step - id: mirror - uses: google/mirror-branch-action@30c52ee21f5d3bd7fb28b95501c11aae7f17eebb - with: - github-token: ${{ secrets.FLUTTERMIRRORINGBOT_TOKEN }} - source: 'master' - dest: 'main' From f715ecb00fd2aca8d330e6c714313ea0bf6ab843 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 23 May 2025 17:51:34 +0900 Subject: [PATCH 06/21] [Tizen] Upgrade llvm 17 to 18 --- .github/workflows/build-docker.yml | 4 ++-- .github/workflows/build.yml | 15 ++++++++------- engine/src/flutter/ci/tizen/build_llvm.sh | 3 ++- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml index 62267c3bbf820..d15fb0f88456b 100644 --- a/.github/workflows/build-docker.yml +++ b/.github/workflows/build-docker.yml @@ -15,7 +15,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - uses: docker/build-push-action@v5 with: - context: ci/tizen - file: ci/tizen/Dockerfile + context: engine/src/flutter/ci/tizen + file: engine/src/flutter/ci/tizen/Dockerfile push: true tags: ghcr.io/${{ github.repository_owner }}/build-engine:latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 34d2bdd939119..61fd921e209ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -119,7 +119,11 @@ jobs: run: | mkdir C:\workspace\flutter cd C:\workspace\flutter - git config --global core.autocrlf true + git config --global core.autocrlf false + git config --global core.filemode false + git config --global core.fscache true + git config --global core.preloadindex true + git config --global depot-tools.allowGlobalGitConfig true git init --quiet git remote add origin https://github.com/${{ github.repository }} git fetch --depth 1 origin ${{ github.sha }} @@ -158,8 +162,7 @@ jobs: --runtime-mode=${{ matrix.mode }} ` --no-goma ` --target-dir build - # TODO(jsuya) : https://github.com/flutter/flutter/issues/163487 - C:\workspace\flutter\engine\src\flutter/third_party/ninja/ninja -C .\out\build gen_snapshot + ninja -C .\out\build gen_snapshot - uses: actions/upload-artifact@v4 with: @@ -216,8 +219,7 @@ jobs: --disable-desktop-embeddings \ --target-dir build cd engine/src - # TODO(jsuya) : https://github.com/flutter/flutter/issues/163487 - flutter/third_party/ninja/ninja -C out/build clang_arm64/gen_snapshot + ninja -C out/build clang_arm64/gen_snapshot - uses: actions/upload-artifact@v4 with: @@ -274,8 +276,7 @@ jobs: --disable-desktop-embeddings \ --target-dir build cd engine/src - # TODO(jsuya) : https://github.com/flutter/flutter/issues/163487 - flutter/third_party/ninja/ninja -C out/build clang_x64/gen_snapshot + ninja -C out/build clang_x64/gen_snapshot - uses: actions/upload-artifact@v4 with: diff --git a/engine/src/flutter/ci/tizen/build_llvm.sh b/engine/src/flutter/ci/tizen/build_llvm.sh index 507395cea8363..7d75d9c6a4252 100755 --- a/engine/src/flutter/ci/tizen/build_llvm.sh +++ b/engine/src/flutter/ci/tizen/build_llvm.sh @@ -18,7 +18,7 @@ else cd llvm-project git init git remote add origin https://github.com/llvm/llvm-project.git - git fetch --depth=1 origin llvmorg-17.0.6 + git fetch --depth=1 origin llvmorg-18.1.8 git checkout FETCH_HEAD fi @@ -29,6 +29,7 @@ cmake -G Ninja \ -DLLVM_ENABLE_PROJECTS="clang" \ -DLLVM_TARGETS_TO_BUILD="X86;ARM;AArch64" \ -DCMAKE_C_COMPILER=clang-11 \ + -DCMAKE_CXX_FLAGS="-mssse3" \ -DCMAKE_CXX_COMPILER=clang++-11 \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX="$OUTPUT_DIR" \ From 3a9c54ea050b73bfa6732ed39cfddb78c3ab67e5 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Mon, 23 Jun 2025 10:54:44 +0900 Subject: [PATCH 07/21] [Tizen] Temporary fix to Microsoft STL compiler compatibility checks --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 61fd921e209ed..0beee16550bbb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -150,6 +150,10 @@ jobs: (Get-Content ".gclient") | ForEach-Object { $_ -replace "'flutter'","'.'" } | Set-Content ".gclient" # TODO(jsuya) : pipes deprecated in python 3.13. (https://dart-review.googlesource.com/c/sdk/+/307620) (Get-Content "engine/src/build/vs_toolchain.py") | ForEach-Object { $_ -replace 'import pipes','' } | Set-Content "engine/src/build/vs_toolchain.py" + + # TODO(jsuya) : Temporary fix to Microsoft STL compiler compatibility checks(https://github.com/flutter-tizen/flutter-tizen/pull/635#issuecomment-2990206946) + (Get-Content "engine/src/build/config/compiler/BUILD.gn") | ForEach-Object { $_; if ($_.Trim() -eq '"__STD_C",') { ' "_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH",' } } | Set-Content "engine/src/build/config/compiler/BUILD.gn" + gclient setdep --var=download_dart_sdk=False --var=download_android_deps=False --var=download_fuchsia_deps=False --deps-file=DEPS gclient sync -v --no-history --shallow From fa368b8896caab431ac911812836428f8d2b7989 Mon Sep 17 00:00:00 2001 From: xiaowei guan <60122246+xiaowei-guan@users.noreply.github.com> Date: Fri, 29 Aug 2025 09:21:53 +0800 Subject: [PATCH 08/21] [Tizen] Enable vulkan (#11) --- engine/src/build_overrides/vulkan_headers.gni | 2 +- engine/src/flutter/impeller/tools/args.gni | 2 +- engine/src/flutter/shell/config.gni | 2 +- engine/src/flutter/tools/gn | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/src/build_overrides/vulkan_headers.gni b/engine/src/build_overrides/vulkan_headers.gni index 8ef7d23936589..8a4144db207b6 100644 --- a/engine/src/build_overrides/vulkan_headers.gni +++ b/engine/src/build_overrides/vulkan_headers.gni @@ -6,6 +6,6 @@ # set anything. if (is_linux) { - vulkan_use_x11 = !is_minimal_linux + vulkan_use_x11 = false vulkan_use_wayland = true } diff --git a/engine/src/flutter/impeller/tools/args.gni b/engine/src/flutter/impeller/tools/args.gni index 2759a69136c9f..4be3a3d64eb8c 100644 --- a/engine/src/flutter/impeller/tools/args.gni +++ b/engine/src/flutter/impeller/tools/args.gni @@ -18,7 +18,7 @@ declare_args() { enable_unittests) && target_os != "fuchsia" # Whether the Vulkan backend is enabled. - impeller_enable_vulkan = (is_win || is_android || is_mac || + impeller_enable_vulkan = (is_linux || is_win || is_android || is_mac || enable_unittests) && target_os != "fuchsia" } diff --git a/engine/src/flutter/shell/config.gni b/engine/src/flutter/shell/config.gni index 9ad466439ee2e..8aa62e02417ba 100644 --- a/engine/src/flutter/shell/config.gni +++ b/engine/src/flutter/shell/config.gni @@ -7,7 +7,7 @@ declare_args() { # The logic for enabling Vulkan and Metal is in tools/gn. shell_enable_metal = false - shell_enable_vulkan = false + shell_enable_vulkan = true shell_enable_software = true } diff --git a/engine/src/flutter/tools/gn b/engine/src/flutter/tools/gn index edd73a4c0f418..3de39014d3507 100755 --- a/engine/src/flutter/tools/gn +++ b/engine/src/flutter/tools/gn @@ -654,7 +654,7 @@ def to_gn_args(args): # Enable Vulkan on all platforms except for iOS. This is just # to save on mobile binary size, as there's no reason the Vulkan embedder # features can't work on these platforms. - if gn_args['target_os'] not in ['ios', 'mac', 'linux']: + if gn_args['target_os'] not in ['ios', 'mac']: gn_args['skia_use_vulkan'] = True gn_args['skia_use_vma'] = False gn_args['shell_enable_vulkan'] = True From 3a978c74824bf51778577f513ed69e5a3cf24f83 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 12 Sep 2025 12:06:23 +0900 Subject: [PATCH 09/21] [Tizen] Add x64 release (#13) flutter-tizen/flutter-tizen#554 Added x64 artifacts for x64 emulator support (Currently, x64 Release mode is only supported on Linux hosts.) --- .github/workflows/build.yml | 41 +++++++++++++++++++++-- engine/src/flutter/ci/tizen/build_llvm.sh | 1 + engine/src/flutter/testing/testing.gni | 3 +- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0beee16550bbb..e828f82a2b2a3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - arch: [arm, arm64, x86] + arch: [arm, arm64, x86, x64] mode: [debug, release, profile] include: - arch: arm @@ -21,6 +21,8 @@ jobs: triple: aarch64-linux-gnu - arch: x86 triple: i686-linux-gnu + - arch: x64 + triple: x86_64-linux-gnu exclude: - arch: x86 mode: release @@ -58,6 +60,7 @@ jobs: run: flutter/engine/src/flutter/ci/tizen/generate_sysroot.py --out /tizen_tools/sysroot - name: Build + if: ${{ matrix.arch != 'x64' }} run: | cd flutter # Ignore unsupported linker option. @@ -78,12 +81,37 @@ jobs: ninja -C out/build flutter_engine_library cp -f flutter/third_party/icu/flutter/icudtl.dat out/build + - name: Build(x64) + if: ${{ matrix.arch == 'x64' }} + run: | + cd flutter + + engine/src/flutter/tools/gn \ + --target-os linux \ + --linux-cpu ${{ matrix.arch }} \ + --no-goma \ + --target-triple ${{ matrix.triple }} \ + --runtime-mode ${{ matrix.mode }} \ + --enable-fontconfig \ + --disable-desktop-embeddings \ + --target-dir build + + cd engine/src + ninja -C out/build flutter_engine_library + cp -f flutter/third_party/icu/flutter/icudtl.dat out/build + - name: Build gen_snapshot - if: ${{ matrix.mode != 'debug' }} + if: ${{ matrix.mode != 'debug' && matrix.arch != 'x64'}} run: | cd flutter ninja -C engine/src/out/build clang_x64/gen_snapshot + - name: Build gen_snapshot(x64) + if: ${{ matrix.mode != 'debug' && matrix.arch == 'x64'}} + run: | + cd flutter + ninja -C engine/src/out/build gen_snapshot + - uses: actions/upload-artifact@v4 with: name: tizen-${{ matrix.arch }}-${{ matrix.mode }} @@ -100,12 +128,19 @@ jobs: if-no-files-found: error - uses: actions/upload-artifact@v4 - if: ${{ matrix.mode != 'debug' }} + if: ${{ matrix.mode != 'debug' && matrix.arch != 'x64'}} with: name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_linux-x64 path: flutter/engine/src/out/build/clang_x64/gen_snapshot if-no-files-found: error + - uses: actions/upload-artifact@v4 + if: ${{ matrix.mode != 'debug' && matrix.arch == 'x64'}} + with: + name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_linux-x64 + path: flutter/engine/src/out/build/gen_snapshot + if-no-files-found: error + windows-build: runs-on: windows-latest diff --git a/engine/src/flutter/ci/tizen/build_llvm.sh b/engine/src/flutter/ci/tizen/build_llvm.sh index 7d75d9c6a4252..de27efb73a9b6 100755 --- a/engine/src/flutter/ci/tizen/build_llvm.sh +++ b/engine/src/flutter/ci/tizen/build_llvm.sh @@ -43,4 +43,5 @@ for name in ar readelf nm strip; do ln -sf llvm-$name arm-linux-gnueabi-$name ln -sf llvm-$name aarch64-linux-gnu-$name ln -sf llvm-$name i686-linux-gnu-$name + ln -sf llvm-$name x86_64-linux-gnu-$name done diff --git a/engine/src/flutter/testing/testing.gni b/engine/src/flutter/testing/testing.gni index 5ead3d22e922c..c25746c779cec 100644 --- a/engine/src/flutter/testing/testing.gni +++ b/engine/src/flutter/testing/testing.gni @@ -15,7 +15,8 @@ declare_args() { # * host_toolchain: non-cross-compile. We can run tests on the host. # * Fuchsia: build unittests for testing on device. # * macOS: arm64 builds can run x64 binaries. - enable_unittests = current_toolchain == host_toolchain || is_fuchsia || is_mac + # Disable unit test + enable_unittests = false # Build iOS target device unit tests. # From 0581237ca79ea3fbe61039bf9ea23104f8b1a163 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 17 Sep 2025 13:02:27 +0900 Subject: [PATCH 10/21] [Tizen] Disable x64 symbol generation temporary (#14) --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e828f82a2b2a3..0eb01ef09b086 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -121,7 +121,7 @@ jobs: if-no-files-found: error - uses: actions/upload-artifact@v4 - if: ${{ github.event_name == 'push' }} + if: ${{ github.event_name == 'push' && matrix.arch != 'x64' }} with: name: tizen-${{ matrix.arch }}-${{ matrix.mode }}_symbols path: flutter/engine/src/out/build/so.unstripped/libflutter_engine.so From ddc3543edbd91098f3928074ecf3348bbfdd9032 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 18 Sep 2025 17:48:28 +0900 Subject: [PATCH 11/21] [Tizen] Update sysroot download URL (#15) https://github.com/flutter-tizen/embedder/pull/118#discussion_r2357867428 --- engine/src/flutter/ci/tizen/generate_sysroot.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/flutter/ci/tizen/generate_sysroot.py b/engine/src/flutter/ci/tizen/generate_sysroot.py index c4bdc51f347cf..210f7e9ecf9e7 100755 --- a/engine/src/flutter/ci/tizen/generate_sysroot.py +++ b/engine/src/flutter/ci/tizen/generate_sysroot.py @@ -41,10 +41,10 @@ def generate_sysroot(sysroot: Path, api_version: float, arch: str, quiet=False): else: sys.exit('Unknown arch: ' + arch) - base_repo = 'http://download.tizen.org/snapshots/TIZEN/Tizen-{}/Tizen-{}-Base/latest/repos/standard/packages'.format( + base_repo = 'http://download.tizen.org/snapshots/TIZEN/Tizen-{}/Tizen-{}-Base/reference/repos/standard/packages'.format( api_version, api_version ) - unified_repo = 'http://download.tizen.org/snapshots/TIZEN/Tizen-{}/Tizen-{}-Unified/latest/repos/standard/packages'.format( + unified_repo = 'http://download.tizen.org/snapshots/TIZEN/Tizen-{}/Tizen-{}-Unified/reference/repos/standard/packages'.format( api_version, api_version ) From 4a1aeb01d505af5b1cf6a9bc6dc4f6b54433dac1 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 19 Sep 2025 18:15:14 +0900 Subject: [PATCH 12/21] [ci] Fix window version to 2022 flutter engine's window build uses Window SDKs 10.0.22621.0. window-2025 runner in gitHub actions no longer supports the 10.0.22621.0 SDK. --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0eb01ef09b086..cb97449ae2e30 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -142,7 +142,7 @@ jobs: if-no-files-found: error windows-build: - runs-on: windows-latest + runs-on: windows-2022 strategy: matrix: From 13aba5f581489403abc34db8b6f6f1f8f668d543 Mon Sep 17 00:00:00 2001 From: xiaowei guan <60122246+xiaowei-guan@users.noreply.github.com> Date: Sat, 11 Oct 2025 10:42:02 +0800 Subject: [PATCH 13/21] [Tizen] Support render texture for vulkan + impeller (#17) Add new struct FlutterVulkanTexture for embedder : ``` typedef struct { /// Handle to the VkImage that is owned by the embedder. The engine will /// bind this image for writing the frame. FlutterVulkanImageHandle image; /// The VkDeviceMemory that backs the iamge. FlutterVulkanDeviceMemoryHandle image_memory; /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). uint32_t format; /// User data to be returned on the invocation of the destruction callback. void* user_data; /// Callback invoked (on an engine managed thread) that asks the embedder to /// collect the texture. VoidCallback destruction_callback; /// Optional parameters for texture height/width, default is 0, non-zero means /// the texture has the specified width/height. /// Width of the texture. size_t width; /// Height of the texture. size_t height; } FlutterVulkanTexture; ``` The implement of [texture source](https://github.com/flutter-tizen/flutter/pull/17/files#diff-7955a8522a753162869f2e8ca0017a83f4854b60800c844202e70c3aa00ff0c9R5-R204) refer to the solution of android platform(https://github.com/flutter-tizen/flutter/blob/flutter-3.35.3/engine/src/flutter/impeller/renderer/backend/vulkan/android/ahb_texture_source_vk.cc) and I have submitted the code [Support render texture for embedder](https://github.com/xiaowei-guan/embedder/commit/6a94746b5a006730e6f5280d5a4fecf8eef53b4d), I will create a new PR after[ support vulkan backend](https://github.com/flutter-tizen/embedder/pull/110) PR released. --- .../flutter/shell/platform/embedder/BUILD.gn | 4 + .../shell/platform/embedder/embedder.cc | 21 ++ .../shell/platform/embedder/embedder.h | 39 +++- .../embedder_external_texture_resolver.cc | 19 ++ .../embedder_external_texture_resolver.h | 12 ++ ...embedder_external_texture_source_vulkan.cc | 204 ++++++++++++++++++ .../embedder_external_texture_source_vulkan.h | 70 ++++++ .../embedder_external_texture_vulkan.cc | 195 +++++++++++++++++ .../embedder_external_texture_vulkan.h | 64 ++++++ 9 files changed, 627 insertions(+), 1 deletion(-) create mode 100644 engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.cc create mode 100644 engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h create mode 100644 engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc create mode 100644 engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.h diff --git a/engine/src/flutter/shell/platform/embedder/BUILD.gn b/engine/src/flutter/shell/platform/embedder/BUILD.gn index de073b38654f6..cda34ae1bb4b5 100644 --- a/engine/src/flutter/shell/platform/embedder/BUILD.gn +++ b/engine/src/flutter/shell/platform/embedder/BUILD.gn @@ -167,6 +167,8 @@ template("embedder_source_set") { if (embedder_enable_vulkan) { sources += [ + "embedder_external_texture_vulkan.cc", + "embedder_external_texture_vulkan.h", "embedder_surface_vulkan.cc", "embedder_surface_vulkan.h", ] @@ -175,6 +177,8 @@ template("embedder_source_set") { sources += [ "embedder_surface_vulkan_impeller.cc", "embedder_surface_vulkan_impeller.h", + "embedder_external_texture_source_vulkan.cc", + "embedder_external_texture_source_vulkan.h", ] } diff --git a/engine/src/flutter/shell/platform/embedder/embedder.cc b/engine/src/flutter/shell/platform/embedder/embedder.cc index a2e5b51086d86..27390d7239127 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder.cc @@ -2345,6 +2345,27 @@ FlutterEngineResult FlutterEngineInitialize(size_t version, external_texture_metal_callback); } } +#endif +#ifdef SHELL_ENABLE_VULKAN + if (config->type == kVulkan) { + const FlutterVulkanRendererConfig* vulkan_config = &config->vulkan; + if (auto callback = SAFE_ACCESS(vulkan_config, + external_texture_frame_callback, nullptr)) { + auto external_texture_vulkan_callback = + [ptr = callback, user_data]( + int64_t texture_identifier, size_t width, + size_t height) -> std::unique_ptr { + std::unique_ptr texture = + std::make_unique(); + if (!ptr(user_data, texture_identifier, width, height, texture.get())) { + return nullptr; + } + return texture; + }; + external_texture_resolver = std::make_unique( + external_texture_vulkan_callback); + } + } #endif auto custom_task_runners = SAFE_ACCESS(args, custom_task_runners, nullptr); auto thread_config_callback = [&custom_task_runners]( diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index 61bac5028417a..3e7f64e67247f 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -930,6 +930,9 @@ typedef void* FlutterVulkanQueueHandle; /// Alias for VkImage. typedef uint64_t FlutterVulkanImageHandle; +/// Alias for VkDeviceMemory. +typedef uint64_t FlutterVulkanDeviceMemoryHandle; + typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanImage). size_t struct_size; @@ -958,6 +961,36 @@ typedef bool (*FlutterVulkanPresentCallback)( void* /* user data */, const FlutterVulkanImage* /* image */); +typedef struct { + /// Handle to the VkImage that is owned by the embedder. The engine will + /// bind this image for writing the frame. + FlutterVulkanImageHandle image; + /// The VkDeviceMemory that backs the iamge. + FlutterVulkanDeviceMemoryHandle image_memory; + /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). + uint32_t format; + /// User data to be returned on the invocation of the destruction callback. + void* user_data; + /// Callback invoked (on an engine managed thread) that asks the embedder to + /// collect the texture. + VoidCallback destruction_callback; + /// Optional parameters for texture height/width, default is 0, non-zero means + /// the texture has the specified width/height. + /// Width of the texture. + size_t width; + /// Height of the texture. + size_t height; +} FlutterVulkanTexture; + +/// Callback to provide an external texture for a given texture_id. +/// See: external_texture_frame_callback. +typedef bool (*FlutterVulkanTextureFrameCallback)( + void* /* user data */, + int64_t /* texture identifier */, + size_t /* width */, + size_t /* height */, + FlutterVulkanTexture* /* texture out */); + typedef struct { /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). size_t struct_size; @@ -1021,7 +1054,11 @@ typedef struct { /// without any additional synchronization. /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. FlutterVulkanPresentCallback present_image_callback; - + /// When the embedder specifies that a texture has a frame available, the + /// engine will call this method (on an internal engine managed thread) so + /// that external texture details can be supplied to the engine for subsequent + /// composition. + FlutterVulkanTextureFrameCallback external_texture_frame_callback; } FlutterVulkanRendererConfig; typedef struct { diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc index 4e4b41b8d4ad2..2dcef86b2061c 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.cc @@ -21,6 +21,12 @@ EmbedderExternalTextureResolver::EmbedderExternalTextureResolver( : metal_callback_(std::move(metal_callback)) {} #endif +#ifdef SHELL_ENABLE_VULKAN +EmbedderExternalTextureResolver::EmbedderExternalTextureResolver( + EmbedderExternalTextureVulkan::ExternalTextureCallback vulkan_callback) + : vulkan_callback_(std::move(vulkan_callback)) {} +#endif + std::unique_ptr EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) { #ifdef SHELL_ENABLE_GL @@ -37,6 +43,13 @@ EmbedderExternalTextureResolver::ResolveExternalTexture(int64_t texture_id) { } #endif +#ifdef SHELL_ENABLE_VULKAN + if (vulkan_callback_) { + return std::make_unique(texture_id, + vulkan_callback_); + } +#endif + return nullptr; } @@ -53,6 +66,12 @@ bool EmbedderExternalTextureResolver::SupportsExternalTextures() { } #endif +#ifdef SHELL_ENABLE_VULKAN + if (vulkan_callback_) { + return true; + } +#endif + return false; } diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h index 412301736e566..1079a006d6359 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_resolver.h @@ -17,6 +17,10 @@ #include "flutter/shell/platform/embedder/embedder_external_texture_metal.h" #endif +#ifdef SHELL_ENABLE_VULKAN +#include "flutter/shell/platform/embedder/embedder_external_texture_vulkan.h" +#endif + namespace flutter { class EmbedderExternalTextureResolver { public: @@ -34,6 +38,11 @@ class EmbedderExternalTextureResolver { EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback); #endif +#ifdef SHELL_ENABLE_VULKAN + explicit EmbedderExternalTextureResolver( + EmbedderExternalTextureVulkan::ExternalTextureCallback vulkan_callback); +#endif + std::unique_ptr ResolveExternalTexture(int64_t texture_id); bool SupportsExternalTextures(); @@ -47,6 +56,9 @@ class EmbedderExternalTextureResolver { EmbedderExternalTextureMetal::ExternalTextureCallback metal_callback_; #endif +#ifdef SHELL_ENABLE_VULKAN + EmbedderExternalTextureVulkan::ExternalTextureCallback vulkan_callback_; +#endif FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureResolver); }; } // namespace flutter diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.cc new file mode 100644 index 0000000000000..31a959f9ba0c5 --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.cc @@ -0,0 +1,204 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h" + +#include "impeller/renderer/backend/vulkan/allocator_vk.h" +#include "impeller/renderer/backend/vulkan/context_vk.h" +#include "impeller/renderer/backend/vulkan/texture_source_vk.h" +#include "impeller/renderer/backend/vulkan/yuv_conversion_library_vk.h" +#include "vulkan/vulkan.hpp" + +namespace flutter { + +bool RequiresYCBCRConversion(impeller::vk::Format format) { + switch (format) { + case impeller::vk::Format::eG8B8R83Plane420Unorm: + case impeller::vk::Format::eG8B8R82Plane420Unorm: + case impeller::vk::Format::eG8B8R83Plane422Unorm: + case impeller::vk::Format::eG8B8R82Plane422Unorm: + case impeller::vk::Format::eG8B8R83Plane444Unorm: + return true; + default: + // NOTE: NOT EXHAUSTIVE. + break; + } + return false; +} + +EmbedderExternalTextureSourceVulkan::EmbedderExternalTextureSourceVulkan( + const std::shared_ptr& p_context, + FlutterVulkanTexture* embedder_desc) + : TextureSourceVK(ToTextureDescriptor(embedder_desc)) { + const auto& context = impeller::ContextVK::Cast(*p_context); + const auto& device = context.GetDevice(); + texture_image_ = + impeller::vk::Image(reinterpret_cast(embedder_desc->image)); + texture_device_memory_ = impeller::vk::DeviceMemory( + reinterpret_cast(embedder_desc->image_memory)); + + needs_yuv_conversion_ = RequiresYCBCRConversion( + static_cast(embedder_desc->format)); + std::shared_ptr yuv_conversion; + if (needs_yuv_conversion_) { + // Figure out how to perform YUV conversions. + yuv_conversion = CreateYUVConversion(context, embedder_desc); + if (!yuv_conversion || !yuv_conversion->IsValid()) { + VALIDATION_LOG << "Fail to create yuv conversion"; + return; + } + } + + // Create image view for the newly created image. + if (!CreateTextureImageView(device, embedder_desc, yuv_conversion)) { + VALIDATION_LOG << "Fail to create texture image view"; + return; + } + + yuv_conversion_ = std::move(yuv_conversion); + is_valid_ = true; +} + +impeller::PixelFormat ToPixelFormat(int32_t vk_format) { + switch (vk_format) { + case VK_FORMAT_UNDEFINED: + return impeller::PixelFormat::kUnknown; + case VK_FORMAT_R8G8B8A8_UNORM: + return impeller::PixelFormat::kR8G8B8A8UNormInt; + case VK_FORMAT_R8G8B8A8_SRGB: + return impeller::PixelFormat::kR8G8B8A8UNormIntSRGB; + case VK_FORMAT_B8G8R8A8_UNORM: + return impeller::PixelFormat::kB8G8R8A8UNormInt; + case VK_FORMAT_B8G8R8A8_SRGB: + return impeller::PixelFormat::kB8G8R8A8UNormIntSRGB; + case VK_FORMAT_R32G32B32A32_SFLOAT: + return impeller::PixelFormat::kR32G32B32A32Float; + case VK_FORMAT_R16G16B16A16_SFLOAT: + return impeller::PixelFormat::kR16G16B16A16Float; + case VK_FORMAT_S8_UINT: + return impeller::PixelFormat::kS8UInt; + case VK_FORMAT_D24_UNORM_S8_UINT: + return impeller::PixelFormat::kD24UnormS8Uint; + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return impeller::PixelFormat::kD32FloatS8UInt; + case VK_FORMAT_R8_UNORM: + return impeller::PixelFormat::kR8UNormInt; + case VK_FORMAT_R8G8_UNORM: + return impeller::PixelFormat::kR8G8UNormInt; + default: + return impeller::PixelFormat::kUnknown; + } +} + +impeller::TextureDescriptor +EmbedderExternalTextureSourceVulkan::ToTextureDescriptor( + FlutterVulkanTexture* embedder_desc) { + const auto size = + impeller::ISize{static_cast(embedder_desc->width), + static_cast(embedder_desc->height)}; + impeller::TextureDescriptor desc; + desc.storage_mode = impeller::StorageMode::kDevicePrivate; + desc.format = ToPixelFormat(embedder_desc->format); + desc.size = size; + desc.type = impeller::TextureType::kTexture2D; + desc.sample_count = impeller::SampleCount::kCount1; + desc.compression_type = impeller::CompressionType::kLossless; + desc.mip_count = 1u; + desc.usage = impeller::TextureUsage::kRenderTarget; + return desc; +} + +std::shared_ptr +EmbedderExternalTextureSourceVulkan::CreateYUVConversion( + const impeller::ContextVK& context, + FlutterVulkanTexture* embedder_desc) { + impeller::YUVConversionDescriptorVK conversion_chain; + auto& conversion_info = conversion_chain.get(); + + conversion_info.format = + static_cast(embedder_desc->format); + conversion_info.ycbcrModel = + impeller::vk::SamplerYcbcrModelConversion::eYcbcr709; + conversion_info.ycbcrRange = impeller::vk::SamplerYcbcrRange::eItuFull; + conversion_info.components = {impeller::vk::ComponentSwizzle::eIdentity, + impeller::vk::ComponentSwizzle::eIdentity, + impeller::vk::ComponentSwizzle::eIdentity, + impeller::vk::ComponentSwizzle::eIdentity}; + conversion_info.xChromaOffset = impeller::vk::ChromaLocation::eCositedEven; + conversion_info.yChromaOffset = impeller::vk::ChromaLocation::eCositedEven; + conversion_info.chromaFilter = impeller::vk::Filter::eNearest; + conversion_info.forceExplicitReconstruction = false; + return context.GetYUVConversionLibrary()->GetConversion(conversion_chain); +} + +bool EmbedderExternalTextureSourceVulkan::CreateTextureImageView( + const impeller::vk::Device& device, + FlutterVulkanTexture* embedder_desc, + const std::shared_ptr& yuv_conversion_wrapper) { + impeller::vk::StructureChain + view_chain; + auto& view_info = view_chain.get(); + view_info.image = texture_image_; + view_info.viewType = impeller::vk::ImageViewType::e2D; + view_info.format = static_cast(embedder_desc->format); + view_info.subresourceRange.aspectMask = + impeller::vk::ImageAspectFlagBits::eColor; + view_info.subresourceRange.baseMipLevel = 0u; + view_info.subresourceRange.baseArrayLayer = 0u; + view_info.subresourceRange.levelCount = 1; + view_info.subresourceRange.layerCount = 1; + + if (RequiresYCBCRConversion( + static_cast(embedder_desc->format))) { + view_chain.get().conversion = + yuv_conversion_wrapper->GetConversion(); + } else { + view_chain.unlink(); + } + auto image_view = device.createImageViewUnique(view_info); + if (image_view.result != impeller::vk::Result::eSuccess) { + return false; + } + texture_image_view_ = std::move(image_view.value); + return true; +} + +// |TextureSourceVK| +EmbedderExternalTextureSourceVulkan::~EmbedderExternalTextureSourceVulkan() = + default; + +bool EmbedderExternalTextureSourceVulkan::IsValid() const { + return is_valid_; +} + +// |TextureSourceVK| +impeller::vk::Image EmbedderExternalTextureSourceVulkan::GetImage() const { + return texture_image_; +} + +// |TextureSourceVK| +impeller::vk::ImageView EmbedderExternalTextureSourceVulkan::GetImageView() + const { + return texture_image_view_.get(); +} + +// |TextureSourceVK| +impeller::vk::ImageView +EmbedderExternalTextureSourceVulkan::GetRenderTargetView() const { + return texture_image_view_.get(); +} + +// |TextureSourceVK| +bool EmbedderExternalTextureSourceVulkan::IsSwapchainImage() const { + return is_swapchain_image_; +} + +// |TextureSourceVK| +std::shared_ptr +EmbedderExternalTextureSourceVulkan::GetYUVConversion() const { + return needs_yuv_conversion_ ? yuv_conversion_ : nullptr; +} + +} // namespace flutter diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h new file mode 100644 index 0000000000000..57bad4034fe59 --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h @@ -0,0 +1,70 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_SOURCE_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_SOURCE_VULKAN_H_ + +#include "flutter/shell/platform/embedder/embedder.h" +#include "impeller/renderer/backend/vulkan/context_vk.h" +#include "impeller/renderer/backend/vulkan/texture_source_vk.h" +#include "impeller/renderer/backend/vulkan/vk.h" +#include "impeller/renderer/backend/vulkan/yuv_conversion_vk.h" + +namespace flutter { + +class ContextVK; + +class EmbedderExternalTextureSourceVulkan final + : public impeller::TextureSourceVK { + public: + EmbedderExternalTextureSourceVulkan( + const std::shared_ptr& context, + FlutterVulkanTexture* embedder_desc); + + // |TextureSourceVK| + ~EmbedderExternalTextureSourceVulkan() override; + + // |TextureSourceVK| + impeller::vk::Image GetImage() const override; + + // |TextureSourceVK| + impeller::vk::ImageView GetImageView() const override; + + // |TextureSourceVK| + impeller::vk::ImageView GetRenderTargetView() const override; + + bool IsValid() const; + + // |TextureSourceVK| + bool IsSwapchainImage() const override; + + // |TextureSourceVK| + std::shared_ptr GetYUVConversion() const override; + + private: + bool CreateTextureImageView( + const impeller::vk::Device& device, + FlutterVulkanTexture* embedder_desc, + const std::shared_ptr& yuv_conversion_wrapper); + impeller::TextureDescriptor ToTextureDescriptor( + FlutterVulkanTexture* embedder_desc); + std::shared_ptr CreateYUVConversion( + const impeller::ContextVK& context, + FlutterVulkanTexture* embedder_desc); + std::shared_ptr yuv_conversion_ = {}; + bool needs_yuv_conversion_ = false; + bool is_swapchain_image_ = false; + bool is_valid_ = false; + impeller::vk::Image texture_image_; + impeller::vk::DeviceMemory texture_device_memory_; + impeller::vk::UniqueImageView texture_image_view_ = {}; + EmbedderExternalTextureSourceVulkan( + const EmbedderExternalTextureSourceVulkan&) = delete; + EmbedderExternalTextureSourceVulkan& operator=( + const EmbedderExternalTextureSourceVulkan&) = delete; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_SOURCE_VULKAN_H_ diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc new file mode 100644 index 0000000000000..ced35eb6d5e85 --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc @@ -0,0 +1,195 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_external_texture_vulkan.h" + +#include "flutter/fml/logging.h" +#include "flutter/impeller/display_list/dl_image_impeller.h" +#include "flutter/impeller/renderer/backend/vulkan/command_buffer_vk.h" +#include "flutter/shell/platform/embedder/embedder_external_texture_source_vulkan.h" +#include "impeller/core/texture_descriptor.h" +#include "impeller/display_list/aiks_context.h" +#include "impeller/renderer/backend/vulkan/texture_vk.h" +#include "impeller/renderer/context.h" +#include "include/core/SkCanvas.h" +#include "include/core/SkPaint.h" +#include "third_party/skia/include/core/SkAlphaType.h" +#include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkColorType.h" +#include "third_party/skia/include/core/SkImage.h" +#include "third_party/skia/include/core/SkSize.h" +#include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h" +#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" +#include "third_party/skia/include/gpu/ganesh/vk/GrVkBackendSurface.h" +#include "third_party/skia/include/gpu/ganesh/vk/GrVkTypes.h" + +namespace flutter { +EmbedderExternalTextureVulkan::EmbedderExternalTextureVulkan( + int64_t texture_identifier, + const ExternalTextureCallback& callback) + : Texture(texture_identifier), external_texture_callback_(callback) { + FML_DCHECK(external_texture_callback_); +} + +// |flutter::Texture| +void EmbedderExternalTextureVulkan::Paint(PaintContext& context, + const DlRect& bounds, + bool freeze, + const DlImageSampling sampling) { + if (last_image_ == nullptr) { + last_image_ = + ResolveTexture(Id(), context.gr_context, context.aiks_context, + SkISize::Make(bounds.GetWidth(), bounds.GetHeight())); + } + + DlCanvas* canvas = context.canvas; + const DlPaint* paint = context.paint; + + if (last_image_) { + DlRect image_bounds = DlRect::Make(last_image_->GetBounds()); + if (bounds != image_bounds) { + canvas->DrawImageRect(last_image_, image_bounds, bounds, sampling, paint); + } else { + canvas->DrawImage(last_image_, bounds.GetOrigin(), sampling, paint); + } + } +} + +sk_sp EmbedderExternalTextureVulkan::ResolveTexture( + int64_t texture_id, + GrDirectContext* context, + impeller::AiksContext* aiks_context, + const SkISize& size) { + if (!!aiks_context) { + return ResolveTextureImpeller(texture_id, aiks_context, size); + } else { + return ResolveTextureSkia(texture_id, context, size); + } +} + +sk_sp EmbedderExternalTextureVulkan::ResolveTextureSkia( + int64_t texture_id, + GrDirectContext* context, + const SkISize& size) { + context->flushAndSubmit(); + context->resetContext(kAll_GrBackendState); + std::unique_ptr texture = + external_texture_callback_(texture_id, size.width(), size.height()); + + if (!texture) { + return nullptr; + } + + size_t width = size.width(); + size_t height = size.height(); + + if (texture->width != 0 && texture->height != 0) { + width = texture->width; + height = texture->height; + } + + GrVkImageInfo image_info = { + .fImage = reinterpret_cast(texture->image), + .fImageTiling = VK_IMAGE_TILING_OPTIMAL, + .fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .fFormat = static_cast(texture->format), + .fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT | + VK_IMAGE_USAGE_TRANSFER_DST_BIT | + VK_IMAGE_USAGE_SAMPLED_BIT, + .fSampleCount = 1, + .fLevelCount = 1, + }; + + auto gr_backend_texture = + GrBackendTextures::MakeVk(width, height, image_info); + SkImages::TextureReleaseProc release_proc = texture->destruction_callback; + auto image = + SkImages::BorrowTextureFrom(context, // context + gr_backend_texture, // texture handle + kTopLeft_GrSurfaceOrigin, // origin + kRGB_888x_SkColorType, // color type + kPremul_SkAlphaType, // alpha type + nullptr, // colorspace + release_proc, // texture release proc + texture->user_data // texture release context + ); + + if (!image) { + // In case Skia rejects the image, call the release proc so that + // embedders can perform collection of intermediates. + if (release_proc) { + release_proc(texture->user_data); + } + return nullptr; + } + + return DlImage::Make(std::move(image)); +} + +sk_sp EmbedderExternalTextureVulkan::ResolveTextureImpeller( + int64_t texture_id, + impeller::AiksContext* aiks_context, + const SkISize& size) { + std::unique_ptr texture_desc = + external_texture_callback_(texture_id, size.width(), size.height()); + if (!texture_desc) { + return nullptr; + } + + const auto& impeller_context = + impeller::ContextVK::Cast(*aiks_context->GetContext()); + + auto texture_source = std::make_shared( + aiks_context->GetContext(), texture_desc.get()); + + auto texture = std::make_shared( + aiks_context->GetContext(), texture_source); + // Transition the layout to shader read. + { + auto buffer = impeller_context.CreateCommandBuffer(); + impeller::CommandBufferVK& buffer_vk = + impeller::CommandBufferVK::Cast(*buffer); + + impeller::BarrierVK barrier; + barrier.cmd_buffer = buffer_vk.GetCommandBuffer(); + barrier.src_access = impeller::vk::AccessFlagBits::eColorAttachmentWrite | + impeller::vk::AccessFlagBits::eTransferWrite; + barrier.src_stage = + impeller::vk::PipelineStageFlagBits::eColorAttachmentOutput | + impeller::vk::PipelineStageFlagBits::eTransfer; + barrier.dst_access = impeller::vk::AccessFlagBits::eShaderRead; + barrier.dst_stage = impeller::vk::PipelineStageFlagBits::eFragmentShader; + + barrier.new_layout = impeller::vk::ImageLayout::eShaderReadOnlyOptimal; + + if (!texture_source->SetLayout(barrier).ok()) { + return nullptr; + } + if (!impeller_context.GetCommandQueue()->Submit({buffer}).ok()) { + return nullptr; + } + } + + return impeller::DlImageImpeller::Make(texture); +} + +EmbedderExternalTextureVulkan::~EmbedderExternalTextureVulkan() = default; + +// |flutter::Texture| +void EmbedderExternalTextureVulkan::OnGrContextCreated() {} + +// |flutter::Texture| +void EmbedderExternalTextureVulkan::OnGrContextDestroyed() {} + +// |flutter::Texture| +void EmbedderExternalTextureVulkan::MarkNewFrameAvailable() { + last_image_ = nullptr; +} + +// |flutter::Texture| +void EmbedderExternalTextureVulkan::OnTextureUnregistered() {} + +} // namespace flutter diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.h new file mode 100644 index 0000000000000..07611b4b729bf --- /dev/null +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.h @@ -0,0 +1,64 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_VULKAN_H_ + +#include "flutter/common/graphics/texture.h" +#include "flutter/fml/macros.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "include/core/SkTypes.h" +#include "include/gpu/vk/VulkanTypes.h" +#include "third_party/skia/include/core/SkSize.h" + +namespace flutter { + +class EmbedderExternalTextureVulkan : public flutter::Texture { + public: + using ExternalTextureCallback = std::function< + std::unique_ptr(int64_t, size_t, size_t)>; + EmbedderExternalTextureVulkan(int64_t texture_identifier, + const ExternalTextureCallback& callback); + + ~EmbedderExternalTextureVulkan(); + + private: + const ExternalTextureCallback& external_texture_callback_; + + sk_sp last_image_; + + sk_sp ResolveTexture(int64_t texture_id, + GrDirectContext* context, + impeller::AiksContext* aiks_context, + const SkISize& size); + sk_sp ResolveTextureSkia(int64_t texture_id, + GrDirectContext* context, + const SkISize& size); + sk_sp ResolveTextureImpeller(int64_t texture_id, + impeller::AiksContext* aiks_context, + const SkISize& size); + + // |flutter::Texture| + void Paint(PaintContext& context, + const DlRect& bounds, + bool freeze, + const DlImageSampling sampling) override; + + // |flutter::Texture| + void OnGrContextCreated() override; + + // |flutter::Texture| + void OnGrContextDestroyed() override; + + // |flutter::Texture| + void MarkNewFrameAvailable() override; + + // |flutter::Texture| + void OnTextureUnregistered() override; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderExternalTextureVulkan); +}; +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_VULKAN_H_ From e1083edd759e32c0a4b0fd7be932a5f3d4431fc2 Mon Sep 17 00:00:00 2001 From: xiaowei guan <60122246+xiaowei-guan@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:57:50 +0800 Subject: [PATCH 14/21] [Tizen] Fix external texture gl crash issue (#18) --- .../shell/platform/embedder/embedder_external_texture_gl.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index 1a627ec864516..e8d2ad8bd12a3 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -70,8 +70,10 @@ sk_sp EmbedderExternalTextureGL::ResolveTexture( const SkISize& size) { if (!!aiks_context) { return ResolveTextureImpeller(texture_id, aiks_context, size); - } else { + } else if (!!context) { return ResolveTextureSkia(texture_id, context, size); + } else { + return nullptr; } } From 4f3935baacd3a6ec84ea49ca971bf3e22aee01d8 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 5 Dec 2025 14:47:59 +0900 Subject: [PATCH 15/21] [Tizen][ci] Add ignore linker option --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cb97449ae2e30..2d4597630f465 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,6 +65,7 @@ jobs: cd flutter # Ignore unsupported linker option. sed -i "/-Wl,--undefined-version/d" engine/src/build/config/compiler/BUILD.gn + sed -i "s/Wno-nontrivial-memcall/Wno-nontrivial-memaccess/g" engine/src/build/config/compiler/BUILD.gn engine/src/flutter/tools/gn \ --target-os linux \ From 707a629ee871b92b29f94bcd9ea8e4410e9bb7b5 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 5 Dec 2025 14:55:30 +0900 Subject: [PATCH 16/21] [Tizen] Remove unnecessary CI --- .github/dependabot.yml | 23 --- .github/labeler.yml | 261 ----------------------------- .github/release.yml | 68 -------- .github/workflows/labeler.yml | 22 --- .github/workflows/no-response.yaml | 44 ----- 5 files changed, 418 deletions(-) delete mode 100644 .github/dependabot.yml delete mode 100644 .github/labeler.yml delete mode 100644 .github/release.yml delete mode 100644 .github/workflows/labeler.yml delete mode 100644 .github/workflows/no-response.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index d0f70fdd13cea..0000000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,23 +0,0 @@ -# See Dependabot documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - groups: - all-github-actions: - patterns: [ "*" ] - reviewers: - - "christopherfujino" - - "jmagman" - labels: - - "team-infra" - - "autosubmit" - # Updating patch versions for "github-actions" is too chatty. - # See https://github.com/flutter/flutter/issues/158350. - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-patch"] diff --git a/.github/labeler.yml b/.github/labeler.yml deleted file mode 100644 index 72b7c66fd1ae1..0000000000000 --- a/.github/labeler.yml +++ /dev/null @@ -1,261 +0,0 @@ -# Copyright 2013 The Flutter Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# See https://github.com/actions/labeler/blob/main/README.md for docs. -# Use git ls-files '' to see the list of matching files. - -'a: accessibility': - - changed-files: - - any-glob-to-any-file: - - '**/accessibility/*' - - '**/*accessibility*' - - '**/semantics/*' - - '**/*semantics*' - -'a: animation': - - changed-files: - - any-glob-to-any-file: - - '**/animation/*' - - '**/*animation*' - -'a: desktop': - - changed-files: - - any-glob-to-any-file: - - '**/linux/**/*' - - '**/macos/**/*' - - '**/windows/**/*' - - engine/src/flutter/shell/platform/darwin/common/**/* - -'a: internationalization': - - changed-files: - - any-glob-to-any-file: - - packages/flutter_localizations/**/* - -'a: tests': - - changed-files: - - any-glob-to-any-file: - - packages/flutter_driver/**/* - - packages/flutter_goldens/**/* - - packages/flutter_test/**/* - - packages/integration_test/**/* - -'a: text input': - - changed-files: - - all-globs-to-any-file: - - '**/*text*' - - '!**/*context*' - - '!**/*texture*' - -'d: api docs': - - changed-files: - - any-glob-to-any-file: - - examples/api/**/* - -'d: docs/': - - changed-files: - - any-glob-to-any-file: - - docs/**/* - -'d: examples': - - changed-files: - - any-glob-to-any-file: - - examples/**/* - -'e: embedder': - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/shell/platform/embedder - -'e: impeller': - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/impeller/**/* - -engine: - - changed-files: - - any-glob-to-any-file: - - DEPS - - engine/**/* - - docs/engine/**/* - -'f: cupertino': - - changed-files: - - any-glob-to-any-file: - - '**/cupertino/*' - - '**/*cupertino*' - - docs/libraries/cupertino/**/* - -'f: focus': - - changed-files: - - any-glob-to-any-file: - - '**/focus/*' - - '**/*focus*' - -'f: gestures': - - changed-files: - - any-glob-to-any-file: - - '**/gestures/*' - - '**/*gestures*' - -'f: material design': - - changed-files: - - any-glob-to-any-file: - - '**/material/*' - - '**/*material*' - - docs/libraries/material/**/* - -'f: routes': - - changed-files: - - any-glob-to-any-file: - - '**/navigator/*' - - '**/*navigator*' - - '**/route/*' - - '**/*route*' - -'f: scrolling': - - changed-files: - - any-glob-to-any-file: - - '**/*scroll*' - - '**/scroll/*' - - '**/*sliver*' - - '**/sliver/*' - - '**/*viewport*' - - '**/viewport/*' - -framework: - - changed-files: - - any-glob-to-any-file: - - packages/flutter/**/* - - packages/flutter_driver/**/* - - packages/flutter_goldens/**/* - - packages/flutter_localizations/**/* - - packages/flutter_test/**/* - - packages/integration_test/**/* - - examples/api/**/* - - docs/about/**/* - - docs/contributing/**/* - - docs/libraries/**/* - -'f: integration_test': - - changed-files: - - any-glob-to-any-file: - - packages/integration_test/**/* - -package: - - changed-files: - - any-glob-to-any-file: - - docs/ecosystem/**/* - -platform-android: - - changed-files: - - any-glob-to-any-file: - - docs/platform/android/**/* - - engine/src/flutter/shell/platform/android/**/* - - packages/flutter_tools/*android* - - packages/flutter_tools/gradle/**/* - -platform-ios: - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/shell/platform/darwin/common/**/* - - engine/src/flutter/shell/platform/darwin/ios/**/* - - packages/flutter_tools/lib/src/ios/**/* - -platform-fuchsia: - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/shell/platform/fuchsia/**/* - -platform-linux: - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/shell/platform/linux/**/* - -platform-macos: - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/src/flutter/shell/platform/darwin/common/**/* - - engine/src/flutter/shell/platform/darwin/macos/**/* - -platform-web: - - changed-files: - - any-glob-to-any-file: - - '**/web_sdk/**/*' - - engine/src/flutter/lib/web_ui/**/* - - packages/flutter_web_plugins - -platform-windows: - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/shell/platform/windows/**/* - -'customer: gallery': - - changed-files: - - any-glob-to-any-file: - - examples/flutter_gallery/**/* - -'c: tech-debt': - - changed-files: - - any-glob-to-any-file: - - '**/fix_data.yaml' - - '**/*.expect' - - '**/*test_fixes*' -'c: contributor-productivity': - - changed-files: - - any-glob-to-any-file: - - docs/contributing/**/* - -# Keep this synced with CODEOWNERS. -team-android: - - changed-files: - - any-glob-to-any-file: - - docs/platform/android/**/* - - engine/src/flutter/shell/platform/android/**/* - - packages/flutter_tools/**/*android* - - packages/flutter_tools/**/*gradle* - -team-ecosystem: - - changed-files: - - any-glob-to-any-file: - - docs/ecosystem/**/* - -team-engine: - - changed-files: - - any-glob-to-any-file: - - docs/engine/**/* - -team-infra: - - changed-files: - - any-glob-to-any-file: - - docs/infra/**/* - - docs/releases/**/* - -# Keep this synced with CODEOWNERS. -team-ios: - - changed-files: - - any-glob-to-any-file: - - engine/src/flutter/shell/platform/darwin/common/**/* - - engine/src/flutter/shell/platform/darwin/ios/framework/**/* - - packages/flutter_tools/**/ios/* - - packages/flutter_tools/**/macos/* - - packages/flutter_tools/**/*xcode* - - packages/flutter_tools/**/*ios* - - packages/flutter_tools/**/*macos* - -team-tool: - - changed-files: - - any-glob-to-any-file: - - docs/tool/**/* - -team-web: - - changed-files: - - any-glob-to-any-file: - - docs/platforms/web/**/* - -tool: - - changed-files: - - any-glob-to-any-file: - - packages/flutter_tools/**/* - - packages/fuchsia_remote_debug_protocol/**/* - - docs/tool/**/* diff --git a/.github/release.yml b/.github/release.yml deleted file mode 100644 index 5c6decc52930e..0000000000000 --- a/.github/release.yml +++ /dev/null @@ -1,68 +0,0 @@ -changelog: - exclude: - authors: - - engine-flutter-autoroll - - fluttergithubbot - labels: - - passed first triage - - passed secondary triage - - "team: flakes" - - revert - categories: - - title: Framework - labels: - - framework - - "a: text input" - - "f: scrolling" - - "f: routes" - - "f: selection" - - "f: gestures" - exclude: - labels: - - "f: material design" - - title: Material - labels: - - "f: material design" - # Mobile - - title: iOS - labels: - - platform-ios - - "f: cupertino" - - title: Android - labels: - - platform-android - # Desktop - - title: macOS - labels: - - platform-mac - - title: Windows - labels: - - platform-windows - - title: Linux - labels: - - platform-linux - # Web - - title: Web - labels: - - platform-web - - "browser: chrome-desktop" - - "browser: edge" - - "browser: firefox" - - "browser: safari-macos" - # Misc - - title: Tooling - labels: - - tool - - title: DevTools - labels: - - "d: devtools" - - "d: intellij" - - "d: tools_metadata" - - "f: inspector" - - title: Documentation - labels: - - "d: examples" - - "d: api docs" - - title: Other Changes - labels: - - '*' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 193049ebb9400..0000000000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2013 The Flutter Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -name: "Pull Request Labeler" -on: -- pull_request_target - -# Declare default permissions as read only. -permissions: read-all - -jobs: - triage: - if: ${{ github.repository == 'flutter/flutter' }} - permissions: - pull-requests: write - runs-on: ubuntu-latest - steps: - # Source available at https://github.com/actions/labeler/blob/main/README.md - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b - with: - sync-labels: true diff --git a/.github/workflows/no-response.yaml b/.github/workflows/no-response.yaml deleted file mode 100644 index 94d4d8fc988ce..0000000000000 --- a/.github/workflows/no-response.yaml +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2013 The Flutter Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -name: No Response - -# Both `issue_comment` and `scheduled` event types are required for this Action -# to work properly. -on: - issue_comment: - types: [created] - schedule: - # Schedule for five minutes after the hour, every hour - - cron: '5 * * * *' - -# By specifying the access of one of the scopes, all of those that are not -# specified are set to 'none'. -permissions: - issues: write - -jobs: - noResponse: - runs-on: ubuntu-latest - if: ${{ github.repository == 'flutter/flutter' }} - steps: - - uses: godofredoc/no-response@0ce2dc0e63e1c7d2b87752ceed091f6d32c9df09 - with: - token: ${{ github.token }} - # Comment to post when closing an Issue for lack of response. Set to `false` to disable - closeComment: > - Without additional information, we are unfortunately not sure how to - resolve this issue. We are therefore reluctantly going to close this - bug for now. - - If you find this problem please file a new issue with the same description, - what happens, logs and the output of 'flutter doctor -v'. All system setups - can be slightly different so it's always better to open new issues and reference - the related ones. - - Thanks for your contribution. - # Number of days of inactivity before an issue is closed for lack of response. - daysUntilClose: 21 - # Label requiring a response. - responseRequiredLabel: "waiting for customer response" From e79a28367f8ae4b2c722ff815688534ab3c5c6dc Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 5 Dec 2025 17:07:40 +0900 Subject: [PATCH 17/21] [Tizen] Disable lto option --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2d4597630f465..0fee350a485cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -71,6 +71,7 @@ jobs: --target-os linux \ --linux-cpu ${{ matrix.arch }} \ --no-goma \ + --no-lto \ --target-toolchain /tizen_tools/toolchains \ --target-sysroot /tizen_tools/sysroot/${{ matrix.arch }} \ --target-triple ${{ matrix.triple }} \ From 96af97888e664a4c0b7467d3bb6cf744cf03e671 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 12 Dec 2025 19:02:34 +0900 Subject: [PATCH 18/21] [Tizen][ci] Update macos runnner for intel mac Replaced macos-13 with macos-15-intel https://github.com/actions/runner-images/issues/13046 --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0fee350a485cd..67a4a1cfcec32 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -269,7 +269,7 @@ jobs: if-no-files-found: error macos-intel-build: - runs-on: macos-13 + runs-on: macos-15-intel strategy: matrix: From 51446ac9022b27db645975a64b857953f393e39d Mon Sep 17 00:00:00 2001 From: xiaowei guan <60122246+xiaowei-guan@users.noreply.github.com> Date: Tue, 23 Dec 2025 16:30:24 +0800 Subject: [PATCH 19/21] [Tizen] Fix GPU memory leak issue (#21) Because Tizen platform don't support hardware key, so we can't create a cache source to store the gpu resource. so we should reset the resouce before the frame end. --- .../platform/embedder/embedder_external_texture_vulkan.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc index ced35eb6d5e85..b50d9644b914a 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_vulkan.cc @@ -139,7 +139,7 @@ sk_sp EmbedderExternalTextureVulkan::ResolveTextureImpeller( return nullptr; } - const auto& impeller_context = + auto& impeller_context = impeller::ContextVK::Cast(*aiks_context->GetContext()); auto texture_source = std::make_shared( @@ -172,7 +172,7 @@ sk_sp EmbedderExternalTextureVulkan::ResolveTextureImpeller( return nullptr; } } - + impeller_context.DisposeThreadLocalCachedResources(); return impeller::DlImageImpeller::Make(texture); } From 2f9517552aab62592377e8db2a8fc1735b755bfe Mon Sep 17 00:00:00 2001 From: xiaowei guan <60122246+xiaowei-guan@users.noreply.github.com> Date: Fri, 6 Feb 2026 10:19:44 +0800 Subject: [PATCH 20/21] [Tizen] Re-implemented render external texture gl for impeller to avoid change FlutterOpenGLTexture and use deprecated api (#26) We have supported render external texture gl for Impeller https://github.com/flutter-tizen/engine/pull/368 But this PR has two issues: 1. It modify FlutterOpenGLTexture, it added additional variables, not a good design. ```C++ /// The pixel data buffer. const uint8_t* buffer; /// The size of pixel buffer. size_t buffer_size; /// Callback invoked that the gpu surface texture start binding. BoolCallback bind_callback; /// The type of the texture. FlutterGLImpellerTextureType impeller_texture_type; ``` 2. It uses Deprecated API ```C++ // Deprecated: use BlitPass::AddCopy instead. [[nodiscard]] bool SetContents(const uint8_t* contents, size_t length, size_t slice = 0, bool is_opaque = false); ``` So I tried to revert offical PR to render external gl for impeller https://github.com/flutter/engine/pull/56277 But this PR doesn't work on Tizen platform, I think This PR may not have been verified. To avoid change FlutterOpenGLTexture and use deprecated api, so I re-implemented render external texture gl for impeller based on this offical PR. Fix https://github.com/flutter-tizen/embedder/issues/131 *Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.* *List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.* *If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].* ## Pre-launch Checklist - [ ] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [ ] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [ ] I signed the [CLA]. - [ ] I listed at least one issue that this PR fixes in the description above. - [ ] I updated/added relevant documentation (doc comments with `///`). - [ ] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. **Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --- .../shell/platform/embedder/embedder.h | 9 +- .../embedder/embedder_external_texture_gl.cc | 229 ++++++++++++------ .../embedder/embedder_external_texture_gl.h | 50 +++- 3 files changed, 199 insertions(+), 89 deletions(-) diff --git a/engine/src/flutter/shell/platform/embedder/embedder.h b/engine/src/flutter/shell/platform/embedder/embedder.h index 3e7f64e67247f..1fd58e5b2f0b9 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder.h +++ b/engine/src/flutter/shell/platform/embedder/embedder.h @@ -407,7 +407,6 @@ typedef struct { } FlutterTransformation; typedef void (*VoidCallback)(void* /* user data */); -typedef bool (*BoolCallback)(void* /* user data */); typedef enum { /// Specifies an OpenGL texture target type. Textures are specified using @@ -515,13 +514,6 @@ typedef struct { uint32_t name; /// The texture format (example GL_RGBA8). uint32_t format; - /// The pixel data buffer. - const uint8_t* buffer; - /// The size of pixel buffer. - size_t buffer_size; - /// Callback invoked that the gpu surface texture start binding. - BoolCallback bind_callback; - /// User data to be returned on the invocation of the destruction callback. void* user_data; /// Callback invoked (on an engine managed thread) that asks the embedder to @@ -615,6 +607,7 @@ typedef struct { uint32_t format; } FlutterOpenGLSurface; +typedef bool (*BoolCallback)(void* /* user data */); typedef FlutterTransformation (*TransformationCallback)(void* /* user data */); typedef uint32_t (*UIntCallback)(void* /* user data */); typedef bool (*SoftwareSurfacePresentCallback)(void* /* user data */, diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc index e8d2ad8bd12a3..3d7c9bba97bfa 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.cc @@ -27,6 +27,88 @@ namespace flutter { +std::optional TextureLRU::FindTexture( + std::optional key) { + if (!key.has_value()) { + return std::nullopt; + } + auto key_value = key.value(); + for (size_t i = 0u; i < kTextureMaxSize; i++) { + if (textures_[i].key == key_value) { + UpdateTexture(Data{.key = key_value, + .texture = textures_[i].texture, + .width = textures_[i].width, + .height = textures_[i].height}); + return std::make_optional(textures_[i]); + } + } + return std::nullopt; +} + +void TextureLRU::UpdateTexture(Data data) { + if (textures_[0].key == data.key) { + textures_[0] = data; + return; + } + size_t i = 1u; + for (; i < kTextureMaxSize; i++) { + if (textures_[i].key == data.key) { + break; + } + } + + if (i == kTextureMaxSize) { + return; + } + + for (auto j = i; j > 0; j--) { + textures_[j] = textures_[j - 1]; + } + textures_[0] = data; +} + +GLuint TextureLRU::AddTexture(Data data) { + GLuint lru_key = textures_[kTextureMaxSize - 1].key; + bool updated_image = false; + for (size_t i = 0u; i < kTextureMaxSize; i++) { + if (textures_[i].key == lru_key) { + updated_image = true; + textures_[i] = data; + break; + } + } + if (!updated_image) { + textures_[0] = data; + } + UpdateTexture(data); + return lru_key; +} + +void TextureLRU::Clear() { + for (size_t i = 0u; i < kTextureMaxSize; i++) { + textures_[i] = Data{.key = 0u, .texture = nullptr}; + } +} + +void TextureLRU::RemoveTexture(GLuint key) { + size_t i = 0u; + for (; i < kTextureMaxSize; i++) { + if (textures_[i].key == key) { + break; + } + } + + if (i == kTextureMaxSize) { + return; + } + + for (; i < kTextureMaxSize - 1; i++) { + textures_[i] = textures_[i + 1]; + } + + textures_[kTextureMaxSize - 1] = Data{.key = 0u, .texture = nullptr}; +} + EmbedderExternalTextureGL::EmbedderExternalTextureGL( int64_t texture_identifier, const ExternalTextureCallback& callback) @@ -129,46 +211,27 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureSkia( return DlImage::Make(std::move(image)); } -sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( - int64_t texture_id, - impeller::AiksContext* aiks_context, - const SkISize& size) { - std::unique_ptr texture = - external_texture_callback_(texture_id, size.width(), size.height()); - - if (!texture) { - return nullptr; - } - - if (texture->bind_callback != nullptr) { - return ResolveTextureImpellerSurface(aiks_context, std::move(texture)); - } else { - return ResolveTextureImpellerPixelbuffer(aiks_context, std::move(texture)); - } -} - -sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer( +std::shared_ptr +EmbedderExternalTextureGL::CreateTextureGLES( impeller::AiksContext* aiks_context, - std::unique_ptr texture) { + FlutterOpenGLTexture* texture) { impeller::TextureDescriptor desc; desc.size = impeller::ISize(texture->width, texture->height); - desc.type = impeller::TextureType::kTexture2D; desc.storage_mode = impeller::StorageMode::kDevicePrivate; desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; + if (texture->target == GL_TEXTURE_EXTERNAL_OES) { + desc.type = impeller::TextureType::kTextureExternalOES; + } else { + desc.type = impeller::TextureType::kTexture2D; + } impeller::ContextGLES& context = impeller::ContextGLES::Cast(*aiks_context->GetContext()); - std::shared_ptr image = - std::make_shared(context.GetReactor(), desc); + impeller::HandleGLES handle = context.GetReactor()->CreateHandle( + impeller::HandleType::kTexture, texture->name); - image->MarkContentsInitialized(); - if (!image->SetContents(texture->buffer, texture->buffer_size)) { - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - return nullptr; - } - - if (!image) { + auto gles_texture = + impeller::TextureGLES::WrapTexture(context.GetReactor(), desc, handle); + if (!gles_texture) { // In case Skia rejects the image, call the release proc so that // embedders can perform collection of intermediates. if (texture->destruction_callback) { @@ -178,58 +241,74 @@ sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerPixelbuffer( return nullptr; } - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } + gles_texture->SetCoordinateSystem( + impeller::TextureCoordinateSystem::kUploadFromHost); - return impeller::DlImageImpeller::Make(image); + if (texture->destruction_callback && + !context.GetReactor()->RegisterCleanupCallback( + handle, + [callback = texture->destruction_callback, + user_data = texture->user_data]() { callback(user_data); })) { + FML_LOG(ERROR) << "Could not register destruction callback"; + return nullptr; + } + return gles_texture; } -sk_sp EmbedderExternalTextureGL::ResolveTextureImpellerSurface( +sk_sp EmbedderExternalTextureGL::ResolveTextureImpeller( + int64_t texture_id, impeller::AiksContext* aiks_context, - std::unique_ptr texture) { - impeller::TextureDescriptor desc; - desc.size = impeller::ISize(texture->width, texture->height); - desc.storage_mode = impeller::StorageMode::kDevicePrivate; - desc.format = impeller::PixelFormat::kR8G8B8A8UNormInt; - desc.type = impeller::TextureType::kTextureExternalOES; - impeller::ContextGLES& context = - impeller::ContextGLES::Cast(*aiks_context->GetContext()); - std::shared_ptr image = - std::make_shared(context.GetReactor(), desc); - image->MarkContentsInitialized(); - image->SetCoordinateSystem( - impeller::TextureCoordinateSystem::kUploadFromHost); - if (!image->Bind()) { - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - FML_LOG(ERROR) << "Could not bind texture"; - return nullptr; - } + const SkISize& size) { + std::unique_ptr texture = + external_texture_callback_(texture_id, size.width(), size.height()); - if (!image) { - // In case Skia rejects the image, call the release proc so that - // embedders can perform collection of intermediates. - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - FML_LOG(ERROR) << "Could not create external texture"; + if (!texture) { return nullptr; } - if (!texture->bind_callback(texture->user_data)) { - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); - } - return nullptr; - } + std::optional texture_data = + texture_lru_.FindTexture(texture->name); + + bool size_change = false; - if (texture->destruction_callback) { - texture->destruction_callback(texture->user_data); + if (texture_data.has_value() && + (texture_data.value().width != texture->width || + texture_data.value().height != texture->height)) { + size_change = true; } - return impeller::DlImageImpeller::Make(image); + if (texture_data.has_value() && !size_change) { + return impeller::DlImageImpeller::Make(texture_data.value().texture); + } else if (texture_data.has_value() && size_change) { + std::shared_ptr old_gles_texture = + texture_data.value().texture; + old_gles_texture->Leak(); + std::shared_ptr new_gles_texture = + CreateTextureGLES(aiks_context, texture.get()); + if (new_gles_texture) { + texture_lru_.UpdateTexture(TextureLRU::Data{.key = texture->name, + .texture = new_gles_texture, + .width = texture->width, + .height = texture->height}); + + return impeller::DlImageImpeller::Make(new_gles_texture); + } else { + texture_lru_.RemoveTexture(texture->name); + return nullptr; + } + } else { + std::shared_ptr new_gles_texture = + CreateTextureGLES(aiks_context, texture.get()); + if (new_gles_texture) { + texture_lru_.AddTexture(TextureLRU::Data{.key = texture->name, + .texture = new_gles_texture, + .width = texture->width, + .height = texture->height}); + return impeller::DlImageImpeller::Make(new_gles_texture); + } else { + return nullptr; + } + } } // |flutter::Texture| @@ -244,6 +323,8 @@ void EmbedderExternalTextureGL::MarkNewFrameAvailable() { } // |flutter::Texture| -void EmbedderExternalTextureGL::OnTextureUnregistered() {} +void EmbedderExternalTextureGL::OnTextureUnregistered() { + texture_lru_.Clear(); +} } // namespace flutter diff --git a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h index 6ecb6843208d1..1fbbb01968a28 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h +++ b/engine/src/flutter/shell/platform/embedder/embedder_external_texture_gl.h @@ -5,12 +5,52 @@ #ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_H_ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_EXTERNAL_TEXTURE_GL_H_ +#include +#include +#include #include "flutter/common/graphics/texture.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "impeller/renderer/backend/gles/texture_gles.h" #include "third_party/skia/include/core/SkSize.h" namespace flutter { +static constexpr size_t kTextureMaxSize = 6u; + +class TextureLRU { + public: + struct Data { + GLuint key = 0u; + std::shared_ptr texture; + size_t width = 0; + size_t height = 0; + }; + + TextureLRU() = default; + + ~TextureLRU() = default; + + /// @brief Retrieve the Texture associated with the given [key], or nullptr. + std::optional FindTexture(std::optional key); + + /// @brief Add a new texture to the cache with a key, returning the key of the + /// LRU entry that was removed. + /// + /// The value may be `0`, in which case nothing was removed. + GLuint AddTexture(Data data); + + /// @brief Remove all entires from the image cache. + void Clear(); + + /// @brief Remove a texture from the cache by key. + void RemoveTexture(GLuint key); + + /// @brief Marks [key] as the most recently used. + void UpdateTexture(Data data); + + private: + std::array textures_; +}; class EmbedderExternalTextureGL : public flutter::Texture { public: @@ -25,7 +65,7 @@ class EmbedderExternalTextureGL : public flutter::Texture { private: const ExternalTextureCallback& external_texture_callback_; sk_sp last_image_; - + TextureLRU texture_lru_ = TextureLRU(); sk_sp ResolveTexture(int64_t texture_id, GrDirectContext* context, impeller::AiksContext* aiks_context, @@ -39,13 +79,9 @@ class EmbedderExternalTextureGL : public flutter::Texture { impeller::AiksContext* aiks_context, const SkISize& size); - sk_sp ResolveTextureImpellerPixelbuffer( - impeller::AiksContext* aiks_context, - std::unique_ptr texture); - - sk_sp ResolveTextureImpellerSurface( + std::shared_ptr CreateTextureGLES( impeller::AiksContext* aiks_context, - std::unique_ptr texture); + FlutterOpenGLTexture* texture); // |flutter::Texture| void Paint(PaintContext& context, From 8e99837f69a49f00123f020187027e19d6ff8e9a Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 11 Mar 2026 17:18:27 +0900 Subject: [PATCH 21/21] [Tizen] Add syscall compat header for custom Linux toolchains Inject a small compat header into the custom cross-toolchain command line so Linux targets built with Tizen sysroots still see __NR_getrandom even when the sysroot headers do not export it. This keeps third_party/dart untouched and fixes builds across common Tizen architectures: - x86: 355 - x64: 318 - arm: 384 - arm64: 278 --- engine/src/build/toolchain/custom/BUILD.gn | 9 ++++-- .../toolchain/custom/tizen_syscall_compat.h | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 engine/src/build/toolchain/custom/tizen_syscall_compat.h diff --git a/engine/src/build/toolchain/custom/BUILD.gn b/engine/src/build/toolchain/custom/BUILD.gn index 3da5f930269b5..12ccc7c56b6f2 100644 --- a/engine/src/build/toolchain/custom/BUILD.gn +++ b/engine/src/build/toolchain/custom/BUILD.gn @@ -20,6 +20,9 @@ toolchain("custom") { target_triple_flags = "--target=${custom_target_triple}" sysroot_flags = "--sysroot ${custom_sysroot}" + syscall_compat_header = + rebase_path("//build/toolchain/custom/tizen_syscall_compat.h", root_build_dir) + syscall_compat_flags = "-include ${syscall_compat_header}" custom_lib_flags = "-L${custom_toolchain}/lib" @@ -29,7 +32,7 @@ toolchain("custom") { tool("cc") { depfile = "{{output}}.d" - command = "$cc -MD -MF $depfile $target_triple_flags $sysroot_flags {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" + command = "$cc -MD -MF $depfile $target_triple_flags $sysroot_flags $syscall_compat_flags {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" depsformat = "gcc" description = "CC {{output}}" outputs = @@ -38,7 +41,7 @@ toolchain("custom") { tool("cxx") { depfile = "{{output}}.d" - command = "$cxx -MD -MF $depfile $target_triple_flags $sysroot_flags {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" + command = "$cxx -MD -MF $depfile $target_triple_flags $sysroot_flags $syscall_compat_flags {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" depsformat = "gcc" description = "CXX {{output}}" outputs = @@ -47,7 +50,7 @@ toolchain("custom") { tool("asm") { depfile = "{{output}}.d" - command = "$cc -MD -MF $depfile $target_triple_flags $sysroot_flags {{defines}} {{include_dirs}} {{asmflags}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" + command = "$cc -MD -MF $depfile $target_triple_flags $sysroot_flags $syscall_compat_flags {{defines}} {{include_dirs}} {{asmflags}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" depsformat = "gcc" description = "ASM {{output}}" outputs = diff --git a/engine/src/build/toolchain/custom/tizen_syscall_compat.h b/engine/src/build/toolchain/custom/tizen_syscall_compat.h new file mode 100644 index 0000000000000..f3658b2ba3c2e --- /dev/null +++ b/engine/src/build/toolchain/custom/tizen_syscall_compat.h @@ -0,0 +1,32 @@ +// Copyright 2026 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BUILD_TOOLCHAIN_CUSTOM_TIZEN_SYSCALL_COMPAT_H_ +#define BUILD_TOOLCHAIN_CUSTOM_TIZEN_SYSCALL_COMPAT_H_ + +// Some Tizen cross-compilation sysroots do not expose __NR_getrandom even +// though the target Linux ABI supports the syscall. Dart's crypto_linux.cc +// references the syscall number directly, so provide the missing arch-specific +// values for custom Linux toolchains without modifying third_party sources. +#if defined(__linux__) + +#if defined(__i386__) && !defined(__NR_getrandom) +#define __NR_getrandom 355 +#endif + +#if defined(__x86_64__) && !defined(__NR_getrandom) +#define __NR_getrandom 318 +#endif + +#if defined(__arm__) && !defined(__NR_getrandom) +#define __NR_getrandom 384 +#endif + +#if defined(__aarch64__) && !defined(__NR_getrandom) +#define __NR_getrandom 278 +#endif + +#endif // defined(__linux__) + +#endif // BUILD_TOOLCHAIN_CUSTOM_TIZEN_SYSCALL_COMPAT_H_