From b8133792c054db845cebbb7d0fb15f8010f3ad8c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 31 Oct 2009 09:10:29 +0000 Subject: [PATCH] - Found out that just omitting the glFinish call is not working glitch-free. I reorganized the code so that the glFinish/SwapBuffers call is delayed until the latest possible moment which is after scene processing for the next frame is complete and right before actual rendering starts. This does not show any obvious problems but it still gives almost the same performance gains as omitting glFinish. git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@591 b0f79afe-0144-0410-b225-9a4edf0717df --- src/gl/renderer/gl_renderer.h | 6 +++--- src/gl/scene/gl_scene.cpp | 24 +++++++++++++++++------- src/gl/system/gl_framebuffer.cpp | 26 +++++++++++++++++++++----- src/gl/system/gl_framebuffer.h | 2 ++ src/gl/textures/gl_cameratexture.cpp | 2 +- 5 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/gl/renderer/gl_renderer.h b/src/gl/renderer/gl_renderer.h index eeaa631d..6cd50e4f 100644 --- a/src/gl/renderer/gl_renderer.h +++ b/src/gl/renderer/gl_renderer.h @@ -89,7 +89,7 @@ public: void SetViewArea(); void ResetViewport(); void SetViewport(GL_IRECT *bounds); - sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview); + sector_t *RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen); void RenderView(player_t *player); void SetCameraPos(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t viewangle); void SetupView(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t viewangle, bool mirror, bool planemirror); @@ -99,7 +99,7 @@ public: void CreateScene(); void RenderScene(int recursion); void RenderTranslucent(); - void DrawScene(); + void DrawScene(bool toscreen = false); void DrawBlend(sector_t * viewsector); void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep); @@ -131,7 +131,7 @@ public: void SetProjection(float fov, float ratio, float fovratio); void SetViewMatrix(bool mirror, bool planemirror); - void ProcessScene(); + void ProcessScene(bool toscreen = false); bool StartOffscreen(); void EndOffscreen(); diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index c8f6ee90..f163abf0 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -546,12 +546,22 @@ void FGLRenderer::RenderTranslucent() // stencil, z-buffer and the projection matrix intact! // //----------------------------------------------------------------------------- +EXTERN_CVAR(Bool, gl_draw_synchronized) -void FGLRenderer::DrawScene() +void FGLRenderer::DrawScene(bool toscreen) { static int recursion=0; CreateScene(); + + // Up to this point in the main draw call no rendering is performed so we can wait + // with swapping the render buffer until now. + if (!gl_draw_synchronized && toscreen) + { + All.Unclock(); + static_cast(screen)->Swap(); + All.Clock(); + } RenderScene(recursion); // Handle all portals after rendering the opaque objects but before @@ -809,13 +819,13 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector) // //----------------------------------------------------------------------------- -void FGLRenderer::ProcessScene() +void FGLRenderer::ProcessScene(bool toscreen) { FDrawInfo::StartDrawInfo(); iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; GLPortal::BeginScene(); - DrawScene(); + DrawScene(toscreen); FDrawInfo::EndDrawInfo(); } @@ -869,7 +879,7 @@ void FGLRenderer::SetFixedColormap (player_t *player) // //----------------------------------------------------------------------------- -sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview) +sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen) { sector_t * retval; R_SetupFrame (camera); @@ -904,7 +914,7 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo angle_t a1 = GLRenderer->FrustumAngle(); clipper.SafeAddClipRange(viewangle+a1, viewangle-a1); - ProcessScene(); + ProcessScene(toscreen); gl_frameCount++; // This counter must be increased right before the interpolations are restored. interpolator.RestoreInterpolations (); @@ -968,7 +978,7 @@ void FGLRenderer::RenderView (player_t* player) TThinkerIterator it(STAT_DLIGHT); GLRenderer->mLightCount = ((it.Next()) != NULL); - sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView * 360.0f / FINEANGLES, ratio, fovratio, true); + sector_t * viewsector = RenderViewpoint(player->camera, NULL, FieldOfView * 360.0f / FINEANGLES, ratio, fovratio, true, true); EndDrawScene(viewsector); All.Unclock(); @@ -996,7 +1006,7 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei GLRenderer->mLightCount = ((it.Next()) != NULL); sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds, - FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true); + FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true, false); gl.Disable(GL_STENCIL_TEST); screen->Begin2D(false); DrawBlend(viewsector); diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index ca5eddc3..8e3869fc 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -88,6 +88,7 @@ OpenGLFrameBuffer::OpenGLFrameBuffer(int width, int height, int bits, int refres gl_GenerateGlobalBrightmapFromColormap(); DoSetGamma(); needsetgamma = true; + swapped = false; } OpenGLFrameBuffer::~OpenGLFrameBuffer() @@ -168,7 +169,7 @@ void OpenGLFrameBuffer::InitializeState() // Updates the screen // //========================================================================== -CVAR(Bool, gl_draw_synchronized, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR(Bool, gl_draw_sync, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) void OpenGLFrameBuffer::Update() { @@ -190,10 +191,26 @@ void OpenGLFrameBuffer::Update() Begin2D(false); } + if (gl_draw_sync || !swapped) + { + Swap(); + } + swapped = false; + Unlock(); +} + + +//========================================================================== +// +// Swap the buffers +// +//========================================================================== + +void OpenGLFrameBuffer::Swap() +{ Finish.Reset(); Finish.Clock(); - if (gl_draw_synchronized) gl.Finish(); - else gl.Flush(); + gl.Finish(); if (needsetgamma) { DoSetGamma(); @@ -201,8 +218,7 @@ void OpenGLFrameBuffer::Update() } gl.SwapBuffers(); Finish.Unclock(); - - Unlock(); + swapped = true; } //=========================================================================== diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 3335ab76..b4a83002 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -86,6 +86,7 @@ public: void WipeEndScreen(); bool WipeDo(int ticks); void WipeCleanup(); + void Swap(); private: @@ -96,6 +97,7 @@ private: int translation; bool iscomplex; bool needsetgamma; + bool swapped; PalEntry SourcePalette[256]; BYTE *ScreenshotBuffer; diff --git a/src/gl/textures/gl_cameratexture.cpp b/src/gl/textures/gl_cameratexture.cpp index 2d279244..d0fe07f8 100644 --- a/src/gl/textures/gl_cameratexture.cpp +++ b/src/gl/textures/gl_cameratexture.cpp @@ -84,7 +84,7 @@ void FCanvasTexture::RenderGLView (AActor *Viewpoint, int FOV) bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth(GLUSE_TEXTURE)); bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight(GLUSE_TEXTURE)); - GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false); + GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false); if (!usefb) {