diff --git a/projects/skia-ftz/Dockerfile b/projects/skia-ftz/Dockerfile new file mode 100644 index 000000000..071288b02 --- /dev/null +++ b/projects/skia-ftz/Dockerfile @@ -0,0 +1,85 @@ +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder + +# Mesa,libz/zlib, and xcb needed to build swiftshader +RUN apt-get update && apt-get install -y python wget libglu1-mesa-dev cmake lib32z1-dev zlib1g-dev libxext-dev libxcb-shm0-dev + +RUN git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git' --depth 1 +ENV PATH="${SRC}/depot_tools:${PATH}" + +RUN git clone https://skia.googlesource.com/skia.git --depth 1 + +# current directory for build script +WORKDIR skia + +RUN bin/sync + +# Make a directory for fuzzing artifacts that won't be clobbered by CIFuzz. +RUN mkdir $SRC/skia_data + +RUN wget -O $SRC/skia_data/image_filter_deserialize_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/image_filter_deserialize_seed_corpus.zip + +RUN wget -O $SRC/skia_data/region_set_path_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/region_set_path_seed_corpus.zip + +RUN wget -O $SRC/skia_data/textblob_deserialize_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/textblob_deserialize_seed_corpus.zip + +RUN wget -O $SRC/skia_data/path_deserialize_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/path_deserialize_seed_corpus.zip + +RUN wget -O $SRC/skia_data/image_decode_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/image_decode_seed_corpus.zip + +RUN wget -O $SRC/skia_data/animated_image_decode_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/animated_image_decode_seed_corpus.zip + +RUN wget -O $SRC/skia_data/api_draw_functions_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/api_draw_functions_seed_corpus.zip + +RUN wget -O $SRC/skia_data/api_gradients_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/api_gradients_seed_corpus.zip + +RUN wget -O $SRC/skia_data/api_image_filter_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/api_image_filter_seed_corpus.zip + +RUN wget -O $SRC/skia_data/api_path_measure_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/api_path_measure_seed_corpus.zip + +RUN wget -O $SRC/skia_data/api_pathop_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/api_pathop_seed_corpus.zip + +RUN wget -O $SRC/skia_data/canvas_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/canvas_seed_corpus.zip + +RUN wget -O $SRC/skia_data/encoder_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/encoder_seed_corpus.zip + +RUN wget -O $SRC/skia_data/skottie_json_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/skottie_json_seed_corpus.zip + +RUN wget -O $SRC/skia_data/skjson_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/skjson_seed_corpus.zip + +RUN wget -O $SRC/skia_data/api_polyutils_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/api_polyutils_seed_corpus.zip + +RUN wget -O $SRC/skia_data/sksl_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/sksl_seed_corpus.zip + +RUN wget -O $SRC/skia_data/svg_dom_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/svg_seed_corpus.zip + +RUN wget -O $SRC/skia_data/skp_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/skp_seed_corpus.zip + +RUN wget -O $SRC/skia_data/skdescriptor_deserialize_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/skdescriptor_deserialize_seed_corpus.zip + +RUN wget -O $SRC/skia_data/colrv1_seed_corpus.zip https://storage.googleapis.com/skia-fuzzer/oss-fuzz/colrv1_seed_corpus.zip + +COPY image_filter_deserialize_width.options $SRC/skia_data/image_filter_deserialize_width.options + +COPY json.dict $SRC/skia_data/json.dict + +COPY sksl.dict $SRC/skia_data/sksl.dict + +WORKDIR $SRC/skia + +COPY build.sh $SRC/ diff --git a/projects/skia-ftz/README.md b/projects/skia-ftz/README.md new file mode 100644 index 000000000..9b15b8e12 --- /dev/null +++ b/projects/skia-ftz/README.md @@ -0,0 +1,7 @@ +When bench testing image_filter_deserialize, it may be useful to have +malloc_limit_mb = 500, and timeout = 10 to find actionable OOM culprits sooner. + +When reproducing, add -malloc_limit_mb=100 -rss_limit_mb=0 after the +repro_test to locate where big memory allocations are happening. + + python infra/helper.py reproduce skia image_decode ~/Downloads/foo -malloc_limit_mb=100 -rss_limit_mb=0 diff --git a/projects/skia-ftz/build.sh b/projects/skia-ftz/build.sh new file mode 100644 index 000000000..5f8a541ff --- /dev/null +++ b/projects/skia-ftz/build.sh @@ -0,0 +1,290 @@ +#!/bin/bash -eu +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +# Build SwiftShader so we can compile in our GPU code and test it in an +# an environment that does not have a real GPU. +pushd third_party/externals/swiftshader/ +export SWIFTSHADER_INCLUDE_PATH=$PWD/include +# SwiftShader already has a build/ directory, use something else +rm -rf build_swiftshader +mkdir build_swiftshader + +cd build_swiftshader +if [ $SANITIZER == "address" ]; then + CMAKE_SANITIZER="SWIFTSHADER_ASAN" +elif [ $SANITIZER == "memory" ]; then + CMAKE_SANITIZER="SWIFTSHADER_MSAN" + # oss-fuzz will patch the rpath for this after compilation and linking, + # so we only need to set this to appease the Swiftshader build rules check. + export SWIFTSHADER_MSAN_INSTRUMENTED_LIBCXX_PATH="/does/not/matter" +elif [ $SANITIZER == "undefined" ]; then + # The current SwiftShader build needs -fno-sanitize=vptr, but it cannot be + # specified here since -fsanitize=undefined will always come after any + # user specified flags passed to cmake. SwiftShader does not need to be + # built with the undefined sanitizer in order to fuzz Skia, so don't. + CMAKE_SANITIZER="SWIFTSHADER_UBSAN_DISABLED" +elif [ $SANITIZER == "coverage" ]; then + CMAKE_SANITIZER="SWIFTSHADER_EMIT_COVERAGE" +elif [ $SANITIZER == "thread" ]; then + CMAKE_SANITIZER="SWIFTSHADER_UBSAN_DISABLED" +else + exit 1 +fi +# These deprecated warnings get quite noisy and mask other issues. +CFLAGS= CXXFLAGS="-stdlib=libc++ -Wno-deprecated-declarations" cmake .. -GNinja \ + -DCMAKE_MAKE_PROGRAM="$SRC/depot_tools/ninja" -D$CMAKE_SANITIZER=1 -DSWIFTSHADER_WARNINGS_AS_ERRORS=FALSE + +# Swiftshader only supports Vulkan, so we will build our fuzzers with Vulkan too. +$SRC/depot_tools/ninja libvk_swiftshader.so +mv libvk_swiftshader.so $OUT +export SWIFTSHADER_LIB_PATH=$OUT + +popd +# These are any clang warnings we need to silence. +DISABLE="-Wno-zero-as-null-pointer-constant -Wno-unused-template + -Wno-cast-qual" +# Disable UBSan vptr since target built with -fno-rtti. +export CFLAGS="$CFLAGS $DISABLE -I$SWIFTSHADER_INCLUDE_PATH \ + -DSK_GPU_TOOLS_VK_LIBRARY_NAME=libvk_swiftshader.so \ + -fno-sanitize=vptr -DSK_BUILD_FOR_LIBFUZZER" +export CXXFLAGS="$CXXFLAGS $DISABLE -I$SWIFTSHADER_INCLUDE_PATH \ + -fno-sanitize=vptr -DSK_BUILD_FOR_LIBFUZZER" +export LDFLAGS="$LIB_FUZZING_ENGINE -l :crtfastmath.o $CXXFLAGS -L$SWIFTSHADER_LIB_PATH" + +# This splits a space separated list into a quoted, comma separated list for gn. +export CFLAGS_ARR=`echo $CFLAGS | sed -e "s/\s/\",\"/g"` +export CXXFLAGS_ARR=`echo $CXXFLAGS | sed -e "s/\s/\",\"/g"` +export LDFLAGS_ARR=`echo $LDFLAGS | sed -e "s/\s/\",\"/g"` + +$SRC/skia/bin/fetch-gn + +# Avoid OOMs on the CI due to lower memory constraints +LIMITED_LINK_POOL="link_pool_depth=1" + +SKIA_ARGS="skia_build_fuzzers=true + skia_enable_fontmgr_custom_directory=false + skia_enable_fontmgr_custom_embedded=false + skia_enable_fontmgr_custom_empty=true + skia_enable_gpu=true + skia_enable_skottie=true + skia_use_vulkan=true + skia_use_egl=false + skia_use_gl=false + skia_use_fontconfig=false + skia_use_freetype=true + skia_use_system_freetype2=false + skia_use_wuffs=true + skia_use_libfuzzer_defaults=false" + +# Even though GPU is "enabled" for all these builds, none really +# uses the gpu except for api_mock_gpu_canvas. +$SRC/skia/bin/gn gen out/Fuzz\ + --args='cc="'$CC'" + cxx="'$CXX'" + '"$LIMITED_LINK_POOL"' + '"${SKIA_ARGS[*]}"' + is_debug=false + extra_cflags_c=["'"$CFLAGS_ARR"'"] + extra_cflags_cc=["'"$CXXFLAGS_ARR"'"] + extra_ldflags=["'"$LDFLAGS_ARR"'"]' + +# Some fuzz targets benefit from assertions so we enable SK_DEBUG to allow SkASSERT +# and SkDEBUGCODE to run. We still enable optimization (via is_debug=false) because +# faster code means more fuzz tests and deeper coverage. +$SRC/skia/bin/gn gen out/FuzzDebug\ + --args='cc="'$CC'" + cxx="'$CXX'" + '"$LIMITED_LINK_POOL"' + '"${SKIA_ARGS[*]}"' + is_debug=false + extra_cflags_c=["-DSK_DEBUG","'"$CFLAGS_ARR"'"] + extra_cflags_cc=["-DSK_DEBUG","'"$CXXFLAGS_ARR"'"] + extra_ldflags=["'"$LDFLAGS_ARR"'"]' + +$SRC/depot_tools/ninja -C out/Fuzz \ + android_codec \ + animated_image_decode \ + api_create_ddl \ + api_ddl_threading \ + api_draw_functions \ + api_gradients \ + api_image_filter \ + api_mock_gpu_canvas \ + api_null_canvas \ + api_path_measure \ + api_pathop \ + api_polyutils \ + api_raster_n32_canvas \ + api_regionop \ + api_skparagraph \ + api_svg_canvas \ + api_triangulation \ + colrv1 \ + image_decode \ + image_decode_incremental \ + image_filter_deserialize \ + jpeg_encoder \ + path_deserialize \ + png_encoder \ + region_deserialize \ + region_set_path \ + skdescriptor_deserialize \ + skjson \ + skottie_json \ + skp \ + svg_dom \ + textblob_deserialize \ + webp_encoder + +$SRC/depot_tools/ninja -C out/FuzzDebug \ + skruntimeeffect \ + sksl2glsl \ + sksl2metal \ + sksl2pipeline \ + sksl2spirv \ + +rm -rf $OUT/data +mkdir $OUT/data + +mv out/Fuzz/region_deserialize $OUT/region_deserialize + +mv out/Fuzz/region_set_path $OUT/region_set_path +mv ../skia_data/region_set_path_seed_corpus.zip $OUT/region_set_path_seed_corpus.zip + +mv out/Fuzz/textblob_deserialize $OUT/textblob_deserialize +mv ../skia_data/textblob_deserialize_seed_corpus.zip $OUT/textblob_deserialize_seed_corpus.zip + +mv out/Fuzz/path_deserialize $OUT/path_deserialize +mv ../skia_data/path_deserialize_seed_corpus.zip $OUT/path_deserialize_seed_corpus.zip + +mv out/Fuzz/animated_image_decode $OUT/animated_image_decode +mv ../skia_data/animated_image_decode_seed_corpus.zip $OUT/animated_image_decode_seed_corpus.zip + +# Only create the width version of image_filter_deserialize if building with +# libfuzzer, since it depends on a libfuzzer specific flag. +if [ "$FUZZING_ENGINE" == "libfuzzer" ] +then + # Use the same binary as image_filter_deserialize. + cp out/Fuzz/image_filter_deserialize $OUT/image_filter_deserialize_width + mv ../skia_data/image_filter_deserialize_width.options $OUT/image_filter_deserialize_width.options + # Use the same seed corpus as image_filter_deserialize. + cp ../skia_data/image_filter_deserialize_seed_corpus.zip $OUT/image_filter_deserialize_width_seed_corpus.zip +fi + +mv out/Fuzz/image_filter_deserialize $OUT/image_filter_deserialize +mv ../skia_data/image_filter_deserialize_seed_corpus.zip $OUT/image_filter_deserialize_seed_corpus.zip + +mv out/Fuzz/api_draw_functions $OUT/api_draw_functions +mv ../skia_data/api_draw_functions_seed_corpus.zip $OUT/api_draw_functions_seed_corpus.zip + +mv out/Fuzz/api_gradients $OUT/api_gradients +mv ../skia_data/api_gradients_seed_corpus.zip $OUT/api_gradients_seed_corpus.zip + +mv out/Fuzz/api_path_measure $OUT/api_path_measure +mv ../skia_data/api_path_measure_seed_corpus.zip $OUT/api_path_measure_seed_corpus.zip + +mv out/Fuzz/api_pathop $OUT/api_pathop +mv ../skia_data/api_pathop_seed_corpus.zip $OUT/api_pathop_seed_corpus.zip + +# These 3 use the same corpus. +mv out/Fuzz/png_encoder $OUT/png_encoder +cp ../skia_data/encoder_seed_corpus.zip $OUT/png_encoder_seed_corpus.zip + +mv out/Fuzz/jpeg_encoder $OUT/jpeg_encoder +cp ../skia_data/encoder_seed_corpus.zip $OUT/jpeg_encoder_seed_corpus.zip + +mv out/Fuzz/webp_encoder $OUT/webp_encoder +mv ../skia_data/encoder_seed_corpus.zip $OUT/webp_encoder_seed_corpus.zip + +mv out/Fuzz/skottie_json $OUT/skottie_json +mv ../skia_data/skottie_json_seed_corpus.zip $OUT/skottie_json_seed_corpus.zip + +mv out/Fuzz/skjson $OUT/skjson +mv ../skia_data/json.dict $OUT/skjson.dict +mv ../skia_data/skjson_seed_corpus.zip $OUT/skjson_seed_corpus.zip + +# These 4 use the same canvas_seed_corpus. +mv out/Fuzz/api_mock_gpu_canvas $OUT/api_mock_gpu_canvas +cp ../skia_data/canvas_seed_corpus.zip $OUT/api_mock_gpu_canvas_seed_corpus.zip + +mv out/Fuzz/api_raster_n32_canvas $OUT/api_raster_n32_canvas +cp ../skia_data/canvas_seed_corpus.zip $OUT/api_raster_n32_canvas_seed_corpus.zip + +mv out/Fuzz/api_svg_canvas $OUT/api_svg_canvas +cp ../skia_data/canvas_seed_corpus.zip $OUT/api_svg_canvas_seed_corpus.zip + +mv out/Fuzz/api_null_canvas $OUT/api_null_canvas +mv ../skia_data/canvas_seed_corpus.zip $OUT/api_null_canvas_seed_corpus.zip + +mv out/Fuzz/api_image_filter $OUT/api_image_filter +mv ../skia_data/api_image_filter_seed_corpus.zip $OUT/api_image_filter_seed_corpus.zip + +mv out/Fuzz/api_polyutils $OUT/api_polyutils +mv ../skia_data/api_polyutils_seed_corpus.zip $OUT/api_polyutils_seed_corpus.zip + +# These 3 use the same corpus. +mv out/Fuzz/image_decode $OUT/image_decode +cp ../skia_data/image_decode_seed_corpus.zip $OUT/image_decode_seed_corpus.zip + +mv out/Fuzz/android_codec $OUT/android_codec +cp ../skia_data/image_decode_seed_corpus.zip $OUT/android_codec_seed_corpus.zip. + +mv out/Fuzz/image_decode_incremental $OUT/image_decode_incremental +mv ../skia_data/image_decode_seed_corpus.zip $OUT/image_decode_incremental_seed_corpus.zip + +# All five SkSL tests share the same sksl_seed_corpus and dictionary. +mv out/FuzzDebug/sksl2glsl $OUT/sksl2glsl +cp ../skia_data/sksl.dict $OUT/sksl2glsl.dict +cp ../skia_data/sksl_seed_corpus.zip $OUT/sksl2glsl_seed_corpus.zip + +mv out/FuzzDebug/sksl2spirv $OUT/sksl2spirv +cp ../skia_data/sksl.dict $OUT/sksl2spirv.dict +cp ../skia_data/sksl_seed_corpus.zip $OUT/sksl2spirv_seed_corpus.zip + +mv out/FuzzDebug/sksl2metal $OUT/sksl2metal +cp ../skia_data/sksl.dict $OUT/sksl2metal.dict +cp ../skia_data/sksl_seed_corpus.zip $OUT/sksl2metal_seed_corpus.zip + +mv out/FuzzDebug/sksl2pipeline $OUT/sksl2pipeline +cp ../skia_data/sksl.dict $OUT/sksl2pipeline.dict +cp ../skia_data/sksl_seed_corpus.zip $OUT/sksl2pipeline_seed_corpus.zip + +mv out/FuzzDebug/skruntimeeffect $OUT/skruntimeeffect +mv ../skia_data/sksl.dict $OUT/skruntimeeffect.dict +mv ../skia_data/sksl_seed_corpus.zip $OUT/skruntimeeffect_seed_corpus.zip + +mv out/Fuzz/skdescriptor_deserialize $OUT/skdescriptor_deserialize +mv ../skia_data/skdescriptor_deserialize_seed_corpus.zip $OUT/skdescriptor_deserialize_seed_corpus.zip + +mv out/Fuzz/svg_dom $OUT/svg_dom +mv ../skia_data/svg_dom_seed_corpus.zip $OUT/svg_dom_seed_corpus.zip + +mv out/Fuzz/api_create_ddl $OUT/api_create_ddl + +mv out/Fuzz/api_ddl_threading $OUT/api_ddl_threading + +mv out/Fuzz/skp $OUT/skp +mv ../skia_data/skp_seed_corpus.zip $OUT/skp_seed_corpus.zip + +mv out/Fuzz/api_skparagraph $OUT/api_skparagraph + +mv out/Fuzz/api_regionop $OUT/api_regionop + +mv out/Fuzz/api_triangulation $OUT/api_triangulation + +mv out/Fuzz/colrv1 $OUT/colrv1 +mv ../skia_data/colrv1_seed_corpus.zip $OUT/colrv1_seed_corpus.zip diff --git a/projects/skia-ftz/image_filter_deserialize_width.options b/projects/skia-ftz/image_filter_deserialize_width.options new file mode 100644 index 000000000..a9c3459f9 --- /dev/null +++ b/projects/skia-ftz/image_filter_deserialize_width.options @@ -0,0 +1,4 @@ +[libfuzzer] +max_len = 10024 +timeout = 10 +use_counters = 0 \ No newline at end of file diff --git a/projects/skia-ftz/json.dict b/projects/skia-ftz/json.dict new file mode 100644 index 000000000..c9ced2116 --- /dev/null +++ b/projects/skia-ftz/json.dict @@ -0,0 +1,52 @@ +# +# AFL dictionary for JSON +# ----------------------- +# +# Just the very basics. +# +# Inspired by a dictionary by Jakub Wilk +# + +"0" +",0" +":0" +"0:" +"-1.2e+3" + +"true" +"false" +"null" + +"\"\"" +",\"\"" +":\"\"" +"\"\":" + +"{}" +",{}" +":{}" +"{\"\":0}" +"{{}}" + +"[]" +",[]" +":[]" +"[0]" +"[[]]" + +"''" +"\\" +"\\b" +"\\f" +"\\n" +"\\r" +"\\t" +"\\u0000" +"\\x00" +"\\0" +"\\uD800\\uDC00" +"\\uDBFF\\uDFFF" + +"\"\":0" +"//" +"/**/" \ No newline at end of file diff --git a/projects/skia-ftz/project.yaml b/projects/skia-ftz/project.yaml new file mode 100644 index 000000000..092914f9f --- /dev/null +++ b/projects/skia-ftz/project.yaml @@ -0,0 +1,12 @@ +homepage: "https://github.com/google/skia" +language: c++ +primary_contact: "brendandg@nyu.edu" +auto_ccs: + - "metzman@google.com" + +sanitizers: + - address + - undefined + - memory +help_url: "https://skia.org/dev/testing/fuzz" +main_repo: 'https://skia.googlesource.com/skia.git' diff --git a/projects/skia-ftz/sksl.dict b/projects/skia-ftz/sksl.dict new file mode 100644 index 000000000..d6b3cc1a6 --- /dev/null +++ b/projects/skia-ftz/sksl.dict @@ -0,0 +1,459 @@ +# Adapted from sksl.lex, SkSLBuiltinTypes.cpp, SkSLIntrinsicList.h, and sksl module files + +# positive float literals +" 0.1" +" 1.2" +" 2.3" + +# negative float literals +" -3.4" +" -4.5" +" -5.6" + +# exponential float literals +" 1e2" +" 2e3" +" -3e4" +" -4e5" + +# positive int literals +" 0" +" 1" +" 2" + +# unsigned int literals +" 3u" +" 4u" + +# negative int literals +" -5" +" -6" + +# hexadecimal prefix +" 0x" + +# bad octal +" 08" + +# unsigned bad octal +" 09u" + +# keywords +" true" +" false" +" if (" +" @if (" +" else" +" for (" +" while (" +" do {" +" switch (" +" @switch (" +" case" +" default:" +" break;" +" continue;" +" discard;" +" return" +" in" +" out" +" inout" +" uniform" +" const" +" flat" +" noperspective" +" inline" +" noinline" +" sk_has_side_effects" +" struct" +" layout (" +" location=" +" offset=" +" binding=" +" index=" +" set=" +" builtin" +" input_attachment_index" +" origin_upper_left" +" blend_support_all_equations" +" push_constant" +" color" +" highp" +" mediump" +" lowp" +" $es3" +" main(" +" #extension" +" : disable" +" : require" +" : enable" +" : warn" + +# reserved words are all treated the same, and always invalidate the whole +# program, so we only include a handful of them in the dictionary +" attribute" +" varying" +" precision" +#"invariant " +#"asm " +#"class " +#"union " +#"enum " +#"typedef " +#"template " +#"this " +#"packed " +#"goto " +#"volatile " +#"public " +#"static " +#"extern " +#"external " +#"interface " +#"long " +#"double " +#"fixed " +#"unsigned " +#"superp " +#"input " +#"output " +#"sizeof " +#"cast " +#"namespace " +#"using " +#"gl_reservedWord " + +# a selection of swizzles +".x " +".xx " +".xxx " +".xxxx " +".y " +".yy " +".yyy " +".yyyy " +".x0 " +".x00 " +".x000 " +".1y " +".11y " +".111y " +".r " +".rg " +".rgb " +".rgba " +".abgr " +".ga " +".xy01 " +".1xw0 " + +# array indexing +"[0]" +"[1]" +"[2]" +"[3]" +"[4]" +"[-1]" +"[12345]" +"[-12345]" + +# symbol tokens +"(" +")" +"{" +"}" +"[" +"]" +"." +"," +"++" +"--" +"+" +"-" +"*" +"/" +"%" +"<<" +">>" +"|" +"^" +"&" +"~" +"||" +"^^" +"&&" +"!" +"?" +":" +"=" +"==" +"!=" +">" +"<" +">=" +"<=" +"+=" +"-=" +"*=" +"/=" +"%=" +"<<=" +">>=" +"|=" +"^=" +"&=" +";" +"//" +"/*" +"*/" + +# types +" void" +" float" +" float2" +" float3" +" float4" +" vec2" +" vec3" +" vec4" +" half" +" half2" +" half3" +" half4" +" int" +" int2" +" int3" +" int4" +" uint" +" uint2" +" uint3" +" uint4" +" short" +" short2" +" short3" +" short4" +" ushort" +" ushort2" +" ushort3" +" ushort4" +" bool" +" bool2" +" bool3" +" bool4" +" $floatLiteral" +" $intLiteral" +" float2x2" +" float3x2" +" float4x2" +" float2x3" +" float3x3" +" float4x3" +" float2x4" +" float3x4" +" float4x4" +" half2x2" +" half3x2" +" half4x2" +" half2x3" +" half3x3" +" half4x3" +" half2x4" +" half3x4" +" half4x4" +" mat2" +" mat3" +" mat4" +" mat2x2" +" mat3x2" +" mat4x2" +" mat2x3" +" mat3x3" +" mat4x3" +" mat2x4" +" mat3x4" +" mat4x4" +" colorFilter" +" shader" +" blender" + +# types that aren't accepted in a runtime effect; skip most of them +" texture2D" +" sampler2D" +" sampler" +#" texture1D" +#" texture3D" +#" textureExternalOES" +#" texture2DRect" +#" itexture2D" +#" sampler1D" +#" sampler3D" +#" samplerExternalOES" +#" sampler2DRect" +#" isampler2D" +#" subpassInput" +#" subpassInputMS" +#" subpassInputMS" + +# generic types shouldn't be accepted; skip most of them +" $genType" +" $sk_Caps" +#" $genHType" +#" $genIType" +#" $genUType" +#" $genBType" +#" $mat" +#" $hmat" +#" $squareMat" +#" $squareHMat" +#" $vec" +#" $hvec" +#" $ivec" +#" $uvec" +#" $svec" +#" $usvec" +#" $bvec" + +# sksl_frag +" sk_FragCoord" +" sk_Clockwise" +" sk_FragColor" +" sk_LastFragColor" +" sk_SecondaryFragColor" + +# sksl_gpu +" blend_clear(" +" blend_src(" +" blend_dst(" +" blend_src_over(" +" blend_dst_over(" +" blend_src_in(" +" blend_dst_in(" +" blend_src_out(" +" blend_dst_out(" +" blend_src_atop(" +" blend_dst_atop(" +" blend_xor(" +" blend_plus(" +" blend_modulate(" +" blend_screen(" +" blend_overlay(" +" blend_darken(" +" blend_lighten(" +" blend_color_dodge(" +" blend_color_burn(" +" blend_hard_light(" +" blend_soft_light(" +" blend_difference(" +" blend_exclusion(" +" blend_multiply(" +" blend_hue(" +" blend_saturation(" +" blend_color(" +" blend_luminosity(" +" unpremul(" +" proj(" +" cross_length_2d(" + +# sksl_public +".eval(" + +# sksl_vert +" sk_PerVertex" +" sk_VertexID" +" sk_InstanceID" + +# SkSLIntrinsicList +" abs(" +" acosh(" +" acos(" +" all(" +" any(" +" asinh(" +" asin(" +" atanh(" +" atan(" +" bitCount(" +" ceil(" +" clamp(" +" cosh(" +" cos(" +" cross(" +" degrees(" +" determinant(" +" dFdx(" +" dFdy(" +" distance(" +" dot(" +" equal(" +" eval(" +" exp2(" +" exp(" +" faceforward(" +" findLSB(" +" findMSB(" +" floatBitsToInt(" +" floatBitsToUint(" +" floor(" +" fma(" +" fract(" +" frexp(" +" fwidth(" +" greaterThanEqual(" +" greaterThan(" +" intBitsToFloat(" +" inversesqrt(" +" inverse(" +" isinf(" +" isnan(" +" ldexp(" +" length(" +" lessThanEqual(" +" lessThan(" +" log2(" +" log(" +" makeSampler2D(" +" matrixCompMult(" +" matrixInverse(" +" max(" +" min(" +" mix(" +" modf(" +" mod(" +" normalize(" +" notEqual(" +" not (" +" outerProduct(" +" packDouble2x32(" +" packHalf2x16(" +" packSnorm2x16(" +" packSnorm4x8(" +" packUnorm2x16(" +" packUnorm4x8(" +" pow(" +" radians(" +" reflect(" +" refract(" +" roundEven(" +" round(" +" sample(" +" saturate(" +" sign(" +" sinh(" +" sin(" +" smoothstep(" +" sqrt(" +" step(" +" subpassLoad(" +" tanh(" +" tan(" +" transpose(" +" trunc(" +" uintBitsToFloat(" +" unpackDouble2x32(" +" unpackHalf2x16(" +" unpackSnorm2x16(" +" unpackSnorm4x8(" +" unpackUnorm2x16(" +" unpackUnorm4x8(" +" toLinearSrgb(" +" fromLinearSrgb("