mirror of https://github.com/snes9xgit/snes9x.git
Gtk/OpenGL/Wayland: Support fractional scale.
This commit is contained in:
parent
f1286eda4c
commit
aa2a46f87b
|
@ -89,18 +89,12 @@ S9xOpenGLDisplayDriver::S9xOpenGLDisplayDriver(Snes9xWindow *window, Snes9xConfi
|
|||
void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int stride_in_pixels)
|
||||
{
|
||||
Gtk::Allocation allocation = drawing_area->get_allocation();
|
||||
|
||||
if (output_window_width != allocation.get_width() ||
|
||||
output_window_height != allocation.get_height())
|
||||
{
|
||||
resize();
|
||||
}
|
||||
|
||||
int scale_factor = drawing_area->get_scale_factor();
|
||||
|
||||
allocation.set_width(allocation.get_width() * scale_factor);
|
||||
allocation.set_height(allocation.get_height() * scale_factor);
|
||||
|
||||
if (!legacy)
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texmap);
|
||||
|
@ -113,8 +107,8 @@ void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int
|
|||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
S9xRect content = S9xApplyAspect(width, height, allocation.get_width(), allocation.get_height());
|
||||
glViewport(content.x, allocation.get_height() - content.y - content.h, content.w, content.h);
|
||||
S9xRect content = S9xApplyAspect(width, height, context->width, context->height);
|
||||
glViewport(content.x, context->height - content.y - content.h, content.w, content.h);
|
||||
window->set_mouseable_area(content.x, content.y, content.w, content.h);
|
||||
|
||||
update_texture_size(width, height);
|
||||
|
@ -124,7 +118,7 @@ void S9xOpenGLDisplayDriver::update(uint16_t *buffer, int width, int height, int
|
|||
|
||||
if (using_glsl_shaders)
|
||||
{
|
||||
glsl_shader->render(texmap, width, height, content.x, allocation.get_height() - content.y - content.h, content.w, content.h, S9xViewportCallback);
|
||||
glsl_shader->render(texmap, width, height, content.x, context->height - content.y - content.h, content.w, content.h, S9xViewportCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -349,8 +343,9 @@ void S9xOpenGLDisplayDriver::resize()
|
|||
{
|
||||
context->resize();
|
||||
context->swap_interval(config->sync_to_vblank);
|
||||
output_window_width = context->width;
|
||||
output_window_height = context->height;
|
||||
Gtk::Allocation allocation = drawing_area->get_allocation();
|
||||
output_window_width = allocation.get_width();
|
||||
output_window_height = allocation.get_height();
|
||||
}
|
||||
|
||||
bool S9xOpenGLDisplayDriver::create_context()
|
||||
|
@ -378,9 +373,6 @@ bool S9xOpenGLDisplayDriver::create_context()
|
|||
if (!context->create_context())
|
||||
return false;
|
||||
|
||||
output_window_width = context->width;
|
||||
output_window_height = context->height;
|
||||
|
||||
context->make_current();
|
||||
|
||||
legacy = false;
|
||||
|
|
|
@ -9,71 +9,20 @@
|
|||
|
||||
#include "gtk_s9x.h"
|
||||
#include "gtk_wayland_egl_context.h"
|
||||
#include "wayland-idle-inhibit-unstable-v1.h"
|
||||
|
||||
static void wl_global(void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
WaylandEGLContext *wl = (WaylandEGLContext *)data;
|
||||
|
||||
if (!strcmp(interface, "wl_compositor"))
|
||||
wl->compositor = (struct wl_compositor *)wl_registry_bind(wl_registry, name, &wl_compositor_interface, 3);
|
||||
else if (!strcmp(interface, "wl_subcompositor"))
|
||||
wl->subcompositor = (struct wl_subcompositor *)wl_registry_bind(wl_registry, name, &wl_subcompositor_interface, 1);
|
||||
else if (!strcmp(interface, zwp_idle_inhibit_manager_v1_interface.name))
|
||||
wl->idle_inhibit_manager = (struct zwp_idle_inhibit_manager_v1 *)wl_registry_bind(wl_registry, name, &zwp_idle_inhibit_manager_v1_interface, 1);
|
||||
}
|
||||
|
||||
static void wl_global_remove(void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener wl_registry_listener = {
|
||||
wl_global,
|
||||
wl_global_remove
|
||||
};
|
||||
|
||||
WaylandEGLContext::WaylandEGLContext()
|
||||
{
|
||||
display = NULL;
|
||||
registry = NULL;
|
||||
compositor = NULL;
|
||||
subcompositor = NULL;
|
||||
parent = NULL;
|
||||
child = NULL;
|
||||
region = NULL;
|
||||
subsurface = NULL;
|
||||
egl_display = NULL;
|
||||
egl_surface = NULL;
|
||||
egl_context = NULL;
|
||||
egl_config = NULL;
|
||||
egl_window = NULL;
|
||||
idle_inhibit_manager = NULL;
|
||||
idle_inhibitor = NULL;
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
WaylandEGLContext::~WaylandEGLContext()
|
||||
{
|
||||
if (idle_inhibitor)
|
||||
zwp_idle_inhibitor_v1_destroy(idle_inhibitor);
|
||||
|
||||
if (idle_inhibit_manager)
|
||||
zwp_idle_inhibit_manager_v1_destroy(idle_inhibit_manager);
|
||||
|
||||
if (subsurface)
|
||||
wl_subsurface_destroy(subsurface);
|
||||
|
||||
if (region)
|
||||
wl_region_destroy(region);
|
||||
|
||||
if (child)
|
||||
wl_surface_destroy(child);
|
||||
|
||||
if (egl_context)
|
||||
eglDestroyContext(egl_display, egl_context);
|
||||
|
||||
|
@ -91,41 +40,14 @@ bool WaylandEGLContext::attach(GtkWidget *widget)
|
|||
if (!GDK_IS_WAYLAND_WINDOW(window))
|
||||
return false;
|
||||
|
||||
gdk_window = window;
|
||||
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||
|
||||
display = gdk_wayland_display_get_wl_display(gdk_window_get_display(gdk_window));
|
||||
parent = gdk_wayland_window_get_wl_surface(gdk_window);
|
||||
registry = wl_display_get_registry(display);
|
||||
|
||||
wl_registry_add_listener(registry, &wl_registry_listener, this);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
if (!compositor || !subcompositor)
|
||||
return false;
|
||||
|
||||
child = wl_compositor_create_surface(compositor);
|
||||
region = wl_compositor_create_region(compositor);
|
||||
subsurface = wl_subcompositor_get_subsurface(subcompositor, child, parent);
|
||||
|
||||
wl_surface_set_input_region(child, region);
|
||||
wl_subsurface_set_desync(subsurface);
|
||||
wl_subsurface_set_position(subsurface, x, y);
|
||||
|
||||
if (idle_inhibit_manager && gui_config->prevent_screensaver)
|
||||
{
|
||||
printf("Inhibiting screensaver.\n");
|
||||
zwp_idle_inhibit_manager_v1_create_inhibitor(idle_inhibit_manager, child);
|
||||
}
|
||||
wayland_surface = std::make_unique<WaylandSurface>();
|
||||
wayland_surface->attach(widget);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WaylandEGLContext::create_context()
|
||||
{
|
||||
int scale = gdk_window_get_scale_factor(gdk_window);
|
||||
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||
|
||||
EGLint surface_attribs[] = {
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
|
||||
EGL_RED_SIZE, 8,
|
||||
|
@ -148,10 +70,7 @@ bool WaylandEGLContext::create_context()
|
|||
|
||||
EGLint num_configs = 0;
|
||||
|
||||
if (!subsurface)
|
||||
return false;
|
||||
|
||||
egl_display = eglGetDisplay((EGLNativeDisplayType)display);
|
||||
egl_display = eglGetDisplay((EGLNativeDisplayType)wayland_surface->display);
|
||||
eglInitialize(egl_display, NULL, NULL);
|
||||
|
||||
if (!eglChooseConfig(egl_display, surface_attribs, &egl_config, 1, &num_configs))
|
||||
|
@ -161,7 +80,8 @@ bool WaylandEGLContext::create_context()
|
|||
}
|
||||
eglBindAPI(EGL_OPENGL_API);
|
||||
|
||||
egl_window = wl_egl_window_create(child, width * scale, height * scale);
|
||||
std::tie(width, height) = wayland_surface->get_size();
|
||||
egl_window = wl_egl_window_create(wayland_surface->child, width, height);
|
||||
if (!egl_window)
|
||||
{
|
||||
printf("Couldn't create window.\n");
|
||||
|
@ -186,21 +106,15 @@ bool WaylandEGLContext::create_context()
|
|||
}
|
||||
}
|
||||
|
||||
wl_surface_set_buffer_scale(child, scale);
|
||||
gdk_window_invalidate_rect(gdk_window, NULL, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WaylandEGLContext::resize()
|
||||
{
|
||||
int scale;
|
||||
|
||||
gdk_window_get_geometry(gdk_window, &x, &y, &width, &height);
|
||||
scale = gdk_window_get_scale_factor(gdk_window);
|
||||
|
||||
wl_egl_window_resize(egl_window, width * scale, height * scale, 0, 0);
|
||||
wl_subsurface_set_position(subsurface, x, y);
|
||||
wayland_surface->resize();
|
||||
|
||||
std::tie(width, height) = wayland_surface->get_size();
|
||||
wl_egl_window_resize(egl_window, width, height, 0, 0);
|
||||
|
||||
make_current();
|
||||
}
|
||||
|
@ -208,7 +122,7 @@ void WaylandEGLContext::resize()
|
|||
void WaylandEGLContext::swap_buffers()
|
||||
{
|
||||
eglSwapBuffers(egl_display, egl_surface);
|
||||
wl_surface_commit(child);
|
||||
wl_surface_commit(wayland_surface->child);
|
||||
}
|
||||
|
||||
bool WaylandEGLContext::ready()
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
#define __GTK_WAYLAND_EGL_CONTEXT_H
|
||||
|
||||
#include "gtk_opengl_context.h"
|
||||
#include "gtk_wayland_surface.h"
|
||||
#include "gtk_compat.h"
|
||||
|
||||
#include <epoxy/egl.h>
|
||||
#include <memory>
|
||||
#include <wayland-egl.h>
|
||||
|
||||
class WaylandEGLContext : public OpenGLContext
|
||||
|
@ -28,16 +30,6 @@ class WaylandEGLContext : public OpenGLContext
|
|||
|
||||
GdkWindow *gdk_window;
|
||||
|
||||
struct wl_display *display;
|
||||
struct wl_registry *registry;
|
||||
struct wl_compositor *compositor;
|
||||
struct wl_subcompositor *subcompositor;
|
||||
|
||||
struct wl_surface *parent;
|
||||
struct wl_surface *child;
|
||||
struct wl_subsurface *subsurface;
|
||||
struct wl_region *region;
|
||||
|
||||
EGLDisplay egl_display;
|
||||
EGLSurface egl_surface;
|
||||
EGLContext egl_context;
|
||||
|
@ -45,8 +37,7 @@ class WaylandEGLContext : public OpenGLContext
|
|||
|
||||
wl_egl_window *egl_window;
|
||||
|
||||
struct zwp_idle_inhibit_manager_v1 *idle_inhibit_manager;
|
||||
struct zwp_idle_inhibitor_v1 *idle_inhibitor;
|
||||
std::unique_ptr<WaylandSurface> wayland_surface;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -147,6 +147,8 @@ bool WaylandSurface::attach(GtkWidget *widget)
|
|||
zwp_idle_inhibit_manager_v1_create_inhibitor(idle_inhibit_manager, child);
|
||||
}
|
||||
|
||||
resize();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue