Skip to content

Commit

Permalink
enhancement: added VSync option (fixes #1149)
Browse files Browse the repository at this point in the history
You can now enable/disable VSync from the GUI (Display panel)
  • Loading branch information
midwan committed Nov 8, 2023
1 parent 9f97d0e commit 5d86449
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 58 deletions.
97 changes: 44 additions & 53 deletions src/osdep/amiberry_gfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ Uint32 pixel_format;
static unsigned long last_synctime;
static int deskhz;

#ifdef AMIBERRY
bool vsync_changed = false;
#endif

#ifdef USE_DISPMANX
/* Possible screen modes (x and y resolutions) */
#define MAX_SCREEN_MODES 14
Expand Down Expand Up @@ -783,7 +787,7 @@ static void open_screen(struct uae_prefs* p)
wasfullwindow_p = p->gfx_apmode[1].gfx_fullscreen == GFX_FULLWINDOW ? 1 : -1;

update_win_fs_mode(0, p);

#ifdef USE_DISPMANX
next_synctime = 0;
current_resource_amigafb = 0;
Expand Down Expand Up @@ -831,9 +835,10 @@ static void open_screen(struct uae_prefs* p)
}
#endif
if (isfullscreen() == 0 && !is_maximized)
{
SDL_SetWindowSize(mon->sdl_window, display_width, display_height);
// Center window, sigurbjornl 20220122
SDL_SetWindowPosition(mon->sdl_window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
}
else
{
Expand Down Expand Up @@ -954,48 +959,6 @@ static void open_screen(struct uae_prefs* p)
}
}

void SDL2_toggle_vsync(bool vsync)
{
struct AmigaMonitor* mon = &AMonitors[0];

#ifdef USE_OPENGL
if (vsync)
{
if (SDL_GL_SetSwapInterval(1) < 0)
{
write_log("Warning: failed to enable Vsync for the current GL context!\n");
}
}
else
{
if (SDL_GL_SetSwapInterval(0) < 0)
{
write_log("Warning: failed to disable Vsync for the current GL context!\n");
}
}
#else
if (sdl_renderer)
{
SDL_DestroyRenderer(sdl_renderer);
sdl_renderer = nullptr;
}

Uint32 flags;
if (vsync)
{
flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
}
else
{
flags = SDL_RENDERER_ACCELERATED;
}
sdl_renderer = SDL_CreateRenderer(mon->sdl_window, -1, flags);
check_error_sdl(sdl_renderer == nullptr, "Unable to create a renderer:");
#endif
open_screen(&currprefs);
}


extern int vstrt; // vertical start
extern int vstop; // vertical stop
extern int hstrt; // horizontal start
Expand Down Expand Up @@ -1055,7 +1018,7 @@ void auto_crop_image()
new_height = new_height << currprefs.gfx_vresolution;
\
last_x = x;
const int y = vstrt - minfirstline << currprefs.gfx_vresolution > 0 ? vstrt - minfirstline << currprefs.gfx_vresolution : 0;
const int y = (vstrt - minfirstline) << currprefs.gfx_vresolution > 0 ? (vstrt - minfirstline) << currprefs.gfx_vresolution : 0;

#ifdef USE_DISPMANX
// Still using the old approach for DMX, for now
Expand Down Expand Up @@ -1214,6 +1177,12 @@ int check_prefs_changed_gfx()
}
monitors[0] = true;

#ifdef AMIBERRY
if (currprefs.gfx_apmode[0].gfx_vsync != changed_prefs.gfx_apmode[0].gfx_vsync)
{
vsync_changed = true;
}
#endif
c |= currprefs.color_mode != changed_prefs.color_mode ? 2 | 16 : 0;
c |= currprefs.gfx_apmode[0].gfx_fullscreen != changed_prefs.gfx_apmode[0].gfx_fullscreen ? 16 : 0;
c |= currprefs.gfx_apmode[1].gfx_fullscreen != changed_prefs.gfx_apmode[1].gfx_fullscreen ? 16 : 0;
Expand Down Expand Up @@ -1485,7 +1454,16 @@ int check_prefs_changed_gfx()
open_screen(&currprefs);
}
if ((c & 16) || ((c & 8) && keepfsmode)) {
open_screen(&currprefs);
if (vsync_changed)
{
graphics_leave();
graphics_init(true);
vsync_changed = false;
}
else
{
open_screen(&currprefs);
}
c |= 2;
}
if ((c & 32) || ((c & 2) && !keepfsmode)) {
Expand All @@ -1498,7 +1476,7 @@ int check_prefs_changed_gfx()
currprefs.gfx_api = changed_prefs.gfx_api;
currprefs.gfx_api_options = changed_prefs.gfx_api_options;
}
graphics_init(dontcapture ? false : true);
graphics_init(!dontcapture);
}
}

