mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-06 06:50:07 +00:00
Use CityHash for tiles
This reduces the level of collisions between hash buckets between different image tiles.
This commit is contained in:
parent
b90c56487d
commit
80322af02e
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -66,3 +66,6 @@
|
|||||||
[submodule "src/tga"]
|
[submodule "src/tga"]
|
||||||
path = src/tga
|
path = src/tga
|
||||||
url = https://github.com/aseprite/tga.git
|
url = https://github.com/aseprite/tga.git
|
||||||
|
[submodule "third_party/cityhash"]
|
||||||
|
path = third_party/cityhash
|
||||||
|
url = https://github.com/aseprite/cityhash.git
|
||||||
|
@ -53,6 +53,30 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|||||||
SOFTWARE.
|
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)
|
# [cmark](https://github.com/jgm/cmark)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Aseprite Document Library
|
# 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
|
# Copyright (C) 2001-2018 David Capello
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
@ -80,4 +80,5 @@ add_library(doc-lib
|
|||||||
target_link_libraries(doc-lib
|
target_link_libraries(doc-lib
|
||||||
laf-gfx
|
laf-gfx
|
||||||
laf-base
|
laf-base
|
||||||
fixmath-lib)
|
fixmath-lib
|
||||||
|
cityhash)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Document Library
|
// 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
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -72,6 +72,9 @@ namespace doc {
|
|||||||
else
|
else
|
||||||
m_buffer->resizeIfNecessary(required_size);
|
m_buffer->resizeIfNecessary(required_size);
|
||||||
|
|
||||||
|
std::fill(m_buffer->buffer(),
|
||||||
|
m_buffer->buffer()+required_size, 0);
|
||||||
|
|
||||||
m_rows = (address_t*)m_buffer->buffer();
|
m_rows = (address_t*)m_buffer->buffer();
|
||||||
m_bits = (address_t)(m_buffer->buffer() + for_rows);
|
m_bits = (address_t)(m_buffer->buffer() + for_rows);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite Document Library
|
// 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
|
// Copyright (c) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -20,6 +20,8 @@
|
|||||||
#include "doc/tile.h"
|
#include "doc/tile.h"
|
||||||
#include "gfx/region.h"
|
#include "gfx/region.h"
|
||||||
|
|
||||||
|
#include <city.h>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
@ -442,21 +444,30 @@ template <typename ImageTraits, uint32_t Mask>
|
|||||||
static uint32_t calculate_image_hash_templ(const Image* image,
|
static uint32_t calculate_image_hash_templ(const Image* image,
|
||||||
const gfx::Rect& bounds)
|
const gfx::Rect& bounds)
|
||||||
{
|
{
|
||||||
uint32_t hash = 0;
|
#if defined(__LP64__) || defined(__x86_64__) || defined(_WIN64)
|
||||||
for (int y=0; y<bounds.h; ++y) {
|
#define CITYHASH(buf, len) (CityHash64(buf, len) & 0xffffffff)
|
||||||
auto p = (typename ImageTraits::address_t)image->getPixelAddress(bounds.x, bounds.y+y);
|
static_assert(sizeof(void*) == 8, "This CPU is not 64-bit");
|
||||||
for (int x=0; x<bounds.w; ++x, ++p) {
|
#else
|
||||||
uint32_t value = *p;
|
#define CITYHASH(buf, len) CityHash32(buf, len)
|
||||||
uint32_t mask = Mask;
|
static_assert(sizeof(void*) == 4, "This CPU is not 32-bit");
|
||||||
while (mask) {
|
#endif
|
||||||
hash += value & mask & 0xff;
|
|
||||||
hash <<= 1;
|
const uint32_t rowlen = ImageTraits::getRowStrideBytes(bounds.w);
|
||||||
value >>= 8;
|
const uint32_t len = rowlen * bounds.h;
|
||||||
mask >>= 8;
|
if (bounds == image->bounds()) {
|
||||||
|
return CITYHASH((const char*)image->getPixelAddress(0, 0), len);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ASSERT(false); // TODO not used at this moment
|
||||||
|
|
||||||
|
std::vector<uint8_t> buf(len);
|
||||||
|
uint8_t* dst = &buf[0];
|
||||||
|
for (int y=0; y<bounds.h; ++y, dst+=rowlen) {
|
||||||
|
auto src = image->getPixelAddress(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)
|
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<IndexedTraits, 0xff>(img, bounds);
|
case IMAGE_INDEXED: return calculate_image_hash_templ<IndexedTraits, 0xff>(img, bounds);
|
||||||
case IMAGE_BITMAP: return calculate_image_hash_templ<BitmapTraits, 1>(img, bounds);
|
case IMAGE_BITMAP: return calculate_image_hash_templ<BitmapTraits, 1>(img, bounds);
|
||||||
}
|
}
|
||||||
|
ASSERT(false);
|
||||||
uint32_t hash = 0;
|
return 0;
|
||||||
for (int y=0; y<bounds.h; ++y) {
|
|
||||||
int bytes = img->getRowStrideSize(bounds.w);
|
|
||||||
uint8_t* p = img->getPixelAddress(bounds.x, bounds.y+y);
|
|
||||||
while (bytes-- > 0) {
|
|
||||||
hash += *p;
|
|
||||||
hash <<= 1;
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace doc
|
} // namespace doc
|
||||||
|
3
third_party/CMakeLists.txt
vendored
3
third_party/CMakeLists.txt
vendored
@ -112,6 +112,9 @@ endif()
|
|||||||
add_library(tinyexpr tinyexpr/tinyexpr.c)
|
add_library(tinyexpr tinyexpr/tinyexpr.c)
|
||||||
target_include_directories(tinyexpr PUBLIC tinyexpr)
|
target_include_directories(tinyexpr PUBLIC tinyexpr)
|
||||||
|
|
||||||
|
# cityhash
|
||||||
|
add_subdirectory(cityhash)
|
||||||
|
|
||||||
# lua
|
# lua
|
||||||
if(ENABLE_SCRIPTING)
|
if(ENABLE_SCRIPTING)
|
||||||
add_library(lua
|
add_library(lua
|
||||||
|
1
third_party/cityhash
vendored
Submodule
1
third_party/cityhash
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 757152d474e395adfcd1440d275b5dd0d1997f49
|
Loading…
Reference in New Issue
Block a user