dxx-rebirth/common/arch/ogl/ogl_sync.cpp
Kp 12b57e84e6 Switch most in-tree http:// links to https://
For each link given as http://, verify that the site is accessible over
https:// and, if so, switch to it.  These domains were converted:

* llvm.org
* clang.llvm.org
* en.cppreference.com
* www.dxx-rebirth.com
* www.libsdl.org
* www.scons.org
2018-09-02 00:57:29 +00:00

139 lines
3.6 KiB
C++

/*
* This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
* It is copyright by its individual contributors, as recorded in the
* project's Git history. See COPYING.txt at the top level for license
* terms and a link to the Git history.
*/
/* OpenGL Synchronization code:
* either use fence sync objects or glFinish() to prevent the GPU from
* lagging behind too much.
*/
#include <stdlib.h>
#include <SDL.h>
#include "args.h"
#include "config.h"
#include "console.h"
#include "game.h"
#include "maths.h"
#include "multi.h"
#include "ogl_sync.h"
#include "timer.h"
namespace dcx {
ogl_sync::ogl_sync()
{
method=SYNC_GL_NONE;
wait_timeout = 0;
}
ogl_sync::~ogl_sync()
{
if (fence)
con_puts(CON_URGENT, "DXX-Rebirth: OpenGL: fence sync object was never destroyed!");
}
void ogl_sync::sync_deleter::operator()(GLsync fence_func) const
{
glDeleteSyncFunc(fence_func);
}
void ogl_sync::before_swap()
{
if (const auto local_fence = std::move(fence))
{
/// use a fence sync object to prevent the GPU from queuing up more than one frame
const auto waitsync = glClientWaitSyncFunc;
if (method == SYNC_GL_FENCE_SLEEP) {
const auto local_wait_timeout = wait_timeout;
const auto multiplayer = Game_mode & GM_MULTI;
while (waitsync(local_fence.get(), GL_SYNC_FLUSH_COMMANDS_BIT, 0ULL) == GL_TIMEOUT_EXPIRED) {
if (multiplayer) {
multi_do_frame(); // during long wait, keep packets flowing
}
timer_delay_ms(local_wait_timeout);
}
} else {
waitsync(local_fence.get(), GL_SYNC_FLUSH_COMMANDS_BIT, 34000000ULL);
}
} else if (method == SYNC_GL_FINISH_BEFORE_SWAP) {
glFinish();
}
}
void ogl_sync::after_swap()
{
if (method == SYNC_GL_FENCE || method == SYNC_GL_FENCE_SLEEP ) {
fence.reset(glFenceSyncFunc(GL_SYNC_GPU_COMMANDS_COMPLETE, 0));
} else if (method == SYNC_GL_FINISH_AFTER_SWAP) {
glFinish();
}
}
void ogl_sync::init(SyncGLMethod sync_method, int wait)
{
method = sync_method;
fence = NULL;
fix a = i2f(wait);
fix b = i2f(1000);
wait_timeout = f2i(fixdiv(a, b) * 1000);
bool need_ARB_sync;
switch (method) {
case SYNC_GL_FENCE:
case SYNC_GL_FENCE_SLEEP:
case SYNC_GL_AUTO:
need_ARB_sync = true;
break;
default:
need_ARB_sync = false;
}
if (method == SYNC_GL_AUTO) {
if (!CGameCfg.VSync) {
con_puts(CON_NORMAL, "DXX-Rebirth: OpenGL: disabling automatic GL sync since VSync is turned off");
method = SYNC_GL_NONE;
need_ARB_sync = false;
} else if (!ogl_have_ARB_sync) {
con_puts(CON_NORMAL, "DXX-Rebirth: OpenGL: GL_ARB_sync not available, disabling sync");
method = SYNC_GL_NONE;
need_ARB_sync = false;
} else {
method = SYNC_GL_FENCE_SLEEP;
}
}
if (need_ARB_sync && !ogl_have_ARB_sync) {
con_puts(CON_URGENT, "DXX-Rebirth: OpenGL: GL_ARB_sync not available, using fallback");
method = SYNC_GL_FINISH_BEFORE_SWAP;
}
switch(method) {
case SYNC_GL_FENCE:
con_puts(CON_VERBOSE, "DXX-Rebirth: OpenGL: using GL_ARB_sync for synchronization (direct)");
break;
case SYNC_GL_FENCE_SLEEP:
con_printf(CON_VERBOSE, "DXX-Rebirth: OpenGL: using GL_ARB_sync for synchronization with interval %dms", wait);
break;
case SYNC_GL_FINISH_AFTER_SWAP:
con_puts(CON_VERBOSE, "DXX-Rebirth: OpenGL: using glFinish synchronization (method 1: after swap)");
break;
case SYNC_GL_FINISH_BEFORE_SWAP:
con_puts(CON_VERBOSE, "DXX-Rebirth: OpenGL: using glFinish synchronization (method 2: before swap)");
break;
default:
con_puts(CON_VERBOSE, "DXX-Rebirth: OpenGL: using no explicit GPU synchronization");
break;
}
}
void ogl_sync::deinit()
{
fence.reset();
}
}