summaryrefslogtreecommitdiff
path: root/present
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2015-02-14 09:58:43 +0000
committerHans de Goede <hdegoede@redhat.com>2016-06-17 11:21:30 +0200
commitfbe660b7652b945bdd8e3eb0780179d83cc7de96 (patch)
tree8ade0158bed441a78c2257913cf3ebdb485d2b35 /present
parentc6511d0142040654140bdedd6f03d43af0abba21 (diff)
present: Improve scaling of vblank handler
With large numbers of queued vblank, the list iteration on every interupt dominates processing time. If we reorder the list to be in ascending event order, then not only is also likely to be in order for notification queries (i.e. the notification will be near the start of the list), we can also stop iterating when past the target event_id. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de@gmail.com> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Diffstat (limited to 'present')
-rw-r--r--present/present.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/present/present.c b/present/present.c
index 105e2bf47..2ae7d3a80 100644
--- a/present/present.c
+++ b/present/present.c
@@ -517,19 +517,22 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
void
present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc)
{
- present_vblank_ptr vblank, tmp;
+ present_vblank_ptr vblank;
int s;
if (!event_id)
return;
DebugPresent(("\te %lld ust %lld msc %lld\n", event_id, ust, msc));
- xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
- if (vblank->event_id == event_id) {
+ xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) {
+ int64_t match = event_id - vblank->event_id;
+ if (match == 0) {
present_execute(vblank, ust, msc);
return;
}
+ if (match < 0)
+ break;
}
- xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) {
+ xorg_list_for_each_entry(vblank, &present_flip_queue, event_queue) {
if (vblank->event_id == event_id) {
present_flip_notify(vblank, ust, msc);
return;
@@ -943,7 +946,7 @@ present_pixmap(WindowPtr window,
vblank->pixmap->drawable.id, vblank->window->drawable.id,
target_crtc, vblank->flip, vblank->sync_flip, vblank->serial));
- xorg_list_add(&vblank->event_queue, &present_exec_queue);
+ xorg_list_append(&vblank->event_queue, &present_exec_queue);
vblank->queued = TRUE;
if (msc_is_after(target_msc, crtc_msc)) {
ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
@@ -967,7 +970,7 @@ no_mem:
void
present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
{
- present_vblank_ptr vblank, tmp;
+ present_vblank_ptr vblank;
if (crtc == NULL)
present_fake_abort_vblank(screen, event_id, msc);
@@ -978,14 +981,17 @@ present_abort_vblank(ScreenPtr screen, RRCrtcPtr crtc, uint64_t event_id, uint64
(*screen_priv->info->abort_vblank) (crtc, event_id, msc);
}
- xorg_list_for_each_entry_safe(vblank, tmp, &present_exec_queue, event_queue) {
- if (vblank->event_id == event_id) {
+ xorg_list_for_each_entry(vblank, &present_exec_queue, event_queue) {
+ int64_t match = event_id - vblank->event_id;
+ if (match == 0) {
xorg_list_del(&vblank->event_queue);
vblank->queued = FALSE;
return;
}
+ if (match < 0)
+ break;
}
- xorg_list_for_each_entry_safe(vblank, tmp, &present_flip_queue, event_queue) {
+ xorg_list_for_each_entry(vblank, &present_flip_queue, event_queue) {
if (vblank->event_id == event_id) {
xorg_list_del(&vblank->event_queue);
return;