[PATCH 1/2] present: Improve scaling of vblank handler
Mario Kleiner
mario.kleiner.de at gmail.com
Fri May 8 16:23:30 PDT 2015
On 02/14/2015 10:58 AM, Chris Wilson wrote:
> 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 at chris-wilson.co.uk>
> ---
> present/present.c | 24 +++++++++++++++---------
> 1 file changed, 15 insertions(+), 9 deletions(-)
>
> diff --git a/present/present.c b/present/present.c
> index ba88f79..b132f4d 100644
> --- a/present/present.c
> +++ b/present/present.c
> @@ -482,19 +482,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;
> @@ -887,7 +890,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 ((pixmap && target_msc >= crtc_msc) || (!pixmap && target_msc > crtc_msc)) {
> ret = present_queue_vblank(screen, target_crtc, vblank->event_id, target_msc);
> @@ -911,7 +914,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);
> @@ -922,14 +925,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;
>
Looks good to me, also no problems during testing on top of current
master, so
Reviewed-and-tested-by: Mario Kleiner <mario.kleiner.de at gmail.com>
-mario
More information about the xorg-devel
mailing list