GTK: Swap glFenceSync for sync control extension.
This commit is contained in:
parent
70484ba612
commit
7b310a0cf4
@ -151,8 +151,8 @@ int Snes9xConfig::load_defaults ()
|
|||||||
npot_textures = false;
|
npot_textures = false;
|
||||||
use_shaders = false;
|
use_shaders = false;
|
||||||
shader_filename.clear ();
|
shader_filename.clear ();
|
||||||
sync_every_frame = false;
|
use_glfinish = false;
|
||||||
use_fences = false;
|
use_sync_control = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Snes9x Variables */
|
/* Snes9x Variables */
|
||||||
@ -267,8 +267,8 @@ int Snes9xConfig::save_config_file ()
|
|||||||
#undef z
|
#undef z
|
||||||
#define z "OpenGL::"
|
#define z "OpenGL::"
|
||||||
outbool (cf, z"VSync", sync_to_vblank);
|
outbool (cf, z"VSync", sync_to_vblank);
|
||||||
outbool (cf, z"glFinish", sync_every_frame);
|
outbool (cf, z"glFinish", use_glfinish);
|
||||||
outbool (cf, z"glFenceSync", use_fences);
|
outbool (cf, z"SyncControl", use_sync_control);
|
||||||
outbool (cf, z"UsePixelBufferObjects", use_pbos);
|
outbool (cf, z"UsePixelBufferObjects", use_pbos);
|
||||||
cf.SetInt (z"PixelBufferObjectBitDepth", pbo_format);
|
cf.SetInt (z"PixelBufferObjectBitDepth", pbo_format);
|
||||||
outbool (cf, z"UseNonPowerOfTwoTextures", npot_textures);
|
outbool (cf, z"UseNonPowerOfTwoTextures", npot_textures);
|
||||||
@ -497,8 +497,8 @@ int Snes9xConfig::load_config_file ()
|
|||||||
#undef z
|
#undef z
|
||||||
#define z "OpenGL::"
|
#define z "OpenGL::"
|
||||||
inbool (z"VSync", sync_to_vblank);
|
inbool (z"VSync", sync_to_vblank);
|
||||||
inbool (z"glFinish", sync_every_frame);
|
inbool (z"glFinish", use_glfinish);
|
||||||
inbool (z"glFenceSync", use_fences);
|
inbool (z"SyncControl", use_sync_control);
|
||||||
inbool (z"UsePixelBufferObjects", use_pbos);
|
inbool (z"UsePixelBufferObjects", use_pbos);
|
||||||
inint (z"PixelBufferObjectBitDepth", pbo_format);
|
inint (z"PixelBufferObjectBitDepth", pbo_format);
|
||||||
inbool (z"UseNonPowerOfTwoTextures", npot_textures);
|
inbool (z"UseNonPowerOfTwoTextures", npot_textures);
|
||||||
|
@ -151,8 +151,8 @@ class Snes9xConfig
|
|||||||
bool npot_textures;
|
bool npot_textures;
|
||||||
bool use_shaders;
|
bool use_shaders;
|
||||||
std::string shader_filename;
|
std::string shader_filename;
|
||||||
bool sync_every_frame;
|
bool use_glfinish;
|
||||||
bool use_fences;
|
bool use_sync_control;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JoyDevice **joystick;
|
JoyDevice **joystick;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "gtk_2_3_compat.h"
|
#include "gtk_2_3_compat.h"
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
#include <epoxy/glx_generated.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -88,7 +89,6 @@ S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver (Snes9xWindow *window,
|
|||||||
this->window = window;
|
this->window = window;
|
||||||
this->config = config;
|
this->config = config;
|
||||||
this->drawing_area = GTK_WIDGET (window->drawing_area);
|
this->drawing_area = GTK_WIDGET (window->drawing_area);
|
||||||
fence = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
void S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
@ -609,9 +609,6 @@ bool S9xOpenGLDisplayDriver::create_context()
|
|||||||
else
|
else
|
||||||
core = false;
|
core = false;
|
||||||
|
|
||||||
if (version >= 31 || epoxy_has_gl_extension ("GL_ARB_sync"))
|
|
||||||
fences = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,17 +663,11 @@ void S9xOpenGLDisplayDriver::swap_buffers ()
|
|||||||
{
|
{
|
||||||
context->swap_buffers ();
|
context->swap_buffers ();
|
||||||
|
|
||||||
if (config->sync_every_frame && !config->use_fences)
|
if (config->use_glfinish && !config->use_sync_control)
|
||||||
{
|
{
|
||||||
usleep (0);
|
usleep (0);
|
||||||
glFinish ();
|
glFinish ();
|
||||||
}
|
}
|
||||||
else if (config->use_fences && fences)
|
|
||||||
{
|
|
||||||
if (fence)
|
|
||||||
glDeleteSync (fence);
|
|
||||||
fence = glFenceSync (GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S9xOpenGLDisplayDriver::deinit ()
|
void S9xOpenGLDisplayDriver::deinit ()
|
||||||
@ -740,14 +731,10 @@ int S9xOpenGLDisplayDriver::query_availability ()
|
|||||||
|
|
||||||
bool S9xOpenGLDisplayDriver::is_ready ()
|
bool S9xOpenGLDisplayDriver::is_ready ()
|
||||||
{
|
{
|
||||||
if (!fence)
|
if (context->ready())
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (glClientWaitSync (fence, GL_SYNC_FLUSH_COMMANDS_BIT, 0) == GL_TIMEOUT_EXPIRED)
|
return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
glDeleteSync (fence);
|
|
||||||
fence = NULL;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,6 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver
|
|||||||
|
|
||||||
OpenGLContext *context;
|
OpenGLContext *context;
|
||||||
|
|
||||||
GLsync fence;
|
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
GTKGLXContext glx;
|
GTKGLXContext glx;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
For further information, consult the LICENSE file in the root directory.
|
For further information, consult the LICENSE file in the root directory.
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#include <epoxy/glx_generated.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -22,6 +23,8 @@ GTKGLXContext::GTKGLXContext ()
|
|||||||
|
|
||||||
version_major = -1;
|
version_major = -1;
|
||||||
version_minor = -1;
|
version_minor = -1;
|
||||||
|
use_oml_sync_control = false;
|
||||||
|
ust = msc = sbc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GTKGLXContext::~GTKGLXContext ()
|
GTKGLXContext::~GTKGLXContext ()
|
||||||
@ -120,6 +123,9 @@ bool GTKGLXContext::create_context ()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strstr(extensions, "GLX_OML_sync_control") && gui_config->use_sync_control)
|
||||||
|
use_oml_sync_control = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,9 +150,27 @@ void GTKGLXContext::resize ()
|
|||||||
|
|
||||||
void GTKGLXContext::swap_buffers ()
|
void GTKGLXContext::swap_buffers ()
|
||||||
{
|
{
|
||||||
|
if (use_oml_sync_control)
|
||||||
|
glXGetSyncValuesOML(display, xid, &ust, &msc, &sbc);
|
||||||
|
|
||||||
glXSwapBuffers (display, xid);
|
glXSwapBuffers (display, xid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GTKGLXContext::ready()
|
||||||
|
{
|
||||||
|
if (use_oml_sync_control)
|
||||||
|
{
|
||||||
|
int64 ust, msc, sbc;
|
||||||
|
glXGetSyncValuesOML(display, xid, &ust, &msc, &sbc);
|
||||||
|
|
||||||
|
if (sbc != this->sbc || msc - this->msc > 2)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void GTKGLXContext::make_current ()
|
void GTKGLXContext::make_current ()
|
||||||
{
|
{
|
||||||
glXMakeCurrent (display, xid, context);
|
glXMakeCurrent (display, xid, context);
|
||||||
|
@ -23,6 +23,7 @@ class GTKGLXContext : public OpenGLContext
|
|||||||
void swap_buffers ();
|
void swap_buffers ();
|
||||||
void swap_interval (int frames);
|
void swap_interval (int frames);
|
||||||
void make_current ();
|
void make_current ();
|
||||||
|
bool ready();
|
||||||
|
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
|
||||||
@ -40,6 +41,9 @@ class GTKGLXContext : public OpenGLContext
|
|||||||
|
|
||||||
int version_major;
|
int version_major;
|
||||||
int version_minor;
|
int version_minor;
|
||||||
|
|
||||||
|
bool use_oml_sync_control;
|
||||||
|
int64_t ust, msc, sbc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -19,6 +19,7 @@ class OpenGLContext
|
|||||||
virtual void swap_buffers () = 0;
|
virtual void swap_buffers () = 0;
|
||||||
virtual void swap_interval (int frames) = 0;
|
virtual void swap_interval (int frames) = 0;
|
||||||
virtual void make_current () = 0;
|
virtual void make_current () = 0;
|
||||||
|
virtual bool ready() { return true; };
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
@ -715,8 +715,8 @@ Snes9xPreferences::move_settings_to_dialog ()
|
|||||||
|
|
||||||
#ifdef USE_OPENGL
|
#ifdef USE_OPENGL
|
||||||
set_check ("sync_to_vblank", config->sync_to_vblank);
|
set_check ("sync_to_vblank", config->sync_to_vblank);
|
||||||
set_check ("sync_every_frame", config->sync_every_frame);
|
set_check ("use_glfinish", config->use_glfinish);
|
||||||
set_check ("use_fences", config->use_fences);
|
set_check ("use_sync_control", config->use_sync_control);
|
||||||
set_check ("use_pbos", config->use_pbos);
|
set_check ("use_pbos", config->use_pbos);
|
||||||
set_combo ("pixel_format", config->pbo_format == 16 ? 0 : 1);
|
set_combo ("pixel_format", config->pbo_format == 16 ? 0 : 1);
|
||||||
set_check ("npot_textures", config->npot_textures);
|
set_check ("npot_textures", config->npot_textures);
|
||||||
@ -859,6 +859,7 @@ Snes9xPreferences::get_settings_from_dialog ()
|
|||||||
int pbo_format = get_combo ("pixel_format") == 1 ? 32 : 16;
|
int pbo_format = get_combo ("pixel_format") == 1 ? 32 : 16;
|
||||||
|
|
||||||
if (config->sync_to_vblank != get_check ("sync_to_vblank") ||
|
if (config->sync_to_vblank != get_check ("sync_to_vblank") ||
|
||||||
|
config->use_sync_control != get_check ("use_sync_control") ||
|
||||||
config->npot_textures != get_check ("npot_textures") ||
|
config->npot_textures != get_check ("npot_textures") ||
|
||||||
config->use_pbos != get_check ("use_pbos") ||
|
config->use_pbos != get_check ("use_pbos") ||
|
||||||
config->pbo_format != pbo_format ||
|
config->pbo_format != pbo_format ||
|
||||||
@ -872,8 +873,8 @@ Snes9xPreferences::get_settings_from_dialog ()
|
|||||||
config->use_pbos = get_check ("use_pbos");
|
config->use_pbos = get_check ("use_pbos");
|
||||||
config->npot_textures = get_check ("npot_textures");
|
config->npot_textures = get_check ("npot_textures");
|
||||||
config->use_shaders = get_check ("use_shaders");
|
config->use_shaders = get_check ("use_shaders");
|
||||||
config->sync_every_frame = get_check ("sync_every_frame");
|
config->use_glfinish = get_check ("use_glfinish");
|
||||||
config->use_fences = get_check ("use_fences");
|
config->use_sync_control = get_check ("use_sync_control");
|
||||||
|
|
||||||
config->shader_filename = get_entry_text ("fragment_shader");
|
config->shader_filename = get_entry_text ("fragment_shader");
|
||||||
|
|
||||||
|
@ -4,28 +4,30 @@
|
|||||||
For further information, consult the LICENSE file in the root directory.
|
For further information, consult the LICENSE file in the root directory.
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
|
#include <epoxy/egl_generated.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gtk_s9x.h"
|
||||||
#include "gtk_wayland_egl_context.h"
|
#include "gtk_wayland_egl_context.h"
|
||||||
|
|
||||||
static void wl_global (void *data,
|
static void wl_global(void *data,
|
||||||
struct wl_registry *wl_registry,
|
struct wl_registry *wl_registry,
|
||||||
uint32_t name,
|
uint32_t name,
|
||||||
const char *interface,
|
const char *interface,
|
||||||
uint32_t version)
|
uint32_t version)
|
||||||
{
|
{
|
||||||
WaylandEGLContext *wl = (WaylandEGLContext *) data;
|
WaylandEGLContext *wl = (WaylandEGLContext *)data;
|
||||||
|
|
||||||
if (!strcmp (interface, "wl_compositor"))
|
if (!strcmp(interface, "wl_compositor"))
|
||||||
wl->compositor = (struct wl_compositor *) wl_registry_bind (wl_registry, name, &wl_compositor_interface, 3);
|
wl->compositor = (struct wl_compositor *)wl_registry_bind(wl_registry, name, &wl_compositor_interface, 3);
|
||||||
else if (!strcmp (interface, "wl_subcompositor"))
|
else if (!strcmp(interface, "wl_subcompositor"))
|
||||||
wl->subcompositor = (struct wl_subcompositor *) wl_registry_bind (wl_registry, name, &wl_subcompositor_interface, 1);
|
wl->subcompositor = (struct wl_subcompositor *)wl_registry_bind(wl_registry, name, &wl_subcompositor_interface, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void wl_global_remove (void *data,
|
static void wl_global_remove(void *data,
|
||||||
struct wl_registry *wl_registry,
|
struct wl_registry *wl_registry,
|
||||||
uint32_t name)
|
uint32_t name)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,79 +36,81 @@ static const struct wl_registry_listener wl_registry_listener = {
|
|||||||
wl_global_remove
|
wl_global_remove
|
||||||
};
|
};
|
||||||
|
|
||||||
WaylandEGLContext::WaylandEGLContext ()
|
WaylandEGLContext::WaylandEGLContext()
|
||||||
{
|
{
|
||||||
display = NULL;
|
display = NULL;
|
||||||
registry = NULL;
|
registry = NULL;
|
||||||
compositor = NULL;
|
compositor = NULL;
|
||||||
subcompositor = NULL;
|
subcompositor = NULL;
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
child = NULL;
|
child = NULL;
|
||||||
region = NULL;
|
region = NULL;
|
||||||
subsurface = NULL;
|
subsurface = NULL;
|
||||||
egl_display = NULL;
|
egl_display = NULL;
|
||||||
egl_surface = NULL;
|
egl_surface = NULL;
|
||||||
egl_context = NULL;
|
egl_context = NULL;
|
||||||
egl_config = NULL;
|
egl_config = NULL;
|
||||||
egl_window = NULL;
|
egl_window = NULL;
|
||||||
|
use_sync_control = false;
|
||||||
|
ust = msc = sbc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaylandEGLContext::~WaylandEGLContext ()
|
WaylandEGLContext::~WaylandEGLContext()
|
||||||
{
|
{
|
||||||
if (subsurface)
|
if (subsurface)
|
||||||
wl_subsurface_destroy (subsurface);
|
wl_subsurface_destroy(subsurface);
|
||||||
|
|
||||||
if (region)
|
if (region)
|
||||||
wl_region_destroy (region);
|
wl_region_destroy(region);
|
||||||
|
|
||||||
if (child)
|
if (child)
|
||||||
wl_surface_destroy (child);
|
wl_surface_destroy(child);
|
||||||
|
|
||||||
if (egl_context)
|
if (egl_context)
|
||||||
eglDestroyContext (egl_display, egl_context);
|
eglDestroyContext(egl_display, egl_context);
|
||||||
|
|
||||||
if (egl_surface)
|
if (egl_surface)
|
||||||
eglDestroySurface (egl_display, egl_surface);
|
eglDestroySurface(egl_display, egl_surface);
|
||||||
|
|
||||||
if (egl_window)
|
if (egl_window)
|
||||||
wl_egl_window_destroy (egl_window);
|
wl_egl_window_destroy(egl_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaylandEGLContext::attach (GtkWidget *widget)
|
bool WaylandEGLContext::attach(GtkWidget *widget)
|
||||||
{
|
{
|
||||||
GdkWindow *window = gtk_widget_get_window (widget);
|
GdkWindow *window = gtk_widget_get_window(widget);
|
||||||
|
|
||||||
if (!GDK_IS_WAYLAND_WINDOW (window))
|
if (!GDK_IS_WAYLAND_WINDOW(window))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
gdk_window = window;
|
gdk_window = window;
|
||||||
gdk_window_get_geometry (gdk_window, &x, &y, &width, &height);
|
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||||
|
|
||||||
display = gdk_wayland_display_get_wl_display (gdk_window_get_display (gdk_window));
|
display = gdk_wayland_display_get_wl_display(gdk_window_get_display(gdk_window));
|
||||||
parent = gdk_wayland_window_get_wl_surface (gdk_window);
|
parent = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||||
registry = wl_display_get_registry (display);
|
registry = wl_display_get_registry(display);
|
||||||
|
|
||||||
wl_registry_add_listener (registry, &wl_registry_listener, this);
|
wl_registry_add_listener(registry, &wl_registry_listener, this);
|
||||||
wl_display_roundtrip (display);
|
wl_display_roundtrip(display);
|
||||||
|
|
||||||
if (!compositor || !subcompositor)
|
if (!compositor || !subcompositor)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
child = wl_compositor_create_surface (compositor);
|
child = wl_compositor_create_surface(compositor);
|
||||||
region = wl_compositor_create_region (compositor);
|
region = wl_compositor_create_region(compositor);
|
||||||
subsurface = wl_subcompositor_get_subsurface (subcompositor, child, parent);
|
subsurface = wl_subcompositor_get_subsurface(subcompositor, child, parent);
|
||||||
|
|
||||||
wl_surface_set_input_region (child, region);
|
wl_surface_set_input_region(child, region);
|
||||||
wl_subsurface_set_desync (subsurface);
|
wl_subsurface_set_desync(subsurface);
|
||||||
wl_subsurface_set_position (subsurface, x, y);
|
wl_subsurface_set_position(subsurface, x, y);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaylandEGLContext::create_context ()
|
bool WaylandEGLContext::create_context()
|
||||||
{
|
{
|
||||||
int scale = gdk_window_get_scale_factor (gdk_window);
|
int scale = gdk_window_get_scale_factor(gdk_window);
|
||||||
gdk_window_get_geometry (gdk_window, &x, &y, &width, &height);
|
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||||
|
|
||||||
EGLint surface_attribs[] = {
|
EGLint surface_attribs[] = {
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||||
@ -133,74 +137,96 @@ bool WaylandEGLContext::create_context ()
|
|||||||
if (!subsurface)
|
if (!subsurface)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
egl_display = eglGetDisplay ((EGLNativeDisplayType) display);
|
egl_display = eglGetDisplay((EGLNativeDisplayType)display);
|
||||||
eglInitialize (egl_display, NULL, NULL);
|
eglInitialize(egl_display, NULL, NULL);
|
||||||
|
|
||||||
if (!eglChooseConfig (egl_display, surface_attribs, &egl_config, 1, &num_configs))
|
if (!eglChooseConfig(egl_display, surface_attribs, &egl_config, 1, &num_configs))
|
||||||
{
|
{
|
||||||
printf ("Couldn't find matching config.\n");
|
printf("Couldn't find matching config.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
eglBindAPI (EGL_OPENGL_API);
|
eglBindAPI(EGL_OPENGL_API);
|
||||||
|
|
||||||
egl_window = wl_egl_window_create (child, width * scale, height * scale);
|
egl_window = wl_egl_window_create(child, width * scale, height * scale);
|
||||||
if (!egl_window)
|
if (!egl_window)
|
||||||
{
|
{
|
||||||
printf ("Couldn't create window.\n");
|
printf("Couldn't create window.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_surface = eglCreateWindowSurface (egl_display, egl_config, (EGLNativeWindowType) egl_window, NULL);
|
egl_surface = eglCreateWindowSurface(egl_display, egl_config, (EGLNativeWindowType)egl_window, NULL);
|
||||||
if (!egl_surface)
|
if (!egl_surface)
|
||||||
{
|
{
|
||||||
printf ("Couldn't create surface.\n");
|
printf("Couldn't create surface.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, core_context_attribs);
|
egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, core_context_attribs);
|
||||||
if (!egl_context)
|
if (!egl_context)
|
||||||
{
|
{
|
||||||
egl_context = eglCreateContext (egl_display, egl_config, EGL_NO_CONTEXT, compatibility_context_attribs);
|
egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, compatibility_context_attribs);
|
||||||
if (!egl_context)
|
if (!egl_context)
|
||||||
{
|
{
|
||||||
printf ("Couldn't create context.\n");
|
printf("Couldn't create context.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_set_buffer_scale (child, scale);
|
if (gui_config->use_sync_control && epoxy_has_egl_extension(egl_display, "EGL_CHROMIUM_sync_control"))
|
||||||
gdk_window_invalidate_rect (gdk_window, NULL, false);
|
{
|
||||||
|
eglGetSyncValuesCHROMIUM = (PEGLGETSYNCVALUESCHROMIUM)eglGetProcAddress("eglGetSyncValuesCHROMIUM");
|
||||||
|
if (eglGetSyncValuesCHROMIUM)
|
||||||
|
use_sync_control = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_surface_set_buffer_scale(child, scale);
|
||||||
|
gdk_window_invalidate_rect(gdk_window, NULL, false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEGLContext::resize ()
|
void WaylandEGLContext::resize()
|
||||||
{
|
{
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
gdk_window_get_geometry (gdk_window, &x, &y, &width, &height);
|
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||||
scale = gdk_window_get_scale_factor (gdk_window);
|
scale = gdk_window_get_scale_factor(gdk_window);
|
||||||
|
|
||||||
wl_egl_window_resize (egl_window, width * scale, height * scale, 0, 0);
|
wl_egl_window_resize(egl_window, width * scale, height * scale, 0, 0);
|
||||||
wl_subsurface_set_position (subsurface, x, y);
|
wl_subsurface_set_position(subsurface, x, y);
|
||||||
|
|
||||||
make_current ();
|
make_current();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEGLContext::swap_buffers ()
|
void WaylandEGLContext::swap_buffers()
|
||||||
{
|
{
|
||||||
eglSwapBuffers (egl_display, egl_surface);
|
if (use_sync_control)
|
||||||
wl_surface_commit (child);
|
eglGetSyncValuesCHROMIUM(egl_display, egl_surface, &ust, &msc, &sbc);
|
||||||
|
|
||||||
|
eglSwapBuffers(egl_display, egl_surface);
|
||||||
|
wl_surface_commit(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEGLContext::make_current ()
|
bool WaylandEGLContext::ready()
|
||||||
{
|
{
|
||||||
eglMakeCurrent (egl_display, egl_surface, egl_surface, egl_context);
|
if (use_sync_control)
|
||||||
|
{
|
||||||
|
EGLuint64KHR ust, msc, sbc;
|
||||||
|
eglGetSyncValuesCHROMIUM(egl_display, egl_surface, &ust, &msc, &sbc);
|
||||||
|
if (sbc != this->sbc || msc - this->msc > 2)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEGLContext::swap_interval (int frames)
|
void WaylandEGLContext::make_current()
|
||||||
{
|
{
|
||||||
eglSwapInterval (egl_display, frames);
|
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WaylandEGLContext::swap_interval(int frames)
|
||||||
|
{
|
||||||
|
eglSwapInterval(egl_display, frames);
|
||||||
|
}
|
||||||
|
@ -7,22 +7,24 @@
|
|||||||
#ifndef __GTK_WAYLAND_EGL_CONTEXT_H
|
#ifndef __GTK_WAYLAND_EGL_CONTEXT_H
|
||||||
#define __GTK_WAYLAND_EGL_CONTEXT_H
|
#define __GTK_WAYLAND_EGL_CONTEXT_H
|
||||||
|
|
||||||
#include <wayland-egl.h>
|
|
||||||
#include <epoxy/egl.h>
|
#include <epoxy/egl.h>
|
||||||
|
#include <epoxy/egl_generated.h>
|
||||||
|
#include <wayland-egl.h>
|
||||||
|
|
||||||
#include "gtk_opengl_context.h"
|
#include "gtk_opengl_context.h"
|
||||||
|
|
||||||
class WaylandEGLContext : public OpenGLContext
|
class WaylandEGLContext : public OpenGLContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WaylandEGLContext ();
|
WaylandEGLContext();
|
||||||
~WaylandEGLContext ();
|
~WaylandEGLContext();
|
||||||
bool attach (GtkWidget *widget);
|
bool attach(GtkWidget *widget);
|
||||||
bool create_context ();
|
bool create_context();
|
||||||
void resize ();
|
void resize();
|
||||||
void swap_buffers ();
|
void swap_buffers();
|
||||||
void swap_interval (int frames);
|
void swap_interval(int frames);
|
||||||
void make_current ();
|
void make_current();
|
||||||
|
bool ready();
|
||||||
|
|
||||||
GdkWindow *gdk_window;
|
GdkWindow *gdk_window;
|
||||||
|
|
||||||
@ -39,9 +41,14 @@ class WaylandEGLContext : public OpenGLContext
|
|||||||
EGLDisplay egl_display;
|
EGLDisplay egl_display;
|
||||||
EGLSurface egl_surface;
|
EGLSurface egl_surface;
|
||||||
EGLContext egl_context;
|
EGLContext egl_context;
|
||||||
EGLConfig egl_config;
|
EGLConfig egl_config;
|
||||||
|
|
||||||
wl_egl_window *egl_window;
|
wl_egl_window *egl_window;
|
||||||
|
|
||||||
|
typedef EGLBoolean (*PEGLGETSYNCVALUESCHROMIUM)(EGLDisplay, EGLSurface, EGLuint64KHR *, EGLuint64KHR *, EGLuint64KHR *);
|
||||||
|
PEGLGETSYNCVALUESCHROMIUM eglGetSyncValuesCHROMIUM;
|
||||||
|
bool use_sync_control;
|
||||||
|
EGLuint64KHR ust, msc, sbc;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3777,7 +3777,7 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="sync_every_frame">
|
<object class="GtkCheckButton" id="use_glfinish">
|
||||||
<property name="label" translatable="yes">Reduce input lag with glFinish</property>
|
<property name="label" translatable="yes">Reduce input lag with glFinish</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
@ -3792,12 +3792,12 @@
|
|||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<object class="GtkCheckButton" id="use_fences">
|
<object class="GtkCheckButton" id="use_sync_control">
|
||||||
<property name="label" translatable="yes">Reduce input lag with glFenceSync</property>
|
<property name="label" translatable="yes">Reduce input lag with sync control</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="receives_default">False</property>
|
<property name="receives_default">False</property>
|
||||||
<property name="tooltip_text" translatable="yes">Sync the program with the video output after every displayed frame to reduce input latency, but allow GUI events to occur in the meantime</property>
|
<property name="tooltip_text" translatable="yes">More modern method for syncing the program with the video output to reduce input latency. Allows GUI events to occur in the meantime</property>
|
||||||
<property name="draw_indicator">True</property>
|
<property name="draw_indicator">True</property>
|
||||||
</object>
|
</object>
|
||||||
<packing>
|
<packing>
|
||||||
|
Loading…
Reference in New Issue
Block a user