GUI: add option to disable VSync

also add frame rate limiter
This commit is contained in:
tildearrow 2024-04-02 17:49:48 -05:00
parent 9dbda09cd0
commit fc68f17107
11 changed files with 145 additions and 75 deletions

View file

@ -59,6 +59,10 @@ bool FurnaceGUIRender::newFrame() {
return true;
}
bool FurnaceGUIRender::canVSync() {
return true;
}
void FurnaceGUIRender::createFontsTexture() {
}
@ -89,10 +93,13 @@ int FurnaceGUIRender::getWindowFlags() {
return 0;
}
void FurnaceGUIRender::setSwapInterval(int swapInterval) {
}
void FurnaceGUIRender::preInit() {
}
bool FurnaceGUIRender::init(SDL_Window* win) {
bool FurnaceGUIRender::init(SDL_Window* win, int swapInterval) {
return false;
}

View file

@ -293,6 +293,11 @@ bool FurnaceGUIRenderDX11::newFrame() {
return ImGui_ImplDX11_NewFrame();
}
bool FurnaceGUIRenderDX11::canVSync() {
// TODO: find out how to retrieve VSync status
return true;
}
void FurnaceGUIRenderDX11::createFontsTexture() {
ImGui_ImplDX11_CreateDeviceObjects();
}
@ -345,7 +350,7 @@ void FurnaceGUIRenderDX11::wipe(float alpha) {
}
void FurnaceGUIRenderDX11::present() {
HRESULT result=swapchain->Present(1,0);
HRESULT result=swapchain->Present(swapInterval,0);
if (result==DXGI_ERROR_DEVICE_REMOVED || result==DXGI_ERROR_DEVICE_RESET) {
dead=true;
} else if (result!=S_OK && result!=DXGI_STATUS_OCCLUDED) {
@ -363,6 +368,10 @@ int FurnaceGUIRenderDX11::getWindowFlags() {
return 0;
}
void FurnaceGUIRenderDX11::setSwapInterval(int swapInt) {
swapInterval=swapInt;
}
void FurnaceGUIRenderDX11::preInit() {
}
@ -373,7 +382,7 @@ const float wipeVertices[4][4]={
{ 1.0, 1.0, 0.0, 1.0}
};
bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
bool FurnaceGUIRenderDX11::init(SDL_Window* win, int swapInt) {
SDL_SysWMinfo sysWindow;
D3D_FEATURE_LEVEL featureLevel;
@ -384,6 +393,8 @@ bool FurnaceGUIRenderDX11::init(SDL_Window* win) {
}
HWND window=(HWND)sysWindow.info.win.window;
swapInterval=swapInt;
DXGI_SWAP_CHAIN_DESC chainDesc;
memset(&chainDesc,0,sizeof(chainDesc));
chainDesc.BufferDesc.Width=0;

View file

@ -41,7 +41,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
ID3D11BlendState* omBlendState;
ID3D11Buffer* quadVertex;
int outW, outH;
int outW, outH, swapInterval;
bool dead;
@ -71,6 +71,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
void resized(const SDL_Event& ev);
void clear(ImVec4 color);
bool newFrame();
bool canVSync();
void createFontsTexture();
void destroyFontsTexture();
void renderGUI();
@ -78,8 +79,9 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
void present();
bool getOutputSize(int& w, int& h);
int getWindowFlags();
void setSwapInterval(int swapInterval);
void preInit();
bool init(SDL_Window* win);
bool init(SDL_Window* win, int swapInterval);
void initGUI(SDL_Window* win);
void quitGUI();
bool quit();
@ -94,6 +96,7 @@ class FurnaceGUIRenderDX11: public FurnaceGUIRender {
quadVertex(NULL),
outW(0),
outH(0),
swapInterval(1),
dead(false),
sh_wipe_vertex(NULL),
sh_wipe_fragment(NULL),

View file

@ -360,6 +360,10 @@ bool FurnaceGUIRenderGL::newFrame() {
return ImGui_ImplOpenGL3_NewFrame();
}
bool FurnaceGUIRenderGL::canVSync() {
return swapIntervalSet;
}
void FurnaceGUIRenderGL::createFontsTexture() {
ImGui_ImplOpenGL3_CreateFontsTexture();
}
@ -527,6 +531,16 @@ int FurnaceGUIRenderGL::getWindowFlags() {
return SDL_WINDOW_OPENGL;
}
void FurnaceGUIRenderGL::setSwapInterval(int swapInterval) {
SDL_GL_SetSwapInterval(swapInterval);
if (swapInterval>0 && SDL_GL_GetSwapInterval()==0) {
swapIntervalSet=false;
logW("tried to enable VSync but couldn't!");
} else {
swapIntervalSet=true;
}
}
void FurnaceGUIRenderGL::preInit() {
#if defined(USE_GLES)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
@ -567,14 +581,20 @@ void FurnaceGUIRenderGL::preInit() {
logW(_s " not found"); \
}
bool FurnaceGUIRenderGL::init(SDL_Window* win) {
bool FurnaceGUIRenderGL::init(SDL_Window* win, int swapInterval) {
sdlWin=win;
context=SDL_GL_CreateContext(win);
if (context==NULL) {
return false;
}
SDL_GL_MakeCurrent(win,context);
SDL_GL_SetSwapInterval(1);
SDL_GL_SetSwapInterval(swapInterval);
if (swapInterval>0 && SDL_GL_GetSwapInterval()==0) {
swapIntervalSet=false;
logW("tried to enable VSync but couldn't!");
} else {
swapIntervalSet=true;
}
LOAD_PROC_MANDATORY(furGenBuffers,PFNGLGENBUFFERSPROC,"glGenBuffers");
LOAD_PROC_MANDATORY(furBindBuffer,PFNGLBINDBUFFERPROC,"glBindBuffer");

View file

@ -46,6 +46,8 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
int sh_oscRender_oscVal;
bool sh_oscRender_have;
bool swapIntervalSet;
bool createShader(const char* vertexS, const char* fragmentS, int& vertex, int& fragment, int& program, const char** attribNames);
public:
@ -61,6 +63,7 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
bool regenOscShader(const char* fragment);
void clear(ImVec4 color);
bool newFrame();
bool canVSync();
void createFontsTexture();
void destroyFontsTexture();
void renderGUI();
@ -70,15 +73,17 @@ class FurnaceGUIRenderGL: public FurnaceGUIRender {
bool getOutputSize(int& w, int& h);
bool supportsDrawOsc();
int getWindowFlags();
void setSwapInterval(int swapInterval);
void preInit();
bool init(SDL_Window* win);
bool init(SDL_Window* win, int swapInterval);
void initGUI(SDL_Window* win);
void quitGUI();
bool quit();
bool isDead();
FurnaceGUIRenderGL():
context(NULL),
sdlWin(NULL) {
sdlWin(NULL),
swapIntervalSet(true) {
memset(quadVertex,0,4*3*sizeof(float));
memset(oscVertex,0,4*5*sizeof(float));
memset(oscData,0,2048*sizeof(float));

View file

@ -112,6 +112,10 @@ bool FurnaceGUIRenderSDL::newFrame() {
return ImGui_ImplSDLRenderer2_NewFrame();
}
bool FurnaceGUIRenderSDL::canVSync() {
return swapIntervalSet;
}
void FurnaceGUIRenderSDL::createFontsTexture() {
ImGui_ImplSDLRenderer2_CreateFontsTexture();
}
@ -142,12 +146,27 @@ int FurnaceGUIRenderSDL::getWindowFlags() {
return 0;
}
void FurnaceGUIRenderSDL::setSwapInterval(int swapInterval) {
if (SDL_RenderSetVSync(sdlRend,(swapInterval>=0)?1:0)!=0) {
swapIntervalSet=false;
logW("tried to enable VSync but couldn't!");
} else {
swapIntervalSet=true;
}
}
void FurnaceGUIRenderSDL::preInit() {
}
bool FurnaceGUIRenderSDL::init(SDL_Window* win) {
bool FurnaceGUIRenderSDL::init(SDL_Window* win, int swapInterval) {
logV("creating SDL renderer...");
sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_PRESENTVSYNC|SDL_RENDERER_TARGETTEXTURE);
sdlRend=SDL_CreateRenderer(win,-1,SDL_RENDERER_ACCELERATED|((swapInterval>0)?SDL_RENDERER_PRESENTVSYNC:0)|SDL_RENDERER_TARGETTEXTURE);
if (SDL_RenderSetVSync(sdlRend,(swapInterval>=0)?1:0)!=0) {
swapIntervalSet=false;
logW("tried to enable VSync but couldn't!");
} else {
swapIntervalSet=true;
}
logV("(post creation)");
return (sdlRend!=NULL);
}

View file

@ -21,6 +21,7 @@
class FurnaceGUIRenderSDL: public FurnaceGUIRender {
SDL_Renderer* sdlRend;
bool swapIntervalSet;
public:
ImTextureID getTextureID(FurnaceGUITexture* which);
bool lockTexture(FurnaceGUITexture* which, void** data, int* pitch);
@ -32,6 +33,7 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender {
void setBlendMode(FurnaceGUIBlendMode mode);
void clear(ImVec4 color);
bool newFrame();
bool canVSync();
void createFontsTexture();
void destroyFontsTexture();
void renderGUI();
@ -39,11 +41,13 @@ class FurnaceGUIRenderSDL: public FurnaceGUIRender {
void present();
bool getOutputSize(int& w, int& h);
int getWindowFlags();
void setSwapInterval(int swapInterval);
void preInit();
bool init(SDL_Window* win);
bool init(SDL_Window* win, int swapInterval);
void initGUI(SDL_Window* win);
void quitGUI();
bool quit();
FurnaceGUIRenderSDL():
sdlRend(NULL) {}
sdlRend(NULL),
swapIntervalSet(true) {}
};