- separated DFrameBuffer from DCanvas.

This was a bad idea from the start and really only made sense with DirectDraw.
These days a FrameBuffer represents an abstract hardware canvas that shares nothing with a software canvas so having these classes linked together makes things needlessly complicated.
The software render buffer is now a canvas object owned by the FrameBuffer.

Note that this commit deactivates a few things in the software renderer, but from the looks of it none of those will be needed anymore if we set OpenGL 2 as minimum target.
This commit is contained in:
Christoph Oelckers 2018-03-27 14:14:46 +02:00
parent bb9283a9af
commit c06ad5c59c
14 changed files with 43 additions and 51 deletions

View file

@ -771,7 +771,6 @@ static int f_y;
// size of window on screen // size of window on screen
static int f_w; static int f_w;
static int f_h; static int f_h;
static int f_p; // [RH] # of bytes from start of a line to start of next
static int amclock; static int amclock;
@ -3222,7 +3221,6 @@ void AM_Drawer (int bottom)
f_x = f_y = 0; f_x = f_y = 0;
f_w = screen->GetWidth (); f_w = screen->GetWidth ();
f_h = bottom; f_h = bottom;
f_p = screen->GetPitch ();
AM_clearFB(AMColors[AMColors.Background]); AM_clearFB(AMColors[AMColors.Background]);
} }
@ -3232,7 +3230,6 @@ void AM_Drawer (int bottom)
f_y = viewwindowy; f_y = viewwindowy;
f_w = viewwidth; f_w = viewwidth;
f_h = viewheight; f_h = viewheight;
f_p = screen->GetPitch ();
} }
AM_activateNewScale(); AM_activateNewScale();

View file

