Sprite cache: Allow caching only required subset of sprite zoom levels
Enable for blitters based on 32bpp_optimized or SSE
This commit is contained in:
@@ -210,7 +210,6 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case BM_BLACK_REMAP:
|
||||
memset_colour(dst, _black_colour, n);
|
||||
memset(anim, 0, n * sizeof(*anim));
|
||||
|
@@ -36,6 +36,12 @@ class Blitter_32bppSSE4_Anim FINAL : public Blitter_32bppSSE2_Anim, public Blitt
|
||||
private:
|
||||
|
||||
public:
|
||||
Blitter_32bppSSE4_Anim()
|
||||
{
|
||||
this->Blitter_32bppSSE2_Anim::SetSupportsMissingZoomLevels(true);
|
||||
this->Blitter_32bppSSE4::SetSupportsMissingZoomLevels(true);
|
||||
}
|
||||
|
||||
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent, bool animated>
|
||||
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
|
@@ -301,6 +301,7 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
||||
|
||||
ZoomLevel zoom_min;
|
||||
ZoomLevel zoom_max;
|
||||
uint8 missing_zoom_levels = 0;
|
||||
|
||||
if (sprite->type == SpriteType::Font) {
|
||||
zoom_min = ZOOM_LVL_NORMAL;
|
||||
@@ -317,6 +318,7 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
||||
uint n_size = 0;
|
||||
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
||||
const SpriteLoader::Sprite *src_orig = &sprite[z];
|
||||
if (src_orig->data == nullptr) continue;
|
||||
|
||||
uint size = src_orig->height * src_orig->width;
|
||||
|
||||
@@ -339,6 +341,13 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
||||
|
||||
const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *)src_orig->data;
|
||||
|
||||
if (src == nullptr) {
|
||||
lengths[z][0] = 0;
|
||||
lengths[z][1] = 0;
|
||||
SetBit(missing_zoom_levels, z);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint y = src_orig->height; y > 0; y--) {
|
||||
/* Index 0 of dst_px and dst_n is left as space to save the length of the row to be filled later. */
|
||||
Colour *dst_px = (Colour *)&dst_px_ln[1];
|
||||
@@ -448,24 +457,34 @@ template <bool Tpal_to_rgb> Sprite *Blitter_32bppOptimized::EncodeInternal(const
|
||||
len += lengths[z][0] + lengths[z][1];
|
||||
}
|
||||
|
||||
Sprite *dest_sprite = (Sprite *)allocator(sizeof(*dest_sprite) + sizeof(SpriteData) + len);
|
||||
Sprite *dest_sprite = (Sprite *)allocator(sizeof(Sprite) + sizeof(SpriteData) + len);
|
||||
|
||||
if (len == 0) {
|
||||
/* Mark sprite as having no levels at all, and therefore replaceable */
|
||||
missing_zoom_levels = UINT8_MAX;
|
||||
}
|
||||
|
||||
dest_sprite->height = sprite->height;
|
||||
dest_sprite->width = sprite->width;
|
||||
dest_sprite->x_offs = sprite->x_offs;
|
||||
dest_sprite->y_offs = sprite->y_offs;
|
||||
dest_sprite->next = nullptr;
|
||||
dest_sprite->missing_zoom_levels = missing_zoom_levels;
|
||||
|
||||
SpriteData *dst = (SpriteData *)dest_sprite->data;
|
||||
memset(dst, 0, sizeof(*dst));
|
||||
/* Store sprite flags. */
|
||||
dst->flags = flags;
|
||||
|
||||
uint32 next_offset = 0;
|
||||
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
||||
dst->offset[z][0] = z == zoom_min ? 0 : lengths[z - 1][1] + dst->offset[z - 1][1];
|
||||
dst->offset[z][1] = lengths[z][0] + dst->offset[z][0];
|
||||
dst->offset[z][0] = next_offset;
|
||||
dst->offset[z][1] = lengths[z][0] + next_offset;
|
||||
|
||||
memcpy(dst->data + dst->offset[z][0], dst_px_orig[z], lengths[z][0]);
|
||||
memcpy(dst->data + dst->offset[z][1], dst_n_orig[z], lengths[z][1]);
|
||||
next_offset += lengths[z][0] + lengths[z][1];
|
||||
|
||||
if (lengths[z][0] != 0) memcpy(dst->data + dst->offset[z][0], dst_px_orig[z], lengths[z][0]);
|
||||
if (lengths[z][1] != 0) memcpy(dst->data + dst->offset[z][1], dst_n_orig[z], lengths[z][1]);
|
||||
}
|
||||
|
||||
free(px_buffer);
|
||||
|
@@ -22,6 +22,11 @@ public:
|
||||
byte data[]; ///< Data, all zoomlevels.
|
||||
};
|
||||
|
||||
Blitter_32bppOptimized()
|
||||
{
|
||||
this->SetSupportsMissingZoomLevels(true);
|
||||
}
|
||||
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override;
|
||||
|
||||
|
@@ -137,6 +137,8 @@ Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::Sprite *sprite, Allocato
|
||||
dest_sprite->width = sprite->width;
|
||||
dest_sprite->x_offs = sprite->x_offs;
|
||||
dest_sprite->y_offs = sprite->y_offs;
|
||||
dest_sprite->next = nullptr;
|
||||
dest_sprite->missing_zoom_levels = 0;
|
||||
|
||||
dst = (Blitter_32bppSimple::Pixel *)dest_sprite->data;
|
||||
SpriteLoader::CommonPixel *src = (SpriteLoader::CommonPixel *)sprite->data;
|
||||
|
@@ -28,6 +28,7 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
*/
|
||||
ZoomLevel zoom_min = ZOOM_LVL_NORMAL;
|
||||
ZoomLevel zoom_max = ZOOM_LVL_NORMAL;
|
||||
uint8 missing_zoom_levels = 0;
|
||||
if (sprite->type != SpriteType::Font) {
|
||||
zoom_min = _settings_client.gui.zoom_min;
|
||||
zoom_max = (ZoomLevel) std::min(_settings_client.gui.zoom_max, ZOOM_LVL_DRAW_SPR);
|
||||
@@ -40,6 +41,15 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
uint all_sprites_size = 0;
|
||||
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
||||
const SpriteLoader::Sprite *src_sprite = &sprite[z];
|
||||
if (src_sprite->data == nullptr) {
|
||||
sd.infos[z].sprite_offset = 0;
|
||||
sd.infos[z].mv_offset = 0;
|
||||
sd.infos[z].sprite_line_size = 0;
|
||||
sd.infos[z].sprite_width = 0;
|
||||
SetBit(missing_zoom_levels, z);
|
||||
continue;
|
||||
}
|
||||
|
||||
sd.infos[z].sprite_width = src_sprite->width;
|
||||
sd.infos[z].sprite_offset = all_sprites_size;
|
||||
sd.infos[z].sprite_line_size = sizeof(Colour) * src_sprite->width + sizeof(uint32) * META_LENGTH;
|
||||
@@ -56,6 +66,8 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
dst_sprite->width = sprite->width;
|
||||
dst_sprite->x_offs = sprite->x_offs;
|
||||
dst_sprite->y_offs = sprite->y_offs;
|
||||
dst_sprite->next = nullptr;
|
||||
dst_sprite->missing_zoom_levels = missing_zoom_levels;
|
||||
memcpy(dst_sprite->data, &sd, sizeof(SpriteData));
|
||||
|
||||
/* Copy colours and determine flags. */
|
||||
@@ -64,6 +76,9 @@ Sprite *Blitter_32bppSSE_Base::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
bool has_translucency = false;
|
||||
for (ZoomLevel z = zoom_min; z <= zoom_max; z++) {
|
||||
const SpriteLoader::Sprite *src_sprite = &sprite[z];
|
||||
if (src_sprite->data == nullptr) {
|
||||
continue;
|
||||
}
|
||||
const SpriteLoader::CommonPixel *src = (const SpriteLoader::CommonPixel *) src_sprite->data;
|
||||
Colour *dst_rgba_line = (Colour *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].sprite_offset];
|
||||
MapValue *dst_mv = (MapValue *) &dst_sprite->data[sizeof(SpriteData) + sd.infos[z].mv_offset];
|
||||
|
@@ -70,6 +70,11 @@ public:
|
||||
/** The SSE2 32 bpp blitter (without palette animation). */
|
||||
class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base {
|
||||
public:
|
||||
Blitter_32bppSSE2()
|
||||
{
|
||||
this->SetSupportsMissingZoomLevels(true);
|
||||
}
|
||||
|
||||
void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override;
|
||||
template <BlitterMode mode, Blitter_32bppSSE_Base::ReadMode read_mode, Blitter_32bppSSE_Base::BlockType bt_last, bool translucent>
|
||||
void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom);
|
||||
|
@@ -225,6 +225,8 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca
|
||||
dest_sprite->width = sprite->width;
|
||||
dest_sprite->x_offs = sprite->x_offs;
|
||||
dest_sprite->y_offs = sprite->y_offs;
|
||||
dest_sprite->next = nullptr;
|
||||
dest_sprite->missing_zoom_levels = 0;
|
||||
memcpy(dest_sprite->data, temp_dst, size);
|
||||
|
||||
return dest_sprite;
|
||||
|
@@ -70,6 +70,8 @@ Sprite *Blitter_8bppSimple::Encode(const SpriteLoader::Sprite *sprite, Allocator
|
||||
dest_sprite->width = sprite->width;
|
||||
dest_sprite->x_offs = sprite->x_offs;
|
||||
dest_sprite->y_offs = sprite->y_offs;
|
||||
dest_sprite->next = nullptr;
|
||||
dest_sprite->missing_zoom_levels = 0;
|
||||
|
||||
/* Copy over only the 'remap' channel, as that is what we care about in 8bpp */
|
||||
for (int i = 0; i < sprite->height * sprite->width; i++) {
|
||||
|
@@ -24,6 +24,8 @@ Sprite *Blitter_Null::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *
|
||||
dest_sprite->width = sprite->width;
|
||||
dest_sprite->x_offs = sprite->x_offs;
|
||||
dest_sprite->y_offs = sprite->y_offs;
|
||||
dest_sprite->next = nullptr;
|
||||
dest_sprite->missing_zoom_levels = 0;
|
||||
|
||||
return dest_sprite;
|
||||
}
|
||||
|
Reference in New Issue
Block a user