mirror of https://github.com/snes9xgit/snes9x.git
Make OpenGL context management separate.
This commit is contained in:
parent
b35d8d9ae5
commit
f9b553638f
|
@ -239,9 +239,11 @@ if OPENGL
|
||||||
snes9x_gtk_SOURCES += \
|
snes9x_gtk_SOURCES += \
|
||||||
src/gtk_display_driver_opengl.cpp \
|
src/gtk_display_driver_opengl.cpp \
|
||||||
src/gtk_display_driver_opengl.h \
|
src/gtk_display_driver_opengl.h \
|
||||||
|
src/gtk_glx_context.cpp \
|
||||||
../shaders/glsl.cpp \
|
../shaders/glsl.cpp \
|
||||||
../shaders/shader_helpers.cpp \
|
../shaders/shader_helpers.cpp \
|
||||||
src/gtk_shader_parameters.cpp
|
src/gtk_shader_parameters.cpp
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if XV
|
if XV
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
#include <gdk/gdkx.h>
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#endif
|
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
#include <libxml/tree.h>
|
#include <libxml/tree.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -13,18 +9,8 @@
|
||||||
#include "gtk_display.h"
|
#include "gtk_display.h"
|
||||||
#include "gtk_display_driver_opengl.h"
|
#include "gtk_display_driver_opengl.h"
|
||||||
#include "gtk_shader_parameters.h"
|
#include "gtk_shader_parameters.h"
|
||||||
|
|
||||||
#include "shaders/shader_helpers.h"
|
#include "shaders/shader_helpers.h"
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
|
||||||
#define ON_WAYLAND(BLOCK) if (GDK_IS_WAYLAND_DISPLAY (gdk_display_get_default())) \
|
|
||||||
{ \
|
|
||||||
BLOCK \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define ON_WAYLAND(BLOCK) do {} while (0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void S9xViewportCallback (int src_width, int src_height,
|
static void S9xViewportCallback (int src_width, int src_height,
|
||||||
int viewport_x, int viewport_y,
|
int viewport_x, int viewport_y,
|
||||||
int viewport_width, int viewport_height,
|
int viewport_width, int viewport_height,
|
||||||
|
@ -65,7 +51,7 @@ S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
if (output_window_width != allocation.width ||
|
if (output_window_width != allocation.width ||
|
||||||
output_window_height != allocation.height)
|
output_window_height != allocation.height)
|
||||||
{
|
{
|
||||||
resize_window (allocation.width, allocation.height);
|
resize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GTK_CHECK_VERSION(3,10,0)
|
#if GTK_CHECK_VERSION(3,10,0)
|
||||||
|
@ -253,7 +239,7 @@ S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
if (using_shaders && using_glsl_shaders)
|
if (using_shaders && using_glsl_shaders)
|
||||||
{
|
{
|
||||||
glsl_shader->render (texmap, width, height, x, allocation.height - y - h, w, h, S9xViewportCallback);
|
glsl_shader->render (texmap, width, height, x, allocation.height - y - h, w, h, S9xViewportCallback);
|
||||||
gl_swap ();
|
swap_buffers ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (using_shaders)
|
else if (using_shaders)
|
||||||
|
@ -281,7 +267,7 @@ S9xOpenGLDisplayDriver::update (int width, int height, int yoffset)
|
||||||
|
|
||||||
glDrawArrays (GL_QUADS, 0, 4);
|
glDrawArrays (GL_QUADS, 0, 4);
|
||||||
|
|
||||||
gl_swap ();
|
swap_buffers ();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -668,117 +654,44 @@ S9xOpenGLDisplayDriver::refresh (int width, int height)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
S9xOpenGLDisplayDriver::resize_window (int width, int height)
|
S9xOpenGLDisplayDriver::resize ()
|
||||||
{
|
{
|
||||||
ON_WAYLAND
|
context->resize ();
|
||||||
(
|
context->swap_interval (config->sync_to_vblank);
|
||||||
wl.resize (width, height);
|
output_window_width = context->width;
|
||||||
wl.swap_interval (config->sync_to_vblank);
|
output_window_height = context->height;
|
||||||
output_window_width = width;
|
|
||||||
output_window_height = height;
|
|
||||||
return;
|
|
||||||
)
|
|
||||||
|
|
||||||
gdk_window_destroy (gdk_window);
|
|
||||||
create_window (width, height);
|
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
glXMakeCurrent (display, xwindow, glx_context);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
swap_control (config->sync_to_vblank);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
S9xOpenGLDisplayDriver::create_window (int width, int height)
|
|
||||||
{
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
GdkWindowAttr window_attr;
|
|
||||||
memset (&window_attr, 0, sizeof (GdkWindowAttr));
|
|
||||||
window_attr.event_mask = GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK;
|
|
||||||
window_attr.width = width;
|
|
||||||
window_attr.height = height;
|
|
||||||
window_attr.x = 0;
|
|
||||||
window_attr.y = 0;
|
|
||||||
window_attr.wclass = GDK_INPUT_OUTPUT;
|
|
||||||
window_attr.window_type = GDK_WINDOW_CHILD;
|
|
||||||
window_attr.visual = gdk_x11_screen_lookup_visual (gtk_widget_get_screen (drawing_area), vi->visualid);
|
|
||||||
|
|
||||||
gdk_window = gdk_window_new (gtk_widget_get_window (drawing_area),
|
|
||||||
&window_attr,
|
|
||||||
GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
|
|
||||||
gdk_window_set_user_data (gdk_window, (gpointer) drawing_area);
|
|
||||||
|
|
||||||
gdk_window_show (gdk_window);
|
|
||||||
xwindow = GDK_COMPAT_WINDOW_XID (gdk_window);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
output_window_width = width;
|
|
||||||
output_window_height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
S9xOpenGLDisplayDriver::init_gl (void)
|
S9xOpenGLDisplayDriver::init_gl (void)
|
||||||
{
|
{
|
||||||
ON_WAYLAND
|
gdk_window = gtk_widget_get_window (drawing_area);
|
||||||
(
|
|
||||||
gdk_window = gtk_widget_get_window (drawing_area);
|
|
||||||
if (!wl.attach (gdk_window))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!wl.create_egl_context (256, 224))
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
return 0;
|
if (GDK_IS_WAYLAND_WINDOW (gdk_window))
|
||||||
|
|
||||||
output_window_width = 256;
|
|
||||||
output_window_height = 224;
|
|
||||||
|
|
||||||
wl.make_current ();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
)
|
|
||||||
|
|
||||||
int glx_attribs[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None };
|
|
||||||
|
|
||||||
display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
|
||||||
|
|
||||||
vi = glXChooseVisual (display, DefaultScreen (display), glx_attribs);
|
|
||||||
|
|
||||||
if (!vi)
|
|
||||||
{
|
{
|
||||||
fprintf (stderr, _("Couldn't find an adequate OpenGL visual.\n"));
|
context = &wl;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
xcolormap = XCreateColormap (display,
|
#ifdef GDK_WINDOWING_X11
|
||||||
GDK_COMPAT_WINDOW_XID (gtk_widget_get_window (drawing_area)),
|
if (GDK_IS_X11_WINDOW (gdk_window))
|
||||||
vi->visual,
|
|
||||||
AllocNone);
|
|
||||||
|
|
||||||
create_window (1, 1);
|
|
||||||
gdk_window_hide (gdk_window);
|
|
||||||
|
|
||||||
glx_context = glXCreateContext (display, vi, 0, 1);
|
|
||||||
|
|
||||||
if (!glx_context)
|
|
||||||
{
|
{
|
||||||
XFreeColormap (display, xcolormap);
|
context = &glx;
|
||||||
gdk_window_destroy (gdk_window);
|
|
||||||
|
|
||||||
fprintf (stderr, _("Couldn't create an OpenGL context.\n"));
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!glXMakeCurrent (display, xwindow, glx_context))
|
if (!context->attach (drawing_area))
|
||||||
{
|
|
||||||
XFreeColormap (display, xcolormap);
|
|
||||||
g_object_unref (gdk_window);
|
|
||||||
gdk_window_destroy (gdk_window);
|
|
||||||
|
|
||||||
fprintf (stderr, "glXMakeCurrent failed.\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
if (!context->create_context ())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
output_window_width = context->width;
|
||||||
|
output_window_height = context->height;
|
||||||
|
|
||||||
|
context->make_current ();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -809,39 +722,13 @@ S9xOpenGLDisplayDriver::init (void)
|
||||||
GFX.Screen = (uint16 *) padded_buffer[0];
|
GFX.Screen = (uint16 *) padded_buffer[0];
|
||||||
GFX.Pitch = image_width * image_bpp;
|
GFX.Pitch = image_width * image_bpp;
|
||||||
|
|
||||||
swap_control (config->sync_to_vblank);
|
context->swap_interval (config->sync_to_vblank);
|
||||||
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
S9xOpenGLDisplayDriver::swap_control (int enable)
|
|
||||||
{
|
|
||||||
enable = enable ? 1 : 0;
|
|
||||||
|
|
||||||
ON_WAYLAND
|
|
||||||
(
|
|
||||||
wl.swap_interval (enable);
|
|
||||||
)
|
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
|
||||||
|
|
||||||
if (strstr (extensions, "EXT_swap_control"))
|
|
||||||
{
|
|
||||||
glXSwapIntervalEXT (display, xwindow, enable);
|
|
||||||
}
|
|
||||||
else if (strstr (extensions, "SGI_swap_control"))
|
|
||||||
{
|
|
||||||
glXSwapIntervalSGI (enable);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16 *
|
uint16 *
|
||||||
S9xOpenGLDisplayDriver::get_next_buffer (void)
|
S9xOpenGLDisplayDriver::get_next_buffer (void)
|
||||||
{
|
{
|
||||||
|
@ -863,24 +750,9 @@ S9xOpenGLDisplayDriver::get_current_buffer (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
S9xOpenGLDisplayDriver::gl_swap (void)
|
S9xOpenGLDisplayDriver::swap_buffers (void)
|
||||||
{
|
{
|
||||||
ON_WAYLAND
|
context->swap_buffers ();
|
||||||
(
|
|
||||||
wl.swap_buffers ();
|
|
||||||
|
|
||||||
if (config->sync_every_frame)
|
|
||||||
{
|
|
||||||
usleep (0);
|
|
||||||
glFinish ();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
)
|
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
glXSwapBuffers (display, xwindow);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (config->sync_every_frame)
|
if (config->sync_every_frame)
|
||||||
{
|
{
|
||||||
|
@ -931,16 +803,6 @@ S9xOpenGLDisplayDriver::deinit (void)
|
||||||
|
|
||||||
glDeleteTextures (1, &texmap);
|
glDeleteTextures (1, &texmap);
|
||||||
|
|
||||||
ON_WAYLAND
|
|
||||||
(
|
|
||||||
return;
|
|
||||||
)
|
|
||||||
|
|
||||||
glXDestroyContext (display, glx_context);
|
|
||||||
gdk_window_destroy (gdk_window);
|
|
||||||
XFree (vi);
|
|
||||||
XFreeColormap (display, xcolormap);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -955,10 +817,12 @@ S9xOpenGLDisplayDriver::query_availability (void)
|
||||||
{
|
{
|
||||||
GdkDisplay *gdk_display = gdk_display_get_default ();
|
GdkDisplay *gdk_display = gdk_display_get_default ();
|
||||||
|
|
||||||
ON_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
(
|
if (GDK_IS_WAYLAND_DISPLAY (gdk_display))
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
)
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
#ifdef GDK_WINDOWING_X11
|
||||||
if (GDK_IS_X11_DISPLAY (gdk_display))
|
if (GDK_IS_X11_DISPLAY (gdk_display))
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
#include "gtk_display_driver.h"
|
#include "gtk_display_driver.h"
|
||||||
|
|
||||||
#include <epoxy/gl.h>
|
#include <epoxy/gl.h>
|
||||||
#ifdef GDK_WINDOWING_X11
|
|
||||||
#include <epoxy/glx.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#include "gtk_opengl_context.h"
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
#include "gtk_glx_context.h"
|
||||||
|
#endif
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
#include "gtk_wayland_egl_context.h"
|
#include "gtk_wayland_egl_context.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -36,29 +37,27 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver
|
||||||
public:
|
public:
|
||||||
S9xOpenGLDisplayDriver (Snes9xWindow *window, Snes9xConfig *config);
|
S9xOpenGLDisplayDriver (Snes9xWindow *window, Snes9xConfig *config);
|
||||||
void refresh (int width, int height);
|
void refresh (int width, int height);
|
||||||
int init (void);
|
int init ();
|
||||||
void deinit (void);
|
void deinit ();
|
||||||
void clear_buffers (void);
|
void clear_buffers ();
|
||||||
void update (int width, int height, int yoffset);
|
void update (int width, int height, int yoffset);
|
||||||
uint16 *get_next_buffer (void);
|
uint16 *get_next_buffer ();
|
||||||
uint16 *get_current_buffer (void);
|
uint16 *get_current_buffer ();
|
||||||
void push_buffer (uint16 *src);
|
void push_buffer (uint16 *src);
|
||||||
void reconfigure (int width, int height);
|
void reconfigure (int width, int height);
|
||||||
void *get_parameters (void);
|
void *get_parameters ();
|
||||||
void save (const char *filename);
|
void save (const char *filename);
|
||||||
static int query_availability (void);
|
static int query_availability ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int opengl_defaults (void);
|
int opengl_defaults ();
|
||||||
void swap_control (int enable);
|
void swap_buffers ();
|
||||||
void gl_swap (void);
|
int pbos_available ();
|
||||||
int pbos_available (void);
|
int shaders_available ();
|
||||||
int shaders_available (void);
|
|
||||||
int load_shaders (const char *);
|
int load_shaders (const char *);
|
||||||
void update_texture_size (int width, int height);
|
void update_texture_size (int width, int height);
|
||||||
int init_gl (void);
|
int init_gl ();
|
||||||
void create_window (int width, int height);
|
void resize ();
|
||||||
void resize_window (int width, int height);
|
|
||||||
|
|
||||||
GLint texture_width;
|
GLint texture_width;
|
||||||
GLint texture_height;
|
GLint texture_height;
|
||||||
|
@ -82,16 +81,13 @@ class S9xOpenGLDisplayDriver : public S9xDisplayDriver
|
||||||
int output_window_width;
|
int output_window_width;
|
||||||
int output_window_height;
|
int output_window_height;
|
||||||
|
|
||||||
#ifdef GDK_WINDOWING_X11
|
OpenGLContext *context;
|
||||||
Display *display;
|
|
||||||
Window xwindow;
|
|
||||||
Colormap xcolormap;
|
|
||||||
XVisualInfo *vi;
|
|
||||||
GLXContext glx_context;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#ifdef GDK_WINDOWING_X11
|
||||||
|
GTKGLXContext glx;
|
||||||
|
#endif
|
||||||
#ifdef GDK_WINDOWING_WAYLAND
|
#ifdef GDK_WINDOWING_WAYLAND
|
||||||
WaylandEGLContext wl;
|
WaylandEGLContext wl;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,146 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "gtk_s9x.h"
|
||||||
|
#include "gtk_glx_context.h"
|
||||||
|
|
||||||
|
GTKGLXContext::GTKGLXContext ()
|
||||||
|
{
|
||||||
|
gdk_display = NULL;
|
||||||
|
parent_gdk_window = NULL;
|
||||||
|
gdk_window = NULL;
|
||||||
|
display = NULL;
|
||||||
|
vi = NULL;
|
||||||
|
context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
GTKGLXContext::~GTKGLXContext ()
|
||||||
|
{
|
||||||
|
if (context)
|
||||||
|
glXDestroyContext (display, context);
|
||||||
|
|
||||||
|
if (gdk_window)
|
||||||
|
gdk_window_destroy (gdk_window);
|
||||||
|
|
||||||
|
if (vi)
|
||||||
|
XFree (vi);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GTKGLXContext::attach (GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GdkScreen *gdk_screen;
|
||||||
|
GdkWindow *window;
|
||||||
|
GLXFBConfig *fbconfigs;
|
||||||
|
int num_fbconfigs;
|
||||||
|
int screen;
|
||||||
|
|
||||||
|
int attribs[] = {
|
||||||
|
GLX_DOUBLEBUFFER, True,
|
||||||
|
GLX_X_RENDERABLE, True,
|
||||||
|
GLX_RED_SIZE, 8,
|
||||||
|
GLX_GREEN_SIZE, 8,
|
||||||
|
GLX_BLUE_SIZE, 8,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
window = gtk_widget_get_window (widget);
|
||||||
|
this->widget = widget;
|
||||||
|
|
||||||
|
if (!GDK_IS_X11_WINDOW (window))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
parent_gdk_window = window;
|
||||||
|
gdk_display = gdk_window_get_display (window);
|
||||||
|
gdk_screen = gdk_window_get_screen (window);
|
||||||
|
screen = gdk_x11_screen_get_screen_number (gdk_screen);
|
||||||
|
display = GDK_DISPLAY_XDISPLAY (gdk_display);
|
||||||
|
|
||||||
|
fbconfigs = glXChooseFBConfig (display, screen, attribs, &num_fbconfigs);
|
||||||
|
if (!fbconfigs || num_fbconfigs < 1)
|
||||||
|
{
|
||||||
|
printf ("Couldn't match a GLX framebuffer config.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
fbconfig = fbconfigs[0];
|
||||||
|
XFree (fbconfigs);
|
||||||
|
|
||||||
|
vi = glXGetVisualFromFBConfig (display, fbconfig);
|
||||||
|
|
||||||
|
gdk_window_get_geometry (window, &x, &y, &width, &height);
|
||||||
|
memset (&window_attr, 0, sizeof (GdkWindowAttr));
|
||||||
|
window_attr.width = width;
|
||||||
|
window_attr.height = height;
|
||||||
|
window_attr.wclass = GDK_INPUT_OUTPUT;
|
||||||
|
window_attr.window_type = GDK_WINDOW_CHILD;
|
||||||
|
window_attr.visual = gdk_x11_screen_lookup_visual (gdk_screen, vi->visualid);
|
||||||
|
|
||||||
|
gdk_window = gdk_window_new (window, &window_attr, GDK_WA_VISUAL);
|
||||||
|
gdk_window_set_user_data (gdk_window, (gpointer) widget);
|
||||||
|
gdk_window_show (gdk_window);
|
||||||
|
xid = GDK_COMPAT_WINDOW_XID (gdk_window);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GTKGLXContext::create_context ()
|
||||||
|
{
|
||||||
|
int context_attribs[] = {
|
||||||
|
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||||
|
GLX_CONTEXT_MINOR_VERSION_ARB, 5,
|
||||||
|
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
context = glXCreateContextAttribsARB (display, fbconfig, NULL, True, context_attribs);
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
{
|
||||||
|
printf ("Couldn't create GLX context.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTKGLXContext::resize ()
|
||||||
|
{
|
||||||
|
gdk_window_get_geometry (parent_gdk_window, &x, &y, &width, &height);
|
||||||
|
|
||||||
|
if (window_attr.width == width && window_attr.height == height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window_attr.width = width;
|
||||||
|
window_attr.height = height;
|
||||||
|
|
||||||
|
gdk_window_destroy (gdk_window);
|
||||||
|
gdk_window = gdk_window_new (parent_gdk_window, &window_attr, GDK_WA_VISUAL);
|
||||||
|
gdk_window_set_user_data (gdk_window, (gpointer) widget);
|
||||||
|
gdk_window_show (gdk_window);
|
||||||
|
xid = GDK_COMPAT_WINDOW_XID (gdk_window);
|
||||||
|
|
||||||
|
make_current ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTKGLXContext::swap_buffers ()
|
||||||
|
{
|
||||||
|
glXSwapBuffers (display, xid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTKGLXContext::make_current ()
|
||||||
|
{
|
||||||
|
glXMakeCurrent (display, xid, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GTKGLXContext::swap_interval (int frames)
|
||||||
|
{
|
||||||
|
const char *extensions = (const char *) glGetString (GL_EXTENSIONS);
|
||||||
|
if (!extensions)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (strstr (extensions, "EXT_swap_control"))
|
||||||
|
glXSwapIntervalEXT (display, xid, frames);
|
||||||
|
else if (strstr (extensions, "SGI_swap_control"))
|
||||||
|
glXSwapIntervalSGI (frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#pragma once
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gdk/gdkx.h>
|
||||||
|
#include <epoxy/glx.h>
|
||||||
|
|
||||||
|
#include "gtk_opengl_context.h"
|
||||||
|
|
||||||
|
struct GTKGLXContext : OpenGLContext
|
||||||
|
{
|
||||||
|
GTKGLXContext ();
|
||||||
|
~GTKGLXContext ();
|
||||||
|
bool attach (GtkWidget *widget);
|
||||||
|
bool create_context ();
|
||||||
|
void resize ();
|
||||||
|
void swap_buffers ();
|
||||||
|
void swap_interval (int frames);
|
||||||
|
void make_current ();
|
||||||
|
|
||||||
|
GtkWidget *widget;
|
||||||
|
|
||||||
|
GdkDisplay *gdk_display;
|
||||||
|
GdkWindow *parent_gdk_window;
|
||||||
|
GdkWindow *gdk_window;
|
||||||
|
GdkWindowAttr window_attr;
|
||||||
|
|
||||||
|
GLXContext context;
|
||||||
|
GLXFBConfig fbconfig;
|
||||||
|
Display *display;
|
||||||
|
XVisualInfo *vi;
|
||||||
|
Window xid;
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
struct OpenGLContext
|
||||||
|
{
|
||||||
|
virtual bool attach (GtkWidget *widget) = 0;
|
||||||
|
virtual bool create_context () = 0;
|
||||||
|
virtual void resize () = 0;
|
||||||
|
virtual void swap_buffers () = 0;
|
||||||
|
virtual void swap_interval (int frames) = 0;
|
||||||
|
virtual void make_current () = 0;
|
||||||
|
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
|
@ -66,15 +66,15 @@ WaylandEGLContext::~WaylandEGLContext ()
|
||||||
wl_egl_window_destroy (egl_window);
|
wl_egl_window_destroy (egl_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaylandEGLContext::attach (GdkWindow *window)
|
bool WaylandEGLContext::attach (GtkWidget *widget)
|
||||||
{
|
{
|
||||||
int x, y, w, h;
|
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, &w, &h);
|
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);
|
||||||
|
@ -97,9 +97,10 @@ bool WaylandEGLContext::attach (GdkWindow *window)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WaylandEGLContext::create_egl_context (int width, int height)
|
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);
|
||||||
|
|
||||||
EGLint surface_attribs[] = {
|
EGLint surface_attribs[] = {
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||||
|
@ -156,14 +157,14 @@ bool WaylandEGLContext::create_egl_context (int width, int height)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaylandEGLContext::resize (int width, int height)
|
void WaylandEGLContext::resize ()
|
||||||
{
|
{
|
||||||
int x, y, w, h, scale;
|
int scale;
|
||||||
|
|
||||||
gdk_window_get_geometry (gdk_window, &x, &y, &w, &h);
|
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, w * scale, h * 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 ();
|
||||||
|
|
|
@ -3,13 +3,15 @@
|
||||||
#include <wayland-egl.h>
|
#include <wayland-egl.h>
|
||||||
#include <epoxy/egl.h>
|
#include <epoxy/egl.h>
|
||||||
|
|
||||||
struct WaylandEGLContext
|
#include "gtk_opengl_context.h"
|
||||||
|
|
||||||
|
struct WaylandEGLContext : OpenGLContext
|
||||||
{
|
{
|
||||||
WaylandEGLContext ();
|
WaylandEGLContext ();
|
||||||
~WaylandEGLContext ();
|
~WaylandEGLContext ();
|
||||||
bool attach (GdkWindow *window);
|
bool attach (GtkWidget *widget);
|
||||||
bool create_egl_context (int width, int height);
|
bool create_context ();
|
||||||
void resize (int width, int height);
|
void resize ();
|
||||||
void swap_buffers ();
|
void swap_buffers ();
|
||||||
void swap_interval (int frames);
|
void swap_interval (int frames);
|
||||||
void make_current ();
|
void make_current ();
|
||||||
|
|
Loading…
Reference in New Issue