Skip to content

Commit

Permalink
Animated palette image caching
Browse files Browse the repository at this point in the history
  • Loading branch information
Cacodemon345 committed Sep 12, 2023
1 parent da824b2 commit bfb9124
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 18 deletions.
43 changes: 43 additions & 0 deletions src/common/textures/formats/webptexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class FWebPTexture : public FImageSource
int CopyPixels(FBitmap *bmp, int conversion, int frame = 0) override;
int GetDurationOfFrame(int frame) override;
int CopyPixelsIntoFrames(std::function<FBitmap* (int)> GetBitmap, int conversion) override;
void CreatePalettedPixelsOfFrames(std::function<PalettedPixels& (int)> GetPixels, int conversion) override;

private:
std::vector<int, FImageArenaAllocator<int>> durations;
Expand Down Expand Up @@ -178,6 +179,48 @@ PalettedPixels FWebPTexture::CreatePalettedPixels(int conversion, int frame)
return Pixels;
}

void FWebPTexture::CreatePalettedPixelsOfFrames(std::function<PalettedPixels& (int)> GetPixels, int conversion)
{
TArray<FBitmap> bitmaps(GetNumOfFrames(), true);
CopyPixelsIntoFrames([&bitmaps, this](int index) -> FBitmap*
{
bitmaps[index].Create(Width, Height);
return &bitmaps[index];
}, conversion);

for (int i = 0; i < GetNumOfFrames(); i++)
{
FBitmap& bitmap = bitmaps[i];
const uint8_t *data = bitmap.GetPixels();

uint8_t *dest_p;
int dest_adv = Height;
int dest_rew = Width * Height - 1;

PalettedPixels Pixels(Width*Height);
dest_p = Pixels.Data();

bool doalpha = conversion == luminance;
// Convert the source image from row-major to column-major format and remap it
for (int y = Height; y != 0; --y)
{
for (int x = Width; x != 0; --x)
{
int b = *data++;
int g = *data++;
int r = *data++;
int a = *data++;
if (a < 128) *dest_p = 0;
else *dest_p = ImageHelpers::RGBToPalette(doalpha, r, g, b);
dest_p += dest_adv;
}
dest_p -= dest_rew;
}

GetPixels(i) = Pixels;
}
}

int FWebPTexture::CopyPixelsIntoFrames(std::function<FBitmap* (int)> GetBitmap, int conversion)
{
auto bytes = fileSystem.ReadFile(SourceLump);
Expand Down
67 changes: 50 additions & 17 deletions src/common/textures/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,40 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion, int frame)
{
//Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->second);
// This is the first time it gets accessed and needs to be placed in the cache.
PrecacheDataPaletted *pdp = &precacheDataPaletted[precacheDataPaletted.Reserve(1)];
if (frame >= 1)
{
// Share reference count with the default frame.
int RefCount = (info && info->second) ? (info->second - 1) : 1;

// Cache ALL frames, and I mean, ALL frames, to avoid massive overhead when loading animated images.
PrecacheDataPaletted *pdp = &precacheDataPaletted[precacheDataPaletted.Reserve(GetNumOfFrames())];

for (int i = 0; i < GetNumOfFrames(); i++)
{
pdp[i].ImageID = imageID;
pdp[i].Frame = i + 1;
pdp[i].RefCount = RefCount;
}

CreatePalettedPixelsOfFrames([&pdp](int idx) -> PalettedPixels&
{
return pdp[idx].Pixels;
}, normal);

pdp->ImageID = imageID;
pdp->RefCount = info->second - 1;
info->second = 0;
pdp->Pixels = CreatePalettedPixels(normal, frame);
ret.Pixels.Set(pdp->Pixels.Data(), pdp->Pixels.Size());
if (info) info->second = 0;

ret.Pixels.Set(pdp[frame - 1].Pixels.Data(), pdp[frame - 1].Pixels.Size());
}
else
{
PrecacheDataPaletted *pdp = &precacheDataPaletted[precacheDataPaletted.Reserve(1)];

pdp->ImageID = imageID;
pdp->RefCount = info->second - 1;
info->second = 0;
pdp->Pixels = CreatePalettedPixels(normal, frame);
ret.Pixels.Set(pdp->Pixels.Data(), pdp->Pixels.Size());
}
}
}
return ret;
Expand Down Expand Up @@ -200,17 +227,27 @@ int FImageSource::CopyPixelsIntoFrames(std::function<FBitmap* (int)> GetBitmap,
return trans;
}

TArray<PalettedPixels> FImageSource::CreatePalettedPixelsFrames(int conversion)
{
TArray<PalettedPixels> palettedPixelFrames;
//==========================================================================
//
//
//
//==========================================================================

void FImageSource::CreatePalettedPixelsOfFrames(std::function<PalettedPixels& (int)> GetPixels, int conversion)
{
for (int i = 0; i < NumOfFrames; i++)
{
palettedPixelFrames.Push(CreatePalettedPixels(conversion, i + 1));
GetPixels(i) = CreatePalettedPixels(conversion, i + 1);
}
return palettedPixelFrames;
return;
}

//==========================================================================
//
//
//
//==========================================================================

FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int *ptrans, int frame)
{
FBitmap ret;
Expand Down Expand Up @@ -279,13 +316,8 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int
if (frame >= 1)
{
// Share reference count with the default frame.
unsigned defaultIndex = precacheDataRgba.FindEx([=](PrecacheDataRgba& entry) { return entry.ImageID == imageID && entry.Frame == 0; });
int RefCount = 1;
int RefCount = (info && info->first) ? (info->first - 1) : 1;

if (defaultIndex < precacheDataRgba.Size() && precacheDataRgba[defaultIndex].RefCount)
{
RefCount = precacheDataRgba[defaultIndex].RefCount;
}
// Cache ALL frames, and I mean, ALL frames, to avoid massive overhead when loading animated images.
PrecacheDataRgba *pdr = &precacheDataRgba[precacheDataRgba.Reserve(GetNumOfFrames())];

Expand All @@ -307,6 +339,7 @@ FBitmap FImageSource::GetCachedBitmap(const PalEntry *remap, int conversion, int
pdr[i].TransInfo = trans;
}

if (info) info->first = 0;
ret.Copy(pdr[frame - 1].Pixels, false);
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/common/textures/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ class FImageSource
bool UsesPastFrame() { return true; }

virtual int CopyPixelsIntoFrames(std::function<FBitmap* (int)> GetBitmap, int conversion);
virtual TArray<PalettedPixels> CreatePalettedPixelsFrames(int conversion);
virtual void CreatePalettedPixelsOfFrames(std::function<PalettedPixels& (int)> GetPixels, int conversion);

// Conversion option
enum EType
Expand Down

0 comments on commit bfb9124

Please sign in to comment.