diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 00000000..f60ff8ae --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,11 @@ +[target.aarch64-unknown-linux-gnu] +linker = "aarch64-linux-gnu-gcc-10" + +[target.armv7-unknown-linux-gnueabihf] +linker = "arm-linux-gnueabihf-gcc-10" + +[target.x86_64-unknown-linux-musl] +rustflags = [ + "-C", + "target-feature=-crt-static", +] diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index 8b74a6da..46e82b39 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -3,6 +3,7 @@ name: CI env: DEBUG: 'napi:*' APP_NAME: 'skia' + MACOSX_DEPLOYMENT_TARGET: '10.13' on: push: @@ -19,10 +20,57 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - - name: stable - ${{ matrix.os }} - node@14 - runs-on: ${{ matrix.os }} + settings: + - host: macos-latest + target: 'x86_64-apple-darwin' + build: yarn build + downloadTarget: '' + - host: windows-latest + build: yarn build + target: 'x86_64-pc-windows-msvc' + downloadTarget: '' + - host: ubuntu-20.04 + target: 'x86_64-unknown-linux-gnu' + downloadTarget: '' + docker: | + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY_URL + docker pull docker.pkg.github.com/brooooooklyn/canvas/debian-builder:stretch + docker tag docker.pkg.github.com/brooooooklyn/canvas/debian-builder:stretch builder + build: | + docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd):/canvas -w /canvas builder yarn build + - host: ubuntu-20.04 + downloadTarget: 'x86_64-unknown-linux-musl' + target: 'x86_64-unknown-linux-musl' + docker: | + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY_URL + docker pull docker.pkg.github.com/brooooooklyn/canvas/musl-builder:lts + docker tag docker.pkg.github.com/brooooooklyn/canvas/musl-builder:lts builder + build: docker run --rm -v ~/.cargo/git:/root/.cargo/git -v ~/.cargo/registry:/root/.cargo/registry -v $(pwd):/canvas -w /canvas builder yarn build + - host: macos-latest + downloadTarget: 'aarch64-apple-darwin' + target: 'aarch64-apple-darwin' + build: yarn build --target=aarch64-apple-darwin + - host: ubuntu-20.04 + downloadTarget: 'aarch64-unknown-linux-gnu' + target: 'aarch64-unknown-linux-gnu' + setup: | + sudo apt-get install g++-10-aarch64-linux-gnu gcc-10-aarch64-linux-gnu -y + build: yarn build --target=aarch64-unknown-linux-gnu + - host: ubuntu-20.04 + target: 'armv7-unknown-linux-gnueabihf' + downloadTarget: 'armv7-unknown-linux-gnueabihf' + setup: | + sudo apt-get install gcc-10-arm-linux-gnueabihf g++-10-arm-linux-gnueabihf -y + build: yarn build --target=armv7-unknown-linux-gnueabihf + - host: ubuntu-20.04 + target: 'aarch64-linux-android' + downloadTarget: 'aarch64-linux-android' + build: | + export CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang" + yarn build --target aarch64-linux-android + + name: stable - ${{ matrix.settings.target }} - node@14 + runs-on: ${{ matrix.settings.host }} steps: - uses: actions/checkout@v2 @@ -36,16 +84,16 @@ jobs: check-latest: true - name: Set env - if: matrix.os == 'windows-latest' + if: matrix.settings.host == 'windows-latest' run: echo "C:\\msys64\\mingw64\\bin" >> $GITHUB_PATH shell: bash - name: Install uses: actions-rs/toolchain@v1 with: - toolchain: stable profile: minimal override: true + target: ${{ matrix.settings.target }} - name: Generate Cargo.lock uses: actions-rs/cargo@v1 @@ -56,54 +104,109 @@ jobs: uses: actions/cache@v1 with: path: ~/.cargo/registry - key: stable-${{ matrix.os }}-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.settings.target }}-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index uses: actions/cache@v1 with: path: ~/.cargo/git - key: stable-${{ matrix.os }}-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.settings.target }}-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache NPM dependencies uses: actions/cache@v1 with: path: node_modules - key: npm-cache-${{ matrix.os }}-node@14-${{ hashFiles('yarn.lock') }} - restore-keys: | - npm-cache- + key: npm-cache-${{ matrix.settings.target }}-node@14-${{ hashFiles('yarn.lock') }} + + - name: Pull latest image + run: ${{ matrix.settings.docker }} + env: + DOCKER_REGISTRY_URL: docker.pkg.github.com + DOCKER_USERNAME: ${{ github.actor }} + DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + if: ${{ matrix.settings.docker }} + + - name: Setup toolchain + run: ${{ matrix.settings.setup }} + if: ${{ matrix.settings.setup }} - name: 'Install dependencies' run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 - name: Download skia binary - run: node ./scripts/release-skia-binary.js --download + run: node ./scripts/release-skia-binary.js --download --target=${{ matrix.settings.downloadTarget }} - name: 'Build' - run: yarn build - env: - MACOSX_DEPLOYMENT_TARGET: '10.13' + run: ${{ matrix.settings.build }} - name: Upload artifact uses: actions/upload-artifact@v2 with: - name: bindings-${{ matrix.os }} + name: bindings-${{ matrix.settings.target }} path: ${{ env.APP_NAME }}.*.node - - name: Clear the cargo caches - run: | - cargo install cargo-cache --no-default-features --features ci-autoclean - cargo-cache + test-macOS-windows-binding: + name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + settings: + - host: macos-latest + target: 'x86_64-apple-darwin' + - host: windows-latest + target: 'x86_64-pc-windows-msvc' + node: ['10', '12', '14', '15'] + runs-on: ${{ matrix.settings.host }} + + steps: + - uses: actions/checkout@v2 + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-test-${{ matrix.settings.target }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-${{ matrix.settings.target }} + path: . + + - name: List packages + run: ls -R . + shell: bash + + - name: Test bindings + run: yarn test - test_binding: - name: Test bindings on ${{ matrix.os }} - node@${{ matrix.node }} + - name: Test failed + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: failure-images-${{ matrix.settings.target }}-${{ matrix.node }} + path: __test__/failure/** + + test-linux-x64-gnu-binding: + name: Test bindings on Linux-x64-gnu - node@${{ matrix.node }} needs: - build strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] node: ['10', '12', '14', '15'] - runs-on: ${{ matrix.os }} + runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 @@ -114,19 +217,59 @@ jobs: node-version: ${{ matrix.node }} check-latest: true - - name: Set platform name - run: | - export NODE_PLATFORM_NAME=$(node -e "console.log(require('os').platform())") - echo "PLATFORM_NAME=${NODE_PLATFORM_NAME}" >> $GITHUB_ENV + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-test-linux-x64-gnu-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-x86_64-unknown-linux-gnu + path: . + + - name: List packages + run: ls -R . shell: bash + - name: Test bindings + run: docker run --rm -v $(pwd):/canvas -w /canvas node:${{ matrix.node }}-slim yarn test + + - name: Test failed + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: failure-images-x86_64-unknown-linux-gnu-${{ matrix.node }} + path: __test__/failure/** + + test-linux-x64-musl-binding: + name: Test bindings on x86_64-unknown-linux-musl - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: ['10', '12', '14', '15'] + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node }} + check-latest: true + - name: Cache NPM dependencies uses: actions/cache@v1 with: path: node_modules - key: npm-cache-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} - restore-keys: | - npm-cache- + key: npm-cache-test-x86_64-unknown-linux-musl-${{ matrix.node }}-${{ hashFiles('yarn.lock') }} - name: 'Install dependencies' run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 @@ -134,7 +277,7 @@ jobs: - name: Download artifacts uses: actions/download-artifact@v2 with: - name: bindings-${{ matrix.os }} + name: bindings-x86_64-unknown-linux-musl path: . - name: List packages @@ -142,20 +285,140 @@ jobs: shell: bash - name: Test bindings - run: yarn test + run: docker run --rm -v $(pwd):/canvas -w /canvas node:${{ matrix.node }}-alpine yarn test + + - name: Test failed + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: failure-images-x86_64-unknown-linux-gnu-${{ matrix.node }} + path: __test__/failure/** + + test-linux-aarch64-gnu-binding: + name: Test bindings on aarch64-unknown-linux-gnu - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: ['10', '12', '14', '15'] + runs-on: ubuntu-20.04 + + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + + - uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-aarch64-unknown-linux-gnu + path: . + + - name: List packages + run: ls -R . + shell: bash + + - uses: uraimo/run-on-arch-action@v2.0.9 + name: Setup and run tests + id: runcmd + with: + arch: aarch64 + distro: ubuntu20.04 + + dockerRunArgs: | + --volume "${PWD}:/canvas" + -w /canvas + + # Not required, but speeds up builds by storing container images in + # a GitHub package registry. + githubToken: ${{ github.token }} + + install: | + apt-get update && \ + apt-get install -y ca-certificates gnupg2 curl apt-transport-https && \ + curl -sL https://deb.nodesource.com/setup_${{ matrix.node }}.x | bash - && \ + apt-get install -y nodejs && \ + npm install -g yarn + run: | + yarn install --ignore-scripts --registry https://registry.npmjs.org --network-timeout 300000 + yarn test + ls -la + + - name: Test failed + if: ${{ failure() }} + uses: actions/upload-artifact@v2 + with: + name: failure-images-aarch64-unknown-linux-gnu-${{ matrix.node }} + path: __test__/failure/** + + test-linux-arm-gnueabihf-binding: + name: Test bindings on armv7-unknown-linux-gnueabihf - node@${{ matrix.node }} + needs: + - build + strategy: + fail-fast: false + matrix: + node: ['10', '12', '14', '15'] + runs-on: ubuntu-20.04 + + steps: + - run: docker run --rm --privileged multiarch/qemu-user-static:register --reset + + - uses: actions/checkout@v2 + + - name: Download artifacts + uses: actions/download-artifact@v2 + with: + name: bindings-armv7-unknown-linux-gnueabihf + path: . + + - name: List packages + run: ls -R . + shell: bash + + - uses: uraimo/run-on-arch-action@v2.0.9 + name: Setup and run tests + id: runcmd + with: + arch: armv7 + distro: ubuntu20.04 + + dockerRunArgs: | + --volume "${PWD}:/canvas" + -w /canvas + + # Not required, but speeds up builds by storing container images in + # a GitHub package registry. + githubToken: ${{ github.token }} + + install: | + apt-get update && \ + apt-get install -y ca-certificates gnupg2 curl apt-transport-https && \ + curl -sL https://deb.nodesource.com/setup_${{ matrix.node }}.x | bash - && \ + apt-get install -y nodejs && \ + npm install -g yarn + run: | + yarn install --ignore-scripts --registry https://registry.npmjs.org --network-timeout 300000 + yarn test + ls -la - name: Test failed if: ${{ failure() }} uses: actions/upload-artifact@v2 with: - name: failure-images-${{ matrix.os }}-${{ matrix.node }} + name: failure-images-armv7-unknown-linux-gnueabihf-${{ matrix.node }} path: __test__/failure/** dependabot: needs: - - test_binding + - test-linux-x64-gnu-binding + - test-linux-x64-musl-binding + - test-linux-aarch64-gnu-binding + - test-linux-arm-gnueabihf-binding + - test-macOS-windows-binding - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 steps: - name: auto-merge uses: ridedott/dependabot-auto-merge-action@master @@ -165,9 +428,13 @@ jobs: publish: name: Publish - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 needs: - - test_binding + - test-linux-x64-gnu-binding + - test-linux-x64-musl-binding + - test-linux-aarch64-gnu-binding + - test-linux-arm-gnueabihf-binding + - test-macOS-windows-binding steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 3601b0f6..9048620d 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -29,7 +29,6 @@ jobs: - name: Install uses: actions-rs/toolchain@v1 with: - toolchain: stable profile: default override: true diff --git a/.github/workflows/cargo-test.yaml b/.github/workflows/cargo-test.yaml index fdf813ed..32d9c3e6 100644 --- a/.github/workflows/cargo-test.yaml +++ b/.github/workflows/cargo-test.yaml @@ -26,7 +26,6 @@ jobs: - name: Install uses: actions-rs/toolchain@v1 with: - toolchain: stable profile: minimal override: true @@ -39,13 +38,13 @@ jobs: uses: actions/cache@v1 with: path: ~/.cargo/registry - key: stable-${{ matrix.os }}-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.os }}-node@14-cargo-registry-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index uses: actions/cache@v1 with: path: ~/.cargo/git - key: stable-${{ matrix.os }}-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} + key: ${{ matrix.os }}-node@14-cargo-index-trimmed-${{ hashFiles('**/Cargo.lock') }} - name: Cache NPM dependencies uses: actions/cache@v1 @@ -63,8 +62,3 @@ jobs: - name: Test run: cargo test -- --nocapture - - - name: Clear the cargo caches - run: | - cargo install cargo-cache --no-default-features --features ci-autoclean - cargo-cache diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..ab7340e4 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,30 @@ +name: Docker nightly build + +on: + schedule: + - cron: '0 1 * * *' + +jobs: + build_image: + name: Build debian-builder:stretch + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + + - name: Login to registry + run: | + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY_URL + env: + DOCKER_REGISTRY_URL: docker.pkg.github.com + DOCKER_USERNAME: ${{ github.actor }} + DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + + - name: Build docker image + run: | + docker build . --pull -t docker.pkg.github.com/brooooooklyn/canvas/debian-builder:stretch + docker build . --pull --no-cache -f musl.Dockerfile -t docker.pkg.github.com/brooooooklyn/canvas/musl-builder:lts + - name: Push docker image + run: | + docker push docker.pkg.github.com/brooooooklyn/canvas/debian-builder:stretch + docker push docker.pkg.github.com/brooooooklyn/canvas/musl-builder:lts diff --git a/.github/workflows/skia.yaml b/.github/workflows/skia.yaml index b6a37d7f..748838ae 100644 --- a/.github/workflows/skia.yaml +++ b/.github/workflows/skia.yaml @@ -13,7 +13,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] + os: [ubuntu-20.04, macos-latest, windows-latest] name: stable - ${{ matrix.os }} - build skia runs-on: ${{ matrix.os }} @@ -29,6 +29,11 @@ jobs: node-version: 14 check-latest: true + - uses: actions/setup-python@v2 + with: + python-version: '2.x' + architecture: 'x64' + - name: Set env run: echo "${PWD}/depot_tools" >> $GITHUB_PATH shell: bash @@ -41,14 +46,27 @@ jobs: if: matrix.os == 'windows-latest' run: | choco install llvm ninja -y - choco upgrade python -y pip install certifi - name: Compile skia - if: matrix.os != 'windows-latest' + if: matrix.os == 'ubuntu-20.04' + run: | + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY_URL + docker pull docker.pkg.github.com/brooooooklyn/canvas/debian-builder:stretch + docker tag docker.pkg.github.com/brooooooklyn/canvas/debian-builder:stretch builder + docker run --user "$(id -u):$(id -g)" --rm -v $(pwd):/canvas -w /canvas builder node ./scripts/build-skia.js env: PYTHONHTTPSVERIFY: 0 - run: node ./scripts/build-skia.js + DOCKER_REGISTRY_URL: docker.pkg.github.com + DOCKER_USERNAME: ${{ github.actor }} + DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + + - name: Compile skia + if: matrix.os == 'macos-latest' + env: + PYTHONHTTPSVERIFY: 0 + run: | + node ./scripts/build-skia.js - name: Compile skia shell: powershell @@ -72,3 +90,237 @@ jobs: run: node ./scripts/release-skia-binary.js --upload env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-apple-silicon: + if: "!contains(github.event.head_commit.message, 'skip skia')" + + name: stable - apple-silicon - build skia + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true + + - uses: actions/setup-python@v2 + with: + python-version: '2.x' + architecture: 'x64' + + - name: Set env + run: echo "${PWD}/depot_tools" >> $GITHUB_PATH + shell: bash + + - name: Install tools on macOS + run: brew install ninja + + - name: Compile skia + run: node ./scripts/build-skia.js --target=aarch64-apple-darwin + + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-apple-silicon-node@14-${{ hashFiles('yarn.lock') }} + restore-keys: | + npm-cache- + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Upload release + run: node ./scripts/release-skia-binary.js --upload --target=aarch64-apple-darwin + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-x64-linux-musl: + if: "!contains(github.event.head_commit.message, 'skip skia')" + + name: stable - linux-x64-musl - build skia + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true + + - name: Compile skia + run: | + docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD $DOCKER_REGISTRY_URL + docker pull docker.pkg.github.com/brooooooklyn/canvas/musl-builder:lts + docker tag docker.pkg.github.com/brooooooklyn/canvas/musl-builder:lts builder + docker run --user "$(id -u):$(id -g)" --rm -v $(pwd):/canvas -w /canvas builder node ./scripts/build-skia.js + env: + PYTHONHTTPSVERIFY: 0 + DOCKER_REGISTRY_URL: docker.pkg.github.com + DOCKER_USERNAME: ${{ github.actor }} + DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} + + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-linux-x64-musl-node@14-${{ hashFiles('yarn.lock') }} + restore-keys: | + npm-cache- + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Upload release + run: node ./scripts/release-skia-binary.js --upload --target=x86_64-unknown-linux-musl + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-aarch64-linux-gnu: + if: "!contains(github.event.head_commit.message, 'skip skia')" + + name: stable - aarch64-linux - build skia + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true + + - uses: actions/setup-python@v2 + with: + python-version: '2.x' + architecture: 'x64' + + - name: Set env + run: echo "${PWD}/depot_tools" >> $GITHUB_PATH + shell: bash + + - name: Install cross compile tools + run: sudo apt-get install g++-10-aarch64-linux-gnu gcc-10-aarch64-linux-gnu -y + + - name: Compile skia + run: node ./scripts/build-skia.js --target=aarch64-unknown-linux-gnu + + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-aarch64-linux-node@14-${{ hashFiles('yarn.lock') }} + restore-keys: | + npm-cache- + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Upload release + run: node ./scripts/release-skia-binary.js --upload --target=aarch64-unknown-linux-gnu + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-armv7-linux-gnu: + if: "!contains(github.event.head_commit.message, 'skip skia')" + + name: stable - armv7-linux - build skia + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true + + - uses: actions/setup-python@v2 + with: + python-version: '2.x' + architecture: 'x64' + + - name: Set env + run: echo "${PWD}/depot_tools" >> $GITHUB_PATH + shell: bash + + - name: Install cross compile tools + run: sudo apt-get install gcc-10-arm-linux-gnueabihf g++-10-arm-linux-gnueabihf -y + + - name: Compile skia + run: node ./scripts/build-skia.js --target=armv7-unknown-linux-gnueabihf + + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-armv7-linux-node@14-${{ hashFiles('yarn.lock') }} + restore-keys: | + npm-cache- + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Upload release + run: node ./scripts/release-skia-binary.js --upload --target=armv7-unknown-linux-gnueabihf + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + build-aarch64-linux-android: + if: "!contains(github.event.head_commit.message, 'skip skia')" + + name: stable - aarch64-linux-android - build skia + runs-on: ubuntu-20.04 + + steps: + - uses: actions/checkout@v2 + with: + submodules: true + + - name: Setup node + uses: actions/setup-node@v2 + with: + node-version: 14 + check-latest: true + + - uses: actions/setup-python@v2 + with: + python-version: '2.x' + architecture: 'x64' + + - name: Set env + run: echo "${PWD}/depot_tools" >> $GITHUB_PATH + shell: bash + + - name: Compile skia + run: node ./scripts/build-skia.js --target=aarch64-linux-android + + - name: Cache NPM dependencies + uses: actions/cache@v1 + with: + path: node_modules + key: npm-cache-armv7-linux-node@14-${{ hashFiles('yarn.lock') }} + restore-keys: | + npm-cache- + + - name: 'Install dependencies' + run: yarn install --ignore-scripts --frozen-lockfile --registry https://registry.npmjs.org --network-timeout 300000 + + - name: Upload release + run: node ./scripts/release-skia-binary.js --upload --target=aarch64-linux-android + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/Cargo.toml b/Cargo.toml index 1aec1b5a..37b2aba0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["strip"] + [package] authors = ["LongYinan "] edition = "2018" @@ -16,7 +18,7 @@ once_cell = "1.5" regex = "1.4" thiserror = "1.0" -[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64")))'.dependencies] +[target.'cfg(all(unix, not(target_env = "musl"), not(target_arch = "aarch64"), not(target_arch = "arm")))'.dependencies] jemallocator = {version = "0.3", features = ["disable_initial_exec_tls"]} [build-dependencies] @@ -24,5 +26,5 @@ cc = "1" napi-build = "1" [profile.release] -codegen-units = 1 -opt-level = 3 +lto = true +strip = 'symbols' diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..0f7a949a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM node:lts + +ENV RUSTUP_HOME=/usr/local/rustup \ + CARGO_HOME=/usr/local/cargo \ + PATH=/usr/local/cargo/bin:$PATH + +RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - && \ + echo "deb http://apt.llvm.org/stretch/ llvm-toolchain-stretch main" >> /etc/apt/sources.list && \ + echo "deb-src http://apt.llvm.org/stretch/ llvm-toolchain-stretch main" >> /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y --fix-missing \ + llvm \ + clang \ + rcs \ + ninja-build && \ + curl https://sh.rustup.rs -sSf | sh -s -- -y diff --git a/README.md b/README.md index de010938..7daf9003 100644 --- a/README.md +++ b/README.md @@ -2,18 +2,23 @@ ![CI](https://github.com/Brooooooklyn/canvas/workflows/CI/badge.svg) -Google Skia binding to NodeJS via `N-API`. +Google Skia binding to Node.js via `N-API`. > ⚠️ This project is in very early stage.
> For details on planned features and future direction please refer to the [Roadmap](https://github.com/Brooooooklyn/canvas/issues/113). # Support matrix -| | node10 | node12 | node14 | node15 | -| ----------- | ------ | ------ | ------ | ------ | -| Windows x64 | ✅ | ✅ | ✅ | ✅ | -| macOS x64 | ✅ | ✅ | ✅ | ✅ | -| Linux x64 | ✅ | ✅ | ✅ | ✅ | +| | node10 | node12 | node14 | node15 | +| --------------------- | ------ | ------ | ------ | ------ | +| Windows x64 | ✓ | ✓ | ✓ | ✓ | +| macOS x64 | ✓ | ✓ | ✓ | ✓ | +| macOS aarch64 | ✓ | ✓ | ✓ | ✓ | +| Linux x64 gnu | ✓ | ✓ | ✓ | ✓ | +| Linux x64 musl | ✓ | ✓ | ✓ | ✓ | +| Linux aarch64 gnu | ✓ | ✓ | ✓ | ✓ | +| Linux arm gnueabihf | ✓ | ✓ | ✓ | ✓ | +| Linux aarch64 android | ✓ | ✓ | ✓ | ✓ | # Usage @@ -110,6 +115,8 @@ export class Path2D { # Building +## Build skia from source + You can build this project from source, with no OS-specific package installing commands required: ```sh @@ -122,7 +129,29 @@ $ node scripts/build-skia.js # Install NPM packages, build the Node.js addon: $ yarn install --ignore-scripts -$ yarn run build +$ yarn build + +# All done! Run test cases or examples now: +$ yarn test +$ node example/tiger.js +``` + +## Pull pre-build skia binary from Github + +You can pull skia pre-build binaries if you just care the `Rust` part: + +```sh +# Clone the code: +$ git clone --recurse-submodules https://github.com/Brooooooklyn/canvas.git +$ cd canvas + +# Download Skia binaries: +# It will pull the binaries match the git hash in `./skia` submodule +$ node scripts/release-skia-binary.js --download + +# Install NPM packages, build the Node.js addon: +$ yarn install --ignore-scripts +$ yarn build # All done! Run test cases or examples now: $ yarn test diff --git a/build.rs b/build.rs index 38e075a2..2db7d9be 100644 --- a/build.rs +++ b/build.rs @@ -2,6 +2,7 @@ extern crate napi_build; use std::env; use std::path; +use std::process; fn main() { println!("cargo:rerun-if-env-changed=SKIA_DIR"); @@ -10,6 +11,8 @@ fn main() { println!("cargo:rerun-if-changed=skia-c/skia_c.cpp"); println!("cargo:rerun-if-changed=skia-c/skia_c.hpp"); + let compile_target = env::var("TARGET").unwrap(); + #[cfg(target_os = "windows")] { env::set_var("CC", "clang-cl"); @@ -28,11 +31,95 @@ fn main() { let mut build = cc::Build::new(); - build - .cpp(true) - .file("skia-c/skia_c.cpp") - .include("skia-c") - .include(skia_path); + build.cpp(true).file("skia-c/skia_c.cpp"); + + match compile_target.as_str() { + "aarch64-unknown-linux-gnu" => { + build + .flag("--sysroot=/usr/aarch64-linux-gnu") + .flag("--gcc-toolchain=aarch64-linux-gnu-gcc") + .include("/usr/aarch64-linux-gnu/include/c++/10") + .include("/usr/aarch64-linux-gnu/include/c++/10/aarch64-linux-gnu"); + } + "armv7-unknown-linux-gnueabihf" => { + build + .flag("--sysroot=/usr/arm-linux-gnueabihf") + .flag("--gcc-toolchain=arm-linux-gnueabihf-gcc-10") + .include("/usr/arm-linux-gnueabihf/include/c++/10") + .include("/usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf"); + } + "x86_64-unknown-linux-musl" => { + let gcc_version = String::from_utf8( + process::Command::new("ls") + .arg("/usr/include/c++") + .output() + .unwrap() + .stdout, + ) + .unwrap(); + let gcc_version_trim = gcc_version.trim(); + build + .static_flag(true) + .include("/usr/include") + .include(format!("/usr/include/c++/{}", gcc_version_trim)) + .include(format!( + "/usr/include/c++/{}/x86_64-alpine-linux-musl", + gcc_version_trim + )); + } + "aarch64-apple-darwin" => { + build.target("arm64-apple-darwin"); + } + "aarch64-linux-android" => { + let nkd_home = env::var("ANDROID_NDK_HOME").unwrap(); + env::set_var( + "CC", + format!( + "{}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang", + nkd_home + ) + .as_str(), + ); + env::set_var( + "CXX", + format!( + "{}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang++", + nkd_home + ) + .as_str(), + ); + build + .include( + format!( + "{}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include", + nkd_home + ) + .as_str(), + ) + .include( + format!( + "{}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/c++/v1", + nkd_home + ) + .as_str(), + ) + .include( + format!( + "{}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/include/aarch64-linux-android", + nkd_home + ) + .as_str(), + ) + .archiver( + format!( + "{}/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar", + nkd_home + ) + .as_str(), + ); + } + _ => {} + } #[cfg(target_os = "windows")] { @@ -48,6 +135,11 @@ fn main() { build.cpp_set_stdlib("stdc++"); } + #[cfg(target_os = "macos")] + { + build.cpp_set_stdlib("c++"); + } + #[cfg(not(target_os = "windows"))] { build @@ -70,12 +162,18 @@ fn main() { println!("cargo:rustc-link-lib=framework=ApplicationServices"); } + let out_dir = env::var("OUT_DIR").unwrap(); + build + .include("./skia-c") + .include(skia_path) .cargo_metadata(true) - .out_dir(env::var("OUT_DIR").unwrap()) + .out_dir(&out_dir) .compile("skiac"); println!("cargo:rustc-link-search={}", skia_lib_dir); + println!("cargo:rustc-link-search={}", &out_dir); + #[cfg(target_os = "linux")] { println!("cargo:rustc-link-lib=static=skia"); diff --git a/musl.Dockerfile b/musl.Dockerfile new file mode 100644 index 00000000..ffb0dddf --- /dev/null +++ b/musl.Dockerfile @@ -0,0 +1,21 @@ +FROM node:lts-alpine + +ENV PATH="/usr/local/cargo/bin/rustup:/root/.cargo/bin:$PATH" \ + CC="clang" \ + CXX="clang++" \ + GN_EXE=gn + +RUN sed -i -e 's/v[[:digit:]]\..*\//edge\//g' /etc/apk/repositories && \ + apk add --update --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/testing \ + rustup \ + bash \ + python3 \ + python2 \ + git \ + musl-dev \ + build-base \ + clang \ + llvm \ + gn \ + ninja && \ + rustup-init -y diff --git a/npm/android-arm64/README.md b/npm/android-arm64/README.md new file mode 100644 index 00000000..3ff76885 --- /dev/null +++ b/npm/android-arm64/README.md @@ -0,0 +1,3 @@ +# `@napi-rs/canvas-android-arm64` + +This is the **aarch64-linux-android** binary for `@napi-rs/canvas` diff --git a/npm/android-arm64/package.json b/npm/android-arm64/package.json new file mode 100644 index 00000000..ef2c89ce --- /dev/null +++ b/npm/android-arm64/package.json @@ -0,0 +1,31 @@ +{ + "name": "@napi-rs/canvas-android-arm64", + "version": "0.0.1-alpha.3", + "os": ["android"], + "cpu": ["arm64"], + "main": "skia.android-arm64.node", + "files": ["skia.android-arm64.node"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": "https://github.com/Brooooooklyn/canvas.git" +} diff --git a/npm/darwin-arm64/README.md b/npm/darwin-arm64/README.md new file mode 100644 index 00000000..36f901c4 --- /dev/null +++ b/npm/darwin-arm64/README.md @@ -0,0 +1,3 @@ +# `@napi-rs/canvas-darwin-arm64` + +This is the **aarch64-apple-darwin** binary for `@napi-rs/canvas` diff --git a/npm/darwin-arm64/package.json b/npm/darwin-arm64/package.json new file mode 100644 index 00000000..88adf575 --- /dev/null +++ b/npm/darwin-arm64/package.json @@ -0,0 +1,31 @@ +{ + "name": "@napi-rs/canvas-darwin-arm64", + "version": "0.0.1-alpha.3", + "os": ["darwin"], + "cpu": ["arm64"], + "main": "skia.darwin-arm64.node", + "files": ["skia.darwin-arm64.node"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": "https://github.com/Brooooooklyn/canvas.git" +} diff --git a/npm/darwin-x64/README.md b/npm/darwin-x64/README.md index 368bbb82..b464a356 100644 --- a/npm/darwin-x64/README.md +++ b/npm/darwin-x64/README.md @@ -1,3 +1,3 @@ -# `@napi-rs/skia-darwin-x64` +# `@napi-rs/canvas-darwin-x64` -This is the **x86_64-apple-darwin** binary for `@napi-rs/skia` +This is the **x86_64-apple-darwin** binary for `@napi-rs/canvas` diff --git a/npm/darwin-x64/package.json b/npm/darwin-x64/package.json index d42a98b8..db6deb53 100644 --- a/npm/darwin-x64/package.json +++ b/npm/darwin-x64/package.json @@ -1,12 +1,24 @@ { - "name": "@napi-rs/skia-darwin-x64", + "name": "@napi-rs/canvas-darwin-x64", "version": "0.0.1-alpha.3", "os": ["darwin"], "cpu": ["x64"], "main": "skia.darwin-x64.node", "files": ["skia.darwin-x64.node"], - "description": "Template project for writing node package with napi-rs", - "keywords": ["napi-rs", "NAPI", "N-API", "Rust", "node-addon", "node-addon-api"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/npm/linux-arm-gnueabihf/README.md b/npm/linux-arm-gnueabihf/README.md new file mode 100644 index 00000000..4c4e56c2 --- /dev/null +++ b/npm/linux-arm-gnueabihf/README.md @@ -0,0 +1,3 @@ +# `@napi-rs/canvas-linux-arm-gnueabihf` + +This is the **armv7-unknown-linux-gnueabihf** binary for `@napi-rs/canvas` diff --git a/npm/linux-arm-gnueabihf/package.json b/npm/linux-arm-gnueabihf/package.json new file mode 100644 index 00000000..afe56438 --- /dev/null +++ b/npm/linux-arm-gnueabihf/package.json @@ -0,0 +1,31 @@ +{ + "name": "@napi-rs/canvas-linux-arm-gnueabihf", + "version": "0.0.1-alpha.3", + "os": ["linux"], + "cpu": ["arm"], + "main": "skia.linux-arm-gnueabihf.node", + "files": ["skia.linux-arm-gnueabihf.node"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": "https://github.com/Brooooooklyn/canvas.git" +} diff --git a/npm/linux-arm64-gnu/README.md b/npm/linux-arm64-gnu/README.md new file mode 100644 index 00000000..f77016bc --- /dev/null +++ b/npm/linux-arm64-gnu/README.md @@ -0,0 +1,3 @@ +# `@napi-rs/canvas-linux-arm64-gnu` + +This is the **aarch64-unknown-linux-gnu** binary for `@napi-rs/canvas` diff --git a/npm/linux-arm64-gnu/package.json b/npm/linux-arm64-gnu/package.json new file mode 100644 index 00000000..9fe168ed --- /dev/null +++ b/npm/linux-arm64-gnu/package.json @@ -0,0 +1,31 @@ +{ + "name": "@napi-rs/canvas-linux-arm64-gnu", + "version": "0.0.1-alpha.3", + "os": ["linux"], + "cpu": ["arm64"], + "main": "skia.linux-arm64-gnu.node", + "files": ["skia.linux-arm64-gnu.node"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": "https://github.com/Brooooooklyn/canvas.git" +} diff --git a/npm/linux-x64-gnu/README.md b/npm/linux-x64-gnu/README.md index c4754c82..01202461 100644 --- a/npm/linux-x64-gnu/README.md +++ b/npm/linux-x64-gnu/README.md @@ -1,3 +1,3 @@ -# `@napi-rs/skia-linux-x64-gnu` +# `@napi-rs/canvas-linux-x64-gnu` -This is the **x86_64-unknown-linux-gnu** binary for `@napi-rs/skia` +This is the **x86_64-unknown-linux-gnu** binary for `@napi-rs/canvas` diff --git a/npm/linux-x64-gnu/package.json b/npm/linux-x64-gnu/package.json index 7697d0d3..ec4098bc 100644 --- a/npm/linux-x64-gnu/package.json +++ b/npm/linux-x64-gnu/package.json @@ -1,12 +1,24 @@ { - "name": "@napi-rs/skia-linux-x64-gnu", + "name": "@napi-rs/canvas-linux-x64-gnu", "version": "0.0.1-alpha.3", "os": ["linux"], "cpu": ["x64"], "main": "skia.linux-x64-gnu.node", "files": ["skia.linux-x64-gnu.node"], - "description": "Template project for writing node package with napi-rs", - "keywords": ["napi-rs", "NAPI", "N-API", "Rust", "node-addon", "node-addon-api"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/npm/linux-x64-musl/README.md b/npm/linux-x64-musl/README.md new file mode 100644 index 00000000..8908007f --- /dev/null +++ b/npm/linux-x64-musl/README.md @@ -0,0 +1,3 @@ +# `@napi-rs/canvas-linux-x64-musl` + +This is the **x86_64-unknown-linux-musl** binary for `@napi-rs/canvas` diff --git a/npm/linux-x64-musl/package.json b/npm/linux-x64-musl/package.json new file mode 100644 index 00000000..86bcf0e1 --- /dev/null +++ b/npm/linux-x64-musl/package.json @@ -0,0 +1,31 @@ +{ + "name": "@napi-rs/canvas-linux-x64-musl", + "version": "0.0.1-alpha.3", + "os": ["linux"], + "cpu": ["x64"], + "main": "skia.linux-x64-musl.node", + "files": ["skia.linux-x64-musl.node"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public" + }, + "repository": "https://github.com/Brooooooklyn/canvas.git" +} diff --git a/npm/win32-x64-msvc/README.md b/npm/win32-x64-msvc/README.md index f92f791d..f2b4f2ac 100644 --- a/npm/win32-x64-msvc/README.md +++ b/npm/win32-x64-msvc/README.md @@ -1,3 +1,3 @@ -# `@napi-rs/skia-win32-x64-msvc` +# `@napi-rs/canvas-win32-x64-msvc` -This is the **x86_64-pc-windows-msvc** binary for `@napi-rs/skia` +This is the **x86_64-pc-windows-msvc** binary for `@napi-rs/canvas` diff --git a/npm/win32-x64-msvc/package.json b/npm/win32-x64-msvc/package.json index b87f2613..91be7b00 100644 --- a/npm/win32-x64-msvc/package.json +++ b/npm/win32-x64-msvc/package.json @@ -1,12 +1,24 @@ { - "name": "@napi-rs/skia-win32-x64-msvc", + "name": "@napi-rs/canvas-win32-x64-msvc", "version": "0.0.1-alpha.3", "os": ["win32"], "cpu": ["x64"], "main": "skia.win32-x64-msvc.node", "files": ["skia.win32-x64-msvc.node"], - "description": "Template project for writing node package with napi-rs", - "keywords": ["napi-rs", "NAPI", "N-API", "Rust", "node-addon", "node-addon-api"], + "description": "Canvas for Node.js with skia backend", + "keywords": [ + "napi-rs", + "NAPI", + "N-API", + "Rust", + "node-addon", + "node-addon-api", + "canvas", + "image", + "pdf", + "svg", + "skia" + ], "license": "MIT", "engines": { "node": ">= 10" diff --git a/package.json b/package.json index 660667d2..4d6b9055 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,19 @@ "svg", "skia" ], - "files": ["index.d.ts", "index.js"], + "files": ["index.d.ts", "index.js", "geometry.js"], "napi": { - "name": "skia" + "name": "skia", + "triples": { + "defaults": true, + "additional": [ + "armv7-unknown-linux-gnueabihf", + "x86_64-unknown-linux-musl", + "aarch64-unknown-linux-gnu", + "aarch64-apple-darwin", + "aarch64-linux-android" + ] + } }, "engines": { "node": ">= 10" @@ -87,7 +97,8 @@ "require": ["@swc-node/register"], "extensions": ["ts"], "environmentVariables": { - "SWC_NODE_PROJECT": "./tsconfig.json" + "SWC_NODE_PROJECT": "./tsconfig.json", + "NODE_ENV": "ava" } }, "prettier": { diff --git a/rust-toolchain b/rust-toolchain new file mode 100644 index 00000000..07ade694 --- /dev/null +++ b/rust-toolchain @@ -0,0 +1 @@ +nightly \ No newline at end of file diff --git a/scripts/__test__/utils.spec.ts b/scripts/__test__/utils.spec.ts new file mode 100644 index 00000000..14e4baec --- /dev/null +++ b/scripts/__test__/utils.spec.ts @@ -0,0 +1,25 @@ +import { sep } from 'path' + +import test from 'ava' + +const { libPath } = require('../utils') + +const TEST_MATRIX = [ + { platform: 'win32' }, + { platform: 'linux' }, + { platform: 'darwin' }, + { platform: 'linux', triple: 'aarch64-unknown-linux-gnu' }, + { platform: 'linux', triple: 'armv7-unknown-linux-gnueabihf' }, + { platform: 'linux', triple: 'x86_64-unknown-linux-musl' }, + { platform: 'linux', triple: 'aarch64-linux-android' }, +] + +for (const { platform, triple } of TEST_MATRIX) { + const title = triple ? `parse ${triple} path` : `parse ${platform} path` + test(title, (t) => { + const { downloadUrl, binary, copy } = libPath('skia', platform, triple, '000') + t.snapshot(downloadUrl) + t.snapshot(binary.replace(process.cwd(), '').split(sep).join('/')) + t.snapshot(copy.replace(process.cwd(), '').split(sep).join('/')) + }) +} diff --git a/scripts/__test__/utils.spec.ts.md b/scripts/__test__/utils.spec.ts.md new file mode 100644 index 00000000..625c1db1 --- /dev/null +++ b/scripts/__test__/utils.spec.ts.md @@ -0,0 +1,103 @@ +# Snapshot report for `scripts/__test__/utils.spec.ts` + +The actual snapshot is saved in `utils.spec.ts.snap`. + +Generated by [AVA](https://avajs.dev). + +## parse win32 path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/skia-win32-x64-msvc.lib' + +> Snapshot 2 + + '/skia/out/Static/skia.lib' + +> Snapshot 3 + + '/skia-win32-x64-msvc.lib' + +## parse linux path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/libskia-linux-x64-gnu.a' + +> Snapshot 2 + + '/skia/out/Static/libskia.a' + +> Snapshot 3 + + '/libskia-linux-x64-gnu.a' + +## parse darwin path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/libskia-darwin-x64.a' + +> Snapshot 2 + + '/skia/out/Static/libskia.a' + +> Snapshot 3 + + '/libskia-darwin-x64.a' + +## parse aarch64-unknown-linux-gnu path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/libskia-linux-aarch64-gnu.a' + +> Snapshot 2 + + '/skia/out/Static/libskia.a' + +> Snapshot 3 + + '/libskia-linux-aarch64-gnu.a' + +## parse armv7-unknown-linux-gnueabihf path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/libskia-linux-armv7-gnueabihf.a' + +> Snapshot 2 + + '/skia/out/Static/libskia.a' + +> Snapshot 3 + + '/libskia-linux-armv7-gnueabihf.a' + +## parse x86_64-unknown-linux-musl path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/libskia-linux-x64-musl.a' + +> Snapshot 2 + + '/skia/out/Static/libskia.a' + +> Snapshot 3 + + '/libskia-linux-x64-musl.a' + +## parse aarch64-linux-android path + +> Snapshot 1 + + 'https://github.com/Brooooooklyn/canvas/releases/download/000/libskia-android-aarch64.a' + +> Snapshot 2 + + '/skia/out/Static/libskia.a' + +> Snapshot 3 + + '/libskia-android-aarch64.a' diff --git a/scripts/__test__/utils.spec.ts.snap b/scripts/__test__/utils.spec.ts.snap new file mode 100644 index 00000000..7e18de93 Binary files /dev/null and b/scripts/__test__/utils.spec.ts.snap differ diff --git a/scripts/build-skia.js b/scripts/build-skia.js index a315ac23..f591a95c 100644 --- a/scripts/build-skia.js +++ b/scripts/build-skia.js @@ -2,7 +2,14 @@ const { execSync } = require('child_process') const path = require('path') const { platform } = require('os') -const platformName = platform() +const PLATFORM_NAME = platform() + +const [, , TARGET] = process.argv + +let TARGET_TRIPLE = '' +if (TARGET && TARGET.startsWith('--target=')) { + TARGET_TRIPLE = TARGET.replace('--target=', '') +} function exec(command) { console.info(command) @@ -10,54 +17,32 @@ function exec(command) { stdio: 'inherit', cwd: path.join(__dirname, '..', 'skia'), env: process.env, - shell: platformName === 'win32' ? 'powershell' : 'bash', + shell: PLATFORM_NAME === 'win32' ? 'powershell' : 'bash', }) } exec('python ./tools/git-sync-deps') -const CC = platformName === 'win32' ? '\\"clang-cl\\"' : platformName === 'linux' ? '"clang-9"' : '"clang"' -const CXX = platformName === 'win32' ? '\\"clang-cl\\"' : platformName === 'linux' ? '"clang++-9"' : '"clang++"' +const CC = PLATFORM_NAME === 'win32' ? '\\"clang-cl\\"' : '"clang"' +const CXX = PLATFORM_NAME === 'win32' ? '\\"clang-cl\\"' : '"clang++"' let ExtraCflagsCC = '' let ExtraSkiaBuildFlag = '' -switch (platformName) { - case 'win32': - ExtraCflagsCC = `\\"/std:c++17\\", \\"/MT\\", \\"-DSK_FORCE_RASTER_PIPELINE_BLITTER\\"` - ExtraSkiaBuildFlag = 'clang_win=\\"C:\\\\Program Files\\\\LLVM\\"' - break - case 'linux': - ExtraCflagsCC = '"-std=c++17", "-fno-rtti", "-fno-exceptions", "-DSK_FORCE_RASTER_PIPELINE_BLITTER"' - ExtraSkiaBuildFlag = ['skia_use_system_freetype2=false', 'skia_use_fontconfig=false'].join(' ') - break - case 'darwin': - ExtraCflagsCC = '"-std=c++17", "-fno-rtti", "-fno-exceptions", "-DSK_FORCE_RASTER_PIPELINE_BLITTER"' - break - default: - throw new TypeError(`Don't support ${platformName} for now`) -} - -const OUTPUT_PATH = path.join('out', 'Static') const GN_ARGS = [ `is_official_build=false`, `is_component_build=false`, `is_debug=false`, - `cc=${CC}`, - `cxx=${CXX}`, - `extra_cflags_cc=[${ExtraCflagsCC}]`, `werror=false`, `paragraph_gms_enabled=false`, `paragraph_tests_enabled=false`, `skia_enable_android_utils=false`, `skia_enable_discrete_gpu=false`, `skia_enable_gpu=false`, - `skia_enable_nvpr=false`, `skia_enable_particles=true`, `skia_enable_pdf=true`, `skia_enable_skottie=false`, `skia_enable_skrive=false`, `skia_enable_skshaper=true`, - `skia_enable_sksl_interpreter=false`, `skia_enable_tools=false`, `skia_use_expat=false`, `skia_use_gl=false`, @@ -65,18 +50,121 @@ const GN_ARGS = [ `skia_pdf_subset_harfbuzz=true`, `skia_use_sfntly=false`, `skia_enable_skparagraph=true`, - `skia_use_icu=false`, - `skia_use_libgifcodec=false`, - `skia_use_libheif=false`, - `skia_use_libjpeg_turbo_decode=false`, - `skia_use_libjpeg_turbo_encode=false`, - `skia_use_libwebp_decode=false`, - `skia_use_libwebp_encode=false`, + `skia_use_icu=true`, + `skia_use_libgifcodec=true`, + `skia_use_libheif=true`, + `skia_use_libjpeg_turbo_decode=true`, + `skia_use_libjpeg_turbo_encode=true`, + `skia_use_libwebp_decode=true`, + `skia_use_libwebp_encode=true`, `skia_use_lua=false`, - ExtraSkiaBuildFlag, `skia_use_piex=false`, -].join(' ') +] -exec(`${path.join('bin', 'gn')} gen ${OUTPUT_PATH} --args='${GN_ARGS}'`) +switch (PLATFORM_NAME) { + case 'win32': + ExtraCflagsCC = `\\"/std:c++17\\", \\"/MT\\", \\"-DSK_FORCE_RASTER_PIPELINE_BLITTER\\"` + ExtraSkiaBuildFlag = 'clang_win=\\"C:\\\\Program Files\\\\LLVM\\"' + break + case 'linux': + ExtraCflagsCC = '"-std=c++17", "-fno-exceptions", "-DSK_FORCE_RASTER_PIPELINE_BLITTER"' + ExtraSkiaBuildFlag = ['skia_use_system_freetype2=false', 'skia_use_fontconfig=false'].join(' ') + break + case 'darwin': + ExtraCflagsCC = '"-std=c++17", "-fno-exceptions", "-DSK_FORCE_RASTER_PIPELINE_BLITTER"' + break + default: + throw new TypeError(`Don't support ${PLATFORM_NAME} for now`) +} + +let ExtraCflags +let ExtraLdFlags +let ExtraAsmFlags + +switch (TARGET_TRIPLE) { + case 'aarch64-unknown-linux-gnu': + ExtraSkiaBuildFlag += ' target_cpu="arm64" target_os="linux"' + ExtraCflags = + '"--target=aarch64-unknown-linux-gnu", "--sysroot=/usr/aarch64-linux-gnu", "--gcc-toolchain=aarch64-linux-gnu-gcc-10", "-B/usr/aarch64-linux-gnu/bin", "-I/usr/aarch64-linux-gnu/include/c++/10", "-I/usr/aarch64-linux-gnu/include/c++/10/aarch64-linux-gnu"' + ExtraCflagsCC += + ', "--target=aarch64-unknown-linux-gnu", "--sysroot=/usr/aarch64-linux-gnu", "--gcc-toolchain=aarch64-linux-gnu-gcc-10", "-B/usr/aarch64-linux-gnu/bin", "-I/usr/aarch64-linux-gnu/include/c++/10", "-I/usr/aarch64-linux-gnu/include/c++/10/aarch64-linux-gnu"' + ExtraLdFlags = + '"--target=aarch64-unknown-linux-gnu", "-B/usr/aarch64-linux-gnu/bin", "-L/usr/aarch64-linux-gnu/lib", "-L/usr/lib/gcc-cross/aarch64-linux-gnu/10"' + ExtraAsmFlags = '"--sysroot=/usr/aarch64-linux-gnu", "--target=aarch64-unknown-linux-gnu"' + + GN_ARGS.push( + `extra_ldflags=[${ExtraLdFlags}]`, + `ar="aarch64-linux-gnu-gcc-ar-10"`, + `extra_asmflags=[${ExtraAsmFlags}]`, + `extra_cflags=[${ExtraCflags}]`, + `extra_cflags_c=[${ExtraCflags}]`, + ) + break + case 'armv7-unknown-linux-gnueabihf': + ExtraSkiaBuildFlag += ' target_cpu="armv7a" target_os="linux"' + ExtraCflags = + '"--target=arm-unknown-linux-gnueabihf", "--sysroot=/usr/arm-linux-gnueabihf", "--gcc-toolchain=arm-linux-gnueabihf-gcc-10", "-B/usr/arm-linux-gnueabihf/bin", "-I/usr/arm-linux-gnueabihf/include/c++/10", "-I/usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf"' + ExtraCflagsCC += + ', "--target=arm-unknown-linux-gnueabihf", "--sysroot=/usr/arm-linux-gnueabihf", "--gcc-toolchain=arm-linux-gnueabihf-gcc-10", "-B/usr/arm-linux-gnueabihf/bin", "-I/usr/arm-linux-gnueabihf/include/c++/10", "-I/usr/arm-linux-gnueabihf/include/c++/10/arm-linux-gnueabihf"' + ExtraLdFlags = + '"--target=arm-unknown-linux-gnueabihf", "-B/usr/arm-linux-gnueabihf/bin", "-L/usr/arm-linux-gnueabihf/lib", "-L/usr/lib/gcc-cross/arm-linux-gnueabihf/10"' + ExtraAsmFlags = + '"--sysroot=/usr/arm-linux-gnueabihf", "--target=arm-unknown-linux-gnueabihf", "-march=armv7-a", "-mfpu=neon", "-mthumb"' + + GN_ARGS.push( + `extra_ldflags=[${ExtraLdFlags}]`, + `ar="arm-linux-gnueabihf-gcc-ar-10"`, + `extra_asmflags=[${ExtraAsmFlags}]`, + `extra_cflags=[${ExtraCflags}]`, + `extra_cflags_c=[${ExtraCflags}]`, + ) + break + case 'aarch64-apple-darwin': + ExtraSkiaBuildFlag += ' target_cpu="arm64" target_os="mac"' + ExtraCflagsCC += ', "--target=arm64-apple-darwin"' + ExtraLdFlags = '"--target=arm64-apple-darwin"' + ExtraAsmFlags = '"--target=arm64-apple-darwin"' + ExtraCflags = '"--target=arm64-apple-darwin"' + GN_ARGS.push( + `extra_ldflags=[${ExtraLdFlags}]`, + `extra_asmflags=[${ExtraAsmFlags}]`, + `extra_cflags=[${ExtraCflags}]`, + `extra_cflags_c=[${ExtraCflags}]`, + ) + break + case 'aarch64-linux-android': + const { ANDROID_NDK_HOME } = process.env + if (!ANDROID_NDK_HOME) { + throw new TypeError('ANDROID_NDK_HOME must be specified in env variable') + } + ExtraSkiaBuildFlag += ` target_cpu="arm64" ndk="${ANDROID_NDK_HOME}"` + break + case '': + break + default: + throw new TypeError(`[${TARGET_TRIPLE}] is not a valid target`) +} + +const OUTPUT_PATH = path.join('out', 'Static') + +GN_ARGS.push(`cc=${CC}`, `cxx=${CXX}`, `extra_cflags_cc=[${ExtraCflagsCC}]`, ExtraSkiaBuildFlag) + +exec( + `${process.env.GN_EXE ? process.env.GN_EXE : path.join('bin', 'gn')} gen ${OUTPUT_PATH} --args='${GN_ARGS.join( + ' ', + )}'`, +) + +// linux musl +// don't know why generated: python3 ../../third_party/externals/icu/scripts/make_data_assembly.py ../../third_party/externals/icu/common/icudtl.dat gen/third_party/icu/icudtl_dat.S +// `python3` should be `python` +if (process.env.GN_EXE) { + const { readFileSync, writeFileSync } = require('fs') + const { join } = require('path') + + const ninjaToolchain = join(__dirname, '..', 'skia', 'out', 'Static', 'toolchain.ninja') + const ninjaToolchainContent = readFileSync(ninjaToolchain, 'utf8') + writeFileSync(ninjaToolchain, ninjaToolchainContent.replace('python3', 'python')) +} exec(`ninja -C ${OUTPUT_PATH}`) diff --git a/scripts/release-skia-binary.js b/scripts/release-skia-binary.js index e8ac8f69..d81e67ca 100644 --- a/scripts/release-skia-binary.js +++ b/scripts/release-skia-binary.js @@ -1,41 +1,40 @@ const { execSync } = require('child_process') const { promises: fs } = require('fs') const { platform } = require('os') -const { join, parse } = require('path') +const { parse } = require('path') const { Octokit } = require('@octokit/rest') const chalk = require('chalk') -const OWNER = 'Brooooooklyn' -const REPO = 'canvas' +const { libPath, TAG, OWNER, REPO } = require('./utils') -const [FULL_HASH] = execSync(`git submodule status skia`).toString('utf8').trim().split(' ') - -const SHORT_HASH = FULL_HASH.substr(0, 8) +const PLATFORM_NAME = platform() -const TAG = `skia-${SHORT_HASH}` +const [, , ARG, TARGET] = process.argv -const PLATFORM_NAME = platform() +let TARGET_TRIPLE -const [, , ARG] = process.argv +if (TARGET && TARGET.startsWith('--target=')) { + TARGET_TRIPLE = TARGET.replace('--target=', '') +} -const SKIA_BINARY = join(__dirname, '..', 'skia', 'out', 'Static', PLATFORM_NAME === 'win32' ? 'skia.lib' : 'libskia.a') -const SKIA_PLATFORM_NAME = PLATFORM_NAME === 'win32' ? `skia-${PLATFORM_NAME}.lib` : `libskia-${PLATFORM_NAME}.a` -const SKIA_COPY = join(__dirname, '..', SKIA_PLATFORM_NAME) -const DOWNLOAD_URL = `https://github.com/${OWNER}/${REPO}/releases/download/${TAG}/${SKIA_PLATFORM_NAME}` +const LIB = ['skia', 'skparagraph', 'skshaper'] const CLIENT = new Octokit({ auth: process.env.GITHUB_TOKEN, }) async function upload() { + let assets = [] try { console.info(chalk.green(`Fetching release by tag: [${TAG}]`)) - await CLIENT.repos.getReleaseByTag({ - repo: REPO, - owner: OWNER, - tag: TAG, - }) + assets = ( + await CLIENT.repos.getReleaseByTag({ + repo: REPO, + owner: OWNER, + tag: TAG, + }) + ).data.assets } catch (e) { if (e.status === 404) { console.info(chalk.green(`No release tag, creating release tag ${TAG}`)) @@ -50,24 +49,40 @@ async function upload() { } } const putasset = require('putasset') - console.info(chalk.green(`Copy [${SKIA_BINARY}] to [${SKIA_COPY}]`)) - await fs.copyFile(SKIA_BINARY, SKIA_COPY) - console.info(chalk.green(`Uploading [${SKIA_COPY}] to github release: [${TAG}]`)) - await putasset(process.env.GITHUB_TOKEN, { - owner: OWNER, - repo: REPO, - tag: TAG, - filename: SKIA_COPY, - }) + for (const lib of LIB) { + const { copy, binary } = libPath(lib, PLATFORM_NAME, TARGET_TRIPLE) + console.info(chalk.green(`Copy [${binary}] to [${copy}]`)) + await fs.copyFile(binary, copy) + console.info(chalk.green(`Uploading [${copy}] to github release: [${TAG}]`)) + + const asset = assets.find(({ name }) => name === parse(copy).base) + if (asset) { + console.info(chalk.green(`[${copy}] existed, delete it...`)) + await CLIENT.repos.deleteReleaseAsset({ + owner: OWNER, + repo: REPO, + asset_id: asset.id, + }) + } + await putasset(process.env.GITHUB_TOKEN, { + owner: OWNER, + repo: REPO, + tag: TAG, + filename: copy, + }) + } } async function download() { - await fs.mkdir(parse(SKIA_BINARY).dir, { + await fs.mkdir(parse(libPath('skia', PLATFORM_NAME, TARGET_TRIPLE).binary).dir, { recursive: true, }) - execSync(`curl -J -L -H "Accept: application/octet-stream" ${DOWNLOAD_URL} -o ${SKIA_BINARY}`, { - stdio: 'inherit', - }) + for (const lib of LIB) { + const { downloadUrl, binary } = libPath(lib, PLATFORM_NAME, TARGET_TRIPLE) + execSync(`curl -J -L -H "Accept: application/octet-stream" ${downloadUrl} -o ${binary}`, { + stdio: 'inherit', + }) + } } let program = () => { diff --git a/scripts/utils.js b/scripts/utils.js new file mode 100644 index 00000000..69c5e277 --- /dev/null +++ b/scripts/utils.js @@ -0,0 +1,64 @@ +const { execSync } = require('child_process') +const { join } = require('path') + +const OWNER = 'Brooooooklyn' +const REPO = 'canvas' + +const [FULL_HASH] = + process.env.NODE_ENV === 'ava' ? ['000000'] : execSync(`git submodule status skia`).toString('utf8').trim().split(' ') + +const SHORT_HASH = FULL_HASH.substr(0, 8) + +const TAG = `skia-${SHORT_HASH}` + +/** + * @param {string} lib Static lib name + * @param {string} hostPlatform require('os').platform() + * @param {string | undefined} triple rust target triple + * @returns {{ binary: string; copy: string; downloadUrl: string }} + */ +function libPath(lib, hostPlatform, triple, tag = TAG) { + let platformName + if (!triple) { + switch (hostPlatform) { + case 'win32': + platformName = `${lib}-win32-x64-msvc.lib` + break + case 'darwin': + platformName = `lib${lib}-darwin-x64.a` + break + case 'linux': + platformName = `lib${lib}-linux-x64-gnu.a` + break + default: + throw new TypeError(`[${hostPlatform}] is not a valid platform`) + } + } else { + switch (triple) { + case 'aarch64-unknown-linux-gnu': + platformName = `lib${lib}-linux-aarch64-gnu.a` + break + case 'armv7-unknown-linux-gnueabihf': + platformName = `lib${lib}-linux-armv7-gnueabihf.a` + break + case 'x86_64-unknown-linux-musl': + platformName = `lib${lib}-linux-x64-musl.a` + break + case 'aarch64-apple-darwin': + platformName = `lib${lib}-darwin-aarch64.a` + break + case 'aarch64-linux-android': + platformName = `lib${lib}-android-aarch64.a` + break + default: + throw new TypeError(`[${triple}] is not a valid target`) + } + } + const binary = join(__dirname, '..', 'skia', 'out', 'Static', hostPlatform === 'win32' ? `${lib}.lib` : `lib${lib}.a`) + + const copy = join(__dirname, '..', platformName) + const downloadUrl = `https://github.com/${OWNER}/${REPO}/releases/download/${tag}/${platformName}` + return { binary, copy, downloadUrl } +} + +module.exports = { libPath, OWNER, REPO, TAG } diff --git a/skia b/skia index ed1b25f0..adbb69cd 160000 --- a/skia +++ b/skia @@ -1 +1 @@ -Subproject commit ed1b25f0aa5c1df9d1a4a7b6a001634bdddde7cf +Subproject commit adbb69cd7fe4e1c321e1526420e30265655e809c diff --git a/skia-c/skia_c.cpp b/skia-c/skia_c.cpp index ed5500f5..67af8a03 100644 --- a/skia-c/skia_c.cpp +++ b/skia-c/skia_c.cpp @@ -213,9 +213,12 @@ extern "C" void skiac_canvas_draw_image(skiac_canvas *c_canvas, skiac_bitmap *c_bitmap, float sx, float sy, float s_width, float s_height, float dx, float dy, float d_width, float d_height, skiac_paint *c_paint) { - auto src_rect = SkRect::MakeXYWH(sx, sy, s_width, s_height); - auto dst_rect = SkRect::MakeXYWH(dx, dy, d_width, d_height); - CANVAS_CAST->drawBitmapRect(*BITMAP_CAST, src_rect, dst_rect, PAINT_CAST); + const auto src_rect = SkRect::MakeXYWH(sx, sy, s_width, s_height); + const auto dst_rect = SkRect::MakeXYWH(dx, dy, d_width, d_height); + auto sk_image = SkImage::MakeFromBitmap(*BITMAP_CAST); + const auto sampling = SkSamplingOptions(); + auto paint = reinterpret_cast(c_paint); + CANVAS_CAST->drawImageRect(sk_image, src_rect, dst_rect, sampling, paint, SkCanvas::kFast_SrcRectConstraint); } void skiac_canvas_draw_path(skiac_canvas *c_canvas, skiac_path *c_path, skiac_paint *c_paint) @@ -245,7 +248,8 @@ extern "C" paint.setFilterQuality((SkFilterQuality)filter_quality); paint.setAlpha(alpha); paint.setBlendMode((SkBlendMode)blend_mode); - CANVAS_CAST->drawImage(image, left, top, &paint); + const auto sampling = SkSamplingOptions(); + CANVAS_CAST->drawImage(image, left, top, sampling, &paint); } void skiac_canvas_draw_surface_rect( @@ -259,7 +263,8 @@ extern "C" paint.setFilterQuality((SkFilterQuality)filter_quality); auto src = SkRect::MakeXYWH(0, 0, image->width(), image->height()); auto dst = SkRect::MakeXYWH(x, y, w, h); - CANVAS_CAST->drawImageRect(image, src, dst, &paint); + const auto sampling = SkSamplingOptions(); + CANVAS_CAST->drawImageRect(image, src, dst, sampling, &paint, SkCanvas::kFast_SrcRectConstraint); } void skiac_canvas_reset_transform(skiac_canvas *c_canvas) @@ -302,7 +307,8 @@ extern "C" auto image = SkImage::MakeRasterData(info, data, row_bytes); auto src_rect = SkRect::MakeXYWH(dirty_x, dirty_y, dirty_width, dirty_height); auto dst_rect = SkRect::MakeXYWH(x + dirty_x, y + dirty_y, dirty_width, dirty_height); - CANVAS_CAST->drawImageRect(image, src_rect, dst_rect, nullptr); + const auto sampling = SkSamplingOptions(); + CANVAS_CAST->drawImageRect(image, src_rect, dst_rect, sampling, nullptr, SkCanvas::kFast_SrcRectConstraint); } // Paint diff --git a/src/lib.rs b/src/lib.rs index 23ed2f6c..a2b60cdc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,7 +12,7 @@ use sk::SurfaceDataRef; unix, not(target_env = "musl"), not(target_arch = "aarch64"), - not(target_arch = "armv7"), + not(target_arch = "arm"), not(debug_assertions) ))] #[global_allocator]