From 80322af02e73aaf70fd22a982aa6521eb29f71b8 Mon Sep 17 00:00:00 2001 From: David Capello Date: Mon, 19 Apr 2021 15:53:04 -0300 Subject: [PATCH] Use CityHash for tiles This reduces the level of collisions between hash buckets between different image tiles. --- .gitmodules | 3 +++ docs/LICENSES.md | 24 +++++++++++++++++ src/doc/CMakeLists.txt | 5 ++-- src/doc/image_impl.h | 5 +++- src/doc/primitives.cpp | 55 +++++++++++++++++++------------------- third_party/CMakeLists.txt | 3 +++ third_party/cityhash | 1 + 7 files changed, 66 insertions(+), 30 deletions(-) create mode 160000 third_party/cityhash diff --git a/.gitmodules b/.gitmodules index 780aaf1c3..387d007ff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -66,3 +66,6 @@ [submodule "src/tga"] path = src/tga url = https://github.com/aseprite/tga.git +[submodule "third_party/cityhash"] + path = third_party/cityhash + url = https://github.com/aseprite/cityhash.git diff --git a/docs/LICENSES.md b/docs/LICENSES.md index 46794370f..c81bcd4db 100644 --- a/docs/LICENSES.md +++ b/docs/LICENSES.md @@ -53,6 +53,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` +# [cityhash](https://github.com/google/cityhash) + +``` +Copyright (c) 2011 Google, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +``` + # [cmark](https://github.com/jgm/cmark) ``` diff --git a/src/doc/CMakeLists.txt b/src/doc/CMakeLists.txt index a3348c99c..ddaead008 100644 --- a/src/doc/CMakeLists.txt +++ b/src/doc/CMakeLists.txt @@ -1,5 +1,5 @@ # Aseprite Document Library -# Copyright (C) 2019-2020 Igara Studio S.A. +# Copyright (C) 2019-2021 Igara Studio S.A. # Copyright (C) 2001-2018 David Capello if(WIN32) @@ -80,4 +80,5 @@ add_library(doc-lib target_link_libraries(doc-lib laf-gfx laf-base - fixmath-lib) + fixmath-lib + cityhash) diff --git a/src/doc/image_impl.h b/src/doc/image_impl.h index 0287131f3..15ad69376 100644 --- a/src/doc/image_impl.h +++ b/src/doc/image_impl.h @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (C) 2018-2020 Igara Studio S.A. +// Copyright (C) 2018-2021 Igara Studio S.A. // Copyright (C) 2001-2016 David Capello // // This file is released under the terms of the MIT license. @@ -72,6 +72,9 @@ namespace doc { else m_buffer->resizeIfNecessary(required_size); + std::fill(m_buffer->buffer(), + m_buffer->buffer()+required_size, 0); + m_rows = (address_t*)m_buffer->buffer(); m_bits = (address_t)(m_buffer->buffer() + for_rows); diff --git a/src/doc/primitives.cpp b/src/doc/primitives.cpp index 03a390841..4f3e1fc62 100644 --- a/src/doc/primitives.cpp +++ b/src/doc/primitives.cpp @@ -1,5 +1,5 @@ // Aseprite Document Library -// Copyright (c) 2018-2020 Igara Studio S.A. +// Copyright (c) 2018-2021 Igara Studio S.A. // Copyright (c) 2001-2016 David Capello // // This file is released under the terms of the MIT license. @@ -20,6 +20,8 @@ #include "doc/tile.h" #include "gfx/region.h" +#include + #include namespace doc { @@ -442,21 +444,30 @@ template static uint32_t calculate_image_hash_templ(const Image* image, const gfx::Rect& bounds) { - uint32_t hash = 0; - for (int y=0; ygetPixelAddress(bounds.x, bounds.y+y); - for (int x=0; x>= 8; - mask >>= 8; - } - } +#if defined(__LP64__) || defined(__x86_64__) || defined(_WIN64) + #define CITYHASH(buf, len) (CityHash64(buf, len) & 0xffffffff) + static_assert(sizeof(void*) == 8, "This CPU is not 64-bit"); +#else + #define CITYHASH(buf, len) CityHash32(buf, len) + static_assert(sizeof(void*) == 4, "This CPU is not 32-bit"); +#endif + + const uint32_t rowlen = ImageTraits::getRowStrideBytes(bounds.w); + const uint32_t len = rowlen * bounds.h; + if (bounds == image->bounds()) { + return CITYHASH((const char*)image->getPixelAddress(0, 0), len); + } + else { + ASSERT(false); // TODO not used at this moment + + std::vector buf(len); + uint8_t* dst = &buf[0]; + for (int y=0; ygetPixelAddress(bounds.x, bounds.y+y); + std::copy(dst, dst+rowlen, src); + } + return CITYHASH((const char*)&buf[0], buf.size()); } - return hash; } uint32_t calculate_image_hash(const Image* img, const gfx::Rect& bounds) @@ -467,18 +478,8 @@ uint32_t calculate_image_hash(const Image* img, const gfx::Rect& bounds) case IMAGE_INDEXED: return calculate_image_hash_templ(img, bounds); case IMAGE_BITMAP: return calculate_image_hash_templ(img, bounds); } - - uint32_t hash = 0; - for (int y=0; ygetRowStrideSize(bounds.w); - uint8_t* p = img->getPixelAddress(bounds.x, bounds.y+y); - while (bytes-- > 0) { - hash += *p; - hash <<= 1; - ++p; - } - } - return hash; + ASSERT(false); + return 0; } } // namespace doc diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index d03eb0851..30d90857e 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -112,6 +112,9 @@ endif() add_library(tinyexpr tinyexpr/tinyexpr.c) target_include_directories(tinyexpr PUBLIC tinyexpr) +# cityhash +add_subdirectory(cityhash) + # lua if(ENABLE_SCRIPTING) add_library(lua diff --git a/third_party/cityhash b/third_party/cityhash new file mode 160000 index 000000000..757152d47 --- /dev/null +++ b/third_party/cityhash @@ -0,0 +1 @@ +Subproject commit 757152d474e395adfcd1440d275b5dd0d1997f49