mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- merged DCanvas and DSimpleCanvas and use a TArray to hold its memory.
This commit is contained in:
parent
927d333063
commit
024870ba11
8 changed files with 68 additions and 121 deletions
|
@ -181,7 +181,7 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide
|
||||||
|
|
||||||
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height)
|
||||||
{
|
{
|
||||||
DSimpleCanvas pic(width, height, false);
|
DCanvas pic(width, height, false);
|
||||||
PalEntry palette[256];
|
PalEntry palette[256];
|
||||||
|
|
||||||
// Take a snapshot of the player's view
|
// Take a snapshot of the player's view
|
||||||
|
@ -241,7 +241,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
||||||
cameraViewwindow = r_viewwindow;
|
cameraViewwindow = r_viewwindow;
|
||||||
|
|
||||||
uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle());
|
uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle());
|
||||||
DSimpleCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas();
|
DCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas();
|
||||||
|
|
||||||
// curse Doom's overuse of global variables in the renderer.
|
// curse Doom's overuse of global variables in the renderer.
|
||||||
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
|
// These get clobbered by rendering to a camera texture but they need to be preserved so the final rendering can be done with the correct palette.
|
||||||
|
|
|
@ -96,7 +96,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player)
|
||||||
mat->AddTextureLayer(PaletteTexture.get());
|
mat->AddTextureLayer(PaletteTexture.get());
|
||||||
|
|
||||||
Canvas.reset();
|
Canvas.reset();
|
||||||
Canvas.reset(new DSimpleCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()));
|
Canvas.reset(new DCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto buf = fbtex->SystemTexture[0]->MapBuffer();
|
auto buf = fbtex->SystemTexture[0]->MapBuffer();
|
||||||
|
|
|
@ -16,7 +16,7 @@ class SWSceneDrawer
|
||||||
std::unique_ptr<FWrapperTexture> FBTexture[2];
|
std::unique_ptr<FWrapperTexture> FBTexture[2];
|
||||||
int FBTextureIndex = 0;
|
int FBTextureIndex = 0;
|
||||||
bool FBIsTruecolor = false;
|
bool FBIsTruecolor = false;
|
||||||
std::unique_ptr<DSimpleCanvas> Canvas;
|
std::unique_ptr<DCanvas> Canvas;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SWSceneDrawer();
|
SWSceneDrawer();
|
||||||
|
|
|
@ -108,7 +108,7 @@ const uint32_t *FCanvasTexture::GetPixelsBgra()
|
||||||
|
|
||||||
void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical.
|
void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical.
|
||||||
{
|
{
|
||||||
Canvas = new DSimpleCanvas (Width, Height, false);
|
Canvas = new DCanvas (Width, Height, false);
|
||||||
|
|
||||||
if (Width != Height || Width != Canvas->GetPitch())
|
if (Width != Height || Width != Canvas->GetPitch())
|
||||||
{
|
{
|
||||||
|
@ -128,7 +128,7 @@ void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style
|
||||||
|
|
||||||
void FCanvasTexture::MakeTextureBgra()
|
void FCanvasTexture::MakeTextureBgra()
|
||||||
{
|
{
|
||||||
CanvasBgra = new DSimpleCanvas(Width, Height, true);
|
CanvasBgra = new DCanvas(Width, Height, true);
|
||||||
|
|
||||||
if (Width != Height || Width != CanvasBgra->GetPitch())
|
if (Width != Height || Width != CanvasBgra->GetPitch())
|
||||||
{
|
{
|
||||||
|
|
|
@ -754,7 +754,7 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
// A texture that can be drawn to.
|
// A texture that can be drawn to.
|
||||||
class DSimpleCanvas;
|
class DCanvas;
|
||||||
class AActor;
|
class AActor;
|
||||||
|
|
||||||
class FCanvasTexture : public FTexture
|
class FCanvasTexture : public FTexture
|
||||||
|
@ -770,16 +770,16 @@ public:
|
||||||
bool CheckModified (FRenderStyle) override;
|
bool CheckModified (FRenderStyle) override;
|
||||||
void NeedUpdate() { bNeedsUpdate=true; }
|
void NeedUpdate() { bNeedsUpdate=true; }
|
||||||
void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; }
|
void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; }
|
||||||
DSimpleCanvas *GetCanvas() { return Canvas; }
|
DCanvas *GetCanvas() { return Canvas; }
|
||||||
DSimpleCanvas *GetCanvasBgra() { return CanvasBgra; }
|
DCanvas *GetCanvasBgra() { return CanvasBgra; }
|
||||||
bool Mipmapped() override { return false; }
|
bool Mipmapped() override { return false; }
|
||||||
void MakeTexture (FRenderStyle style);
|
void MakeTexture (FRenderStyle style);
|
||||||
void MakeTextureBgra ();
|
void MakeTextureBgra ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
DSimpleCanvas *Canvas = nullptr;
|
DCanvas *Canvas = nullptr;
|
||||||
DSimpleCanvas *CanvasBgra = nullptr;
|
DCanvas *CanvasBgra = nullptr;
|
||||||
uint8_t *Pixels = nullptr;
|
uint8_t *Pixels = nullptr;
|
||||||
uint32_t *PixelsBgra = nullptr;
|
uint32_t *PixelsBgra = nullptr;
|
||||||
Span DummySpans[2];
|
Span DummySpans[2];
|
||||||
|
|
|
@ -82,87 +82,6 @@ void DFrameBuffer::CalcGamma (float gamma, uint8_t gammalookup[256])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// DSimpleCanvas Constructor
|
|
||||||
//
|
|
||||||
// A simple canvas just holds a buffer in main memory.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
DSimpleCanvas::DSimpleCanvas (int width, int height, bool bgra)
|
|
||||||
: DCanvas (width, height, bgra)
|
|
||||||
{
|
|
||||||
PixelBuffer = nullptr;
|
|
||||||
Resize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSimpleCanvas::Resize(int width, int height)
|
|
||||||
{
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
|
|
||||||
if (PixelBuffer != NULL)
|
|
||||||
{
|
|
||||||
delete[] PixelBuffer;
|
|
||||||
PixelBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Making the pitch a power of 2 is very bad for performance
|
|
||||||
// Try to maximize the number of cache lines that can be filled
|
|
||||||
// for each column drawing operation by making the pitch slightly
|
|
||||||
// longer than the width. The values used here are all based on
|
|
||||||
// empirical evidence.
|
|
||||||
|
|
||||||
if (width <= 640)
|
|
||||||
{
|
|
||||||
// For low resolutions, just keep the pitch the same as the width.
|
|
||||||
// Some speedup can be seen using the technique below, but the speedup
|
|
||||||
// is so marginal that I don't consider it worthwhile.
|
|
||||||
Pitch = width;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// If we couldn't figure out the CPU's L1 cache line size, assume
|
|
||||||
// it's 32 bytes wide.
|
|
||||||
if (CPU.DataL1LineSize == 0)
|
|
||||||
{
|
|
||||||
CPU.DataL1LineSize = 32;
|
|
||||||
}
|
|
||||||
// The Athlon and P3 have very different caches, apparently.
|
|
||||||
// I am going to generalize the Athlon's performance to all AMD
|
|
||||||
// processors and the P3's to all non-AMD processors. I don't know
|
|
||||||
// how smart that is, but I don't have a vast plethora of
|
|
||||||
// processors to test with.
|
|
||||||
if (CPU.bIsAMD)
|
|
||||||
{
|
|
||||||
Pitch = width + CPU.DataL1LineSize;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Pitch = width + MAX(0, CPU.DataL1LineSize - 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int bytes_per_pixel = Bgra ? 4 : 1;
|
|
||||||
PixelBuffer = new uint8_t[Pitch * height * bytes_per_pixel];
|
|
||||||
memset (PixelBuffer, 0, Pitch * height * bytes_per_pixel);
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// DSimpleCanvas Destructor
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
DSimpleCanvas::~DSimpleCanvas ()
|
|
||||||
{
|
|
||||||
if (PixelBuffer != NULL)
|
|
||||||
{
|
|
||||||
delete[] PixelBuffer;
|
|
||||||
PixelBuffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DFrameBuffer Constructor
|
// DFrameBuffer Constructor
|
||||||
|
|
|
@ -177,6 +177,7 @@ DCanvas::DCanvas (int _width, int _height, bool _bgra)
|
||||||
Width = _width;
|
Width = _width;
|
||||||
Height = _height;
|
Height = _height;
|
||||||
Bgra = _bgra;
|
Bgra = _bgra;
|
||||||
|
Resize(_width, _height);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -189,6 +190,58 @@ DCanvas::~DCanvas ()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void DCanvas::Resize(int width, int height)
|
||||||
|
{
|
||||||
|
Width = width;
|
||||||
|
Height = height;
|
||||||
|
|
||||||
|
// Making the pitch a power of 2 is very bad for performance
|
||||||
|
// Try to maximize the number of cache lines that can be filled
|
||||||
|
// for each column drawing operation by making the pitch slightly
|
||||||
|
// longer than the width. The values used here are all based on
|
||||||
|
// empirical evidence.
|
||||||
|
|
||||||
|
if (width <= 640)
|
||||||
|
{
|
||||||
|
// For low resolutions, just keep the pitch the same as the width.
|
||||||
|
// Some speedup can be seen using the technique below, but the speedup
|
||||||
|
// is so marginal that I don't consider it worthwhile.
|
||||||
|
Pitch = width;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we couldn't figure out the CPU's L1 cache line size, assume
|
||||||
|
// it's 32 bytes wide.
|
||||||
|
if (CPU.DataL1LineSize == 0)
|
||||||
|
{
|
||||||
|
CPU.DataL1LineSize = 32;
|
||||||
|
}
|
||||||
|
// The Athlon and P3 have very different caches, apparently.
|
||||||
|
// I am going to generalize the Athlon's performance to all AMD
|
||||||
|
// processors and the P3's to all non-AMD processors. I don't know
|
||||||
|
// how smart that is, but I don't have a vast plethora of
|
||||||
|
// processors to test with.
|
||||||
|
if (CPU.bIsAMD)
|
||||||
|
{
|
||||||
|
Pitch = width + CPU.DataL1LineSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pitch = width + MAX(0, CPU.DataL1LineSize - 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int bytes_per_pixel = Bgra ? 4 : 1;
|
||||||
|
Pixels.Resize(Pitch * height * bytes_per_pixel);
|
||||||
|
memset (Pixels.Data(), 0, Pixels.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// V_GetColorFromString
|
// V_GetColorFromString
|
||||||
|
|
|
@ -291,53 +291,29 @@ struct VMVa_List
|
||||||
//
|
//
|
||||||
// VIDEO
|
// VIDEO
|
||||||
//
|
//
|
||||||
// [RH] Made screens more implementation-independant:
|
|
||||||
//
|
//
|
||||||
class DCanvas
|
class DCanvas
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DCanvas (int width, int height, bool bgra);
|
DCanvas (int width, int height, bool bgra);
|
||||||
virtual ~DCanvas ();
|
~DCanvas ();
|
||||||
|
void Resize(int width, int height);
|
||||||
|
|
||||||
// Member variable access
|
// Member variable access
|
||||||
inline uint8_t *GetPixels () const { return PixelBuffer; }
|
inline uint8_t *GetPixels () const { return Pixels.Data(); }
|
||||||
inline int GetWidth () const { return Width; }
|
inline int GetWidth () const { return Width; }
|
||||||
inline int GetHeight () const { return Height; }
|
inline int GetHeight () const { return Height; }
|
||||||
inline int GetPitch () const { return Pitch; }
|
inline int GetPitch () const { return Pitch; }
|
||||||
inline bool IsBgra() const { return Bgra; }
|
inline bool IsBgra() const { return Bgra; }
|
||||||
|
|
||||||
// Note: pitch here is in pixels, not bytes.
|
|
||||||
bool SetBuffer(int width, int height, int pitch, uint8_t *buffer)
|
|
||||||
{
|
|
||||||
assert(buffer);
|
|
||||||
Width = width;
|
|
||||||
Height = height;
|
|
||||||
Pitch = pitch;
|
|
||||||
PixelBuffer = buffer;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint8_t *PixelBuffer;
|
TArray<uint8_t> Pixels;
|
||||||
int Width;
|
int Width;
|
||||||
int Height;
|
int Height;
|
||||||
int Pitch;
|
int Pitch;
|
||||||
bool Bgra;
|
bool Bgra;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A canvas in system memory.
|
|
||||||
|
|
||||||
class DSimpleCanvas : public DCanvas
|
|
||||||
{
|
|
||||||
typedef DCanvas Super;
|
|
||||||
public:
|
|
||||||
DSimpleCanvas (int width, int height, bool bgra);
|
|
||||||
~DSimpleCanvas ();
|
|
||||||
void Resize(int width, int height);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FUniquePalette;
|
class FUniquePalette;
|
||||||
class IHardwareTexture;
|
class IHardwareTexture;
|
||||||
class FTexture;
|
class FTexture;
|
||||||
|
@ -348,7 +324,6 @@ class FTexture;
|
||||||
|
|
||||||
class DFrameBuffer
|
class DFrameBuffer
|
||||||
{
|
{
|
||||||
typedef DSimpleCanvas Super;
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete;
|
void DrawTextureV(FTexture *img, double x, double y, uint32_t tag, va_list tags) = delete;
|
||||||
|
|
Loading…
Reference in a new issue