Commit 1ed739c2 authored by Roman Gilg's avatar Roman Gilg

Send present_pixmap and keep idle fence of auto_pixmap

parent bd747e26
Pipeline #26751 failed with stages
in 2 minutes and 27 seconds
......@@ -39,23 +39,6 @@
*
*/
///* Check if window is in the auto list, i.e. being
// * composited by the XServer directly and not by the
// * compositing window manager process.
// */
//static Bool
//present_scanout_has(WindowPtr target, WindowPtr window)
//{
// present_window_priv_ptr target_priv = present_window_priv(target);
// present_window_priv_ptr window_priv;
// xorg_list_for_each_entry(window_priv, &target_priv->auto_scanout_head, auto_scanout_node) {
// if (window_priv->window == window)
// return TRUE;
// }
// return FALSE;
//}
static Bool
present_render_has(WindowPtr target, WindowPtr window)
{
......@@ -75,7 +58,7 @@ present_render_has(WindowPtr target, WindowPtr window)
static present_vblank_ptr
present_comp_queued(present_window_priv_ptr target_priv, uint64_t msc)
{
present_vblank_ptr vblank;
present_vblank_ptr vblank;
xorg_list_for_each_entry(vblank, &target_priv->vblank, window_list) {
ErrorF("present_comp_queued %p : %d | %d\n", vblank->pixmap, vblank->queued, vblank->target_msc == msc);
......@@ -97,12 +80,51 @@ present_comp_queued(present_window_priv_ptr target_priv, uint64_t msc)
return NULL;
}
/* Returns if the window currently or about to auto-compositing other windows.
*/
static Bool
present_comp_is_target(present_window_priv_ptr window_priv)
{
return !xorg_list_is_empty(&window_priv->auto_render_head) ||
!xorg_list_is_empty(&window_priv->auto_scanout_head);
}
static void
present_comp_cleanup_auto_pixmap(present_window_priv_ptr window_priv)
{
if (window_priv->auto_pixmap) {
present_pixmap_idle(window_priv->auto_pixmap,
window_priv->window,
window_priv->auto_serial,
window_priv->auto_idle_fence);
dixDestroyPixmap(window_priv->auto_pixmap, window_priv->auto_pixmap->drawable.id);
}
present_fence_destroy(window_priv->auto_idle_fence);
window_priv->auto_pixmap = NULL;
window_priv->auto_serial = 0;
window_priv->auto_idle_fence = NULL;
}
static void
present_comp_update_auto_pixmap(present_vblank_ptr vblank, present_window_priv_ptr window_priv)
{
present_comp_cleanup_auto_pixmap(window_priv);
window_priv->auto_pixmap = vblank->pixmap;
window_priv->auto_serial = vblank->serial;
window_priv->auto_idle_fence = vblank->idle_fence;
vblank->pixmap->refcnt++;
}
/* On client Present request try to auto composite the vblank into
* the current scanned out target.
*/
Bool
present_comp_auto_client(present_vblank_ptr vblank)
{
ScreenPtr screen = vblank->screen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
WindowPtr target;
present_window_priv_ptr target_priv, window_priv;
present_vblank_ptr target_vblank;
......@@ -119,15 +141,19 @@ present_comp_auto_client(present_vblank_ptr vblank)
if (!target_priv)
return FALSE;
if (window_priv->auto_pixmap)
present_copy_region(&window_priv->auto_pixmap->drawable,
&vblank->pixmap->drawable,
NULL, // TODO: vblank->update ?
0, 0);
target_vblank = present_comp_queued(target_priv, vblank->target_msc);
ErrorF("present_comp_auto_client!! %p : %p : %p | %d\n", window_priv, target_priv, window_priv->auto_pixmap, !!target_vblank);
if (!target_vblank && !target_priv->auto_pixmap)
return FALSE;
if (!present_comp_is_target(window_priv)) {
/* Update auto pixmap */
present_comp_update_auto_pixmap(vblank, window_priv);
}
vblank->auto_comp_ex = TRUE;
ErrorF("present_comp_auto_client!! queued comp vblank: %d\n", !!target_vblank);
if (target_vblank) {
/* A compositor vblank has been queued for the target msc, copy into that one.
......@@ -140,25 +166,35 @@ present_comp_auto_client(present_vblank_ptr vblank)
&vblank->pixmap->drawable,
NULL,
window_priv->window->drawable.x, window_priv->window->drawable.y);
} else {
} else if (vblank->target_msc <= target_priv->msc + 1) {
// TODO: do we need to send damage to compositor so it spins a new composite frame? (only when target_vblank == NULL?)
// RegionPtr damage = &vblank->window->clipList;
// DamageDamageRegion(&target_priv->window->drawable, damage);
// present_copy_region(&window_priv->window->drawable, &vblank->pixmap->drawable, vblank->update, vblank->x_off, vblank->y_off);
}
vblank->update = NULL;
return TRUE;
}
// TODO: calculate x_off, y_off from window positions / difference
present_copy_region(&target_priv->auto_pixmap->drawable,
&vblank->pixmap->drawable,
NULL,
window_priv->window->drawable.x, window_priv->window->drawable.y);
/* Returns if the window currently or about to auto-compositing other windows.
*/
static Bool
present_comp_is_target(present_window_priv_ptr window_priv)
{
return !xorg_list_is_empty(&window_priv->auto_render_head) ||
!xorg_list_is_empty(&window_priv->auto_scanout_head);
/* Create a new internal Present run with the updated composite window */
screen_priv->present_pixmap(target,
target_priv->auto_pixmap,
0,
NULL,
NULL,
0, 0,
NULL,
NULL, NULL, /* fences */
0, /* options */
vblank->target_msc, /* window_msc */
0, 0, /* divisor, remainder */
NULL, 0,
TRUE);
}
return TRUE;
}
static void
......@@ -169,9 +205,7 @@ present_comp_cleanup_auto(present_window_priv_ptr window_priv)
if (window_priv->auto_render_target || window_priv->auto_scanout_target)
return;
if (window_priv->auto_pixmap)
dixDestroyPixmap(window_priv->auto_pixmap, window_priv->auto_pixmap->drawable.id);
window_priv->auto_pixmap = NULL;
present_comp_cleanup_auto_pixmap(window_priv);
}
/* Switch window from being composited automatically
......@@ -181,7 +215,7 @@ present_comp_cleanup_auto(present_window_priv_ptr window_priv)
static void
present_comp_to_manager(present_window_priv_ptr window_priv)
{
ErrorF("present_comp_to_manager %p\n", window_priv);
ErrorF("present_comp_to_manager %p\n", window_priv->window);
present_copy_region(&window_priv->window->drawable,
&window_priv->auto_pixmap->drawable,
NULL,
......@@ -198,23 +232,16 @@ static void
present_comp_auto_composite_client(present_vblank_ptr vblank, present_window_priv_ptr window_priv)
{
DrawablePtr drawable = &window_priv->window->drawable;
ScreenPtr screen = drawable->pScreen;
if (!window_priv->auto_pixmap) {
window_priv->auto_pixmap = (*screen->CreatePixmap)
(screen, drawable->width, drawable->height, drawable->depth, CREATE_PIXMAP_USAGE_SCRATCH);
present_copy_region(&window_priv->auto_pixmap->drawable,
drawable,
NULL,
0, 0);
}
if (window_priv->auto_pixmap)
drawable = &window_priv->auto_pixmap->drawable;
window_priv->auto_scanout_target = vblank->window;
ErrorF("present_comp_auto_composite_client %p %p\n", window_priv->auto_scanout_target, vblank->window);
// TODO: calculate x_off, y_off from window positions / difference
present_copy_region(&vblank->pixmap->drawable,
&window_priv->auto_pixmap->drawable,
drawable,
NULL,
window_priv->window->drawable.x, window_priv->window->drawable.y);
}
......@@ -227,17 +254,23 @@ present_comp_execute_target(present_vblank_ptr vblank)
present_window_priv_ptr target_priv = present_window_priv(vblank->window);
present_window_priv_ptr window_priv, tmp;
ErrorF("present_comp_execute_target: is_target: %d auto_comp: %d auto_pixmap: %d\n", present_comp_is_target(target_priv), vblank->auto_comp, !!target_priv->auto_pixmap);
if (!present_comp_is_target(target_priv))
return;
// if (vblank->auto_comp)
// /* vblank is product of an auto-composited client change */
// return;
if (vblank->auto_comp)
/* vblank is product of an auto-composited client change */
return;
/* Update auto pixmap */
present_comp_update_auto_pixmap(vblank, target_priv);
vblank->auto_comp_ex = TRUE;
// TODO: do this not here, but already earlier on present_comp_set_auto_list?
/* Clean up windows, which have been auto composited previously, but not anymore. */
xorg_list_for_each_entry_safe(window_priv, tmp, &target_priv->auto_scanout_head, auto_scanout_node) {
ErrorF("present_comp_auto_target scanout list %p\n", &window_priv);
ErrorF("present_comp_execute_target scanout list target: %p client: %p\n", target_priv->window, window_priv->window);
if (!present_render_has(target_priv->window, window_priv->window))
present_comp_to_manager(window_priv);
}
......@@ -256,7 +289,7 @@ present_comp_execute_target(present_vblank_ptr vblank)
// TODO: or do we prescribe a set_auto_list request always before?
// xorg_list_del(&target_priv->auto_render_head);
// present_comp_cleanup_auto(target_priv);
present_comp_cleanup_auto(target_priv);
}
static int
......@@ -271,7 +304,7 @@ present_comp_set_parent_auto_list(present_window_priv_ptr parent, int nwindows,
if (rc != Success)
return rc;
/* check if 'parent' is really the parent window for all windows? */
/* check if 'parent' is really the parent window for all windows (or an overlay)? */
// TODO ^^
window_priv = present_window_priv(window); // TODO: or should we create on the fly?
......@@ -327,6 +360,9 @@ present_comp_remove_from_render(present_window_priv_ptr window_priv)
if (element == window_priv)
xorg_list_del(&element->auto_render_node);
}
/* check if this was the last auto composited window */
present_comp_cleanup_auto(target_priv);
}
static void
......@@ -345,6 +381,9 @@ present_comp_remove_from_scanout(present_window_priv_ptr window_priv)
if (element == window_priv)
xorg_list_del(&element->auto_scanout_node);
}
/* check if this was the last auto composited window */
present_comp_cleanup_auto(target_priv);
}
void
......@@ -355,10 +394,9 @@ present_comp_cleanup_window(WindowPtr window)
if (!window_priv)
return;
if (window_priv->auto_pixmap)
dixDestroyPixmap(window_priv->auto_pixmap, window_priv->auto_pixmap->drawable.id);
window_priv->auto_pixmap = NULL;
present_comp_cleanup_auto_pixmap(window_priv);
present_comp_remove_from_render(window_priv);
present_comp_remove_from_scanout(window_priv);
// TODO: if this is the compositor window, do cleanup for auto composited clients
}
......@@ -88,17 +88,17 @@ present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc)
return;
}
if (!present_comp_auto_client(vblank)) {
/* Can not auto composite, fall back to standard copy. */
present_copy_region(&window->drawable, &vblank->pixmap->drawable, vblank->update, vblank->x_off, vblank->y_off);
/* present_copy_region sticks the region into a scratch GC,
* which is then freed, freeing the region
*/
vblank->update = NULL;
screen_priv->flush(window);
}
if (present_comp_auto_client(vblank))
return;
/* Can not auto composite, fall back to standard copy. */
present_copy_region(&window->drawable, &vblank->pixmap->drawable, vblank->update, vblank->x_off, vblank->y_off);
/* present_copy_region sticks the region into a scratch GC,
* which is then freed, freeing the region
*/
vblank->update = NULL;
screen_priv->flush(window);
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
}
......@@ -122,6 +122,9 @@ present_execute_post(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
else
mode = PresentCompleteModeCopy;
present_vblank_notify(vblank, vblank->kind, mode, ust, crtc_msc);
ErrorF("present_execute_post %p | %d %d\n", vblank->window, vblank->auto_comp, vblank->auto_comp_ex);
if (!vblank->auto_comp)
present_vblank_notify(vblank, vblank->kind, mode, ust, crtc_msc);
present_vblank_destroy(vblank);
}
......@@ -90,7 +90,8 @@ struct present_vblank {
PresentFlipReason reason; /* reason for which flip is not possible */
Bool has_suboptimal; /* whether client can support SuboptimalCopy mode */
Bool auto_comp; /* internal vblank for a compositing window */
Bool auto_comp_ex; /* vblank auto composites */
Bool auto_comp; /* internal vblank for a compositing window */
};
typedef struct present_screen_priv present_screen_priv_rec, *present_screen_priv_ptr;
......@@ -239,8 +240,8 @@ struct present_window_priv {
WindowPtr auto_render_target;
PixmapPtr auto_pixmap; /* Compositor copy for subsequent client updates */
PixmapPtr auto_pending_pixmap;
PixmapPtr auto_render_pixmap;
CARD32 auto_serial;
struct present_fence *auto_idle_fence;
/* Used for window flips */
uint64_t event_id;
......
......@@ -292,7 +292,7 @@ present_flip_idle(ScreenPtr screen, Bool auto_comp)
if (!auto_comp)
present_pixmap_idle(screen_priv->flip_pixmap, screen_priv->flip_window,
screen_priv->flip_serial, screen_priv->flip_idle_fence);
if (screen_priv->flip_idle_fence)
if (screen_priv->flip_idle_fence && !auto_comp)
present_fence_destroy(screen_priv->flip_idle_fence);
dixDestroyPixmap(screen_priv->flip_pixmap, screen_priv->flip_pixmap->drawable.id);
screen_priv->flip_crtc = NULL;
......@@ -376,7 +376,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
assert (vblank == screen_priv->flip_pending);
present_flip_idle(screen, vblank->auto_comp);
present_flip_idle(screen, vblank->auto_comp || vblank->auto_comp_ex);
xorg_list_del(&vblank->event_queue);
......@@ -601,17 +601,15 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
present_set_tree_pixmap(vblank->window, NULL, vblank->pixmap);
present_set_tree_pixmap(screen->root, NULL, vblank->pixmap);
if (!vblank->auto_comp) {
/* Report update region as damaged
*/
if (vblank->update) {
damage = vblank->update;
RegionIntersect(damage, damage, &window->clipList);
} else
damage = &window->clipList;
DamageDamageRegion(&vblank->window->drawable, damage);
}
/* Report update region as damaged
*/
if (vblank->update) {
damage = vblank->update;
RegionIntersect(damage, damage, &window->clipList);
} else
damage = &window->clipList;
DamageDamageRegion(&vblank->window->drawable, damage);
return;
}
......@@ -734,10 +732,11 @@ present_scmd_pixmap(WindowPtr window,
vblank->pixmap->drawable.id, vblank->window->drawable.id,
vblank->crtc));
if (!vblank->auto_comp)
if (!vblank->auto_comp && !vblank->auto_comp_ex) {
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
present_fence_destroy(vblank->idle_fence);
dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
present_fence_destroy(vblank->idle_fence);
}
vblank->pixmap = NULL;
vblank->idle_fence = NULL;
......
......@@ -57,6 +57,7 @@ present_get_window_priv(WindowPtr window, Bool create)
window_priv->window = window;
window_priv->crtc = PresentCrtcNeverSet;
window_priv->auto_idle_fence = NULL;
dixSetPrivate(&window->devPrivates, &present_window_private_key, window_priv);
return window_priv;
}
......
......@@ -31,8 +31,10 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_
{
int n;
if (vblank->window)
if (vblank->window) {
ErrorF("present_vblank_notify: window: %p msc: %lu\n", vblank->window, crtc_msc);
present_send_complete_notify(vblank->window, kind, mode, vblank->serial, ust, crtc_msc - vblank->msc_offset);
}
for (n = 0; n < vblank->num_notifies; n++) {
WindowPtr window = vblank->notifies[n].window;
CARD32 serial = vblank->notifies[n].serial;
......@@ -193,7 +195,7 @@ present_vblank_destroy(present_vblank_ptr vblank)
if (vblank->wait_fence)
present_fence_destroy(vblank->wait_fence);
if (vblank->idle_fence)
if (vblank->idle_fence && !vblank->auto_comp && !vblank->auto_comp_ex)
present_fence_destroy(vblank->idle_fence);
if (vblank->notifies)
......
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