From c06ad5c59ca6bdda7f9d377e43b1da97ce375688 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 27 Mar 2018 14:14:46 +0200 Subject: [PATCH] - 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. --- src/am_map.cpp | 3 -- src/gl/system/gl_framebuffer.cpp | 2 +- src/gl/system/gl_swframebuffer.cpp | 1 + src/gl/system/gl_swframebuffer.h | 1 + src/polyrenderer/poly_renderer.cpp | 6 ++-- src/polyrenderer/scene/poly_playersprite.cpp | 8 +++-- src/swrenderer/scene/r_light.cpp | 2 +- src/swrenderer/scene/r_scene.cpp | 6 ++-- src/swrenderer/things/r_playersprite.cpp | 7 +++-- src/swrenderer/viewport/r_viewport.h | 2 +- src/v_video.cpp | 32 +++----------------- src/v_video.h | 14 +++++++-- src/win32/fb_d3d9.cpp | 8 +++-- src/win32/win32swiface.h | 2 ++ 14 files changed, 43 insertions(+), 51 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index df4b79b76..f037ede34 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -771,7 +771,6 @@ static int f_y; // size of window on screen static int f_w; static int f_h; -static int f_p; // [RH] # of bytes from start of a line to start of next static int amclock; @@ -3222,7 +3221,6 @@ void AM_Drawer (int bottom) f_x = f_y = 0; f_w = screen->GetWidth (); f_h = bottom; - f_p = screen->GetPitch (); AM_clearFB(AMColors[AMColors.Background]); } @@ -3232,7 +3230,6 @@ void AM_Drawer (int bottom) f_y = viewwindowy; f_w = viewwidth; f_h = viewheight; - f_p = screen->GetPitch (); } AM_activateNewScale(); diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 8549abb7e..15b9aa306 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -188,7 +188,7 @@ void OpenGLFrameBuffer::Update() if (clientWidth > 0 && clientHeight > 0 && (Width != clientWidth || Height != clientHeight)) { // Do not call Resize here because it's only for software canvases - Pitch = Width = clientWidth; + Width = clientWidth; Height = clientHeight; V_OutputResized(Width, Height); GLRenderer->mVBO->OutputResized(Width, Height); diff --git a/src/gl/system/gl_swframebuffer.cpp b/src/gl/system/gl_swframebuffer.cpp index b89d3d65a..b92a36c86 100644 --- a/src/gl/system/gl_swframebuffer.cpp +++ b/src/gl/system/gl_swframebuffer.cpp @@ -1383,6 +1383,7 @@ void OpenGLSWFrameBuffer::Draw3DPart(bool copy3d) int size = Width * Height * pixelsize; auto MemBuffer = RenderBuffer->GetPixels(); + auto Pitch = RenderBuffer->GetPitch(); uint8_t *dest = (uint8_t*)MapBuffer(GL_PIXEL_UNPACK_BUFFER, size); if (dest) { diff --git a/src/gl/system/gl_swframebuffer.h b/src/gl/system/gl_swframebuffer.h index 6e88a68e3..de6a35e59 100644 --- a/src/gl/system/gl_swframebuffer.h +++ b/src/gl/system/gl_swframebuffer.h @@ -32,6 +32,7 @@ public: OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra); ~OpenGLSWFrameBuffer(); + virtual DCanvas *GetCanvas() { return RenderBuffer; } bool Lock(bool buffered) override; void Unlock() override; void Update() override; diff --git a/src/polyrenderer/poly_renderer.cpp b/src/polyrenderer/poly_renderer.cpp index 2901b1ecb..b10464de5 100644 --- a/src/polyrenderer/poly_renderer.cpp +++ b/src/polyrenderer/poly_renderer.cpp @@ -60,7 +60,7 @@ void PolyRenderer::RenderView(player_t *player) { using namespace swrenderer; - RenderTarget = screen; + RenderTarget = screen->GetCanvas(); int width = SCREENWIDTH; int height = SCREENHEIGHT; @@ -99,7 +99,7 @@ void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int Threads.MainThread()->FlushDrawQueue(); DrawerThreads::WaitForWorkers(); - RenderTarget = screen; + RenderTarget = screen->GetCanvas(); R_ExecuteSetViewSize(Viewpoint, Viewwindow); float trueratio; ActiveRatio(width, height, &trueratio); @@ -166,7 +166,7 @@ void PolyRenderer::SetSceneViewport() { using namespace swrenderer; - if (RenderTarget == screen) // Rendering to screen + if (RenderTarget == screen->GetCanvas()) // Rendering to screen { int height; if (screenblocks >= 10) diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index faf2f2a9a..396ec8c19 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -288,14 +288,16 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p 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() || (renderTarget->GetWidth() > (BASEXCENTER * 2)))) { // Adjust PSprite for fullscreen views AWeapon *weapon = dyn_cast(pspr->GetCaller()); if (weapon != nullptr && weapon->YAdjust != 0) { - if (renderTarget != screen || viewheight == renderTarget->GetHeight()) + if (renderTarget != screencanvas || viewheight == renderTarget->GetHeight()) { 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 // 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; style.CheckFuzz(); diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index 022f2745f..223bb6c60 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -69,7 +69,7 @@ namespace swrenderer if (player->fixedcolormap >= 0 && player->fixedcolormap < (int)SpecialColormaps.Size()) { 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 // apply the special colormap, so it won't be restricted to the diff --git a/src/swrenderer/scene/r_scene.cpp b/src/swrenderer/scene/r_scene.cpp index b84742666..4deba320e 100644 --- a/src/swrenderer/scene/r_scene.cpp +++ b/src/swrenderer/scene/r_scene.cpp @@ -91,7 +91,7 @@ namespace swrenderer void RenderScene::RenderView(player_t *player) { auto viewport = MainThread()->Viewport.get(); - viewport->RenderTarget = screen; + viewport->RenderTarget = screen->GetCanvas(); int width = SCREENWIDTH; int height = SCREENHEIGHT; @@ -369,7 +369,7 @@ namespace swrenderer DrawerThreads::WaitForWorkers(); DrawerWaitCycles.Unclock(); - viewport->RenderTarget = screen; + viewport->RenderTarget = screen->GetCanvas(); R_ExecuteSetViewSize(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow); float trueratio; @@ -384,7 +384,7 @@ namespace swrenderer void RenderScene::ScreenResized() { auto viewport = MainThread()->Viewport.get(); - viewport->RenderTarget = screen; + viewport->RenderTarget = screen->GetCanvas(); int width = SCREENWIDTH; int height = SCREENHEIGHT; float trueratio; diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index b0021ca32..1edf51159 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -290,14 +290,15 @@ namespace swrenderer 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() || (viewport->RenderTarget->GetWidth() > (BASEXCENTER * 2)))) { // Adjust PSprite for fullscreen views AWeapon *weapon = dyn_cast(pspr->GetCaller()); 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; } @@ -419,7 +420,7 @@ namespace swrenderer // 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. - if (!noaccel && viewport->RenderTarget == screen && (DFrameBuffer *)screen->Accel2D) + if (!noaccel && viewport->RenderTarget == screencanvas && (DFrameBuffer *)screen->Accel2D) { FRenderStyle style = vis.RenderStyle; style.CheckFuzz(); diff --git a/src/swrenderer/viewport/r_viewport.h b/src/swrenderer/viewport/r_viewport.h index b8ce166a7..534680bcd 100644 --- a/src/swrenderer/viewport/r_viewport.h +++ b/src/swrenderer/viewport/r_viewport.h @@ -52,7 +52,7 @@ namespace swrenderer 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 PointWorldToScreen(const DVector3 &worldPos) const; diff --git a/src/v_video.cpp b/src/v_video.cpp index 2e963fc0f..fa01a8ec6 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -605,8 +605,12 @@ DSimpleCanvas::~DSimpleCanvas () //========================================================================== 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; Accel2D = false; @@ -796,32 +800,6 @@ void FPaletteTester::MakeTexture() 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 diff --git a/src/v_video.h b/src/v_video.h index 2bd7b101b..1173de177 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -220,7 +220,6 @@ protected: int Height; int Pitch; bool Bgra; - int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; DCanvas() {} @@ -268,7 +267,7 @@ public: // for actually implementing this. Built on top of SimpleCanvas, because it // needs a system memory buffer when buffered output is enabled. -class DFrameBuffer : public DCanvas +class DFrameBuffer { typedef DSimpleCanvas Super; @@ -281,10 +280,20 @@ protected: void DrawTextCommon(FFont *font, int normalcolor, double x, double y, const char *string, DrawParms &parms); int LockCount = 0; + int Width = 0; + int Height = 0; + bool Bgra = 0; + int clipleft = 0, cliptop = 0, clipwidth = -1, clipheight = -1; public: 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 virtual bool IsValid() = delete; virtual bool Lock(bool buffered = true) = 0; // Returns true if the surface was lost since last time @@ -447,7 +456,6 @@ public: protected: void DrawRateStuff (); - void CopyFromBuff (uint8_t *src, int srcPitch, int width, int height, uint8_t *dest); DFrameBuffer () {} diff --git a/src/win32/fb_d3d9.cpp b/src/win32/fb_d3d9.cpp index c3a7e41c4..12e04f1b5 100644 --- a/src/win32/fb_d3d9.cpp +++ b/src/win32/fb_d3d9.cpp @@ -262,7 +262,6 @@ D3DFB::D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen) NeedPalUpdate = false; 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); @@ -1210,9 +1209,12 @@ void D3DFB::Draw3DPart(bool copy3d) SUCCEEDED(FBTexture->LockRect (0, &lockrect, NULL, D3DLOCK_DISCARD))) || SUCCEEDED(FBTexture->LockRect (0, &lockrect, &texrect, 0))) { + auto MemBuffer = RenderBuffer->GetPixels(); + auto Pitch = RenderBuffer->GetPitch(); + if (IsBgra() && FBFormat == D3DFMT_A8R8G8B8) { - auto MemBuffer = RenderBuffer->GetPixels(); + if (lockrect.Pitch == Pitch * sizeof(uint32_t) && Pitch == Width) { memcpy(lockrect.pBits, MemBuffer, Width * Height * sizeof(uint32_t)); @@ -1233,7 +1235,7 @@ void D3DFB::Draw3DPart(bool copy3d) { if (lockrect.Pitch == Pitch && Pitch == Width) { - memcpy(lockrect.pBits, RenderBuffer->GetPixels(), Width * Height); + memcpy(lockrect.pBits, MemBuffer, Width * Height); } else { diff --git a/src/win32/win32swiface.h b/src/win32/win32swiface.h index 5d70a19ab..12e2be755 100644 --- a/src/win32/win32swiface.h +++ b/src/win32/win32swiface.h @@ -26,6 +26,8 @@ class D3DFB : public BaseWinFB public: D3DFB (UINT adapter, int width, int height, bool bgra, bool fullscreen); ~D3DFB (); + virtual DCanvas *GetCanvas() { return RenderBuffer; } + bool Lock (bool buffered); void Unlock ();