Expand Down Expand Up @@ -2137,21 +2115,34 @@ int graphics_init(bool mousecapture)
if (gl_context == nullptr)
gl_context = SDL_GL_CreateContext(mon->sdl_window);

// Enable vsync
if (SDL_GL_SetSwapInterval(-1) < 0)
if (currprefs.gfx_apmode[0].gfx_vsync)
{
write_log("Warning: Adaptive V-Sync not supported on this platform, trying normal V-Sync\n");
if (SDL_GL_SetSwapInterval(1) < 0)
// Enable vsync
if (SDL_GL_SetSwapInterval(-1) < 0)
{
write_log("Warning: Failed to enable V-Sync in the current GL context!\n");
write_log("Warning: Adaptive V-Sync not supported on this platform, trying normal V-Sync\n");
if (SDL_GL_SetSwapInterval(1) < 0)
{
write_log("Warning: Failed to enable V-Sync in the current GL context!\n");
}
}
}

// for old fixed-function pipeline (change when using shaders!)
glEnable(GL_TEXTURE_2D);
#else
if (sdl_renderer == nullptr)
{
sdl_renderer = SDL_CreateRenderer(mon->sdl_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
Uint32 flags;
if (currprefs.gfx_apmode[0].gfx_vsync)
{
flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC;
}
else
{
flags = SDL_RENDERER_ACCELERATED;
}
sdl_renderer = SDL_CreateRenderer(mon->sdl_window, -1, flags);
check_error_sdl(sdl_renderer == nullptr, "Unable to create a renderer:");
}
#endif
Expand Down
7 changes: 4 additions & 3 deletions src/osdep/gui/Navigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ static NavigationMap navMap[] =
{ "sldWidth", "", "", "cboScreenmode", "sldHeight" },
{ "sldHeight", "", "", "sldWidth", "chkAutoCrop" },
{ "chkAutoCrop", "Display", "chkBorderless", "sldHeight", "sldHOffset" },
{ "chkBorderless", "chkAutoCrop", "optSingle", "sldHeight", "sldHOffset" },
{ "chkBorderless", "chkAutoCrop", "chkVsync", "sldHeight", "sldHOffset" },
{ "chkVsync", "chkBorderless", "optSingle", "sldHeight", "sldHOffset" },
{ "sldHOffset", "", "", "chkAutoCrop", "sldVOffset" },
{ "sldVOffset", "", "", "sldHOffset", "cboScalingMethod" },
{ "cboScalingMethod", "Display", "optScanlines", "sldVOffset", "cboResolution" },
Expand All @@ -288,8 +289,8 @@ static NavigationMap navMap[] =

{ "chkHorizontal", "cboScreenmode", "", "optIDouble3", "chkVertical" },
{ "chkVertical", "cboScreenmode", "", "chkHorizontal", "optSingle" },
{ "optSingle", "chkBorderless", "", "chkVertical", "optDouble" },
{ "optDouble", "chkBorderless", "", "optSingle", "optScanlines" },
{ "optSingle", "chkVsync", "", "chkVertical", "optDouble" },
{ "optDouble", "chkVsync", "", "optSingle", "optScanlines" },
{ "optScanlines", "cboScalingMethod", "", "optDouble", "optDouble2" },
{ "optDouble2", "cboResolution", "", "optScanlines", "optDouble3" },
{ "optDouble3", "chkFilterLowRes", "", "optDouble2", "optISingle" },
Expand Down
15 changes: 13 additions & 2 deletions src/osdep/gui/PanelDisplay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ static gcn::Label* lblScreenmode;
static gcn::DropDown* cboScreenmode;
static gcn::Label* lblFullscreen;
static gcn::DropDown* cboFullscreen;
static gcn::CheckBox* chkVsync;

static gcn::Window* grpCentering;
static gcn::CheckBox* chkHorizontal;
Expand Down Expand Up @@ -155,6 +156,9 @@ class AmigaScreenActionListener : public gcn::ActionListener
else if (actionEvent.getSource() == chkBorderless)
changed_prefs.borderless = chkBorderless->isSelected();

else if (actionEvent.getSource() == chkVsync)
changed_prefs.gfx_apmode[0].gfx_vsync = chkVsync->isSelected();

else if (actionEvent.getSource() == sldHOffset)
{
changed_prefs.gfx_horizontal_offset = static_cast<int>(sldHOffset->getValue());
Expand Down Expand Up @@ -395,6 +399,10 @@ void InitPanelDisplay(const config_category& category)
chkBorderless->setId("chkBorderless");
chkBorderless->addActionListener(amigaScreenActionListener);

chkVsync = new gcn::CheckBox("VSync");
chkVsync->setId("chkVsync");
chkVsync->addActionListener(amigaScreenActionListener);

lblHOffset = new gcn::Label("H. Offset:");
lblHOffset->setAlignment(gcn::Graphics::LEFT);
sldHOffset = new gcn::Slider(-60, 60);
Expand Down Expand Up @@ -510,7 +518,8 @@ void InitPanelDisplay(const config_category& category)
posY += sldAmigaHeight->getHeight() + DISTANCE_NEXT_Y;
grpAmigaScreen->add(chkAutoCrop, DISTANCE_BORDER, posY);
grpAmigaScreen->add(chkBorderless, chkAutoCrop->getX() + chkAutoCrop->getWidth() + DISTANCE_NEXT_X, posY);
posY += chkAutoCrop->getHeight() + DISTANCE_NEXT_Y;
grpAmigaScreen->add(chkVsync, chkBorderless->getX() + chkBorderless->getWidth() + DISTANCE_NEXT_X, posY);
posY += chkVsync->getHeight() + DISTANCE_NEXT_Y;
grpAmigaScreen->add(lblHOffset, DISTANCE_BORDER, posY);
grpAmigaScreen->add(sldHOffset, lblHOffset->getX() + lblHOffset->getWidth() + DISTANCE_NEXT_X, posY);
grpAmigaScreen->add(lblHOffsetValue, sldHOffset->getX() + sldHOffset->getWidth() + 8, posY + 2);
Expand All @@ -520,7 +529,7 @@ void InitPanelDisplay(const config_category& category)
grpAmigaScreen->add(lblVOffsetValue, sldVOffset->getX() + sldVOffset->getWidth() + 8, posY + 2);

grpAmigaScreen->setMovable(false);
grpAmigaScreen->setSize(lblAmigaWidth->getX() + lblAmigaWidth->getWidth() + sldAmigaWidth->getWidth() + lblAmigaWidth->getWidth() + txtAmigaHeight->getWidth() + DISTANCE_BORDER, TITLEBAR_HEIGHT + lblVOffset->getY() + lblVOffset->getHeight() + DISTANCE_NEXT_Y);
grpAmigaScreen->setSize(chkVsync->getX() + chkVsync->getWidth() + DISTANCE_BORDER, TITLEBAR_HEIGHT + lblVOffset->getY() + lblVOffset->getHeight() + DISTANCE_NEXT_Y);
grpAmigaScreen->setTitleBarHeight(TITLEBAR_HEIGHT);
grpAmigaScreen->setBaseColor(gui_baseCol);
category.panel->add(grpAmigaScreen);
Expand Down Expand Up @@ -671,6 +680,7 @@ void ExitPanelDisplay()
delete cboScreenmode;
delete lblFullscreen;
delete cboFullscreen;
delete chkVsync;

delete optSingle;
delete optDouble;
Expand Down Expand Up @@ -748,6 +758,7 @@ void RefreshPanelDisplay()
}
#endif
chkBorderless->setSelected(changed_prefs.borderless);
chkVsync->setSelected(changed_prefs.gfx_apmode[0].gfx_vsync);

sldHOffset->setValue(changed_prefs.gfx_horizontal_offset);
lblHOffsetValue->setCaption(std::to_string(changed_prefs.gfx_horizontal_offset));
Expand Down

0 comments on commit 5d86449

Please sign in to comment.