Reland "Build CanvasKit using GN/Ninja"

This is a reland of ecac712bec

Changes (best viewed comparing PS1 to latest)
 - Use emsdk 3.1.3 which includes important bug fixes
 - Remove unnecessary steps in compile.sh
 - Fix use of various gn args.
 - Avoid conflicts with Flutter's GN symbols
 - Add/update docs
 - Make activate-emsdk script compatible with our infra.

Original change's description:
> Build CanvasKit using GN/Ninja
>
> Build with
>
> ./bin/gn gen out/wasm_debug '--args=target_cpu="wasm"'
>
> or
>
> ./bin/gn gen out/wasm_release '--args=target_cpu="wasm" is_debug=false'
>
> Change-Id: Ib74586bf8397d57064a3899eaa6da76f9bce9049
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/502036
> Reviewed-by: Kevin Lubick <kjlubick@google.com>
> Reviewed-by: Ben Wagner <bungeman@google.com>

Change-Id: I601712a8953c2799fa029e782e097905b95e6b59
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/507717
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
This commit is contained in:
Kevin Lubick 2022-02-14 15:08:12 -05:00 committed by SkCQ
parent d184c1b12d
commit c13cd6479d
28 changed files with 695 additions and 361 deletions

View File

@ -7,6 +7,7 @@ import("gn/flutter_defines.gni")
import("gn/fuchsia_defines.gni")
import("gn/shared_sources.gni")
import("gn/skia.gni")
import("gn/toolchain/wasm.gni")
if (is_fuchsia) {
import("//build/fuchsia/sdk.gni")
@ -47,6 +48,9 @@ config("skia_public") {
if (is_fuchsia) {
defines += fuchsia_defines
}
if (is_wasm) {
defines += wasm_defines
}
if (skia_gl_standard == "gles") {
defines += [ "SK_ASSUME_GL_ES=1" ]
} else if (skia_gl_standard == "gl") {
@ -84,7 +88,7 @@ config("skia_private") {
"SK_GAMMA_CONTRAST=0.0",
]
}
if (is_skia_dev_build) {
if (is_skia_dev_build && !is_wasm) {
defines += [
"SK_ALLOW_STATIC_GLOBAL_INITIALIZERS=1",
"GR_TEST_UTILS=1",
@ -1542,6 +1546,10 @@ group("modules") {
"modules/skshaper",
"modules/svg",
]
if (is_wasm) {
deps += [ "modules/canvaskit" ]
}
}
group("experimental") {
@ -2947,7 +2955,7 @@ if (skia_enable_tools) {
group("modules_testonly") {
testonly = true
deps = []
if (target_cpu == "wasm") {
if (is_wasm) {
deps += [ "modules/canvaskit:viewer_wasm" ]
}
}

1
DEPS
View File

@ -23,6 +23,7 @@ deps = {
"third_party/externals/abseil-cpp" : "https://chromium.googlesource.com/chromium/src/third_party/abseil-cpp@789af048b388657987c59d4da406859034fe310f",
"third_party/externals/dng_sdk" : "https://android.googlesource.com/platform/external/dng_sdk.git@c8d0c9b1d16bfda56f15165d39e0ffa360a11123",
"third_party/externals/egl-registry" : "https://skia.googlesource.com/external/github.com/KhronosGroup/EGL-Registry@a0bca08de07c7d7651047bedc0b653cfaaa4f2ae",
"third_party/externals/emsdk" : "https://skia.googlesource.com/external/github.com/emscripten-core/emsdk.git@fc645b7626ebf86530dbd82fbece74d457e7ae07",
"third_party/externals/expat" : "https://chromium.googlesource.com/external/github.com/libexpat/libexpat.git@a28238bdeebc087071777001245df1876a11f5ee",
"third_party/externals/freetype" : "https://chromium.googlesource.com/chromium/src/third_party/freetype2.git@5e9caaee7885cbc82f9f821bbec7f6c86f25b33a",
"third_party/externals/harfbuzz" : "https://chromium.googlesource.com/external/github.com/harfbuzz/harfbuzz.git@a8b7f1880412c7f0c9ecdada0a4935011816c7dc",

32
bin/activate-emsdk Executable file
View File

@ -0,0 +1,32 @@
#!/usr/bin/env python
# Copyright 2022 Google LLC
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import subprocess
import sys
EMSDK_ROOT = os.path.join('third_party', 'externals', 'emsdk')
EMSDK_PATH = os.path.join(EMSDK_ROOT, 'emsdk.py')
EMSDK_VERSION = '3.1.3'
def main():
try:
subprocess.check_call([sys.executable, EMSDK_PATH, 'install', EMSDK_VERSION])
except subprocess.CalledProcessError:
print ('Failed to install emsdk')
return 1
try:
subprocess.check_call([sys.executable, EMSDK_PATH, 'activate', EMSDK_VERSION])
except subprocess.CalledProcessError:
print ('Failed to activate emsdk')
return 1
if __name__ == '__main__':
sys.exit(main())

View File

@ -38,7 +38,8 @@ RUN if [ ! -z "${PATCH_REF}" ] ; then cd /tmp/skia/skia \
RUN cd /tmp/skia/skia \
&& gclient sync \
&& ./bin/fetch-gn
&& ./bin/fetch-gn \
&& ./bin/activate-emsdk
# PathKit should be in /tmp/skia/skia/out/pathkit/
RUN /tmp/skia/skia/modules/pathkit/compile.sh

View File

@ -59,6 +59,7 @@ is_ios = current_os == "ios" || current_os == "tvos"
is_tvos = current_os == "tvos"
is_linux = current_os == "linux"
is_mac = current_os == "mac"
is_wasm = target_os == "wasm"
is_win = current_os == "win"
# This is just to make the Dawn build files happy. Skia itself uses target_os = "linux"
@ -81,7 +82,7 @@ if (current_cpu == "") {
current_cpu = target_cpu
}
is_clang = is_android || is_ios || is_mac || is_fuchsia ||
is_clang = is_android || is_ios || is_mac || is_fuchsia || is_wasm ||
(cc == "clang" && cxx == "clang++") || clang_win != ""
if (!is_clang && !is_win) {
is_clang = exec_script("//gn/is_clang.py",
@ -226,6 +227,10 @@ if (is_win) {
set_default_toolchain("//gn/toolchain:msvc")
default_toolchain_name = "msvc"
host_toolchain = "msvc"
} else if (is_wasm) {
set_default_toolchain("//gn/toolchain:wasm")
default_toolchain_name = "wasm"
host_toolchain = "wasm"
} else {
# GCC-like toolchains, including Clang.
set_default_toolchain("//gn/toolchain:gcc_like")

View File

@ -20,8 +20,9 @@ declare_args() {
skia_enable_fontmgr_fuchsia = is_fuchsia
skia_enable_fontmgr_win = is_win
skia_enable_gpu = true
skia_enable_pdf = true
skia_enable_skottie = !(is_win && is_component_build)
skia_enable_pdf = !is_wasm
skia_enable_skottie = !(is_win && is_component_build) ||
(is_wasm && skia_canvaskit_enable_skottie)
skia_enable_skrive = true
skia_enable_sksl = true
skia_enable_skvm_jit_when_possible = is_skia_dev_build
@ -41,12 +42,12 @@ declare_args() {
skia_use_dawn = false
skia_use_direct3d = false
skia_use_egl = false
skia_use_expat = true
skia_use_expat = !is_wasm
skia_use_ffmpeg = false
skia_use_fixed_gamma_text = is_android
skia_use_fontconfig = is_linux
skia_use_fonthost_mac = is_mac || is_ios
skia_use_freetype = is_android || is_fuchsia || is_linux
skia_use_freetype = is_android || is_fuchsia || is_linux || is_wasm
skia_use_harfbuzz = true
skia_use_gl = !is_fuchsia
skia_use_icu = !is_fuchsia
@ -57,14 +58,14 @@ declare_args() {
skia_use_libpng_decode = true
skia_use_libpng_encode = true
skia_use_libwebp_decode = true
skia_use_libwebp_encode = true
skia_use_libwebp_encode = !is_wasm
skia_use_lua = is_skia_dev_build && !is_ios
skia_use_metal = false
skia_use_ndk_images = is_android && defined(ndk_api) && ndk_api >= 30
skia_use_piex = !is_win
skia_use_piex = !is_win && !is_wasm
skia_use_sfml = false
skia_use_webgl = false
skia_use_wuffs = false
skia_use_webgl = is_wasm
skia_use_wuffs = is_wasm
skia_use_x11 = is_linux
skia_use_xps = true
skia_enable_graphite = false
@ -76,11 +77,15 @@ declare_args() {
skia_ios_identity = ".*Google.*"
skia_ios_profile = "Google Development"
}
}
declare_args() {
if (is_mac) {
skia_gl_standard = "gl"
} else if (is_ios) {
skia_gl_standard = "gles"
} else if (is_wasm && skia_enable_gpu) {
skia_gl_standard = "webgl"
} else {
skia_gl_standard = ""
}
@ -104,16 +109,17 @@ declare_args() {
declare_args() {
skia_compile_sksl_tests = skia_compile_processors
skia_enable_fontmgr_android = skia_use_expat && skia_use_freetype
skia_enable_fontmgr_custom_directory = skia_use_freetype && !is_fuchsia
skia_enable_fontmgr_custom_directory =
skia_use_freetype && !is_fuchsia && !is_wasm
skia_enable_fontmgr_custom_embedded = skia_use_freetype && !is_fuchsia
skia_enable_fontmgr_custom_empty = skia_use_freetype
skia_enable_fontmgr_custom_empty = skia_use_freetype && !is_wasm
skia_enable_fontmgr_fontconfig = skia_use_freetype && skia_use_fontconfig
skia_enable_fontmgr_win_gdi = is_win && !skia_enable_winuwp
skia_enable_fontmgr_FontConfigInterface =
skia_use_freetype && skia_use_fontconfig
skia_enable_spirv_validation = is_skia_dev_build && is_debug && !skia_use_dawn
skia_use_dng_sdk =
!is_fuchsia && skia_use_libjpeg_turbo_decode && skia_use_zlib
!is_fuchsia && !is_wasm && skia_use_libjpeg_turbo_decode && skia_use_zlib
skia_use_libgifcodec = !skia_use_wuffs
skia_use_sfntly = skia_use_icu
skia_enable_vulkan_debug_layers = skia_enable_gpu_debug_layers

View File

@ -6,6 +6,9 @@
if (is_fuchsia) {
import("//build/fuchsia/sdk.gni")
}
if (is_wasm) {
import("//gn/toolchain/wasm.gni")
}
declare_args() {
extra_asmflags = []
@ -267,6 +270,14 @@ config("default") {
}
}
if (is_wasm) {
cflags += [
"--sysroot=$skia_emsdk_dir/upstream/emscripten/cache/sysroot",
"-sMAIN_MODULE=1",
]
ldflags += [ "--sysroot=$skia_emsdk_dir/upstream/emscripten/cache/sysroot" ]
}
if (sanitize != "" && sanitize != "MSVC") {
# You can either pass the sanitizers directly, e.g. "address,undefined",
# or pass one of the couple common aliases used by the bots.
@ -594,20 +605,13 @@ config("optimize") {
cflags = [ "-O3" ]
if (is_mac || is_ios) {
ldflags = [ "-dead_strip" ]
} else {
} else if (!is_wasm) {
cflags += [
"-fdata-sections",
"-ffunction-sections",
]
ldflags = [ "-Wl,--gc-sections" ]
}
if (target_cpu == "wasm") {
# The compiler asks us to add an optimization flag to both cflags
# and ldflags to cut down on the local variables,
# for performance reasons.
# The "linking" step is the conversion to javascript.
ldflags += [ "-O3" ]
}
}
}

View File

@ -1,3 +1,6 @@
if (is_wasm) {
import("wasm.gni")
}
if (is_fuchsia) {
import("//build/fuchsia/sdk.gni")
}
@ -419,3 +422,15 @@ gcc_like_toolchain("gcc_like_host") {
cxx = host_cxx
link = host_link
}
# Only define this toolchain if actually building for wasm.
if (is_wasm) {
gcc_like_toolchain("wasm") {
cpu = "wasm"
os = "wasm"
ar = "$skia_emsdk_dir/upstream/emscripten/emar"
cc = "$skia_emsdk_dir/upstream/emscripten/emcc"
cxx = "$skia_emsdk_dir/upstream/emscripten/em++"
link = cxx
}
}

66
gn/toolchain/wasm.gni Normal file
View File

@ -0,0 +1,66 @@
# Copyright (c) 2022 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("../../modules/canvaskit/canvaskit.gni")
# Defines the configuration of emscripten for building WASM targets.
import("../skia.gni")
declare_args() {
# The location of an activated emsdk. We default to the one brought in by
# DEPS and bin/activate-emsdk.
skia_emsdk_dir = rebase_path("../../third_party/externals/emsdk")
}
skia_wasm_toolchain = "//gn/toolchain:wasm"
is_wasm = target_os == "wasm"
# Defines a WASM library target.
template("skia_wasm_lib") {
_vars_to_forward = [
"cflags",
"ldflags",
"defines",
"deps",
"includes",
"sources",
"include_dirs",
"public_configs",
"testonly",
"visibility",
]
_lib_name = target_name
executable("${_lib_name}.js") {
forward_variables_from(invoker, _vars_to_forward)
output_extension = ""
}
group("$_lib_name") {
deps = [ ":${_lib_name}.js($skia_wasm_toolchain)" ]
}
}
wasm_defines = [
"SKNX_NO_SIMD",
"SK_DISABLE_AAA",
"SK_FORCE_8_BYTE_ALIGNMENT",
]
if (!is_debug && !skia_canvaskit_force_tracing) {
wasm_defines += [ "SK_DISABLE_TRACING" ]
}
if (skia_enable_gpu) {
wasm_defines += [ "SK_DISABLE_LEGACY_SHADERCONTEXT" ]
}
if (!skia_canvaskit_enable_effects_deserialization ||
!skia_canvaskit_enable_skp_serialization) {
wasm_defines += [ "SK_DISABLE_EFFECT_DESERIALIZATION" ]
}
if (!skia_canvaskit_enable_alias_font) {
wasm_defines += [ "CANVASKIT_NO_ALIAS_FONT" ]
}

View File

@ -46,6 +46,7 @@ var (
".clang-format",
".clang-tidy",
".vpython",
"bin/activate-emsdk",
"bin/fetch-clang-format",
"bin/fetch-gn",
"buildtools",

View File

@ -7,6 +7,7 @@ INNER_BUILD_SCRIPT = '/SRC/skia/infra/canvaskit/build_canvaskit.sh'
def compile_fn(api, checkout_root, _ignore):
skia_dir = checkout_root.join('skia')
out_dir = api.vars.cache_dir.join('docker', 'canvaskit')
configuration = api.vars.builder_cfg.get('configuration', '')
extra = api.vars.builder_cfg.get('extra_config', '')
@ -18,7 +19,14 @@ def compile_fn(api, checkout_root, _ignore):
# param. Instead, we use a "canvaskit" subdirectory in the "docker" named_cache.
api.file.ensure_directory('mkdirs out_dir', out_dir, mode=0o777)
# This uses the emscriptem sdk docker image and says "run the
# Download the emsdk binaries (we won't actually use the ones on the Docker
# image anymore, now that we have proper GN support)
with api.context(cwd=skia_dir):
api.run(api.python, 'activate-emsdk',
script=skia_dir.join('bin', 'activate-emsdk'),
infra_step=True)
# This uses the emscripten sdk docker image and says "run the
# build_canvaskit.sh helper script in there". Additionally, it binds two
# folders: the Skia checkout to /SRC and the output directory to /OUT
# The called helper script will make the compile happen and put the

View File

@ -14,6 +14,20 @@
"infra_step": true,
"name": "mkdirs out_dir"
},
{
"cmd": [
"python",
"-u",
"[START_DIR]/cache/work/skia/bin/activate-emsdk"
],
"cwd": "[START_DIR]/cache/work/skia",
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "activate-emsdk"
},
{
"cmd": [
"docker",

View File

@ -14,6 +14,20 @@
"infra_step": true,
"name": "mkdirs out_dir"
},
{
"cmd": [
"python",
"-u",
"[START_DIR]/cache/work/skia/bin/activate-emsdk"
],
"cwd": "[START_DIR]/cache/work/skia",
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "activate-emsdk"
},
{
"cmd": [
"docker",

View File

@ -87215,8 +87215,7 @@
"skia/.vpython",
"skia/BUILD.gn",
"skia/bench",
"skia/bin/fetch-clang-format",
"skia/bin/fetch-gn",
"skia/bin",
"skia/build/fuchsia",
"skia/build_overrides",
"skia/buildtools",

View File

@ -2,54 +2,362 @@
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import("//gn/skia.gni")
import("//gn/toolchain/wasm.gni")
import("canvaskit.gni")
# These targets depend on components that are only declared if
# `skia_enable_tools` is true.
if (skia_enable_tools) {
component("viewer_wasm") {
testonly = true
include_dirs = [ "../.." ]
sources = [
"../../modules/svg/src/SkSVGAttribute.cpp",
"../../modules/svg/src/SkSVGAttributeParser.cpp",
"../../modules/svg/src/SkSVGCircle.cpp",
"../../modules/svg/src/SkSVGClipPath.cpp",
"../../modules/svg/src/SkSVGContainer.cpp",
"../../modules/svg/src/SkSVGDOM.cpp",
"../../modules/svg/src/SkSVGEllipse.cpp",
"../../modules/svg/src/SkSVGFe.cpp",
"../../modules/svg/src/SkSVGFeColorMatrix.cpp",
"../../modules/svg/src/SkSVGFeComposite.cpp",
"../../modules/svg/src/SkSVGFeTurbulence.cpp",
"../../modules/svg/src/SkSVGFilter.cpp",
"../../modules/svg/src/SkSVGFilterContext.cpp",
"../../modules/svg/src/SkSVGGradient.cpp",
"../../modules/svg/src/SkSVGLine.cpp",
"../../modules/svg/src/SkSVGLinearGradient.cpp",
"../../modules/svg/src/SkSVGNode.cpp",
"../../modules/svg/src/SkSVGPath.cpp",
"../../modules/svg/src/SkSVGPattern.cpp",
"../../modules/svg/src/SkSVGPoly.cpp",
"../../modules/svg/src/SkSVGRadialGradient.cpp",
"../../modules/svg/src/SkSVGRect.cpp",
"../../modules/svg/src/SkSVGRenderContext.cpp",
"../../modules/svg/src/SkSVGSVG.cpp",
"../../modules/svg/src/SkSVGShape.cpp",
"../../modules/svg/src/SkSVGStop.cpp",
"../../modules/svg/src/SkSVGText.cpp",
"../../modules/svg/src/SkSVGTransformableNode.cpp",
"../../modules/svg/src/SkSVGUse.cpp",
"../../modules/svg/src/SkSVGValue.cpp",
"../../tools/viewer/SKPSlide.cpp",
"../../tools/viewer/SampleSlide.cpp",
"../../tools/viewer/SvgSlide.cpp",
]
deps = [ "../..:samples" ]
}
component("gm_wasm") {
testonly = true
include_dirs = [ "../.." ]
deps = [
"../..:hash_and_encode",
"../..:tool_utils",
"../../modules/svg:svg",
]
}
}
action("create_notomono_cpp") {
script = "../../tools/embed_resources.py"
inputs = [ "fonts/NotoMono-Regular.ttf" ]
outputs =
[ "$root_out_dir/modules/canvaskit/fonts/NotoMono-Regular.ttf.ninja.cpp" ]
args = [
"--name=SK_EMBEDDED_FONTS",
"--input",
rebase_path("fonts/NotoMono-Regular.ttf"),
"--output",
"modules/canvaskit/fonts/NotoMono-Regular.ttf.ninja.cpp",
"--align=4",
]
}
skia_wasm_lib("canvaskit") {
deps = [ "../..:skia" ]
if (skia_canvaskit_enable_paragraph) {
deps += [ "../../modules/skparagraph:skparagraph" ]
}
if (skia_canvaskit_enable_skottie) {
deps += [
"../../modules/skottie:skottie",
"../../modules/sksg:sksg",
]
}
if (skia_canvaskit_enable_particles) {
deps += [ "../../modules/particles:particles" ]
}
if (skia_canvaskit_enable_skottie || skia_canvaskit_enable_particles) {
deps += [ "../../modules/skresources:skresources" ]
}
if (skia_canvaskit_include_viewer) {
deps += [ ":viewer_wasm" ]
}
if (skia_canvaskit_enable_embedded_font) {
deps += [ ":create_notomono_cpp" ]
}
component("viewer_wasm") {
testonly = true
include_dirs = [ "../.." ]
sources = [
"../../modules/svg/src/SkSVGAttribute.cpp",
"../../modules/svg/src/SkSVGAttributeParser.cpp",
"../../modules/svg/src/SkSVGCircle.cpp",
"../../modules/svg/src/SkSVGClipPath.cpp",
"../../modules/svg/src/SkSVGContainer.cpp",
"../../modules/svg/src/SkSVGDOM.cpp",
"../../modules/svg/src/SkSVGEllipse.cpp",
"../../modules/svg/src/SkSVGFe.cpp",
"../../modules/svg/src/SkSVGFeColorMatrix.cpp",
"../../modules/svg/src/SkSVGFeComposite.cpp",
"../../modules/svg/src/SkSVGFeTurbulence.cpp",
"../../modules/svg/src/SkSVGFilter.cpp",
"../../modules/svg/src/SkSVGFilterContext.cpp",
"../../modules/svg/src/SkSVGGradient.cpp",
"../../modules/svg/src/SkSVGLine.cpp",
"../../modules/svg/src/SkSVGLinearGradient.cpp",
"../../modules/svg/src/SkSVGNode.cpp",
"../../modules/svg/src/SkSVGPath.cpp",
"../../modules/svg/src/SkSVGPattern.cpp",
"../../modules/svg/src/SkSVGPoly.cpp",
"../../modules/svg/src/SkSVGRadialGradient.cpp",
"../../modules/svg/src/SkSVGRect.cpp",
"../../modules/svg/src/SkSVGRenderContext.cpp",
"../../modules/svg/src/SkSVGSVG.cpp",
"../../modules/svg/src/SkSVGShape.cpp",
"../../modules/svg/src/SkSVGStop.cpp",
"../../modules/svg/src/SkSVGText.cpp",
"../../modules/svg/src/SkSVGTransformableNode.cpp",
"../../modules/svg/src/SkSVGUse.cpp",
"../../modules/svg/src/SkSVGValue.cpp",
"../../tools/viewer/SKPSlide.cpp",
"../../tools/viewer/SampleSlide.cpp",
"../../tools/viewer/SvgSlide.cpp",
"WasmCommon.h",
"canvaskit_bindings.cpp",
]
deps = [ "../..:samples" ]
}
if (skia_canvaskit_enable_paragraph) {
sources += [
"paragraph_bindings.cpp",
"paragraph_bindings_gen.cpp",
]
}
if (skia_canvaskit_enable_skottie) {
sources += [ "skottie_bindings.cpp" ]
if (skia_canvaskit_enable_managed_skottie) {
sources += [ "../../modules/skottie/utils/SkottieUtils.cpp" ]
}
}
if (skia_canvaskit_enable_particles) {
sources += [ "particles_bindings.cpp" ]
}
if (skia_canvaskit_enable_skottie || skia_canvaskit_enable_particles) {
sources += [ "../../modules/skresources/src/SkResources.cpp" ]
}
if (skia_canvaskit_include_viewer) {
sources += [ "viewer_bindings.cpp" ]
}
if (skia_canvaskit_enable_embedded_font) {
sources += [
"$root_out_dir/modules/canvaskit/fonts/NotoMono-Regular.ttf.ninja.cpp",
]
}
component("gm_wasm") {
testonly = true
include_dirs = [ "../.." ]
deps = [
"../..:hash_and_encode",
"../..:tool_utils",
"../../modules/svg:svg",
ldflags = []
if (is_debug) {
ldflags += [
"-O0",
"-sDEMANGLE_SUPPORT=1",
"-sASSERTIONS=1",
"-sGL_ASSERTIONS=1",
"-g3",
"--source-map-base",
"/node_modules/canvaskit/bin/",
"--pre-js",
rebase_path("debug.js"),
]
} else {
externs_path = rebase_path("externs.js")
ldflags += [
"-Oz",
"--closure=1",
"--pre-js",
rebase_path("release.js"),
"--closure-args=--externs=$externs_path",
]
}
if (skia_canvaskit_profile_build) {
ldflags += [
"--profiling-funcs",
"--closure=0",
]
}
ldflags += [ "-fno-rtti" ]
if (skia_enable_gpu) {
ldflags += [
"-lGL",
"--pre-js",
rebase_path("cpu.js"),
"--pre-js",
rebase_path("gpu.js"),
"-sUSE_WEBGL2=1",
"-sMAX_WEBGL_VERSION=2",
]
} else {
ldflags += [
"--pre-js",
rebase_path("cpu.js"),
"-sUSE_WEBGL2=0",
]
}
ldflags += [
"-std=c++17",
"--bind",
"--no-entry",
"--pre-js",
rebase_path("preamble.js"),
"--pre-js",
rebase_path("color.js"),
"--pre-js",
rebase_path("memory.js"),
"--pre-js",
rebase_path("util.js"),
"--pre-js",
rebase_path("interface.js"),
]
if (skia_canvaskit_enable_matrix_helper) {
ldflags += [
"--pre-js",
rebase_path("matrix.js"),
]
}
ldflags += [
"--pre-js",
rebase_path("paragraph.js"),
]
if (skia_canvaskit_enable_skottie) {
ldflags += [
"--pre-js",
rebase_path("skottie.js"),
]
}
if (skia_canvaskit_enable_particles) {
ldflags += [
"--pre-js",
rebase_path("particles.js"),
]
}
if (skia_canvaskit_enable_pathops) {
ldflags += [
"--pre-js",
rebase_path("pathops.js"),
]
}
if (skia_canvaskit_enable_font) {
ldflags += [
"--pre-js",
rebase_path("font.js"),
]
}
if (skia_canvaskit_enable_skp_serialization) {
ldflags += [
"--pre-js",
rebase_path("skp.js"),
]
}
if (skia_canvaskit_enable_rt_shader) {
ldflags += [
"--pre-js",
rebase_path("rt_shader.js"),
]
}
if (skia_canvaskit_enable_canvas_bindings) {
ldflags += [
"--pre-js",
rebase_path("htmlcanvas/preamble.js"),
"--pre-js",
rebase_path("htmlcanvas/util.js"),
"--pre-js",
rebase_path("htmlcanvas/color.js"),
"--pre-js",
rebase_path("htmlcanvas/font.js"),
"--pre-js",
rebase_path("htmlcanvas/canvas2dcontext.js"),
"--pre-js",
rebase_path("htmlcanvas/htmlcanvas.js"),
"--pre-js",
rebase_path("htmlcanvas/htmlimage.js"),
"--pre-js",
rebase_path("htmlcanvas/imagedata.js"),
"--pre-js",
rebase_path("htmlcanvas/lineargradient.js"),
"--pre-js",
rebase_path("htmlcanvas/path2d.js"),
"--pre-js",
rebase_path("htmlcanvas/pattern.js"),
"--pre-js",
rebase_path("htmlcanvas/radialgradient.js"),
"--pre-js",
rebase_path("htmlcanvas/postamble.js"),
]
}
ldflags += [
"--pre-js",
rebase_path("postamble.js"),
"-sLLD_REPORT_UNDEFINED",
"-sALLOW_MEMORY_GROWTH",
"-sUSE_PTHREADS=0",
"-sDISABLE_EXCEPTION_CATCHING",
"-sNODEJS_CATCH_EXIT=0",
"-sDYNAMIC_EXECUTION=0",
"-sEXPORT_NAME=CanvasKitInit",
"-sEXPORTED_FUNCTIONS=[_malloc,_free]",
"-sFORCE_FILESYSTEM=0",
"-sFILESYSTEM=0",
"-sMODULARIZE",
"-sNO_EXIT_RUNTIME=1",
"-sINITIAL_MEMORY=128MB",
"-sWASM",
"-sSTRICT=1",
]
defines = []
if (is_debug) {
defines += [ "SK_DEBUG" ]
} else {
defines += [ "SK_RELEASE" ]
}
if (!is_debug && !skia_canvaskit_force_tracing) {
defines += [ "SK_DISABLE_TRACING" ]
}
defines += [
"SK_DISABLE_AAA",
"SK_FORCE_8_BYTE_ALIGNMENT",
"EMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0",
"SK_HAS_ANDROID_CODEC",
"SK_SHAPER_HARFBUZZ_AVAILABLE",
]
if (skia_canvaskit_enable_paragraph) {
defines += [ "SK_INCLUDE_PARAGRAPH=1" ]
}
if (skia_canvaskit_enable_skp_serialization) {
defines += [ "SK_SERIALIZE_SKP" ]
}
if (skia_enable_gpu) {
defines += [
"SK_SUPPORT_GPU=1",
"SK_GL",
"SK_DISABLE_LEGACY_SHADERCONTEXT",
]
} else {
defines += [
"SK_SUPPORT_GPU=0",
"SK_ENABLE_SKSL",
]
}
if (!skia_canvaskit_enable_skottie ||
!skia_canvaskit_enable_managed_skottie) {
defines += [ "SK_INCLUDE_MANAGED_SKOTTIE=0" ]
} else {
defines += [ "SK_INCLUDE_MANAGED_SKOTTIE=1" ]
}
if (skia_canvaskit_enable_pathops) {
defines += [ "SK_INCLUDE_PATHOPS" ]
}
if (skia_canvaskit_enable_rt_shader) {
defines += [ "SK_INCLUDE_RUNTIME_EFFECT" ]
}
if (skia_canvaskit_enable_sksl_trace) {
defines += [ "SK_INCLUDE_SKSL_TRACE" ]
}
if (!skia_canvaskit_enable_alias_font) {
defines += [ "CANVASKIT_NO_ALIAS_FONT" ]
}
if (!skia_canvaskit_enable_font) {
defines += [ "SK_NO_FONTS" ]
}
}

View File

@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `SkPicture.makeShader`
- Skia now has a GN toolchain that is used to compile CanvasKit. Ideally, all settings should
be the same, but there may be some subtle differences in practice. This changes the setup
to build CanvasKit (users no longer need to download emsdk themselves).
### Changed
- If an invalid matrix type is passed in (e.g. not an array, TypedArray, or DOMMatrix), CanvasKit

View File

@ -4,25 +4,23 @@ Node v14 or later is required to run tests. We use npm (the Node Package Manager
test dependencies. Recent installations of Node have npm as well.
CanvasKit has no other external source dependencies.
To compile CanvasKit, you will first need to [install `emscripten`][1]. This
will set the environment `EMSDK` (among others) which is required for
compilation. Which version should you use? [`/infra/wasm-common/docker/emsdk-base/Dockerfile`][2]
shows the version we build and test with. We try to use as recent a version of emscripten as
is reasonable.
[1]: https://emscripten.org/docs/getting_started/downloads.html
[2]: https://github.com/google/skia/blob/main/infra/wasm-common/docker/emsdk-base/Dockerfile
Be sure to both install **and** activate the correct version. For example:
```
./emsdk install 3.1.3
./emsdk activate 3.1.3
```
This document also assumes you have followed the instructions to download Skia and its deps
## Compiling with GN
To build with GN, you need to have followed the instructions to download Skia and its deps
<https://skia.org/user/download>.
## MacOS specific notes
To compile CanvasKit, you will first need to [download and activate `emscripten`][1] using the
script in `//bin/activate-emsdk` (or `//bin/git-sync-deps` which also calls activate-emsdk).
This places the associated files in `//third_party/externals/emsdk` and the GN[2] build scripts
will use those by default.
The compile.sh script automates the default GN settings; users are free to set their own. If users
want to use their own version of emscripten, they should set the `skia_emsdk_dir` argument
(see `//skia/gn/toolchain/wasm.gni`). For other available arguments, see
`//modules/canvaskit/BUILD.gn`.
[1]: https://emscripten.org/
[2]: https://chromium.googlesource.com/chromium/src/tools/gn/+/48062805e19b4697c5fbd926dc649c78b6aaa138/README.md
### MacOS specific notes
Make sure you have Python3 installed, otherwise the downloading emscripten toolchain
can fail with errors about SSL certificates. <https://github.com/emscripten-core/emsdk/pull/273>
@ -80,7 +78,7 @@ the results will only be useful when testing a debug build. Open
## Measuring Performance
We use puppeteer to run a Chrome browser to gather performance data in a consistent way.
See //tools/perf-canvaskit-puppeteer for more.
See `//tools/perf-canvaskit-puppeteer` for more.
## Adding tests
@ -99,8 +97,8 @@ When submitting a CL in gerrit, click "choose tryjobs" and type CanvasKit to fil
select all of them, which at the time of this writing is four jobs, for each combination
of perf/test gpu/cpu.
The performance results are reported to perf.skia.org
gold results are reported to gold.skia.org
The performance results are reported to [perf.skia.org] and correctness results are reported to
[gold.skia.org].
Coverage is not measured while running tests this way.
@ -125,33 +123,11 @@ images used for building and testing.
This presumes you have updated emscripten locally to a newer version of the
sdk and verified/fixed any build issues that have arisen.
1. Edit `$SKIA_ROOT/infra/wasm-common/docker/emsdk-base/Dockerfile` to install
and activate the desired version of Emscripten.
2. Edit `$SKIA_ROOT/infra/wasm-common/docker/Makefile` to have `EMSDK_VERSION` be
set to that desired version. If there is a suffix that is not `_v1`, reset
it to be `_v1`. If testing the image later does not work and edits are made
to the emsdk-base Dockerfile to correct that, increment to `_v2`,`_v3`, etc
to force the bots to pick up the new image.
3. In `$SKIA_ROOT/infra/wasm-common/docker/`, run `make publish_emsdk_base`
4. Edit `$SKIA_ROOT/infra/canvaskit/docker/canvaskit-emsdk/Dockerfile` to be based
off the new version from step 2. CanvasKit has its own docker image because
it needs a few extra dependencies to build with font support.
5. Edit `$SKIA_ROOT/infra/canvaskit/docker/Makefile` to have the same version
from step 2. It's easiest to keep the `emsdk-base` and `canvaskit-emsdk` versions
be in lock-step.
6. In `$SKIA_ROOT/infra/canvaskit/docker/`, run `make publish_canvaskit_emsdk`.
7. In `$SKIA_ROOT/infra/bots/recipe_modules/build/`, update `canvaskit.py`
and `pathkit.py` to have `DOCKER_IMAGE` point to the desired tagged Docker
containers from steps 2 and 5 (which should be the same).
8. In `$SKIA_ROOT/infra/bots/task_drivers/compile_wasm_gm_tests.go`, update dockerImage
to refer to the desired Docker containers from steps 2 and 5.
9. In `$SKIA_ROOT/infra/bots/`, run `make train` to re-train the recipes.
10. Optional: Run something like `git grep 1\\.38\\.` in `$SKIA_ROOT` to see if
there are any other references that need updating.
11. Upload a CL with all the changes. Run all Test.+CanvasKit, Perf.+Puppeteer,
1. Edit `//bin/activate-emsdk` to install and activate the desired version of Emscripten.
2. Upload a CL with all the changes. Run all Test.+CanvasKit, Perf.+Puppeteer,
Test.+PathKit, Perf.+PathKit jobs to make sure the new builds pass all
tests and don't crash the perf harnesses.
12. Send out CL for review. Feel free to point the reviewer at these steps.
3. Send out CL for review. Feel free to point the reviewer at these steps.
## Running Skia's GMs and Unit Tests against wasm+WebGL ##
TODO(kjlubick)

View File

@ -0,0 +1,33 @@
# Copyright 2022 Google LLC. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
declare_args() {
skia_canvaskit_enable_canvas_bindings = true
skia_canvaskit_enable_skottie = true
skia_canvaskit_enable_managed_skottie = true
skia_canvaskit_enable_pathops = true
skia_canvaskit_enable_particles = true
skia_canvaskit_enable_rt_shader = true
skia_canvaskit_enable_sksl_trace = true
skia_canvaskit_enable_alias_font = true
skia_canvaskit_enable_skp_serialization = true
skia_canvaskit_enable_effects_deserialization = true
skia_canvaskit_enable_matrix_helper = true
skia_canvaskit_enable_font = true
skia_canvaskit_enable_embedded_font = true
skia_canvaskit_enable_paragraph = true
skia_canvaskit_include_viewer = false
skia_canvaskit_force_tracing = false
skia_canvaskit_profile_build = false
}
# Assert that skia_canvaskit_profile_build implies release mode.
assert(
!skia_canvaskit_profile_build || !is_debug,
"If you set `skia_canvaskit_profile_build=true` you must set `is_debug=false`.")
# Assert that skia_canvaskit_enable_embedded_font implies skia_canvaskit_enable_font.
assert(
!skia_canvaskit_enable_embedded_font || skia_canvaskit_enable_font,
"If you set `skia_canvaskit_enable_embedded_font=true` you must set `skia_canvaskit_enable_font=true`.")

View File

@ -6,205 +6,132 @@
set -ex
BASE_DIR=`cd $(dirname ${BASH_SOURCE[0]}) && pwd`
# This expects the environment variable EMSDK to be set
if [[ ! -d $EMSDK ]]; then
cat >&2 << "EOF"
Be sure to set the EMSDK environment variable to the location of Emscripten SDK:
https://emscripten.org/docs/getting_started/downloads.html
EOF
exit 1
fi
# Navigate to SKIA_HOME from where this file is located.
BASE_DIR=`cd $(dirname ${BASH_SOURCE[0]}) && pwd`
pushd $BASE_DIR/../..
./bin/fetch-gn
source $EMSDK/emsdk_env.sh
EMCC=`which emcc`
EMCXX=`which em++`
EMAR=`which emar`
RELEASE_CONF="-Oz --closure 1 -DSK_RELEASE --pre-js $BASE_DIR/release.js"
EXTRA_CFLAGS="\"-DSK_RELEASE\","
IS_OFFICIAL_BUILD="true"
IS_DEBUG="false"
FORCE_TRACING="false"
PROFILE_BUILD="false"
# Tracing will be disabled in release/profiling unless this flag is seen. Tracing will
# be on debug builds always.
if [[ $@ != *force_tracing* ]] ; then
RELEASE_CONF+=" -DSK_DISABLE_TRACING"
EXTRA_CFLAGS+="\"-DSK_DISABLE_TRACING\","
FORCE_TRACING="true"
fi
if [[ $@ == *debug* ]]; then
echo "Building a Debug build"
EXTRA_CFLAGS="\"-DSK_DEBUG\","
RELEASE_CONF="-O0 --js-opts 0 -sDEMANGLE_SUPPORT=1 -sASSERTIONS=1 -sGL_ASSERTIONS=1 -g3 \
--source-map-base /node_modules/canvaskit/bin/ -DSK_DEBUG --pre-js $BASE_DIR/debug.js"
IS_DEBUG="true"
IS_OFFICIAL_BUILD="false"
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_debug"}
elif [[ $@ == *profiling* ]]; then
echo "Building a build for profiling"
RELEASE_CONF+=" --profiling-funcs --closure 0"
PROFILE_BUILD="true"
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_profile"}
elif [[ $@ == *simd* ]]; then
echo "Building with SIMD operations"
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm_experimental_simd"}
else
BUILD_DIR=${BUILD_DIR:="out/canvaskit_wasm"}
fi
if [[ $@ == *simd* ]]; then
RELEASE_CONF+=" -msimd128"
EXTRA_CFLAGS+="\"-msimd128\","
fi
mkdir -p $BUILD_DIR
# sometimes the .a files keep old symbols around - cleaning them out makes sure
# we get a fresh build.
rm -f $BUILD_DIR/*.a
GN_GPU="skia_enable_gpu=true skia_gl_standard = \"webgl\""
GN_GPU_FLAGS="\"-DSK_DISABLE_LEGACY_SHADERCONTEXT\","
WASM_GPU="-lGL -DSK_SUPPORT_GPU=1 -DSK_GL \
-DSK_DISABLE_LEGACY_SHADERCONTEXT --pre-js $BASE_DIR/cpu.js --pre-js $BASE_DIR/gpu.js\
-sUSE_WEBGL2=1"
ENABLE_GPU="true"
if [[ $@ == *cpu* ]]; then
echo "Using the CPU backend instead of the GPU backend"
GN_GPU="skia_enable_gpu=false"
GN_GPU_FLAGS=""
WASM_GPU="-DSK_SUPPORT_GPU=0 -DSK_ENABLE_SKSL --pre-js $BASE_DIR/cpu.js -sUSE_WEBGL2=0"
ENABLE_GPU="false"
fi
SKP_JS="--pre-js $BASE_DIR/skp.js"
GN_SKP_FLAGS=""
WASM_SKP="-DSK_SERIALIZE_SKP"
SERIALIZE_SKP="true"
if [[ $@ == *no_skp_serialization* ]]; then
# This saves about 20kb compressed.
SKP_JS=""
WASM_SKP=""
GN_SKP_FLAGS="\"-DSK_DISABLE_EFFECT_DESERIALIZATION\","
echo "disabling SKP serialization"
SERIALIZE_SKP="false"
fi
DESERIALIZE_EFFECTS="true"
if [[ $@ == *no_effects_deserialization* ]]; then
# This saves about 60kb compressed.
echo "disabling effects deserialization"
GN_SKP_FLAGS="\"-DSK_DISABLE_EFFECT_DESERIALIZATION\","
DESERIALIZE_EFFECTS="false"
fi
SKOTTIE_JS="--pre-js $BASE_DIR/skottie.js"
SKOTTIE_BINDINGS="$BASE_DIR/skottie_bindings.cpp"
SKOTTIE_LIB="$BUILD_DIR/libskottie.a \
$BUILD_DIR/libsksg.a"
ENABLE_SKOTTIE="true"
if [[ $@ == *no_skottie* ]]; then
echo "Omitting Skottie"
SKOTTIE_JS=""
SKOTTIE_LIB=""
SKOTTIE_BINDINGS=""
ENABLE_SKOTTIE="false"
fi
GN_VIEWER="skia_use_expat=false"
VIEWER_BINDINGS=""
VIEWER_LIB=""
INCLUDE_VIEWER="false"
USE_EXPAT="false"
if [[ $@ == *viewer* ]]; then
echo "Including viewer"
GN_VIEWER="skia_use_expat=true"
VIEWER_BINDINGS="$BASE_DIR/viewer_bindings.cpp"
VIEWER_LIB="$BUILD_DIR/libviewer_wasm.a"
INCLUDE_VIEWER="true"
USE_EXPAT="true"
IS_OFFICIAL_BUILD="false"
fi
MANAGED_SKOTTIE_BINDINGS="\
-DSK_INCLUDE_MANAGED_SKOTTIE=1 \
modules/skottie/utils/SkottieUtils.cpp"
ENABLE_MANAGED_SKOTTIE="true"
if [[ $@ == *no_managed_skottie* || $@ == *no_skottie* ]]; then
echo "Omitting managed Skottie"
MANAGED_SKOTTIE_BINDINGS="-DSK_INCLUDE_MANAGED_SKOTTIE=0"
ENABLED_MANAGED_SKOTTIE="false"
fi
PARTICLES_JS="--pre-js $BASE_DIR/particles.js"
PARTICLES_BINDINGS="$BASE_DIR/particles_bindings.cpp"
PARTICLES_LIB="$BUILD_DIR/libparticles.a"
ENABLE_PARTICLES="true"
if [[ $@ == *no_particles* ]]; then
echo "Omitting Particles"
PARTICLES_JS=""
PARTICLES_BINDINGS=""
PARTICLES_LIB=""
ENABLE_PARTICLES="false"
fi
if [[ $@ != *no_particles* || $@ != *no_skottie* ]] ; then
PARTICLES_BINDINGS+=" modules/skresources/src/SkResources.cpp"
fi
WASM_PATHOPS="-DSK_INCLUDE_PATHOPS"
PATHOPS_JS="--pre-js $BASE_DIR/pathops.js"
ENABLE_PATHOPS="true"
if [[ $@ == *no_pathops* ]] ; then
# This saves about 2kb compressed.
WASM_PATHOPS=""
PATHOPS_JS=""
echo "Omitting PathOps"
ENABLE_PATHOPS="false"
fi
WASM_RT_SHADER="-DSK_INCLUDE_RUNTIME_EFFECT"
RT_SHADER_JS="--pre-js $BASE_DIR/rt_shader.js"
ENABLE_RT_SHADER="true"
if [[ $@ == *no_rt_shader* ]] ; then
WASM_RT_SHADER=""
RT_SHADER_JS=""
echo "Omitting runtime shaders"
ENABLE_RT_SHADER="false"
fi
WASM_SKSL_TRACE="-DSK_INCLUDE_SKSL_TRACE"
ENABLE_SKSL_TRACE="true"
if [[ $@ == *no_sksl_trace* ]] ; then
WASM_SKSL_TRACE=""
echo "Omitting SkSl trace"
ENABLE_SKSL_TRACE="false"
fi
MATRIX_HELPER_JS="--pre-js $BASE_DIR/matrix.js"
ENABLE_MATRIX="true"
if [[ $@ == *no_matrix* ]]; then
echo "Omitting matrix helper code"
MATRIX_HELPER_JS=""
ENABLE_MATRIX="false"
fi
HTML_CANVAS_API="--pre-js $BASE_DIR/htmlcanvas/preamble.js \
--pre-js $BASE_DIR/htmlcanvas/util.js \
--pre-js $BASE_DIR/htmlcanvas/color.js \
--pre-js $BASE_DIR/htmlcanvas/font.js \
--pre-js $BASE_DIR/htmlcanvas/canvas2dcontext.js \
--pre-js $BASE_DIR/htmlcanvas/htmlcanvas.js \
--pre-js $BASE_DIR/htmlcanvas/htmlimage.js \
--pre-js $BASE_DIR/htmlcanvas/imagedata.js \
--pre-js $BASE_DIR/htmlcanvas/lineargradient.js \
--pre-js $BASE_DIR/htmlcanvas/path2d.js \
--pre-js $BASE_DIR/htmlcanvas/pattern.js \
--pre-js $BASE_DIR/htmlcanvas/radialgradient.js \
--pre-js $BASE_DIR/htmlcanvas/postamble.js "
ENABLE_CANVAS="true"
if [[ $@ == *no_canvas* || $@ == *no_matrix* ]]; then
# Note: HTML Canvas bindings depend on the matrix helpers.
echo "Omitting bindings for HTML Canvas API"
HTML_CANVAS_API=""
ENABLE_CANVAS="false"
fi
GN_FONT="skia_enable_fontmgr_custom_directory=false "
WOFF2_FONT="skia_use_freetype_woff2=true"
FONT_CFLAGS=""
BUILTIN_FONT=""
FONT_JS="--pre-js $BASE_DIR/font.js"
ENABLE_FONT="true"
ENABLE_EMBEDDED_FONT="true"
if [[ $@ == *no_font* ]]; then
echo "Omitting the built-in font(s), font manager and all code dealing with fonts"
FONT_CFLAGS="-DSK_NO_FONTS"
WOFF2_FONT=""
FONT_JS=""
ENABLE_FONT="false"
ENABLE_EMBEDDED_FONT="false"
GN_FONT+="skia_enable_fontmgr_custom_embedded=false skia_enable_fontmgr_custom_empty=false"
elif [[ $@ == *no_embedded_font* ]]; then
echo "Omitting the built-in font(s)"
ENABLE_EMBEDDED_FONT="false"
GN_FONT+="skia_enable_fontmgr_custom_embedded=false skia_enable_fontmgr_custom_empty=true"
else
# Generate the font's binary file (which is covered by .gitignore)
python tools/embed_resources.py \
--name SK_EMBEDDED_FONTS \
--input $BASE_DIR/fonts/NotoMono-Regular.ttf \
--output $BASE_DIR/fonts/NotoMono-Regular.ttf.cpp \
--align 4
BUILTIN_FONT="$BASE_DIR/fonts/NotoMono-Regular.ttf.cpp"
GN_FONT+="skia_enable_fontmgr_custom_embedded=true skia_enable_fontmgr_custom_empty=false"
fi
@ -212,32 +139,21 @@ if [[ $@ == *no_woff2* ]]; then
WOFF2_FONT="skia_use_freetype_woff2=false"
fi
ENABLE_ALIAS_FONT="true"
if [[ $@ == *no_alias_font* ]]; then
EXTRA_CFLAGS+="\"-DCANVASKIT_NO_ALIAS_FONT\","
FONT_CFLAGS+=" -DCANVASKIT_NO_ALIAS_FONT"
ENABLE_ALIAS_FONT="false"
fi
GN_SHAPER="skia_use_icu=true skia_use_system_icu=false skia_use_harfbuzz=true skia_use_system_harfbuzz=false"
SHAPER_LIB="$BUILD_DIR/libskunicode.a \
$BUILD_DIR/libharfbuzz.a \
$BUILD_DIR/libicu.a"
if [[ $@ == *primitive_shaper* ]] || [[ $@ == *no_font* ]]; then
echo "Using the primitive shaper instead of the harfbuzz/icu one"
GN_SHAPER="skia_use_icu=false skia_use_harfbuzz=false"
SHAPER_LIB=""
fi
PARAGRAPH_JS="--pre-js $BASE_DIR/paragraph.js"
PARAGRAPH_LIB="$BUILD_DIR/libskparagraph.a"
PARAGRAPH_BINDINGS="-DSK_INCLUDE_PARAGRAPH=1 \
$BASE_DIR/paragraph_bindings.cpp \
$BASE_DIR/paragraph_bindings_gen.cpp"
ENABLE_PARAGRAPH="true"
if [[ $@ == *no_paragraph* ]] || [[ $@ == *primitive_shaper* ]] || [[ $@ == *no_font* ]]; then
echo "Omitting paragraph (must have fonts and non-primitive shaper)"
PARAGRAPH_JS=""
PARAGRAPH_LIB=""
PARAGRAPH_BINDINGS=""
ENABLE_PARAGRAPH="false"
fi
DO_DECODE="true"
@ -276,23 +192,10 @@ fi
# Re-enable error checking
set -e
./bin/fetch-gn
echo "Compiling"
echo "Compiling bitcode"
# Inspired by https://github.com/Zubnix/skia-wasm-port/blob/master/build_bindings.sh
./bin/gn gen ${BUILD_DIR} \
--args="cc=\"${EMCC}\" \
cxx=\"${EMCXX}\" \
ar=\"${EMAR}\" \
extra_cflags=[\"-s\", \"MAIN_MODULE=1\",
\"-DSKNX_NO_SIMD\", \"-DSK_DISABLE_AAA\",
\"-DSK_FORCE_8_BYTE_ALIGNMENT\",
${GN_GPU_FLAGS}
${GN_SKP_FLAGS}
${EXTRA_CFLAGS}
] \
is_debug=false \
--args="is_debug=${IS_DEBUG} \
is_official_build=${IS_OFFICIAL_BUILD} \
is_component_build=false \
werror=true \
@ -301,6 +204,7 @@ echo "Compiling bitcode"
skia_use_angle=false \
skia_use_dng_sdk=false \
skia_use_webgl=true \
skia_use_expat=${USE_EXPAT} \
skia_use_fontconfig=false \
skia_use_freetype=true \
skia_use_libheif=false \
@ -320,91 +224,31 @@ echo "Compiling bitcode"
skia_use_vulkan=false \
skia_use_wuffs=true \
skia_use_zlib=true \
skia_enable_gpu=${ENABLE_GPU} \
\
${GN_SHAPER} \
${GN_GPU} \
${GN_FONT} \
${WOFF2_FONT} \
${GN_VIEWER} \
\
skia_enable_skshaper=true \
skia_enable_skparagraph=true \
skia_enable_pdf=false"
skia_enable_pdf=false \
skia_canvaskit_force_tracing=${FORCE_TRACING} \
skia_canvaskit_profile_build=${PROFILE_BUILD} \
skia_canvaskit_enable_skp_serialization=${SERIALIZE_SKP} \
skia_canvaskit_enable_effects_deserialization=${DESERIALIZE_EFFECTS} \
skia_canvaskit_enable_skottie=${ENABLE_SKOTTIE} \
skia_canvaskit_include_viewer=${INCLUDE_VIEWER} \
skia_canvaskit_enable_managed_skottie=${ENABLE_MANAGED_SKOTTIE} \
skia_canvaskit_enable_particles=${ENABLE_PARTICLES} \
skia_canvaskit_enable_pathops=${ENABLE_PATHOPS} \
skia_canvaskit_enable_rt_shader=${ENABLE_RT_SHADER} \
skia_canvaskit_enable_sksl_trace=${ENABLE_SKSL_TRACE} \
skia_canvaskit_enable_matrix_helper=${ENABLE_MATRIX} \
skia_canvaskit_enable_canvas_bindings=${ENABLE_CANVAS} \
skia_canvaskit_enable_font=${ENABLE_FONT} \
skia_canvaskit_enable_embedded_font=${ENABLE_EMBEDDED_FONT} \
skia_canvaskit_enable_alias_font=${ENABLE_ALIAS_FONT} \
skia_canvaskit_enable_paragraph=${ENABLE_PARAGRAPH}"
# Build all the libs we will need below
parse_targets() {
for LIBPATH in $@; do
basename $LIBPATH
done
}
${NINJA} -C ${BUILD_DIR} libskia.a libskshaper.a \
$(parse_targets $SKOTTIE_LIB $VIEWER_LIB $PARTICLES_LIB $SHAPER_LIB $PARAGRAPH_LIB)
export EMCC_CLOSURE_ARGS="--externs $BASE_DIR/externs.js "
echo "Generating final wasm"
# Emscripten prefers that the .a files go last in order, otherwise, it
# may drop symbols that it incorrectly thinks aren't used. One day,
# Emscripten will use LLD, which may relax this requirement.
EMCC_DEBUG=1 ${EMCXX} \
$RELEASE_CONF \
-I. \
-Ithird_party/icu \
-Ithird_party/skcms \
-Ithird_party/externals/icu/source/common/ \
-DSK_DISABLE_AAA \
-DSK_FORCE_8_BYTE_ALIGNMENT \
-DEMSCRIPTEN_HAS_UNBOUND_TYPE_NAMES=0 \
-fno-rtti \
$WASM_GPU \
$WASM_PATHOPS \
$WASM_RT_SHADER \
$WASM_SKSL_TRACE \
$WASM_SKP \
$FONT_CFLAGS \
-std=c++17 \
--bind \
--no-entry \
--pre-js $BASE_DIR/preamble.js \
--pre-js $BASE_DIR/color.js \
--pre-js $BASE_DIR/memory.js \
--pre-js $BASE_DIR/util.js \
--pre-js $BASE_DIR/interface.js \
$MATRIX_HELPER_JS \
$PARAGRAPH_JS \
$SKOTTIE_JS \
$PARTICLES_JS \
$PATHOPS_JS \
$FONT_JS \
$SKP_JS \
$RT_SHADER_JS \
$HTML_CANVAS_API \
--pre-js $BASE_DIR/postamble.js \
$BASE_DIR/canvaskit_bindings.cpp \
$PARTICLES_BINDINGS \
$SKOTTIE_BINDINGS \
$VIEWER_BINDINGS \
$MANAGED_SKOTTIE_BINDINGS \
$PARAGRAPH_BINDINGS \
$SKOTTIE_LIB \
$VIEWER_LIB \
$PARTICLES_LIB \
$PARAGRAPH_LIB \
$BUILD_DIR/libskshaper.a \
$SHAPER_LIB \
$BUILD_DIR/libskia.a \
$BUILTIN_FONT \
-sLLD_REPORT_UNDEFINED \
-sALLOW_MEMORY_GROWTH=1 \
-sEXPORT_NAME="CanvasKitInit" \
-sEXPORTED_FUNCTIONS=['_malloc','_free'] \
-sFORCE_FILESYSTEM=0 \
-sFILESYSTEM=0 \
-sMODULARIZE=1 \
-sNO_EXIT_RUNTIME=1 \
-sDYNAMIC_EXECUTION=0 \
-sINITIAL_MEMORY=128MB \
-sWASM=1 \
-sSTRICT=1 \
-o $BUILD_DIR/canvaskit.js
${NINJA} -C ${BUILD_DIR} canvaskit.js

View File

@ -21,9 +21,7 @@ fi
pushd $BASE_DIR/../..
source $EMSDK/emsdk_env.sh
EMCC=`which emcc`
EMCXX=`which em++`
EMAR=`which emar`
if [[ $@ == *debug* ]]; then
echo "Building a Debug build"
@ -85,9 +83,7 @@ echo "Compiling bitcode"
# Inspired by https://github.com/Zubnix/skia-wasm-port/blob/master/build_bindings.sh
./bin/gn gen ${BUILD_DIR} \
--args="cc=\"${EMCC}\" \
cxx=\"${EMCXX}\" \
ar=\"${EMAR}\" \
--args="skia_emsdk_dir=\"${EMSDK}\" \
extra_cflags_cc=[\"-frtti\"] \
extra_cflags=[\"-sMAIN_MODULE=1\",
\"-DSKNX_NO_SIMD\", \"-DSK_DISABLE_AAA\",

View File

@ -72,9 +72,7 @@ fi
OUTPUT="-o $BUILD_DIR/pathkit.js"
source $EMSDK/emsdk_env.sh
EMCC=`which emcc`
EMCXX=`which em++`
EMAR=`which emar`
# Turn off exiting while we check for ninja (which may not be on PATH)
set +e
@ -90,9 +88,7 @@ echo "Compiling bitcode"
./bin/fetch-gn
./bin/gn gen ${BUILD_DIR} \
--args="cc=\"${EMCC}\" \
cxx=\"${EMCXX}\" \
ar=\"${EMAR}\" \
--args="skia_emsdk_dir=\"${EMSDK}\" \
extra_cflags=[
\"-sMAIN_MODULE=1\",
${EXTRA_CFLAGS}

View File

@ -6,8 +6,9 @@
declare_args() {
# TODO: build from source all the time for testing?
skia_use_system_freetype2 =
(is_official_build || !(is_android || sanitize == "MSAN")) && !is_fuchsia
skia_use_freetype_woff2 = false
(is_official_build || !(is_android || sanitize == "MSAN")) &&
!is_fuchsia && !is_wasm
skia_use_freetype_woff2 = is_wasm
}
import("../third_party.gni")

View File

@ -7,7 +7,7 @@ import("../../gn/skia.gni")
import("../third_party.gni")
declare_args() {
skia_use_system_harfbuzz = is_official_build
skia_use_system_harfbuzz = is_official_build && !is_wasm
}
if (skia_use_system_harfbuzz) {

View File

@ -8,7 +8,7 @@ import("../third_party.gni")
import("icu.gni")
declare_args() {
skia_use_system_icu = is_official_build
skia_use_system_icu = is_official_build && !is_wasm
}
if (skia_use_system_icu) {

View File

@ -4,7 +4,7 @@
# found in the LICENSE file.
declare_args() {
skia_use_system_libjpeg_turbo = is_official_build
skia_use_system_libjpeg_turbo = is_official_build && !is_wasm
}
import("../third_party.gni")

View File

@ -4,7 +4,7 @@
# found in the LICENSE file.
declare_args() {
skia_use_system_libpng = is_official_build
skia_use_system_libpng = is_official_build && !is_wasm
}
import("../third_party.gni")

View File

@ -4,7 +4,7 @@
# found in the LICENSE file.
declare_args() {
skia_use_system_libwebp = is_official_build
skia_use_system_libwebp = is_official_build && !is_wasm
}
import("../third_party.gni")

View File

@ -141,7 +141,7 @@ def git_checkout_to_directory(git, repo, commithash, directory, verbose):
if not is_git_toplevel(git, directory):
# if the directory exists, but isn't a git repo, you will modify
# the parent repostory, which isn't what you want.
# the parent repository, which isn't what you want.
sys.stdout.write('%s\n IS NOT TOP-LEVEL GIT DIRECTORY.\n' % directory)
return
@ -262,6 +262,9 @@ def main(argv):
subprocess.check_call(
[sys.executable,
os.path.join(os.path.dirname(deps_file_path), 'bin', 'fetch-gn')])
subprocess.check_call(
[sys.executable,
os.path.join(os.path.dirname(deps_file_path), 'bin', 'activate-emsdk')])
return 0