MA_OPT_SCANLINE_LEVEL,
        MA_OPT_CENTERING,
        MA_OPT_OVERSCAN,
+       MA_OPT_VSYNC,
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
        mee_range_h   ("Scanline brightness",      MA_OPT_SCANLINE_LEVEL, scanline_level, 0, 100, h_scanline_l),
 #endif
        mee_range_h   ("Gamma adjustment",         MA_OPT_GAMMA, g_gamma, 1, 200, h_gamma),
-//     mee_onoff     ("Vsync",                    0, vsync, 1),
+       mee_onoff     ("OpenGL Vsync",             MA_OPT_VSYNC, g_opts, OPT_VSYNC),
        mee_cust_h    ("Setup custom scaler",      MA_OPT_VARSCALER_C, menu_loop_cscaler, NULL, h_cscaler),
        mee_end,
 };
 
        i = me_id2offset(e_menu_gfx_options, MA_OPT_HWFILTER);
        e_menu_gfx_options[i].data = plat_target.hwfilters;
-       me_enable(e_menu_gfx_options, MA_OPT_HWFILTER,
-               plat_target.hwfilters != NULL);
-
-       me_enable(e_menu_gfx_options, MA_OPT_GAMMA,
-               plat_target.gamma_set != NULL);
+       me_enable(e_menu_gfx_options, MA_OPT_HWFILTER, plat_target.hwfilters != NULL);
+       if (plat_target.hwfilters && !strcmp(plat_target.hwfilters[0], "linear"))
+               e_menu_gfx_options[i].name = "OpenGL filter";
+       else
+               me_enable(e_menu_gfx_options, MA_OPT_VSYNC, 0);
 
-#ifdef HAVE_PRE_ARMV7
+       me_enable(e_menu_gfx_options, MA_OPT_GAMMA, plat_target.gamma_set != NULL);
+#ifdef HAVE_NEON32
        me_enable(e_menu_gfx_options, MA_OPT_SWFILTER, 0);
 #endif
        me_enable(e_menu_gfx_options, MA_OPT_VARSCALER, MENU_SHOW_VARSCALER);
 
 static int resized;
 static int in_menu;
 
-static int gl_w_prev, gl_h_prev;
+static int gl_w_prev, gl_h_prev, gl_quirks_prev;
 static float gl_vertices[] = {
        -1.0f,  1.0f,  0.0f, // 0    0  1
         1.0f,  1.0f,  0.0f, // 1  ^
 
 void plat_init(void)
 {
+  static const char *hwfilters[] = { "linear", "nearest", NULL };
   const SDL_version *ver;
   int shadow_size;
   int ret;
 
   plat_sdl_quit_cb = quit_cb;
 
+  old_fullscreen = -1; // hack
+
   ret = plat_sdl_init();
   if (ret != 0)
     exit(1);
   plugin_update();
   if (plat_target.vout_method == vout_mode_gl)
     gl_w_prev = plat_sdl_screen->w, gl_h_prev = plat_sdl_screen->h;
+  if (vout_mode_gl != -1)
+    plat_target.hwfilters = hwfilters;
 }
 
 void plat_finish(void)
   int w = in_menu ? g_menuscreen_w : psx_w;
   int h = in_menu ? g_menuscreen_h : psx_h;
 
+  gl_quirks &= ~(GL_QUIRK_SCALING_NEAREST | GL_QUIRK_VSYNC_ON);
+  if (plat_target.hwfilter) // inverted from plat_sdl_gl_scaling()
+    gl_quirks |= GL_QUIRK_SCALING_NEAREST;
+  if (g_opts & OPT_VSYNC)
+    gl_quirks |= GL_QUIRK_VSYNC_ON;
+
   if (plugin_owns_display())
     w = plat_sdl_screen->w, h = plat_sdl_screen->h;
   if (plat_sdl_gl_active) {
-    if (w == gl_w_prev && h == gl_h_prev)
+    if (w == gl_w_prev && h == gl_h_prev && gl_quirks == gl_quirks_prev)
       return;
     gl_finish_pl();
   }
   plat_sdl_gl_active = (gl_init(display, window, &gl_quirks, w, h) == 0);
   if (plat_sdl_gl_active)
-    gl_w_prev = w, gl_h_prev = h;
+    gl_w_prev = w, gl_h_prev = h, gl_quirks_prev = gl_quirks;
   else {
     fprintf(stderr, "warning: could not init GL.\n");
     plat_target.vout_method = 0;
       (plat_target.vout_fullscreen && scaler_changed)) {
     change_mode(g_menuscreen_w, g_menuscreen_h);
   }
-  else
-    overlay_or_gl_check_enable();
+  overlay_or_gl_check_enable();
   handle_scaler_resize(g_menuscreen_w, g_menuscreen_h);
 
   if (old_ovl != plat_sdl_overlay || scaler_changed)
 
   if (plat_target.vout_fullscreen)
     change_mode(fs_w, fs_h);
-  else
-    overlay_or_gl_check_enable();
+  overlay_or_gl_check_enable();
   centered_clear();
 
   for (d = 0; d < IN_MAX_DEVS; d++)