mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-24 21:11:39 +00:00
- Changed frame buffer locking mechanism so that the only place where a lock is needed is when the software renderer wants to access the render buffer, which is precisely for the duration of the RenderView function.
No more locking insanity! :) There are no locking counters or other saveguards here that would complicate the implementation because there's precisely two places where this buffer must be locked - the RenderView functions of the regular and poly SW renderer which cannot be called recursively.
This commit is contained in:
parent
0c3635e22c
commit
2ed744963c
8 changed files with 100 additions and 127 deletions
|
@ -1069,7 +1069,7 @@ void C_SetTicker (unsigned int at, bool forceUpdate)
|
|||
TickerAt = at > TickerMax ? TickerMax : at;
|
||||
}
|
||||
|
||||
void C_DrawConsole (bool hw2d)
|
||||
void C_DrawConsole ()
|
||||
{
|
||||
static int oldbottom = 0;
|
||||
int lines, left, offset;
|
||||
|
@ -1114,7 +1114,7 @@ void C_DrawConsole (bool hw2d)
|
|||
DTA_DestWidth, screen->GetWidth(),
|
||||
DTA_DestHeight, screen->GetHeight(),
|
||||
DTA_ColorOverlay, conshade,
|
||||
DTA_Alpha, (hw2d && gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1.,
|
||||
DTA_Alpha, (gamestate != GS_FULLCONSOLE) ? (double)con_alpha : 1.,
|
||||
DTA_Masked, false,
|
||||
TAG_DONE);
|
||||
if (conline && visheight < screen->GetHeight())
|
||||
|
@ -1192,21 +1192,6 @@ void C_DrawConsole (bool hw2d)
|
|||
}
|
||||
}
|
||||
|
||||
// Apply palette blend effects
|
||||
if (StatusBar != NULL && !hw2d)
|
||||
{
|
||||
player_t *player = StatusBar->CPlayer;
|
||||
if (player->camera != NULL && player->camera->player != NULL)
|
||||
{
|
||||
player = player->camera->player;
|
||||
}
|
||||
if (player->BlendA != 0 && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL))
|
||||
{
|
||||
screen->Dim (PalEntry ((unsigned char)(player->BlendR*255), (unsigned char)(player->BlendG*255), (unsigned char)(player->BlendB*255)),
|
||||
player->BlendA, 0, ConBottom, screen->GetWidth(), screen->GetHeight() - ConBottom);
|
||||
V_SetBorderNeedRefresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (menuactive != MENU_Off)
|
||||
|
|
|
@ -67,7 +67,7 @@ void AddToConsole (int printlevel, const char *string);
|
|||
int PrintString (int printlevel, const char *string);
|
||||
int VPrintf (int printlevel, const char *format, va_list parms) GCCFORMAT(2);
|
||||
|
||||
void C_DrawConsole (bool hw2d);
|
||||
void C_DrawConsole ();
|
||||
void C_ToggleConsole (void);
|
||||
void C_FullConsole (void);
|
||||
void C_HideConsole (void);
|
||||
|
|
|
@ -669,7 +669,6 @@ CVAR (Flag, compat_pushwindow, compatflags2, COMPATF2_PUSHWINDOW);
|
|||
void D_Display ()
|
||||
{
|
||||
bool wipe;
|
||||
bool hw2d;
|
||||
|
||||
if (nodrawers || screen == NULL)
|
||||
return; // for comparative timing / profiling
|
||||
|
@ -774,9 +773,6 @@ void D_Display ()
|
|||
wipe = false;
|
||||
}
|
||||
|
||||
hw2d = false;
|
||||
|
||||
|
||||
{
|
||||
screen->FrameTime = I_msTimeFS();
|
||||
TexMan.UpdateAnimations(screen->FrameTime);
|
||||
|
@ -785,8 +781,8 @@ void D_Display ()
|
|||
{
|
||||
case GS_FULLCONSOLE:
|
||||
screen->SetBlendingRect(0,0,0,0);
|
||||
hw2d = screen->Begin2D(false);
|
||||
C_DrawConsole (false);
|
||||
screen->Begin2D(false);
|
||||
C_DrawConsole ();
|
||||
M_Drawer ();
|
||||
screen->Update ();
|
||||
return;
|
||||
|
@ -795,10 +791,7 @@ void D_Display ()
|
|||
case GS_TITLELEVEL:
|
||||
if (!gametic)
|
||||
{
|
||||
if (!screen->HasBegun2D())
|
||||
{
|
||||
screen->Begin2D(false);
|
||||
}
|
||||
screen->Begin2D(false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -815,11 +808,8 @@ void D_Display ()
|
|||
//
|
||||
Renderer->RenderView(&players[consoleplayer]);
|
||||
|
||||
if ((hw2d = screen->Begin2D(viewactive)))
|
||||
{
|
||||
// Redraw everything every frame when using 2D accel
|
||||
V_SetBorderNeedRefresh();
|
||||
}
|
||||
screen->Begin2D(viewactive);
|
||||
V_SetBorderNeedRefresh();
|
||||
Renderer->DrawRemainingPlayerSprites();
|
||||
screen->DrawBlendingRect();
|
||||
if (automapactive)
|
||||
|
@ -867,21 +857,21 @@ void D_Display ()
|
|||
|
||||
case GS_INTERMISSION:
|
||||
screen->SetBlendingRect(0,0,0,0);
|
||||
hw2d = screen->Begin2D(false);
|
||||
screen->Begin2D(false);
|
||||
WI_Drawer ();
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_FINALE:
|
||||
screen->SetBlendingRect(0,0,0,0);
|
||||
hw2d = screen->Begin2D(false);
|
||||
screen->Begin2D(false);
|
||||
F_Drawer ();
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
||||
case GS_DEMOSCREEN:
|
||||
screen->SetBlendingRect(0,0,0,0);
|
||||
hw2d = screen->Begin2D(false);
|
||||
screen->Begin2D(false);
|
||||
D_PageDrawer ();
|
||||
CT_Drawer ();
|
||||
break;
|
||||
|
@ -935,7 +925,7 @@ void D_Display ()
|
|||
NetUpdate (); // send out any new accumulation
|
||||
// normal update
|
||||
// draw ZScript UI stuff
|
||||
C_DrawConsole (hw2d); // draw console
|
||||
C_DrawConsole (); // draw console
|
||||
M_Drawer (); // menu is drawn even on top of everything
|
||||
FStat::PrintStat ();
|
||||
screen->Update (); // page flip or blit buffer
|
||||
|
@ -963,7 +953,7 @@ void D_Display ()
|
|||
} while (diff < 1);
|
||||
wipestart = nowtime;
|
||||
done = screen->WipeDo (1);
|
||||
C_DrawConsole (hw2d); // console and
|
||||
C_DrawConsole (); // console and
|
||||
M_Drawer (); // menu are drawn even on top of wipes
|
||||
screen->Update (); // page flip or blit buffer
|
||||
NetUpdate (); // [RH] not sure this is needed anymore
|
||||
|
|
|
@ -168,8 +168,6 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
|
|||
NeedGammaUpdate = false;
|
||||
NeedPalUpdate = false;
|
||||
|
||||
RenderBuffer = new DSimpleCanvas(Width, Height, bgra);
|
||||
|
||||
memcpy(SourcePalette, GPalette.BaseColors, sizeof(PalEntry) * 256);
|
||||
|
||||
// To do: this needs to cooperate with the same static in OpenGLFrameBuffer::InitializeState
|
||||
|
@ -219,12 +217,19 @@ OpenGLSWFrameBuffer::OpenGLSWFrameBuffer(void *hMonitor, int width, int height,
|
|||
TrueHeight = height;
|
||||
|
||||
Valid = CreateResources();
|
||||
|
||||
RenderBuffer = new DSimpleCanvas(Width, Height, bgra);
|
||||
if (UseMappedMemBuffer) MappedBuffer = new DCanvas(Width, Height, bgra);
|
||||
else MappedBuffer = nullptr;
|
||||
|
||||
if (Valid)
|
||||
SetInitialState();
|
||||
}
|
||||
|
||||
OpenGLSWFrameBuffer::~OpenGLSWFrameBuffer()
|
||||
{
|
||||
if (RenderBuffer) delete RenderBuffer;
|
||||
if (MappedBuffer) delete MappedBuffer;
|
||||
ReleaseResources();
|
||||
delete[] QuadExtra;
|
||||
}
|
||||
|
@ -771,7 +776,7 @@ void OpenGLSWFrameBuffer::Present()
|
|||
|
||||
void OpenGLSWFrameBuffer::SetInitialState()
|
||||
{
|
||||
//if (gl.es) re-enable later! First the basics must work.
|
||||
if (gl.es)
|
||||
UseMappedMemBuffer = false;
|
||||
|
||||
AlphaBlendEnabled = false;
|
||||
|
@ -1109,16 +1114,8 @@ int OpenGLSWFrameBuffer::GetPageCount()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
#if 0
|
||||
bool OpenGLSWFrameBuffer::Lock(bool buffered)
|
||||
bool OpenGLSWFrameBuffer::LockCanvas()
|
||||
{
|
||||
if (m_Lock++ > 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
assert(!In2D);
|
||||
|
||||
#if 0 // temporarily disabled. Must be fixed later
|
||||
if (UseMappedMemBuffer)
|
||||
{
|
||||
if (!MappedMemBuffer)
|
||||
|
@ -1126,19 +1123,12 @@ bool OpenGLSWFrameBuffer::Lock(bool buffered)
|
|||
BindFBBuffer();
|
||||
|
||||
MappedMemBuffer = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
|
||||
Pitch = Width;
|
||||
if (MappedMemBuffer == nullptr)
|
||||
return true;
|
||||
return false;
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
Buffer = (uint8_t*)MappedMemBuffer;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if 0
|
||||
//Buffer = MemBuffer;
|
||||
#endif
|
||||
MappedBuffer->SetBuffer(Width, Height, Width, static_cast<uint8_t*>(MappedMemBuffer));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1149,33 +1139,17 @@ bool OpenGLSWFrameBuffer::Lock(bool buffered)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void OpenGLSWFrameBuffer::Unlock()
|
||||
void OpenGLSWFrameBuffer::UnlockCanvas()
|
||||
{
|
||||
if (m_Lock == 0)
|
||||
if (MappedMemBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (UpdatePending && m_Lock == 1)
|
||||
{
|
||||
Update();
|
||||
}
|
||||
else if (--m_Lock == 0)
|
||||
{
|
||||
#if 0
|
||||
Buffer = nullptr;
|
||||
#endif
|
||||
|
||||
if (MappedMemBuffer)
|
||||
{
|
||||
BindFBBuffer();
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
MappedMemBuffer = nullptr;
|
||||
}
|
||||
BindFBBuffer();
|
||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
MappedMemBuffer = nullptr;
|
||||
MappedBuffer->SetBuffer(0, 0, 0, nullptr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
@ -25,6 +25,7 @@ class OpenGLSWFrameBuffer : public SDLGLFB
|
|||
#endif
|
||||
|
||||
DSimpleCanvas *RenderBuffer;
|
||||
DCanvas *MappedBuffer;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -32,6 +33,9 @@ public:
|
|||
OpenGLSWFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen, bool bgra);
|
||||
~OpenGLSWFrameBuffer();
|
||||
|
||||
bool LockCanvas() override;
|
||||
void UnlockCanvas() override;
|
||||
|
||||
virtual DCanvas *GetCanvas() { return RenderBuffer; }
|
||||
void Update() override;
|
||||
PalEntry *GetPalette() override;
|
||||
|
|
|
@ -59,18 +59,22 @@ void PolyRenderer::RenderView(player_t *player)
|
|||
{
|
||||
using namespace swrenderer;
|
||||
|
||||
RenderTarget = screen->GetCanvas();
|
||||
if (screen->LockCanvas())
|
||||
{
|
||||
RenderTarget = screen->GetCanvas();
|
||||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
//viewport->SetViewport(&Thread, width, height, trueratio);
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
//viewport->SetViewport(&Thread, width, height, trueratio);
|
||||
|
||||
RenderActorView(player->mo, false);
|
||||
RenderActorView(player->mo, false);
|
||||
|
||||
Threads.MainThread()->FlushDrawQueue();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
Threads.MainThread()->FlushDrawQueue();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
screen->UnlockCanvas();
|
||||
}
|
||||
}
|
||||
|
||||
void PolyRenderer::RenderViewToCanvas(AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines)
|
||||
|
|
|
@ -89,36 +89,42 @@ namespace swrenderer
|
|||
|
||||
void RenderScene::RenderView(player_t *player)
|
||||
{
|
||||
auto viewport = MainThread()->Viewport.get();
|
||||
viewport->RenderTarget = screen->GetCanvas();
|
||||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
viewport->SetViewport(MainThread(), width, height, trueratio);
|
||||
|
||||
if (r_clearbuffer != 0)
|
||||
if (screen->LockCanvas())
|
||||
{
|
||||
if (!viewport->RenderTarget->IsBgra())
|
||||
auto viewport = MainThread()->Viewport.get();
|
||||
viewport->RenderTarget = screen->GetCanvas();
|
||||
|
||||
int width = SCREENWIDTH;
|
||||
int height = SCREENHEIGHT;
|
||||
float trueratio;
|
||||
ActiveRatio(width, height, &trueratio);
|
||||
viewport->SetViewport(MainThread(), width, height, trueratio);
|
||||
|
||||
if (r_clearbuffer != 0)
|
||||
{
|
||||
memset(viewport->RenderTarget->GetPixels(), clearcolor, viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t bgracolor = GPalette.BaseColors[clearcolor].d;
|
||||
int size = viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight();
|
||||
uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetPixels();
|
||||
for (int i = 0; i < size; i++)
|
||||
dest[i] = bgracolor;
|
||||
if (!viewport->RenderTarget->IsBgra())
|
||||
{
|
||||
memset(viewport->RenderTarget->GetPixels(), clearcolor, viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight());
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t bgracolor = GPalette.BaseColors[clearcolor].d;
|
||||
int size = viewport->RenderTarget->GetPitch() * viewport->RenderTarget->GetHeight();
|
||||
uint32_t *dest = (uint32_t *)viewport->RenderTarget->GetPixels();
|
||||
for (int i = 0; i < size; i++)
|
||||
dest[i] = bgracolor;
|
||||
}
|
||||
}
|
||||
|
||||
RenderActorView(player->mo);
|
||||
|
||||
DrawerWaitCycles.Clock();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
DrawerWaitCycles.Unclock();
|
||||
|
||||
screen->UnlockCanvas();
|
||||
}
|
||||
|
||||
RenderActorView(player->mo);
|
||||
|
||||
DrawerWaitCycles.Clock();
|
||||
DrawerThreads::WaitForWorkers();
|
||||
DrawerWaitCycles.Unclock();
|
||||
}
|
||||
|
||||
void RenderScene::RenderActorView(AActor *actor, bool dontmaplines)
|
||||
|
|
|
@ -206,13 +206,28 @@ public:
|
|||
virtual ~DCanvas ();
|
||||
|
||||
// Member variable access
|
||||
//inline uint8_t *GetBuffer () const { return Buffer; }
|
||||
inline uint8_t *GetPixels () const { return PixelBuffer; }
|
||||
inline int GetWidth () const { return Width; }
|
||||
inline int GetHeight () const { return Height; }
|
||||
inline int GetPitch () const { return Pitch; }
|
||||
inline bool IsBgra() const { return Bgra; }
|
||||
|
||||
bool SetBuffer(int width, int height, int pitch, uint8_t *buffer)
|
||||
{
|
||||
if (PixelBuffer == nullptr)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Pitch = pitch;
|
||||
PixelBuffer = buffer;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
uint8_t *PixelBuffer;
|
||||
|
@ -220,11 +235,6 @@ protected:
|
|||
int Height;
|
||||
int Pitch;
|
||||
bool Bgra;
|
||||
|
||||
|
||||
DCanvas() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
// A canvas in system memory.
|
||||
|
@ -236,10 +246,6 @@ public:
|
|||
DSimpleCanvas (int width, int height, bool bgra);
|
||||
~DSimpleCanvas ();
|
||||
void Resize(int width, int height);
|
||||
|
||||
private:
|
||||
|
||||
DSimpleCanvas() {}
|
||||
};
|
||||
|
||||
// This class represents a native texture, as opposed to an FTexture.
|
||||
|
@ -341,6 +347,10 @@ public:
|
|||
|
||||
virtual bool LegacyHardware() const { return false; } // only for reporting SM1.4 support to the stat collector
|
||||
|
||||
// For FrameBuffers with a software canvas that requires special preparation before being used.
|
||||
virtual bool LockCanvas() { return true; }
|
||||
virtual void UnlockCanvas() {}
|
||||
|
||||
// Begin 2D drawing operations. This is like Update, but it doesn't end
|
||||
// the scene, and it doesn't present the image yet. If you are going to
|
||||
// be covering the entire screen with 2D elements, then pass false to
|
||||
|
|
Loading…
Reference in a new issue