diff options
author | epoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-08 15:22:36 +0000 |
---|---|---|
committer | epoger@google.com <epoger@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2013-05-08 15:22:36 +0000 |
commit | e8d08a0fc294f2df7fc1ea074bcad52fc57c91b4 (patch) | |
tree | 798f1a35f3e901da800762710f1d5c37bde03636 | |
parent | aaf7343e16c4bf9f9c6f07968689669fe6ba71d7 (diff) |
Roll out r9059 to unbreak bots
git-svn-id: http://skia.googlecode.com/svn/trunk@9060 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | DEPS | 1 | ||||
-rw-r--r-- | bench/ChecksumBench.cpp | 23 | ||||
-rw-r--r-- | gm/gm_expectations.cpp | 8 | ||||
-rw-r--r-- | gyp/cityhash.gyp | 33 | ||||
-rw-r--r-- | gyp/utils.gyp | 14 | ||||
-rw-r--r-- | src/utils/SkBitmapHasher.cpp | 18 | ||||
-rw-r--r-- | src/utils/SkBitmapHasher.h | 2 | ||||
-rw-r--r-- | src/utils/SkCityHash.cpp | 23 | ||||
-rw-r--r-- | src/utils/SkCityHash.h | 47 | ||||
-rw-r--r-- | src/utils/cityhash/README | 2 | ||||
-rw-r--r-- | src/utils/cityhash/config.h | 17 | ||||
-rw-r--r-- | tests/ChecksumTest.cpp | 29 |
12 files changed, 215 insertions, 2 deletions
@@ -9,6 +9,7 @@ use_relative_paths = True # deps = { "third_party/externals/angle" : "http://angleproject.googlecode.com/svn/trunk@1268", + "third_party/externals/cityhash" : "http://cityhash.googlecode.com/svn/trunk@11", "third_party/externals/freetype" : "https://android.googlesource.com/platform/external/freetype.git", "third_party/externals/gyp" : "http://gyp.googlecode.com/svn/trunk@1563", "third_party/externals/libjpeg" : "http://src.chromium.org/svn/trunk/src/third_party/libjpeg@125399", diff --git a/bench/ChecksumBench.cpp b/bench/ChecksumBench.cpp index d2497d7f16..5491f0590c 100644 --- a/bench/ChecksumBench.cpp +++ b/bench/ChecksumBench.cpp @@ -7,6 +7,7 @@ #include "SkBenchmark.h" #include "SkCanvas.h" #include "SkChecksum.h" +#include "SkCityHash.h" #include "SkMD5.h" #include "SkRandom.h" #include "SkSHA1.h" @@ -15,7 +16,9 @@ enum ChecksumType { kChecksum_ChecksumType, kMD5_ChecksumType, - kSHA1_ChecksumType + kSHA1_ChecksumType, + kCityHash32, + kCityHash64 }; class ComputeChecksumBench : public SkBenchmark { @@ -42,6 +45,8 @@ protected: case kChecksum_ChecksumType: return "compute_checksum"; case kMD5_ChecksumType: return "compute_md5"; case kSHA1_ChecksumType: return "compute_sha1"; + case kCityHash32: return "compute_cityhash32"; + case kCityHash64: return "compute_cityhash64"; default: SK_CRASH(); return ""; } } @@ -70,6 +75,18 @@ protected: sha1.finish(digest); } } break; + case kCityHash32: { + for (int i = 0; i < N; i++) { + volatile uint32_t result = SkCityHash::Compute32(reinterpret_cast<char*>(fData), sizeof(fData)); + sk_ignore_unused_variable(result); + } + } break; + case kCityHash64: { + for (int i = 0; i < N; i++) { + volatile uint64_t result = SkCityHash::Compute64(reinterpret_cast<char*>(fData), sizeof(fData)); + sk_ignore_unused_variable(result); + } + } break; } } @@ -83,7 +100,11 @@ private: static SkBenchmark* Fact0(void* p) { return new ComputeChecksumBench(p, kChecksum_ChecksumType); } static SkBenchmark* Fact1(void* p) { return new ComputeChecksumBench(p, kMD5_ChecksumType); } static SkBenchmark* Fact2(void* p) { return new ComputeChecksumBench(p, kSHA1_ChecksumType); } +static SkBenchmark* Fact3(void* p) { return new ComputeChecksumBench(p, kCityHash32); } +static SkBenchmark* Fact4(void* p) { return new ComputeChecksumBench(p, kCityHash64); } static BenchRegistry gReg0(Fact0); static BenchRegistry gReg1(Fact1); static BenchRegistry gReg2(Fact2); +static BenchRegistry gReg3(Fact3); +static BenchRegistry gReg4(Fact4); diff --git a/gm/gm_expectations.cpp b/gm/gm_expectations.cpp index 72fb0e6a8d..16e655ed43 100644 --- a/gm/gm_expectations.cpp +++ b/gm/gm_expectations.cpp @@ -16,10 +16,18 @@ const static char kJsonKey_ActualResults_Failed[] = "failed"; const static char kJsonKey_ActualResults_FailureIgnored[]= "failure-ignored"; const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison"; const static char kJsonKey_ActualResults_Succeeded[] = "succeeded"; +#ifdef BITMAPHASHER_USES_TRUNCATED_MD5 const static char kJsonKey_ActualResults_AnyStatus_BitmapHash[] = "bitmap-64bitMD5"; +#else +const static char kJsonKey_ActualResults_AnyStatus_BitmapHash[] = "bitmap-cityhash"; +#endif const static char kJsonKey_ExpectedResults[] = "expected-results"; +#ifdef BITMAPHASHER_USES_TRUNCATED_MD5 const static char kJsonKey_ExpectedResults_AllowedBitmapHashes[] = "allowed-bitmap-64bitMD5s"; +#else +const static char kJsonKey_ExpectedResults_AllowedBitmapHashes[] = "allowed-bitmap-cityhashes"; +#endif const static char kJsonKey_ExpectedResults_IgnoreFailure[] = "ignore-failure"; namespace skiagm { diff --git a/gyp/cityhash.gyp b/gyp/cityhash.gyp new file mode 100644 index 0000000000..f35f1f02d3 --- /dev/null +++ b/gyp/cityhash.gyp @@ -0,0 +1,33 @@ +{ + 'variables': { + 'skia_warnings_as_errors': 0, + }, + 'targets': [ + { + 'target_name': 'cityhash', + 'type': 'static_library', + 'standalone_static_library': 1, + 'include_dirs': [ + '../include/config', + '../include/core', + '../src/utils/cityhash', + '../third_party/externals/cityhash/src', + ], + 'sources': [ + '../third_party/externals/cityhash/src/city.cc', + ], + 'direct_dependent_settings': { + 'include_dirs': [ + '../third_party/externals/cityhash/src', + ], + }, + 'conditions': [ + [ 'skia_os == "android"', { + 'cflags!': [ + '-Wall', + ], + }], + ], + }, + ], +} diff --git a/gyp/utils.gyp b/gyp/utils.gyp index a1820c0517..169bfbf849 100644 --- a/gyp/utils.gyp +++ b/gyp/utils.gyp @@ -5,6 +5,9 @@ 'product_name': 'skia_utils', 'type': 'static_library', 'standalone_static_library': 1, + 'dependencies': [ + 'cityhash.gyp:cityhash', + ], 'include_dirs': [ '../include/config', '../include/core', @@ -61,6 +64,8 @@ '../src/utils/SkBitSet.h', '../src/utils/SkBoundaryPatch.cpp', '../src/utils/SkCamera.cpp', + '../src/utils/SkCityHash.cpp', + '../src/utils/SkCityHash.h', '../src/utils/SkCubicInterval.cpp', '../src/utils/SkCullPoints.cpp', '../src/utils/SkDeferredCanvas.cpp', @@ -190,6 +195,15 @@ ], 'sources!': [ '../src/utils/SkThreadUtils_pthread_linux.cpp', + '../src/utils/SkCityHash.cpp', + '../src/utils/SkCityHash.h', + ], + 'dependencies!': [ + # CityHash is not supported on NaCl because the NaCl toolchain is + # missing byteswap.h which is needed by CityHash. + # TODO(borenet): Find a way to either provide this dependency or + # replace it. + 'cityhash.gyp:cityhash', ], }], [ 'skia_os == "android"', { diff --git a/src/utils/SkBitmapHasher.cpp b/src/utils/SkBitmapHasher.cpp index 5342d18d10..82cbe9fa7e 100644 --- a/src/utils/SkBitmapHasher.cpp +++ b/src/utils/SkBitmapHasher.cpp @@ -10,7 +10,12 @@ #include "SkEndian.h" #include "SkImageEncoder.h" +#ifdef BITMAPHASHER_USES_TRUNCATED_MD5 #include "SkMD5.h" +#else +#include "SkCityHash.h" +#include "SkStream.h" +#endif /** * Write an int32 value to a stream in little-endian order. @@ -32,7 +37,16 @@ static inline uint64_t first_8_bytes_as_uint64(const uint8_t *bytearray) { /*static*/ bool SkBitmapHasher::ComputeDigestInternal(const SkBitmap& bitmap, SkHashDigest *result) { +#ifdef BITMAPHASHER_USES_TRUNCATED_MD5 SkMD5 out; +#else + size_t pixelBufferSize = bitmap.width() * bitmap.height() * 4; + size_t totalBufferSize = pixelBufferSize + 2 * sizeof(uint32_t); + + SkAutoMalloc bufferManager(totalBufferSize); + char *bufferStart = static_cast<char *>(bufferManager.get()); + SkMemoryWStream out(bufferStart, totalBufferSize); +#endif // start with the x/y dimensions write_int32_to_buffer(SkToU32(bitmap.width()), &out); @@ -44,9 +58,13 @@ static inline uint64_t first_8_bytes_as_uint64(const uint8_t *bytearray) { return false; } +#ifdef BITMAPHASHER_USES_TRUNCATED_MD5 SkMD5::Digest digest; out.finish(digest); *result = first_8_bytes_as_uint64(digest.data); +#else + *result = SkCityHash::Compute64(bufferStart, totalBufferSize); +#endif return true; } diff --git a/src/utils/SkBitmapHasher.h b/src/utils/SkBitmapHasher.h index 165da3dcc8..c99421a8d6 100644 --- a/src/utils/SkBitmapHasher.h +++ b/src/utils/SkBitmapHasher.h @@ -11,6 +11,8 @@ #include "SkBitmap.h" +#define BITMAPHASHER_USES_TRUNCATED_MD5 + // TODO(epoger): Soon, SkHashDigest will become a real class of its own, // and callers won't be able to assume it converts to/from a uint64_t. typedef uint64_t SkHashDigest; diff --git a/src/utils/SkCityHash.cpp b/src/utils/SkCityHash.cpp new file mode 100644 index 0000000000..a21aa89634 --- /dev/null +++ b/src/utils/SkCityHash.cpp @@ -0,0 +1,23 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Pass any calls through to the CityHash library. + * This is the only source file that accesses the CityHash code directly. + */ + +#include "SkCityHash.h" +#include "SkTypes.h" +#include "city.h" + +uint32_t SkCityHash::Compute32(const char *data, size_t size) { + return CityHash32(data, size); +} + +uint64_t SkCityHash::Compute64(const char *data, size_t size) { + return CityHash64(data, size); +} diff --git a/src/utils/SkCityHash.h b/src/utils/SkCityHash.h new file mode 100644 index 0000000000..c69e0fb37b --- /dev/null +++ b/src/utils/SkCityHash.h @@ -0,0 +1,47 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Hash functions, using the CityHash algorithm. + * + * Results are guaranteed to be: + * 1. consistent across revisions of the library (for a given set + * of bytes, the checksum generated at one revision of the Skia + * library will match the one generated on any other revision of + * the Skia library) + * 2. consistent across platforms (for a given + * set of bytes, the checksum generated on one platform will + * match the one generated on any other platform) + */ + +#ifndef SkCityHash_DEFINED +#define SkCityHash_DEFINED + +#include "SkTypes.h" + +class SkCityHash : SkNoncopyable { +public: + /** + * Compute a 32-bit checksum for a given data block. + * + * @param data Memory address of the data block to be processed. + * @param size Size of the data block in bytes. + * @return checksum result + */ + static uint32_t Compute32(const char *data, size_t size); + + /** + * Compute a 64-bit checksum for a given data block. + * + * @param data Memory address of the data block to be processed. + * @param size Size of the data block in bytes. + * @return checksum result + */ + static uint64_t Compute64(const char *data, size_t size); +}; + +#endif diff --git a/src/utils/cityhash/README b/src/utils/cityhash/README new file mode 100644 index 0000000000..d93928857f --- /dev/null +++ b/src/utils/cityhash/README @@ -0,0 +1,2 @@ +This directory contains files needed to build third_party/externals/cityhash +(such as the config.h file that would normally be created by autoconf) diff --git a/src/utils/cityhash/config.h b/src/utils/cityhash/config.h new file mode 100644 index 0000000000..bd3641658e --- /dev/null +++ b/src/utils/cityhash/config.h @@ -0,0 +1,17 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +/** + * Converts from Skia build flags to the macro definitions cityhash normally + * gets from autoconf. + */ + +#include "SkTypes.h" + +#ifdef SK_CPU_BENDIAN + #define WORDS_BIGENDIAN 1 +#endif diff --git a/tests/ChecksumTest.cpp b/tests/ChecksumTest.cpp index ee33d32acd..81e7ef396c 100644 --- a/tests/ChecksumTest.cpp +++ b/tests/ChecksumTest.cpp @@ -8,6 +8,7 @@ #include "Test.h" #include "SkChecksum.h" +#include "SkCityHash.h" // Word size that is large enough to hold results of any checksum type. typedef uint64_t checksum_result; @@ -24,7 +25,9 @@ namespace skiatest { } private: enum Algorithm { - kSkChecksum + kSkChecksum, + kSkCityHash32, + kSkCityHash64 }; // Call Compute(data, size) on the appropriate checksum algorithm, @@ -38,6 +41,10 @@ namespace skiatest { REPORTER_ASSERT_MESSAGE(fReporter, SkIsAlign4(size), "test data size is not 32-bit aligned"); return SkChecksum::Compute(reinterpret_cast<const uint32_t *>(data), size); + case kSkCityHash32: + return SkCityHash::Compute32(data, size); + case kSkCityHash64: + return SkCityHash::Compute64(data, size); default: SkString message("fWhichAlgorithm has unknown value "); message.appendf("%d", fWhichAlgorithm); @@ -101,11 +108,31 @@ namespace skiatest { // Test self-consistency of checksum algorithms. fWhichAlgorithm = kSkChecksum; TestChecksumSelfConsistency(128); + fWhichAlgorithm = kSkCityHash32; + TestChecksumSelfConsistency(128); + fWhichAlgorithm = kSkCityHash64; + TestChecksumSelfConsistency(128); // Test checksum results that should be consistent across // versions and platforms. fWhichAlgorithm = kSkChecksum; REPORTER_ASSERT(fReporter, ComputeChecksum(NULL, 0) == 0); + fWhichAlgorithm = kSkCityHash32; + REPORTER_ASSERT(fReporter, ComputeChecksum(NULL, 0) == 0xdc56d17a); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(4) == 0x616e1132); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(8) == 0xeb0fd2d6); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(128) == 0x5321e430); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(132) == 0x924a10e4); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(256) == 0xd4de9dc9); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(260) == 0xecf0325d); + fWhichAlgorithm = kSkCityHash64; + REPORTER_ASSERT(fReporter, ComputeChecksum(NULL, 0) == 0x9ae16a3b2f90404fULL); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(4) == 0x82bffd898958e540ULL); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(8) == 0xad5a13e1e8e93b98ULL); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(128) == 0x10b153630af1f395ULL); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(132) == 0x7db71dc4adcc6647ULL); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(256) == 0xeee763519b91b010ULL); + REPORTER_ASSERT(fReporter, GetTestDataChecksum(260) == 0x2fe19e0b2239bc23ULL); // TODO: note the weakness exposed by these collisions... // We need to improve the SkChecksum algorithm. |