@ -188,7 +188,7 @@ void OpenGLFrameBuffer::Update()
if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight))
{ {
// Do not call Resize here because it's only for software canvases // Do not call Resize here because it's only for software canvases
Pitch = Width = clientWidth; Width = clientWidth;
Height = clientHeight; Height = clientHeight;
V_OutputResized(Width, Height); V_OutputResized(Width, Height);
GLRenderer->mVBO->OutputResized(Width, Height); GLRenderer->mVBO->OutputResized(Width, Height);

View file

@ -1383,6 +1383,7 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d)
int size = Width * Height * pixelsize; int size = Width * Height * pixelsize;
auto MemBuffer = RenderBuffer->GetPixels(); auto MemBuffer = RenderBuffer->GetPixels();
auto Pitch = RenderBuffer->GetPitch();
uint8_t *dest = (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, size); uint8_t *dest = (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, size);
if (dest) if (dest)
{ {

View file

@ -32,6 +32,7 @@ public:
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra); OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
~OpenGLSWFrameBuffer(); ~OpenGLSWFrameBuffer();
virtual DCanvas *GetCanvas() { return RenderBuffer; }
bool Lock(bool buffered) override; bool Lock(bool buffered) override;
void Unlock() override; void Unlock() override;
void Update() override; void Update() override;

View file

@ -60,7 +60,7 @@ void PolyRenderer::RenderView(player_t *player)
{ {
using namespace swrenderer; using namespace swrenderer;
RenderTarget = screen; RenderTarget = screen->GetCanvas();
int width = SCREENWIDTH; int width = SCREENWIDTH;
int height = SCREENHEIGHT; int height = SCREENHEIGHT;
@ -99,7 +99,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int
Threads.MainThread()->FlushDrawQueue(); Threads.MainThread()->FlushDrawQueue();
DrawerThreads::WaitForWorkers(); DrawerThreads::WaitForWorkers();
RenderTarget = screen; RenderTarget = screen->GetCanvas();
R_ExecuteSetViewSize(Viewpoint, Viewwindow); R_ExecuteSetViewSize(Viewpoint, Viewwindow);
float trueratio; float trueratio;
ActiveRatio(width, height, &trueratio); ActiveRatio(width, height, &trueratio);
@ -166,7 +166,7 @@ void PolyRenderer::SetSceneViewport()
{ {
using namespace swrenderer; using namespace swrenderer;
if (RenderTarget == screen) // Rendering to screen if (RenderTarget == screen->GetCanvas()) // Rendering to screen
{ {
int height; int height;
if (screenblocks >= 10) if (screenblocks >= 10)

View file

@ -288,14 +288,16 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
if (viewpoint.camera->player && (renderTarget != screen || auto screencanvas = screen->GetCanvas();
if (viewpoint.camera->player && (renderTarget != screencanvas ||
viewheight == renderTarget->GetHeight() || viewheight == renderTarget->GetHeight() ||
(renderTarget->GetWidth() > (BASEXCENTER * 2)))) (renderTarget->GetWidth() > (BASEXCENTER * 2))))
{ // Adjust PSprite for fullscreen views { // Adjust PSprite for fullscreen views
AWeapon *weapon = dyn_cast<AWeapon>(pspr->GetCaller()); AWeapon *weapon = dyn_cast<AWeapon>(pspr->GetCaller());
if (weapon != nullptr && weapon->YAdjust != 0) if (weapon != nullptr && weapon->YAdjust != 0)
{ {
if (renderTarget != screen || viewheight == renderTarget->GetHeight()) if (renderTarget != screencanvas || viewheight == renderTarget->GetHeight())
{ {
vis.texturemid -= weapon->YAdjust; vis.texturemid -= weapon->YAdjust;
} }
@ -416,7 +418,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p
// Check for hardware-assisted 2D. If it's available, and this sprite is not // Check for hardware-assisted 2D. If it's available, and this sprite is not
// fuzzy, don't draw it until after the switch to 2D mode. // fuzzy, don't draw it until after the switch to 2D mode.
if (!noaccel && renderTarget == screen && (DFrameBuffer *)screen->Accel2D) if (!noaccel && renderTarget == screencanvas && (DFrameBuffer *)screen->Accel2D)
{ {
FRenderStyle style = vis.RenderStyle; FRenderStyle style = vis.RenderStyle;
style.CheckFuzz(); style.CheckFuzz();

View file

@ -69,7 +69,7 @@ namespace swrenderer
if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size()) if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size())
{ {
realfixedcolormap = &SpecialColormaps[player->fixedcolormap]; realfixedcolormap = &SpecialColormaps[player->fixedcolormap];
if (renderTarget == screen && (renderTarget->IsBgra() || ((DFrameBuffer *)screen->Accel2D && r_shadercolormaps))) if (renderTarget == screen->GetCanvas() && (renderTarget->IsBgra() || ((DFrameBuffer *)screen->Accel2D && r_shadercolormaps)))
{ {
// Render everything fullbright. The copy to video memory will // Render everything fullbright. The copy to video memory will
// apply the special colormap, so it won't be restricted to the // apply the special colormap, so it won't be restricted to the

View file

@ -91,7 +91,7 @@ namespace swrenderer
void RenderScene::RenderView(player_t *player) void RenderScene::RenderView(player_t *player)
{ {
auto viewport = MainThread()->Viewport.get(); auto viewport = MainThread()->Viewport.get();
viewport->RenderTarget = screen; viewport->RenderTarget = screen->GetCanvas();
int width = SCREENWIDTH; int width = SCREENWIDTH;
int height = SCREENHEIGHT; int height = SCREENHEIGHT;
@ -369,7 +369,7 @@ namespace swrenderer
DrawerThreads::WaitForWorkers(); DrawerThreads::WaitForWorkers();
DrawerWaitCycles.Unclock(); DrawerWaitCycles.Unclock();
viewport->RenderTarget = screen; viewport->RenderTarget = screen->GetCanvas();
R_ExecuteSetViewSize(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow); R_ExecuteSetViewSize(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow);
float trueratio; float trueratio;
@ -384,7 +384,7 @@ namespace swrenderer
void RenderScene::ScreenResized() void RenderScene::ScreenResized()
{ {
auto viewport = MainThread()->Viewport.get(); auto viewport = MainThread()->Viewport.get();
viewport->RenderTarget = screen; viewport->RenderTarget = screen->GetCanvas();
int width = SCREENWIDTH; int width = SCREENWIDTH;
int height = SCREENHEIGHT; int height = SCREENHEIGHT;
float trueratio; float trueratio;

View file

@ -290,14 +290,15 @@ namespace swrenderer
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset; vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
if (Thread->Viewport->viewpoint.camera->player && (viewport->RenderTarget != screen || auto screencanvas = screen->GetCanvas();
if (Thread->Viewport->viewpoint.camera->player && (viewport->RenderTarget != screencanvas ||
viewheight == viewport->RenderTarget->GetHeight() || viewheight == viewport->RenderTarget->GetHeight() ||
(viewport->RenderTarget->GetWidth() > (BASEXCENTER * 2)))) (viewport->RenderTarget->GetWidth() > (BASEXCENTER * 2))))
{ // Adjust PSprite for fullscreen views { // Adjust PSprite for fullscreen views
AWeapon *weapon = dyn_cast<AWeapon>(pspr->GetCaller()); AWeapon *weapon = dyn_cast<AWeapon>(pspr->GetCaller());
if (weapon != nullptr && weapon->YAdjust != 0) if (weapon != nullptr && weapon->YAdjust != 0)
{ {
if (viewport->RenderTarget != screen || viewheight == viewport->RenderTarget->GetHeight()) if (viewport->RenderTarget != screencanvas || viewheight == viewport->RenderTarget->GetHeight())
{ {
vis.texturemid -= weapon->YAdjust; vis.texturemid -= weapon->YAdjust;
} }
@ -419,7 +420,7 @@ namespace swrenderer
// Check for hardware-assisted 2D. If it's available, and this sprite is not // Check for hardware-assisted 2D. If it's available, and this sprite is not
// fuzzy, don't draw it until after the switch to 2D mode. // fuzzy, don't draw it until after the switch to 2D mode.
if (!noaccel && viewport->RenderTarget == screen && (DFrameBuffer *)screen->Accel2D) if (!noaccel && viewport->RenderTarget == screencanvas && (DFrameBuffer *)screen->Accel2D)
{ {
FRenderStyle style = vis.RenderStyle; FRenderStyle style = vis.RenderStyle;
style.CheckFuzz(); style.CheckFuzz();

View file

@ -52,7 +52,7 @@ namespace swrenderer
uint8_t *GetDest(int x, int y); uint8_t *GetDest(int x, int y);
bool RenderingToCanvas() const { return RenderTarget != screen; } bool RenderingToCanvas() const { return RenderTarget != screen->GetCanvas(); }
DVector3 PointWorldToView(const DVector3 &worldPos) const; DVector3 PointWorldToView(const DVector3 &worldPos) const;
DVector3 PointWorldToScreen(const DVector3 &worldPos) const; DVector3 PointWorldToScreen(const DVector3 &worldPos) const;

View file

@ -605,8 +605,12 @@ DSimpleCanvas::~DSimpleCanvas ()
//========================================================================== //==========================================================================
DFrameBuffer::DFrameBuffer (int width, int height, bool bgra) DFrameBuffer::DFrameBuffer (int width, int height, bool bgra)
: DCanvas (ViewportScaledWidth(width, height), ViewportScaledHeight(width, height), bgra) //: DCanvas
{ {
Width = ViewportScaledWidth(width, height);
Height = ViewportScaledHeight(width, height);
Bgra = bgra;
LastMS = LastSec = FrameCount = LastCount = LastTic = 0; LastMS = LastSec = FrameCount = LastCount = LastTic = 0;
Accel2D = false; Accel2D = false;
@ -796,32 +800,6 @@ void FPaletteTester::MakeTexture()
CurTranslation = t; CurTranslation = t;
} }
//==========================================================================
//
// DFrameBuffer :: CopyFromBuff
//
// Copies pixels from main memory to video memory. This is only used by
// DDrawFB.
//
//==========================================================================
void DFrameBuffer::CopyFromBuff (uint8_t *src, int srcPitch, int width, int height, uint8_t *dest)
{
if (Pitch == width && Pitch == Width && srcPitch == width)
{
memcpy (dest, src, Width * Height);
}
else
{
for (int y = 0; y < height; y++)
{
memcpy (dest, src, width);
dest += Pitch;
src += srcPitch;
}
}
}
//========================================================================== //==========================================================================
// //
// DFrameBuffer :: SetVSync // DFrameBuffer :: SetVSync

View file

@ -220,7 +220,6 @@ protected:
int Height; int Height;
int Pitch; int Pitch;
bool Bgra; bool Bgra;
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
DCanvas() {} DCanvas() {}
@ -268,7 +267,7 @@ public:
// for actually implementing this. Built on top of SimpleCanvas, because it // for actually implementing this. Built on top of SimpleCanvas, because it
// needs a system memory buffer when buffered output is enabled. // needs a system memory buffer when buffered output is enabled.
class DFrameBuffer : public DCanvas class DFrameBuffer
{ {
typedef DSimpleCanvas Super; typedef DSimpleCanvas Super;
@ -281,10 +280,20 @@ protected:
void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms); void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms);
int LockCount = 0; int LockCount = 0;
int Width = 0;
int Height = 0;
bool Bgra = 0;
int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1;
public: public:
DFrameBuffer (int width, int height, bool bgra); DFrameBuffer (int width, int height, bool bgra);
inline int GetWidth() const { return Width; }
inline int GetHeight() const { return Height; }
inline bool IsBgra() const { return Bgra; }
virtual DCanvas *GetCanvas() { return nullptr; }
// Access control // Access control
virtual bool IsValid() = delete; virtual bool IsValid() = delete;
virtual bool Lock(bool buffered = true) = 0; // Returns true if the surface was lost since last time virtual bool Lock(bool buffered = true) = 0; // Returns true if the surface was lost since last time
@ -447,7 +456,6 @@ public:
protected: protected:
void DrawRateStuff (); void DrawRateStuff ();
void CopyFromBuff (uint8_t *src, int srcPitch, int width, int height, uint8_t *dest);
DFrameBuffer () {} DFrameBuffer () {}

View file

@ -262,7 +262,6 @@ D3DFB::D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen)
NeedPalUpdate = false; NeedPalUpdate = false;
RenderBuffer = new DSimpleCanvas(width, height, bgra); RenderBuffer = new DSimpleCanvas(width, height, bgra);
Pitch = RenderBuffer->GetPitch(); // should be removed, but still needed as long as DFrameBuffer inherits from DCanvas
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256); memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry)*256);
@ -1210,9 +1209,12 @@ void D3DFB::Draw3DPart(bool copy3d)
SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) || SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) ||
SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0))) SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0)))
{ {
auto MemBuffer = RenderBuffer->GetPixels();
auto Pitch = RenderBuffer->GetPitch();
if (IsBgra() && FBFormat == D3DFMT_A8R8G8B8) if (IsBgra() && FBFormat == D3DFMT_A8R8G8B8)
{ {
auto MemBuffer = RenderBuffer->GetPixels();
if (lockrect.Pitch == Pitch * sizeof(uint32_t) && Pitch == Width) if (lockrect.Pitch == Pitch * sizeof(uint32_t) && Pitch == Width)
{ {
memcpy(lockrect.pBits, MemBuffer, Width * Height * sizeof(uint32_t)); memcpy(lockrect.pBits, MemBuffer, Width * Height * sizeof(uint32_t));
@ -1233,7 +1235,7 @@ void D3DFB::Draw3DPart(bool copy3d)
{ {
if (lockrect.Pitch == Pitch && Pitch == Width) if (lockrect.Pitch == Pitch && Pitch == Width)
{ {
memcpy(lockrect.pBits, RenderBuffer->GetPixels(), Width * Height); memcpy(lockrect.pBits, MemBuffer, Width * Height);
} }
else else
{ {

View file

@ -26,6 +26,8 @@ class D3DFB : public BaseWinFB
public: public:
D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen); D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen);
~D3DFB (); ~D3DFB ();
virtual DCanvas *GetCanvas() { return RenderBuffer; }
bool Lock (bool buffered); bool Lock (bool buffered);
void Unlock (); void Unlock ();