From 095a5e2c0a73dbd71c4bb29bc030c094dff29179 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 16 Apr 2020 18:46:31 +0200 Subject: [PATCH] - allocate the sprite positioning info on demand only. For most textures this is never needed and it can easily be put in the memory arena being used for image sources. --- src/common/textures/image.cpp | 2 +- src/common/textures/image.h | 2 +- src/common/textures/texture.cpp | 119 ++++++++++++++----------- src/common/textures/texturemanager.cpp | 6 -- src/common/textures/textures.h | 12 +-- 5 files changed, 71 insertions(+), 70 deletions(-) diff --git a/src/common/textures/image.cpp b/src/common/textures/image.cpp index ef40efd19..d68db329d 100644 --- a/src/common/textures/image.cpp +++ b/src/common/textures/image.cpp @@ -41,7 +41,7 @@ #include "cmdlib.h" #include "palettecontainer.h" -FMemArena FImageSource::ImageArena(32768); +FMemArena ImageArena(32768); TArrayFImageSource::ImageForLump; int FImageSource::NextID; static PrecacheInfo precacheInfo; diff --git a/src/common/textures/image.h b/src/common/textures/image.h index 00b541411..38e5a2ee1 100644 --- a/src/common/textures/image.h +++ b/src/common/textures/image.h @@ -7,6 +7,7 @@ class FImageSource; using PrecacheInfo = TMap>; +extern FMemArena ImageArena; // Doom patch format header struct patch_t @@ -38,7 +39,6 @@ class FImageSource friend class FBrightmapTexture; protected: - static FMemArena ImageArena; static TArrayImageForLump; static int NextID; diff --git a/src/common/textures/texture.cpp b/src/common/textures/texture.cpp index adb2b60e4..c41637430 100644 --- a/src/common/textures/texture.cpp +++ b/src/common/textures/texture.cpp @@ -737,29 +737,6 @@ TArray FTexture::Get8BitPixels(bool alphatex) return Pixels; } -//=========================================================================== -// -// Sets up the sprite positioning data for this texture -// -//=========================================================================== - -void FTexture::SetupSpriteData() -{ - spi.mSpriteU[0] = spi.mSpriteV[0] = 0.f; - spi.mSpriteU[1] = spi.mSpriteV[1] = 1.f; - spi.spriteWidth = GetTexelWidth(); - spi.spriteHeight = GetTexelHeight(); - - if (ShouldExpandSprite()) - { - if (mTrimResult == -1) mTrimResult = !!TrimBorders(spi.trim); // get the trim size before adding the empty frame - spi.spriteWidth += 2; - spi.spriteHeight += 2; - } - else mTrimResult = 0; - SetSpriteRect(); -} - //=========================================================================== // // Checks if a sprite may be expanded with an empty frame @@ -875,54 +852,90 @@ outl: } //=========================================================================== +// +// Sets up the sprite positioning data for this texture // -// Set the sprite rectangle +//=========================================================================== + +void FTexture::SetupSpriteData() +{ + // Since this is only needed for real sprites it gets allocated on demand. + // It also allocates from the image memory arena because it has the same lifetime and to reduce maintenance. + if (spi == nullptr) spi = (SpritePositioningInfo*)ImageArena.Alloc(2 * sizeof(SpritePositioningInfo)); + for (int i = 0; i < 2; i++) + { + auto& spi = this->spi[i]; + spi.mSpriteU[0] = spi.mSpriteV[0] = 0.f; + spi.mSpriteU[1] = spi.mSpriteV[1] = 1.f; + spi.spriteWidth = GetTexelWidth(); + spi.spriteHeight = GetTexelHeight(); + + if (i == 1 && ShouldExpandSprite()) + { + spi.mTrimResult = TrimBorders(spi.trim); // get the trim size before adding the empty frame + spi.spriteWidth += 2; + spi.spriteHeight += 2; + } + } + SetSpriteRect(); +} + +//=========================================================================== +// +// Set the sprite rectangle. This is separate because it may be called by a CVAR, too. // //=========================================================================== void FTexture::SetSpriteRect() { + + if (!spi) return; auto leftOffset = GetLeftOffsetHW(); auto topOffset = GetTopOffsetHW(); float fxScale = (float)Scale.X; float fyScale = (float)Scale.Y; - // mSpriteRect is for positioning the sprite in the scene. - spi.mSpriteRect.left = -leftOffset / fxScale; - spi.mSpriteRect.top = -topOffset / fyScale; - spi.mSpriteRect.width = spi.spriteWidth / fxScale; - spi.mSpriteRect.height = spi.spriteHeight / fyScale; - - if (bExpandSprite) + for (int i = 0; i < 2; i++) { - // a little adjustment to make sprites look better with texture filtering: - // create a 1 pixel wide empty frame around them. + auto& spi = this->spi[i]; - int oldwidth = spi.spriteWidth - 2; - int oldheight = spi.spriteHeight - 2; + // mSpriteRect is for positioning the sprite in the scene. + spi.mSpriteRect.left = -leftOffset / fxScale; + spi.mSpriteRect.top = -topOffset / fyScale; + spi.mSpriteRect.width = spi.spriteWidth / fxScale; + spi.mSpriteRect.height = spi.spriteHeight / fyScale; - leftOffset += 1; - topOffset += 1; - - // Reposition the sprite with the frame considered - spi.mSpriteRect.left = -(float)leftOffset / fxScale; - spi.mSpriteRect.top = -(float)topOffset / fyScale; - spi.mSpriteRect.width = (float)spi.spriteWidth / fxScale; - spi.mSpriteRect.height = (float)spi.spriteHeight / fyScale; - - if (mTrimResult > 0) + if (i == 1 && ShouldExpandSprite()) { - spi.mSpriteRect.left += (float)spi.trim[0] / fxScale; - spi.mSpriteRect.top += (float)spi.trim[1] / fyScale; + // a little adjustment to make sprites look better with texture filtering: + // create a 1 pixel wide empty frame around them. - spi.mSpriteRect.width -= float(oldwidth - spi.trim[2]) / fxScale; - spi.mSpriteRect.height -= float(oldheight - spi.trim[3]) / fyScale; + int oldwidth = spi.spriteWidth - 2; + int oldheight = spi.spriteHeight - 2; - spi.mSpriteU[0] = (float)spi.trim[0] / (float)spi.spriteWidth; - spi.mSpriteV[0] = (float)spi.trim[1] / (float)spi.spriteHeight; - spi.mSpriteU[1] -= float(oldwidth - spi.trim[0] - spi.trim[2]) / (float)spi.spriteWidth; - spi.mSpriteV[1] -= float(oldheight - spi.trim[1] - spi.trim[3]) / (float)spi.spriteHeight; + leftOffset += 1; + topOffset += 1; + + // Reposition the sprite with the frame considered + spi.mSpriteRect.left = -(float)leftOffset / fxScale; + spi.mSpriteRect.top = -(float)topOffset / fyScale; + spi.mSpriteRect.width = (float)spi.spriteWidth / fxScale; + spi.mSpriteRect.height = (float)spi.spriteHeight / fyScale; + + if (spi.mTrimResult > 0) + { + spi.mSpriteRect.left += (float)spi.trim[0] / fxScale; + spi.mSpriteRect.top += (float)spi.trim[1] / fyScale; + + spi.mSpriteRect.width -= float(oldwidth - spi.trim[2]) / fxScale; + spi.mSpriteRect.height -= float(oldheight - spi.trim[3]) / fyScale; + + spi.mSpriteU[0] = (float)spi.trim[0] / (float)spi.spriteWidth; + spi.mSpriteV[0] = (float)spi.trim[1] / (float)spi.spriteHeight; + spi.mSpriteU[1] -= float(oldwidth - spi.trim[0] - spi.trim[2]) / (float)spi.spriteWidth; + spi.mSpriteV[1] -= float(oldheight - spi.trim[1] - spi.trim[3]) / (float)spi.spriteHeight; + } } } } diff --git a/src/common/textures/texturemanager.cpp b/src/common/textures/texturemanager.cpp index 5ffac6fc8..ca370dda6 100644 --- a/src/common/textures/texturemanager.cpp +++ b/src/common/textures/texturemanager.cpp @@ -1488,9 +1488,3 @@ FTextureID FTextureID::operator +(int offset) throw() if (texnum + offset >= TexMan.NumTextures()) return FTextureID(-1); return FTextureID(texnum + offset); } - - -CCMD(texinfo) -{ - Printf("Sizeof texture = %d\n", sizeof(FTexture)); -} diff --git a/src/common/textures/textures.h b/src/common/textures/textures.h index c4841cb81..76af078f1 100644 --- a/src/common/textures/textures.h +++ b/src/common/textures/textures.h @@ -229,6 +229,7 @@ struct SpritePositioningInfo int spriteWidth, spriteHeight; float mSpriteU[2], mSpriteV[2]; FloatRect mSpriteRect; + uint8_t mTrimResult; float GetSpriteUL() const { return mSpriteU[0]; } float GetSpriteVT() const { return mSpriteV[0]; } @@ -255,8 +256,7 @@ class FTexture public: - SpritePositioningInfo spi; - int8_t mTrimResult = -1; + SpritePositioningInfo *spi = nullptr; IHardwareTexture* GetHardwareTexture(int translation, bool expanded); static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); @@ -375,12 +375,6 @@ public: protected: ISoftwareTexture *SoftwareTexture = nullptr; - // None of the following pointers are owned by this texture, they are all controlled by the texture manager. - - // Offset-less version for COMPATF_MASKEDMIDTEX - FGameTexture *OffsetLess = nullptr; - // Front sky layer variant where color 0 is transparent - FGameTexture* FrontSkyLayer = nullptr; public: // Material layers FTexture *Brightmap = nullptr; @@ -736,7 +730,7 @@ public: void SetDisplaySize(float w, float h) { wrapped.SetSize((int)w, (int)h); } void SetSpriteRect() { wrapped.SetSpriteRect(); } - const SpritePositioningInfo& GetSpritePositioning(int which) { /* todo: keep two sets of positioning infd*/ if (wrapped.mTrimResult == -1) wrapped.SetupSpriteData(); return wrapped.spi; } + const SpritePositioningInfo& GetSpritePositioning(int which) { if (wrapped.spi == nullptr) wrapped.SetupSpriteData(); return wrapped.spi[which]; } int GetAreas(FloatRect** pAreas) const { return wrapped.GetAreas(pAreas); } PalEntry GetSkyCapColor(bool bottom) { return wrapped.GetSkyCapColor(bottom); }