Commit bbf6760f authored by Alberts Muktupāvels's avatar Alberts Muktupāvels

compositor: add MetaCompositorXPresent

#13
parent af8278f7
Pipeline #213295 passed with stages
in 13 minutes and 6 seconds
......@@ -30,6 +30,7 @@ variables:
libxext-dev
libxfixes-dev
libxinerama-dev
libxpresent-dev
libxrandr-dev
libxrender-dev
libxres-dev
......
......@@ -155,7 +155,7 @@ AC_CHECK_SIZEOF(__int64)
## byte order
AC_C_BIGENDIAN
METACITY_PC_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION gio-2.0 >= $GLIB_REQUIRED_VERSION pango >= $PANGO_REQUIRED_VERSION gsettings-desktop-schemas >= 3.3.0 xcomposite >= $XCOMPOSITE_REQUIRED_VERSION xfixes xrender xdamage xres"
METACITY_PC_MODULES="gtk+-3.0 >= $GTK_REQUIRED_VERSION gio-2.0 >= $GLIB_REQUIRED_VERSION pango >= $PANGO_REQUIRED_VERSION gsettings-desktop-schemas >= 3.3.0 xcomposite >= $XCOMPOSITE_REQUIRED_VERSION xfixes xrender xdamage xres xpresent"
GLIB_GSETTINGS
......
......@@ -33,6 +33,8 @@ metacity_SOURCES = \
compositor/meta-compositor-none.c \
compositor/meta-compositor-none.h \
compositor/meta-compositor-private.h \
compositor/meta-compositor-xpresent.c \
compositor/meta-compositor-xpresent.h \
compositor/meta-compositor-xrender.c \
compositor/meta-compositor-xrender.h \
compositor/meta-shadow-xrender.c \
......
......@@ -1204,6 +1204,7 @@ not_implemented_cb (MetaCompositorVulkan *vulkan)
compositor = "xrender";
break;
case META_COMPOSITOR_TYPE_XPRESENT:
case META_COMPOSITOR_TYPE_EXTERNAL:
case META_COMPOSITOR_TYPE_VULKAN:
default:
......
/*
* Copyright (C) 2020 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "meta-compositor-xpresent.h"
#include <X11/extensions/Xpresent.h>
#include "display-private.h"
#include "errors.h"
#include "screen-private.h"
#define NUM_BUFFER 2
struct _MetaCompositorXPresent
{
MetaCompositorXRender parent;
int major_opcode;
int event_base;
int error_base;
Picture root_buffers[NUM_BUFFER];
Pixmap root_pixmaps[NUM_BUFFER];
int root_current;
gboolean present_pending;
};
G_DEFINE_TYPE (MetaCompositorXPresent,
meta_compositor_xpresent,
META_TYPE_COMPOSITOR_XRENDER)
static gboolean
meta_compositor_xpresent_manage (MetaCompositor *compositor,
GError **error)
{
MetaCompositorClass *compositor_class;
MetaCompositorXPresent *self;
MetaDisplay *display;
Display *xdisplay;
compositor_class = META_COMPOSITOR_CLASS (meta_compositor_xpresent_parent_class);
if (!compositor_class->manage (compositor, error))
return FALSE;
self = META_COMPOSITOR_XPRESENT (compositor);
display = meta_compositor_get_display (compositor);
xdisplay = meta_display_get_xdisplay (display);
if (!XPresentQueryExtension (xdisplay,
&self->major_opcode,
&self->event_base,
&self->error_base))
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Missing present extension required for compositing");
return FALSE;
}
XPresentSelectInput (xdisplay,
meta_compositor_get_overlay_window (compositor),
PresentCompleteNotifyMask);
return TRUE;
}
static void
meta_compositor_xpresent_process_event (MetaCompositor *compositor,
XEvent *event,
MetaWindow *window)
{
MetaCompositorXPresent *self;
MetaCompositorClass *compositor_class;
self = META_COMPOSITOR_XPRESENT (compositor);
if (event->type == GenericEvent)
{
XGenericEvent *generic_event;
XGenericEventCookie *generic_event_cookie;
MetaDisplay *display;
Display *xdisplay;
generic_event = (XGenericEvent *) event;
generic_event_cookie = (XGenericEventCookie *) generic_event;
display = meta_compositor_get_display (compositor);
xdisplay = meta_display_get_xdisplay (display);
if (generic_event_cookie->extension == self->major_opcode)
{
XGetEventData (xdisplay, generic_event_cookie);
if (generic_event_cookie->evtype == PresentCompleteNotify)
{
meta_compositor_queue_redraw (compositor);
self->present_pending = FALSE;
}
XFreeEventData (xdisplay, generic_event_cookie);
}
}
compositor_class = META_COMPOSITOR_CLASS (meta_compositor_xpresent_parent_class);
compositor_class->process_event (compositor, event, window);
}
static gboolean
meta_compositor_xpresent_ready_to_redraw (MetaCompositor *compositor)
{
MetaCompositorXPresent *self;
self = META_COMPOSITOR_XPRESENT (compositor);
return !self->present_pending;
}
static void
meta_compositor_xpresent_redraw (MetaCompositor *compositor,
XserverRegion all_damage)
{
MetaCompositorXPresent *self;
MetaDisplay *display;
Display *xdisplay;
int result;
self = META_COMPOSITOR_XPRESENT (compositor);
display = meta_compositor_get_display (META_COMPOSITOR (self));
xdisplay = meta_display_get_xdisplay (display);
meta_compositor_xrender_draw (META_COMPOSITOR_XRENDER (compositor),
self->root_buffers[self->root_current],
all_damage);
meta_error_trap_push (display);
XPresentPixmap (xdisplay,
meta_compositor_get_overlay_window (compositor),
self->root_pixmaps[self->root_current],
0,
all_damage,
all_damage,
0,
0,
None,
None,
None,
PresentOptionNone,
0,
1,
0,
NULL,
0);
result = meta_error_trap_pop_with_return (display);
if (result != Success)
{
char error_text[64];
XGetErrorText (xdisplay, result, error_text, 63);
g_warning ("XPresentPixmap failed with error %i (%s)",
result, error_text);
g_unsetenv ("META_COMPOSITOR");
meta_display_update_compositor (display);
return;
}
self->root_current = !self->root_current;
self->present_pending = TRUE;
}
static void
meta_compositor_xpresent_ensure_root_buffers (MetaCompositorXRender *xrender)
{
MetaCompositorXPresent *self;
int i;
self = META_COMPOSITOR_XPRESENT (xrender);
for (i = 0; i < NUM_BUFFER; i++)
{
if (self->root_buffers[i] == None &&
self->root_pixmaps[i] == None)
{
meta_compositor_xrender_create_root_buffer (xrender,
&self->root_pixmaps[i],
&self->root_buffers[i]);
}
}
}
static void
meta_compositor_xpresent_free_root_buffers (MetaCompositorXRender *xrender)
{
MetaCompositorXPresent *self;
MetaDisplay *display;
Display *xdisplay;
int i;
self = META_COMPOSITOR_XPRESENT (xrender);
display = meta_compositor_get_display (META_COMPOSITOR (self));
xdisplay = meta_display_get_xdisplay (display);
for (i = 0; i < NUM_BUFFER; i++)
{
if (self->root_buffers[i] != None)
{
XRenderFreePicture (xdisplay, self->root_buffers[i]);
self->root_buffers[i] = None;
}
if (self->root_pixmaps[i] != None)
{
XFreePixmap (xdisplay, self->root_pixmaps[i]);
self->root_pixmaps[i] = None;
}
}
}
static void
meta_compositor_xpresent_class_init (MetaCompositorXPresentClass *self_class)
{
MetaCompositorClass *compositor_class;
MetaCompositorXRenderClass *xrender_class;
compositor_class = META_COMPOSITOR_CLASS (self_class);
xrender_class = META_COMPOSITOR_XRENDER_CLASS (self_class);
compositor_class->manage = meta_compositor_xpresent_manage;
compositor_class->process_event = meta_compositor_xpresent_process_event;
compositor_class->ready_to_redraw = meta_compositor_xpresent_ready_to_redraw;
compositor_class->redraw = meta_compositor_xpresent_redraw;
xrender_class->ensure_root_buffers = meta_compositor_xpresent_ensure_root_buffers;
xrender_class->free_root_buffers = meta_compositor_xpresent_free_root_buffers;
}
static void
meta_compositor_xpresent_init (MetaCompositorXPresent *self)
{
int i;
for (i = 0; i < NUM_BUFFER; i++)
{
self->root_buffers[i] = None;
self->root_pixmaps[i] = None;
}
}
MetaCompositor *
meta_compositor_xpresent_new (MetaDisplay *display,
GError **error)
{
return g_initable_new (META_TYPE_COMPOSITOR_XPRESENT, NULL, error,
"display", display,
NULL);
}
/*
* Copyright (C) 2020 Alberts Muktupāvels
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef META_COMPOSITOR_XPRESENT_H
#define META_COMPOSITOR_XPRESENT_H
#include "meta-compositor-xrender.h"
G_BEGIN_DECLS
#define META_TYPE_COMPOSITOR_XPRESENT (meta_compositor_xpresent_get_type ())
G_DECLARE_FINAL_TYPE (MetaCompositorXPresent, meta_compositor_xpresent,
META, COMPOSITOR_XPRESENT, MetaCompositorXRender)
MetaCompositor *meta_compositor_xpresent_new (MetaDisplay *display,
GError **error);
G_END_DECLS
#endif
......@@ -68,6 +68,7 @@
#include "compositor/meta-compositor-none.h"
#include "compositor/meta-compositor-xrender.h"
#include "compositor/meta-compositor-xpresent.h"
#include "compositor/meta-compositor-external.h"
#ifdef HAVE_VULKAN
......@@ -278,6 +279,8 @@ get_compositor_type (MetaDisplay *display)
type = META_COMPOSITOR_TYPE_VULKAN;
else if (g_strcmp0 (compositor, "xrender") == 0)
type = META_COMPOSITOR_TYPE_XRENDER;
else if (g_strcmp0 (compositor, "xpresent") == 0)
type = META_COMPOSITOR_TYPE_XPRESENT;
else if (g_strcmp0 (compositor, "external") == 0)
type = META_COMPOSITOR_TYPE_EXTERNAL;
else
......@@ -310,6 +313,10 @@ create_compositor (MetaDisplay *display,
compositor = meta_compositor_xrender_new (display, error);
break;
case META_COMPOSITOR_TYPE_XPRESENT:
compositor = meta_compositor_xpresent_new (display, error);
break;
case META_COMPOSITOR_TYPE_EXTERNAL:
compositor = meta_compositor_external_new (display, error);
break;
......
......@@ -35,6 +35,7 @@ typedef enum
{
META_COMPOSITOR_TYPE_NONE,
META_COMPOSITOR_TYPE_XRENDER,
META_COMPOSITOR_TYPE_XPRESENT, /*< skip >*/
META_COMPOSITOR_TYPE_EXTERNAL, /*< skip >*/
META_COMPOSITOR_TYPE_VULKAN /*< skip >*/
} MetaCompositorType;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment