xwayland: Enable Present extension support also without glamor
This allows e.g. xfwm4 --vblank=xpresent to hit the page flip path instead of copies. In the future, Mesa might also use the Present extension with software rendering.
This commit is contained in:
parent
17986658bf
commit
abe3a08245
|
@ -9,6 +9,7 @@ srcs = [
|
|||
'xwayland-glamor.h',
|
||||
'xwayland-pixmap.c',
|
||||
'xwayland-pixmap.h',
|
||||
'xwayland-present.c',
|
||||
'xwayland-present.h',
|
||||
'xwayland-screen.c',
|
||||
'xwayland-screen.h',
|
||||
|
@ -107,7 +108,6 @@ if build_glamor
|
|||
if gbm_dep.found()
|
||||
srcs += [
|
||||
'xwayland-glamor-gbm.c',
|
||||
'xwayland-present.c'
|
||||
]
|
||||
endif
|
||||
if build_eglstream
|
||||
|
|
|
@ -97,9 +97,6 @@ xwl_glamor_check_flip(WindowPtr present_window, PixmapPtr pixmap)
|
|||
if (pixmap->drawable.depth != backing_pixmap->drawable.depth)
|
||||
return FALSE;
|
||||
|
||||
if (!xwl_glamor_pixmap_get_wl_buffer(pixmap))
|
||||
return FALSE;
|
||||
|
||||
if (xwl_screen->egl_backend->check_flip)
|
||||
return xwl_screen->egl_backend->check_flip(pixmap);
|
||||
|
||||
|
|
|
@ -25,14 +25,17 @@
|
|||
|
||||
#include <xwayland-config.h>
|
||||
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
#include <glamor.h>
|
||||
#endif
|
||||
#include <windowstr.h>
|
||||
#include <present.h>
|
||||
|
||||
#include "xwayland-present.h"
|
||||
#include "xwayland-screen.h"
|
||||
#include "xwayland-shm.h"
|
||||
#include "xwayland-window.h"
|
||||
#include "xwayland-pixmap.h"
|
||||
#include "glamor.h"
|
||||
|
||||
#include "tearing-control-v1-client-protocol.h"
|
||||
|
||||
|
@ -608,7 +611,13 @@ xwl_present_abort_vblank(ScreenPtr screen,
|
|||
static void
|
||||
xwl_present_flush(WindowPtr window)
|
||||
{
|
||||
glamor_block_handler(window->drawable.pScreen);
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
ScreenPtr screen = window->drawable.pScreen;
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
|
||||
if (xwl_screen->glamor)
|
||||
glamor_block_handler(screen);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -670,6 +679,9 @@ xwl_present_check_flip(RRCrtcPtr crtc,
|
|||
present_window->drawable.height != pixmap->drawable.height)
|
||||
return FALSE;
|
||||
|
||||
if (!xwl_pixmap_get_wl_buffer(pixmap))
|
||||
return FALSE;
|
||||
|
||||
/* Window must be same region as toplevel window */
|
||||
if ( !RegionEqual(&present_window->winSize, &toplvl_window->winSize) )
|
||||
return FALSE;
|
||||
|
@ -678,8 +690,11 @@ xwl_present_check_flip(RRCrtcPtr crtc,
|
|||
if (!RegionEqual(&present_window->clipList, &present_window->winSize))
|
||||
return FALSE;
|
||||
|
||||
if (!xwl_glamor_check_flip(present_window, pixmap))
|
||||
#ifdef XWL_HAS_GLAMOR
|
||||
if (xwl_window->xwl_screen->glamor &&
|
||||
!xwl_glamor_check_flip(present_window, pixmap))
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
/* Can't flip if the window pixmap doesn't match the xwl_window parent
|
||||
* window's, e.g. because a client redirected this window or one of its
|
||||
|
@ -766,7 +781,7 @@ xwl_present_flip(present_vblank_ptr vblank, RegionPtr damage)
|
|||
if (!xwl_window)
|
||||
return FALSE;
|
||||
|
||||
buffer = xwl_glamor_pixmap_get_wl_buffer(pixmap);
|
||||
buffer = xwl_pixmap_get_wl_buffer(pixmap);
|
||||
if (!buffer) {
|
||||
ErrorF("present: Error getting buffer\n");
|
||||
return FALSE;
|
||||
|
@ -1053,12 +1068,8 @@ xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window)
|
|||
Bool
|
||||
xwl_present_init(ScreenPtr screen)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
present_screen_priv_ptr screen_priv;
|
||||
|
||||
if (!xwl_screen->glamor || !xwl_screen->egl_backend)
|
||||
return FALSE;
|
||||
|
||||
if (!present_screen_register_priv_keys())
|
||||
return FALSE;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#include "xwayland-types.h"
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
struct xwl_present_window {
|
||||
WindowPtr window;
|
||||
|
||||
|
@ -71,6 +70,4 @@ Bool xwl_present_init(ScreenPtr screen);
|
|||
void xwl_present_cleanup(WindowPtr window);
|
||||
void xwl_present_unrealize_window(struct xwl_present_window *xwl_present_window);
|
||||
|
||||
#endif /* GLAMOR_HAS_GBM */
|
||||
|
||||
#endif /* XWAYLAND_PRESENT_H */
|
||||
|
|
|
@ -1015,11 +1015,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
|
|||
xwl_screen->glamor = XWL_GLAMOR_NONE;
|
||||
}
|
||||
}
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (xwl_screen->glamor)
|
||||
xwl_screen->present = xwl_present_init(pScreen);
|
||||
#endif /* GLAMOR_HAS_GBM */
|
||||
#endif /* XWL_HAS_GLAMOR */
|
||||
#endif
|
||||
|
||||
xwl_screen->present = xwl_present_init(pScreen);
|
||||
|
||||
if (!xwl_screen->glamor) {
|
||||
xwl_screen->CreateScreenResources = pScreen->CreateScreenResources;
|
||||
|
|
|
@ -213,6 +213,28 @@ shm_format_for_depth(int depth)
|
|||
}
|
||||
}
|
||||
|
||||
static Bool
|
||||
dimensions_match_toplevel_window(ScreenPtr screen, int width, int height)
|
||||
{
|
||||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
WindowPtr toplevel;
|
||||
|
||||
if (xwl_screen->rootless)
|
||||
toplevel = screen->root->firstChild;
|
||||
else
|
||||
toplevel = screen->root;
|
||||
|
||||
while (toplevel) {
|
||||
if (width == toplevel->drawable.width &&
|
||||
height == toplevel->drawable.height)
|
||||
return TRUE;
|
||||
|
||||
toplevel = toplevel->nextSib;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const struct wl_buffer_listener xwl_shm_buffer_listener = {
|
||||
xwl_pixmap_buffer_release_cb,
|
||||
};
|
||||
|
@ -230,8 +252,9 @@ xwl_shm_create_pixmap(ScreenPtr screen,
|
|||
int fd;
|
||||
|
||||
if (hint == CREATE_PIXMAP_USAGE_GLYPH_PICTURE ||
|
||||
(!xwl_screen->rootless && hint != CREATE_PIXMAP_USAGE_BACKING_PIXMAP) ||
|
||||
(width == 0 && height == 0) || depth < 15)
|
||||
(width == 0 && height == 0) || depth < 15 ||
|
||||
(hint != CREATE_PIXMAP_USAGE_BACKING_PIXMAP &&
|
||||
!dimensions_match_toplevel_window(screen, width, height)))
|
||||
return fbCreatePixmap(screen, width, height, depth, hint);
|
||||
|
||||
stride = PixmapBytePad(width, depth);
|
||||
|
|
|
@ -188,7 +188,6 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
|
|||
|
||||
xwl_screen = xwl_window->xwl_screen;
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (xwl_window->present_flipped) {
|
||||
/* This damage is from a Present flip, which already committed a new
|
||||
* buffer for the surface, so we don't need to do anything in response
|
||||
|
@ -198,7 +197,6 @@ damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data)
|
|||
xwl_window->present_flipped = FALSE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (xorg_list_is_empty(&xwl_window->link_damage))
|
||||
xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list);
|
||||
|
@ -950,10 +948,7 @@ ensure_surface_for_window(WindowPtr window)
|
|||
dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window);
|
||||
xorg_list_init(&xwl_window->link_damage);
|
||||
xorg_list_add(&xwl_window->link_window, &xwl_screen->window_list);
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
xorg_list_init(&xwl_window->frame_callback_list);
|
||||
#endif
|
||||
|
||||
xwl_window_buffers_init(xwl_window);
|
||||
|
||||
|
@ -1181,10 +1176,8 @@ xwl_unrealize_window(WindowPtr window)
|
|||
|
||||
xwl_dmabuf_feedback_destroy(&xwl_window->feedback);
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (xwl_window->xwl_screen->present)
|
||||
xwl_present_for_each_frame_callback(xwl_window, xwl_present_unrealize_window);
|
||||
#endif
|
||||
|
||||
if (xwl_window->tearing_control)
|
||||
wp_tearing_control_v1_destroy(xwl_window->tearing_control);
|
||||
|
@ -1323,7 +1316,6 @@ frame_callback(void *data,
|
|||
wl_callback_destroy (xwl_window->frame_callback);
|
||||
xwl_window->frame_callback = NULL;
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (xwl_window->xwl_screen->present) {
|
||||
xwl_present_for_each_frame_callback(xwl_window, xwl_present_frame_callback);
|
||||
|
||||
|
@ -1334,7 +1326,6 @@ frame_callback(void *data,
|
|||
if (xwl_window->frame_callback)
|
||||
xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct wl_callback_listener frame_listener = {
|
||||
|
@ -1348,14 +1339,12 @@ xwl_window_create_frame_callback(struct xwl_window *xwl_window)
|
|||
wl_callback_add_listener(xwl_window->frame_callback, &frame_listener,
|
||||
xwl_window);
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
/* If we get called from frame_callback, it will take care of calling
|
||||
* xwl_present_reset_timer.
|
||||
*/
|
||||
if (xwl_window->xwl_screen->present &&
|
||||
!xwl_present_entered_for_each_frame_callback())
|
||||
xwl_present_for_each_frame_callback(xwl_window, xwl_present_reset_timer);
|
||||
#endif
|
||||
}
|
||||
|
||||
Bool
|
||||
|
@ -1365,10 +1354,8 @@ xwl_destroy_window(WindowPtr window)
|
|||
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
|
||||
Bool ret;
|
||||
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
if (xwl_screen->present)
|
||||
xwl_present_cleanup(window);
|
||||
#endif
|
||||
|
||||
screen->DestroyWindow = xwl_screen->DestroyWindow;
|
||||
|
||||
|
|
|
@ -110,10 +110,8 @@ struct xwl_window {
|
|||
OsTimerPtr window_buffers_timer;
|
||||
struct wl_output *wl_output;
|
||||
struct wl_output *wl_output_fullscreen;
|
||||
#ifdef GLAMOR_HAS_GBM
|
||||
struct xorg_list frame_callback_list;
|
||||
Bool present_flipped;
|
||||
#endif
|
||||
#ifdef XWL_HAS_LIBDECOR
|
||||
struct libdecor_frame *libdecor_frame;
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue