- decoupled the software renderer entirely from FTexture - it will only look at FSoftwareTexture now, all access to the texture manager has been wrapped.

This commit is contained in:
Christoph Oelckers 2020-04-14 00:42:13 +02:00
commit 9593cb56ae
23 changed files with 170 additions and 162 deletions

View file

@ -38,18 +38,9 @@
#include "bitmap.h"
#include "m_alloc.h"
#include "imagehelpers.h"
#include "texturemanager.h"
FSoftwareTexture *FTexture::GetSoftwareTexture()
{
if (!SoftwareTexture)
{
if (bHasCanvas) SoftwareTexture = new FSWCanvasTexture(this);
else if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped);
else SoftwareTexture = new FSoftwareTexture(this);
}
return SoftwareTexture;
}
//==========================================================================
//
@ -57,16 +48,19 @@ FSoftwareTexture *FTexture::GetSoftwareTexture()
//
//==========================================================================
FSoftwareTexture::FSoftwareTexture(FTexture *tex)
FSoftwareTexture::FSoftwareTexture(FGameTexture *tex)
{
mTexture = tex;
mSource = tex;
mSource = tex->GetTexture();
mBufferFlags = CTF_ProcessData;
auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags);
// calculate the real size after running the scaler.
auto info = mSource->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags);
mPhysicalWidth = info.mWidth;
mPhysicalHeight = info.mHeight;
mPhysicalScale = tex->Width > 0? mPhysicalWidth / tex->Width : mPhysicalWidth;
mPhysicalScale = tex->GetTexelWidth() > 0 ? mPhysicalWidth / tex->GetTexelWidth() : mPhysicalWidth;
Scale.X = (double)tex->GetTexelWidth() / tex->GetDisplayWidth();
Scale.Y = (double)tex->GetTexelHeight() / tex->GetDisplayHeight();
CalcBitSize();
}
@ -119,7 +113,7 @@ const uint8_t *FSoftwareTexture::GetPixels(int style)
}
else
{
auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags);
auto tempbuffer = mSource->CreateTexBuffer(0, mBufferFlags);
Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight());
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
if (!style)
@ -159,12 +153,12 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra()
{
if (mPhysicalScale == 1)
{
FBitmap bitmap = mTexture->GetBgraBitmap(nullptr);
FBitmap bitmap = mSource->GetBgraBitmap(nullptr);
GenerateBgraFromBitmap(bitmap);
}
else
{
auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags);
auto tempbuffer = mSource->CreateTexBuffer(0, mBufferFlags);
CreatePixelsBgraWithMipmaps();
PalEntry *pe = (PalEntry*)tempbuffer.mBuffer;
for (int y = 0; y < GetPhysicalHeight(); y++)
@ -263,7 +257,7 @@ FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const T *pixels)
{
FSoftwareTextureSpan **spans, *span;
if (!mTexture->isMasked())
if (!mSource->isMasked())
{ // Texture does not have holes, so it can use a simpler span structure
spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*GetPhysicalWidth() + sizeof(FSoftwareTextureSpan)*2);
span = (FSoftwareTextureSpan *)&spans[GetPhysicalWidth()];
@ -598,8 +592,28 @@ void FSoftwareTexture::FreeAllSpans()
}
}
void DeleteSoftwareTexture(FSoftwareTexture* swtex)
FSoftwareTexture* GetSoftwareTexture(FGameTexture* tex)
{
delete swtex;
FSoftwareTexture* SoftwareTexture = static_cast<FSoftwareTexture*>(tex->GetSoftwareTexture());
if (!SoftwareTexture)
{
auto source = tex->GetTexture();
if (source->isCanvas()) SoftwareTexture = new FSWCanvasTexture(tex);
else if (tex->isWarped()) SoftwareTexture = new FWarpTexture(tex, tex->isWarped());
else SoftwareTexture = new FSoftwareTexture(tex);
tex->SetSoftwareTexture(SoftwareTexture);
}
return SoftwareTexture;
}
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, FLevelLocals *checkcompat, bool allownull)
{
auto tex = TexMan.GetPalettedTexture(texid, true);
if (checkcompat && tex && tex->isValid() && checkcompat->i_compatflags & COMPATF_MASKEDMIDTEX)
{
tex = tex->GetRawTexture();
}
FSoftwareTexture* pic = tex && (allownull || tex->isValid()) ? GetSoftwareTexture(reinterpret_cast<FGameTexture*>(tex)) : nullptr;
return pic;
}

View file

@ -12,14 +12,15 @@ struct FSoftwareTextureSpan
// For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up.
class FSoftwareTexture
class FSoftwareTexture : public ISoftwareTexture
{
protected:
FTexture *mTexture;
FGameTexture *mTexture;
FTexture *mSource;
TArray<uint8_t> Pixels;
TArray<uint32_t> PixelsBgra;
FSoftwareTextureSpan **Spandata[3] = { };
DVector2 Scale;
uint8_t WidthBits = 0, HeightBits = 0;
uint16_t WidthMask = 0;
int mPhysicalWidth, mPhysicalHeight;
@ -32,14 +33,14 @@ protected:
void CalcBitSize();
public:
FSoftwareTexture(FTexture *tex);
FSoftwareTexture(FGameTexture *tex);
virtual ~FSoftwareTexture()
{
FreeAllSpans();
}
FTexture *GetTexture() const
FGameTexture *GetTexture() const
{
return mTexture;
}
@ -47,32 +48,33 @@ public:
// The feature from hell... :(
bool useWorldPanning(FLevelLocals *Level) const
{
return mTexture->bWorldPanning || (Level->flags3 & LEVEL3_FORCEWORLDPANNING);
return mTexture->useWorldPanning() || (Level->flags3 & LEVEL3_FORCEWORLDPANNING);
}
bool isMasked()
{
return mTexture->bMasked;
return mSource->isMasked();
}
uint16_t GetRotations() const
{
return mTexture->GetRotations();
}
int GetSkyOffset() const { return mTexture->GetSkyOffset(); }
PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); }
PalEntry GetSkyCapColor(bool bottom) const { return mSource->GetSkyCapColor(bottom); }
int GetWidth () { return mTexture->GetTexelWidth(); }
int GetHeight () { return mTexture->GetTexelHeight(); }
int GetWidthBits() { return WidthBits; }
int GetHeightBits() { return HeightBits; }
int GetScaledWidth () { return mTexture->GetScaledWidth(); }
int GetScaledHeight () { return mTexture->GetScaledHeight(); }
double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); }
double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); }
int GetScaledWidth () { return mTexture->GetDisplayWidth(); }
int GetScaledHeight () { return mTexture->GetDisplayHeight(); }
// Now with improved offset adjustment.
int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); }
int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); }
int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); }
int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); }
int GetLeftOffset(int adjusted) { return mTexture->GetTexelLeftOffset(adjusted); }
int GetTopOffset(int adjusted) { return mTexture->GetTexelTopOffset(adjusted); }
// Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets
// should use these, so that if changes are needed, this is the only place to edit.
@ -80,16 +82,10 @@ public:
// For the original software renderer
int GetLeftOffsetSW() { return GetLeftOffset(r_spriteadjustSW); }
int GetTopOffsetSW() { return GetTopOffset(r_spriteadjustSW); }
int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); }
int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); }
double GetScaledLeftOffsetSW() { return mTexture->GetDisplayLeftOffset(r_spriteadjustSW); }
double GetScaledTopOffsetSW() { return mTexture->GetDisplayTopOffset(r_spriteadjustSW); }
// For the softpoly renderer, in case it wants adjustment
int GetLeftOffsetPo() { return GetLeftOffset(r_spriteadjustSW); }
int GetTopOffsetPo() { return GetTopOffset(r_spriteadjustSW); }
int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); }
int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); }
DVector2 GetScale() const { return mTexture->Scale; }
DVector2 GetScale() const { return Scale; }
int GetPhysicalWidth() { return mPhysicalWidth; }
int GetPhysicalHeight() { return mPhysicalHeight; }
int GetPhysicalScale() const { return mPhysicalScale; }
@ -157,7 +153,7 @@ class FWarpTexture : public FSoftwareTexture
int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd]
public:
FWarpTexture (FTexture *source, int warptype);
FWarpTexture (FGameTexture *source, int warptype);
const uint32_t *GetPixelsBgra() override;
const uint8_t *GetPixels(int style) override;
@ -180,7 +176,7 @@ class FSWCanvasTexture : public FSoftwareTexture
public:
FSWCanvasTexture(FTexture *source) : FSoftwareTexture(source) {}
FSWCanvasTexture(FGameTexture *source) : FSoftwareTexture(source) {}
~FSWCanvasTexture();
// Returns the whole texture, stored in column-major order
@ -195,3 +191,6 @@ public:
bool Mipmapped() override { return false; }
};
FSoftwareTexture* GetSoftwareTexture(FGameTexture* tex);
FSoftwareTexture* GetPalettedSWTexture(FTextureID texid, bool animate, FLevelLocals *checkcompat = nullptr, bool allownull = false);

View file

@ -64,7 +64,7 @@ FSWCanvasTexture::~FSWCanvasTexture()
const uint8_t *FSWCanvasTexture::GetPixels(int style)
{
static_cast<FCanvasTexture*>(mTexture)->NeedUpdate();
static_cast<FCanvasTexture*>(mSource)->NeedUpdate();
if (Canvas == nullptr)
{
MakeTexture();
@ -81,7 +81,7 @@ const uint8_t *FSWCanvasTexture::GetPixels(int style)
const uint32_t *FSWCanvasTexture::GetPixelsBgra()
{
static_cast<FCanvasTexture*>(mTexture)->NeedUpdate();
static_cast<FCanvasTexture*>(mSource)->NeedUpdate();
if (CanvasBgra == nullptr)
{
MakeTextureBgra();
@ -181,5 +181,5 @@ void FSWCanvasTexture::UpdatePixels(bool truecolor)
ImageHelpers::FlipNonSquareBlockRemap(Pixels.Data(), Canvas->GetPixels(), GetWidth(), GetHeight(), Canvas->GetPitch(), GPalette.Remap);
}
static_cast<FCanvasTexture*>(mTexture)->SetUpdated(false);
static_cast<FCanvasTexture*>(mSource)->SetUpdated(false);
}

View file

@ -44,7 +44,7 @@ EXTERN_CVAR(Int, gl_texture_hqresizemult)
EXTERN_CVAR(Int, gl_texture_hqresizemode)
EXTERN_CVAR(Int, gl_texture_hqresize_targets)
FWarpTexture::FWarpTexture (FTexture *source, int warptype)
FWarpTexture::FWarpTexture (FGameTexture *source, int warptype)
: FSoftwareTexture (source)
{
if (warptype == 2) SetupMultipliers(256, 128);
@ -69,7 +69,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra()
auto otherpix = FSoftwareTexture::GetPixelsBgra();
WarpedPixelsRgba.Resize(unsigned(GetWidth() * GetHeight() * resizeMult * resizeMult * 4 / 3 + 1));
WarpBuffer(WarpedPixelsRgba.Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->shaderspeed, bWarped);
WarpBuffer(WarpedPixelsRgba.Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->GetShaderSpeed(), bWarped);
GenerateBgraMipmapsFast();
FreeAllSpans();
GenTime[2] = time;
@ -90,7 +90,7 @@ const uint8_t *FWarpTexture::GetPixels(int index)
const uint8_t *otherpix = FSoftwareTexture::GetPixels(index);
WarpedPixels[index].Resize(unsigned(GetWidth() * GetHeight() * resizeMult * resizeMult));
WarpBuffer(WarpedPixels[index].Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->shaderspeed, bWarped);
WarpBuffer(WarpedPixels[index].Data(), otherpix, int(GetWidth() * resizeMult), int(GetHeight() * resizeMult), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->GetShaderSpeed(), bWarped);
FreeAllSpans();
GenTime[index] = time;
}