From fe6b48948cac8b0f8f7185a77c2e6c0d797764a6 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Tue, 5 Jun 2018 17:21:30 -0400 Subject: Add Dockerfile for building and running local Skia checkout with SwiftShader This also adds a little helper to fuzz that allows us to see what GPU is being targeted. This is the first step in getting a SwiftShader fuzz target. To prove that this works, simply download this patch and run: ./docker/skia-with-swift-shader-base/build-with-swift-shader-and-run "out/with-swift-shader/fuzz --gpuInfo -t api -n NativeGLCanvas -b out/with-swift-shader/fiddle" Running supplied command ['out/with-swift-shader/fuzz', '--gpuInfo', '-t', 'api', '-n', 'NativeGLCanvas', '-b', 'out/with-swift-shader/fiddle'] Fuzzing NativeGLCanvas... GL_RENDERER Google SwiftShader GL_VENDOR Google Inc. GL_VERSION OpenGL ES 3.0 SwiftShader 4.0.0.6 Bug: skia: Change-Id: I3cc11a6bcd14f70f6025011722f9a73c94cb1f65 Reviewed-on: https://skia-review.googlesource.com/132269 Reviewed-by: Joe Gregorio Commit-Queue: Kevin Lubick --- docker/README.md | 25 ++++++++- docker/skia-with-swift-shader-base/Dockerfile | 18 +++++++ .../build-with-swift-shader-and-run | 61 ++++++++++++++++++++++ docker/skia-with-swift-shader-base/build.sh | 36 +++++++++++++ fuzz/FuzzCanvas.cpp | 5 ++ fuzz/FuzzCommon.h | 25 +++++++++ fuzz/fuzz.cpp | 1 + 7 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 docker/skia-with-swift-shader-base/Dockerfile create mode 100755 docker/skia-with-swift-shader-base/build-with-swift-shader-and-run create mode 100755 docker/skia-with-swift-shader-base/build.sh diff --git a/docker/README.md b/docker/README.md index c237c61795..41c2a39346 100644 --- a/docker/README.md +++ b/docker/README.md @@ -3,12 +3,35 @@ Docker Docker files for building different Skia targets. -Manual +skia-release ------ +This image is used to build Skia at TOT with SwiftShader. + There is a continuous process that builds this docker image, but if you need to manually push a verison, then run the following commands: docker build -t skia-release ./docker/skia-release/ docker tag skia-release gcr.io/skia-public/skia-release:prod docker push gcr.io/skia-public/skia-release:prod + + +skia-with-swift-shader-base +------ + +This image is used to build a local checkout of Skia with SwiftShader and run the built +executables without requiring the SwiftShader be installed on the host. + +For example (see build-with-swift-shader-and-run for more info), to reproduce a +fuzzer bug in SwiftShader: + + # First, copy the test case into $SKIA_ROOT, say $SKIA_ROOT/skbug_1234 + build-with-swift-shader-and-run "out/with-swift-shader/fuzz -t filter_fuzz -b /skia/skbug_1234" + +There is a continuous process that builds this docker image (which only really changes +if SwiftShader is updated), but if you need to manually push a version, then run the +following commands: + + docker build -t skia-with-swift-shader-base ./docker/skia-with-swift-shader-base/ + docker tag skia-with-swift-shader-base gcr.io/skia-public/skia-with-swift-shader-base:prod + docker push gcr.io/skia-public/skia-with-swift-shader-base:prod \ No newline at end of file diff --git a/docker/skia-with-swift-shader-base/Dockerfile b/docker/skia-with-swift-shader-base/Dockerfile new file mode 100644 index 0000000000..953d375d63 --- /dev/null +++ b/docker/skia-with-swift-shader-base/Dockerfile @@ -0,0 +1,18 @@ +# Dockerfile for building Skia in release mode, using 3rd party libs from DEPS, with SwiftShader. +FROM launcher.gcr.io/google/clang-debian9 AS build +RUN apt-get update && apt-get upgrade -y && apt-get install -y \ + git \ + python \ + curl \ + build-essential \ + libfontconfig-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev + +ADD https://storage.googleapis.com/swiftshader-binaries/OpenGL_ES/Latest/Linux/libGLESv2.so /usr/local/lib/libGLESv2.so +ADD https://storage.googleapis.com/swiftshader-binaries/OpenGL_ES/Latest/Linux/libEGL.so /usr/local/lib/libEGL.so +RUN cd /tmp \ + && git clone 'https://chromium.googlesource.com/chromium/tools/depot_tools.git' \ + && git clone https://swiftshader.googlesource.com/SwiftShader swiftshader + +RUN mkdir -m 0777 /skia \ No newline at end of file diff --git a/docker/skia-with-swift-shader-base/build-with-swift-shader-and-run b/docker/skia-with-swift-shader-base/build-with-swift-shader-and-run new file mode 100755 index 0000000000..3fd96afe89 --- /dev/null +++ b/docker/skia-with-swift-shader-base/build-with-swift-shader-and-run @@ -0,0 +1,61 @@ +#!/usr/bin/python + +import subprocess +import os +import argparse + + +# This script compiles and runs a skia app using Swiftshader in a docker container, making it easy +# to use Swiftshade w/o having to over-write /usr/local/lib/libEGL.so and related on the +# host development machine. + +# The Skia repo to be compiled will be the one on the host machine, which will +# default to the one specified by the environment variable $SKIA_ROOT with a fallback to the +# current working directory. + +# Example usage + +# Prove SwiftShader is really being used: +# build-with-swift-shader-and-run "out/with-swift-shader/fuzz --gpuInfo -t api -n NativeGLCanvas" + +# Notice the output says GL_RENDERER Google SwiftShader +# After running the above, feel free to check out $SKIA_OUT/out/with-swift-shader. It has binaries +# but if you try to run out/with-swift-shader/fuzz --gpuInfo -t api -n NativeGLCanvas w/o using +# Docker, it will use the host's GPU (e.g. GL_VENDOR NVIDIA Corporation). + +# Reproduce a fuzzer bug in SwiftShader: +# First, copy the test case into $SKIA_ROOT, say $SKIA_ROOT/skbug_1234 +# build-with-swift-shader-and-run "out/with-swift-shader/fuzz -t filter_fuzz -b /skia/skbug_1234" + +# $SKIA_ROOT gets mapped to /skia - other than that, the docker container does not have +# access to the host file system. + + +IMAGE = 'gcr.io/skia-public/skia-with-swift-shader-base:prod' + +BUILD_SCRIPT_PATH = '/skia/docker/skia-with-swift-shader-base/build.sh' +EXECUTABLE_DIR = 'out/with-swift-shader/' + +parser = argparse.ArgumentParser() +parser.add_argument('--sync_deps', action='store_true', help='Sync the deps before building?') +parser.add_argument('command', help='A string containing the command to be run ' + '(e.g. out/with-swift-shader/fuzz --help)') +args = parser.parse_args() + +skia_root = os.environ['SKIA_ROOT'] or os.getcwd() + +print 'Assuming SKIA_ROOT to be %s' % skia_root + +build_cmd = ['docker', 'run', '--rm', '-v', '%s:/skia' % skia_root, IMAGE, BUILD_SCRIPT_PATH] +if args.sync_deps: + build_cmd += ['sync-deps'] + +print 'Compiling executables to %s/%s' % (skia_root, EXECUTABLE_DIR) + +print subprocess.check_output(build_cmd) + +supplied_cmd = args.command.split(' ') +print 'Running supplied command %s' % supplied_cmd +run_cmd = ['docker', 'run', '--rm', '-w=/skia', '-v', '%s:/skia' % skia_root, IMAGE] + supplied_cmd + +print subprocess.check_output(run_cmd) \ No newline at end of file diff --git a/docker/skia-with-swift-shader-base/build.sh b/docker/skia-with-swift-shader-base/build.sh new file mode 100755 index 0000000000..cabd931948 --- /dev/null +++ b/docker/skia-with-swift-shader-base/build.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# Copyright 2018 Google, LLC +# +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +set +e + +mkdir -p /skia/out/with-swift-shader + +echo ' +cc = "clang" +cxx = "clang++" +skia_use_egl = true +is_debug = false +skia_use_system_freetype2 = false +extra_cflags = [ + "-I/tmp/swiftshader/include", + "-DGR_EGL_TRY_GLES3_THEN_GLES2", + "-g0", +] +extra_ldflags = [ + "-L/usr/local/lib", + "-Wl,-rpath", + "-Wl,/usr/local/lib" +] ' > /skia/out/with-swift-shader/args.gn + +# /skia is where the host Skia checkout is linked to in the container +cd /skia +if [ "sync-deps" = "$1" ]; then + python tools/git-sync-deps +fi +./bin/fetch-gn +./bin/gn gen out/with-swift-shader +/tmp/depot_tools/ninja -C out/with-swift-shader diff --git a/fuzz/FuzzCanvas.cpp b/fuzz/FuzzCanvas.cpp index 5c92fd1eb5..b66e5187dd 100644 --- a/fuzz/FuzzCanvas.cpp +++ b/fuzz/FuzzCanvas.cpp @@ -1811,12 +1811,17 @@ static void fuzz_ganesh(Fuzz* fuzz, GrContext* context) { fuzz_canvas(fuzz, surface->getCanvas()); } +extern bool FLAGS_gpuInfo; + DEF_FUZZ(NativeGLCanvas, fuzz) { sk_gpu_test::GrContextFactory f; GrContext* context = f.get(sk_gpu_test::GrContextFactory::kGL_ContextType); if (!context) { context = f.get(sk_gpu_test::GrContextFactory::kGLES_ContextType); } + if (FLAGS_gpuInfo) { + dumpGPUInfo(context); + } fuzz_ganesh(fuzz, context); } diff --git a/fuzz/FuzzCommon.h b/fuzz/FuzzCommon.h index 7615fe723e..9435b43552 100644 --- a/fuzz/FuzzCommon.h +++ b/fuzz/FuzzCommon.h @@ -12,6 +12,30 @@ #include "SkPath.h" #include "SkRegion.h" + +#if SK_SUPPORT_GPU +#include "GrContextFactory.h" +#include "gl/GrGLFunctions.h" +#include "gl/GrGLGpu.h" +#include "gl/GrGLUtil.h" +#include "GrContextPriv.h" + +inline void dumpGPUInfo(GrContext* context) { + const GrGLInterface* gl = static_cast(context->contextPriv().getGpu()) + ->glInterface(); + const GrGLubyte* output; + GR_GL_CALL_RET(gl, output, GetString(GR_GL_RENDERER)); + SkDebugf("GL_RENDERER %s\n", (const char*) output); + + GR_GL_CALL_RET(gl, output, GetString(GR_GL_VENDOR)); + SkDebugf("GL_VENDOR %s\n", (const char*) output); + + GR_GL_CALL_RET(gl, output, GetString(GR_GL_VERSION)); + SkDebugf("GL_VERSION %s\n", (const char*) output); +} + +#endif + // We don't always want to test NaNs and infinities. static inline void fuzz_nice_float(Fuzz* fuzz, float* f) { float v; @@ -60,3 +84,4 @@ void FuzzPath(Fuzz* fuzz, SkPath* path, int maxOps); void BuildPath(Fuzz* fuzz, SkPath* path, int last_verb); #endif + diff --git a/fuzz/fuzz.cpp b/fuzz/fuzz.cpp index 0917747790..7bf03f1adf 100644 --- a/fuzz/fuzz.cpp +++ b/fuzz/fuzz.cpp @@ -46,6 +46,7 @@ DEFINE_string2(bytes, b, "", "A path to a file or a directory. If a file, the " DEFINE_string2(name, n, "", "If --type is 'api', fuzz the API with this name."); DEFINE_string2(dump, d, "", "If not empty, dump 'image*' or 'skp' types as a " "PNG with this name."); +DEFINE_bool2(gpuInfo, g, false, "Display GPU information on relevant targets."); DEFINE_bool2(verbose, v, false, "Print more information while fuzzing."); DEFINE_string2(type, t, "", "How to interpret --bytes, one of:\n" "animated_image_decode\n" -- cgit v1.2.3