diff --git a/meson.build b/meson.build index b9a6da01d3145..39907709f71d6 100644 --- a/meson.build +++ b/meson.build @@ -1251,6 +1251,17 @@ endif # TODO: some of these may be conditional dep_zlib = dependency('zlib', version : '>= 1.2.3', fallback : ['zlib', 'zlib_dep']) pre_args += '-DHAVE_ZLIB' + +_zstd = get_option('zstd') +if _zstd != 'false' + dep_zstd = dependency('libzstd', required : _zstd == 'true') + if dep_zstd.found() + pre_args += '-DHAVE_ZSTD' + endif +else + dep_zstd = null_dep +endif + dep_thread = dependency('threads') if dep_thread.found() and host_machine.system() != 'windows' pre_args += '-DHAVE_PTHREAD' diff --git a/meson_options.txt b/meson_options.txt index 626baf3d5c2cf..8c3e997852931 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,4 +1,4 @@ -# Copyright © 2017-2018 Intel Corporation +# Copyright © 2017-2019 Intel Corporation # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -366,3 +366,10 @@ option( value : 25, description : 'Android Platform SDK version. Default: Nougat version.' ) +option( + 'zstd', + type : 'combo', + choices : ['auto', 'true', 'false'], + value : 'auto', + description : 'Use ZSTD instead of ZLIB in some cases.' +) diff --git a/src/util/disk_cache.c b/src/util/disk_cache.c index 0cd92ca2d5bef..e5b21b9a79f56 100644 --- a/src/util/disk_cache.c +++ b/src/util/disk_cache.c @@ -40,6 +40,10 @@ #include #include "zlib.h" +#ifdef HAVE_ZSTD +#include "zstd.h" +#endif + #include "util/crc32.h" #include "util/debug.h" #include "util/rand_xor.h" @@ -75,6 +79,9 @@ */ #define CACHE_VERSION 1 +/* 3 is the recomended level, with 22 as the absolute maximum */ +#define ZSTD_COMPRESSION_LEVEL 3 + struct disk_cache { /* The path to the cache directory. */ char *path; @@ -738,6 +745,23 @@ static size_t deflate_and_write_to_disk(const void *in_data, size_t in_data_size, int dest, const char *filename) { +#ifdef HAVE_ZSTD + /* from the zstd docs (https://facebook.github.io/zstd/zstd_manual.html): + * compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`. + */ + size_t out_size = ZSTD_compressBound(in_data_size); + void * out = malloc(out_size); + + size_t ret = ZSTD_compress(out, out_size, in_data, in_data_size, + ZSTD_COMPRESSION_LEVEL); + if (ZSTD_isError(ret)) { + free(out); + return 0; + } + write_all(dest, out, ret); + free(out); + return ret; +#else unsigned char *out; /* allocate deflate state */ @@ -798,6 +822,7 @@ deflate_and_write_to_disk(const void *in_data, size_t in_data_size, int dest, (void)deflateEnd(&strm); free(out); return compressed_size; +# endif } static struct disk_cache_put_job * @@ -1059,6 +1084,10 @@ static bool inflate_cache_data(uint8_t *in_data, size_t in_data_size, uint8_t *out_data, size_t out_data_size) { +#ifdef HAVE_ZSTD + size_t ret = ZSTD_decompress(out_data, out_data_size, in_data, in_data_size); + return !ZSTD_isError(ret); +#else z_stream strm; /* allocate inflate state */ @@ -1089,6 +1118,7 @@ inflate_cache_data(uint8_t *in_data, size_t in_data_size, /* clean up and return */ (void)inflateEnd(&strm); return true; +#endif } void * diff --git a/src/util/meson.build b/src/util/meson.build index 972d757195a50..a7990ad52cc35 100644 --- a/src/util/meson.build +++ b/src/util/meson.build @@ -149,6 +149,7 @@ deps_for_libmesa_util = [ dep_atomic, dep_m, dep_valgrind, + dep_zstd, ] if with_platform_android