mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 13:21:34 +00:00
Change RgbMap behavior to act like a cache of Palette::findBestfit() calls
Instead of calling findBestfit() for all RGBA colors in RgbMap::regenerate(), we mark all entries as invalid, and then we validate them only when the user require one specific entry from RgbMap::mapColor(). With this we avoid a lot of unnecessary computations each time the palette changes.
This commit is contained in:
parent
48a1af7342
commit
66168d6b06
@ -26,6 +26,7 @@ RgbMap::RgbMap()
|
||||
, m_map(MAPSIZE)
|
||||
, m_palette(NULL)
|
||||
, m_modifications(0)
|
||||
, m_maskIndex(0)
|
||||
{
|
||||
}
|
||||
|
||||
@ -39,24 +40,21 @@ void RgbMap::regenerate(const Palette* palette, int mask_index)
|
||||
{
|
||||
m_palette = palette;
|
||||
m_modifications = palette->getModifications();
|
||||
m_maskIndex = mask_index;
|
||||
|
||||
// TODO This is slow for 256 colors 32*32*32*8 findBestfit calls
|
||||
// Mark all entries as invalid (need to be regenerated)
|
||||
for (uint16_t& entry : m_map)
|
||||
entry |= INVALID;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (int r=0; r<RSIZE; ++r) {
|
||||
for (int g=0; g<GSIZE; ++g) {
|
||||
for (int b=0; b<BSIZE; ++b) {
|
||||
for (int a=0; a<ASIZE; ++a) {
|
||||
m_map[i++] =
|
||||
palette->findBestfit(
|
||||
scale_5bits_to_8bits(r),
|
||||
scale_5bits_to_8bits(g),
|
||||
scale_5bits_to_8bits(b),
|
||||
scale_3bits_to_8bits(a), mask_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int RgbMap::generateEntry(int i, int r, int g, int b, int a) const
|
||||
{
|
||||
return m_map[i] =
|
||||
m_palette->findBestfit(
|
||||
scale_5bits_to_8bits(r>>3),
|
||||
scale_5bits_to_8bits(g>>3),
|
||||
scale_5bits_to_8bits(b>>3),
|
||||
scale_3bits_to_8bits(a>>5), m_maskIndex);
|
||||
}
|
||||
|
||||
} // namespace doc
|
||||
|
@ -17,7 +17,11 @@ namespace doc {
|
||||
|
||||
class Palette;
|
||||
|
||||
// It acts like a cache for Palette:findBestfit() calls.
|
||||
class RgbMap : public Object {
|
||||
// Bit activated on m_map entries that aren't yet calculated.
|
||||
const int INVALID = 256;
|
||||
|
||||
public:
|
||||
RgbMap();
|
||||
|
||||
@ -30,13 +34,18 @@ namespace doc {
|
||||
ASSERT(b >= 0 && b < 256);
|
||||
ASSERT(a >= 0 && a < 256);
|
||||
// bits -> bbbbbgggggrrrrraaa
|
||||
return m_map[(a>>5) | ((b>>3) << 3) | ((g>>3) << 8) | ((r>>3) << 13)];
|
||||
int i = (a>>5) | ((b>>3) << 3) | ((g>>3) << 8) | ((r>>3) << 13);
|
||||
int v = m_map[i];
|
||||
return (v & INVALID) ? generateEntry(i, r, g, b, a): v;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<uint8_t> m_map;
|
||||
int generateEntry(int i, int r, int g, int b, int a) const;
|
||||
|
||||
mutable std::vector<uint16_t> m_map;
|
||||
const Palette* m_palette;
|
||||
int m_modifications;
|
||||
int m_maskIndex;
|
||||
|
||||
DISABLE_COPYING(RgbMap);
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user