mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2025-12-20 07:00:09 +01:00
backend-drm: Count and display KMS page flips
This patch counts the page flips (either in atomic or legacy page flips) for DRM outputs and prints them using the drm-backend scope. Similar to the frame callback timer counter this installs a counter that periodically computes page flips per a pre-defined interval. This also includes a perfetto counter to display these in perfetto. Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
parent
5f1c43de29
commit
cda8de1089
5 changed files with 80 additions and 1 deletions
|
|
@ -272,6 +272,11 @@ struct drm_backend {
|
|||
bool has_underlay;
|
||||
|
||||
struct weston_log_scope *debug;
|
||||
|
||||
struct {
|
||||
uint32_t frame_counter_interval;
|
||||
struct wl_event_source *pageflip_timer_counter;
|
||||
} perf_page_flips_stats;
|
||||
};
|
||||
|
||||
struct drm_mode {
|
||||
|
|
@ -601,6 +606,12 @@ struct drm_output {
|
|||
|
||||
struct wl_event_source *pageflip_timer;
|
||||
|
||||
/* how many page flips */
|
||||
uint32_t page_flips_counted;
|
||||
|
||||
/* how many page flips / interval */
|
||||
float page_flips_per_timer_interval;
|
||||
|
||||
bool is_virtual;
|
||||
void (*virtual_destroy)(struct weston_output *base);
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "shared/string-helpers.h"
|
||||
#include "shared/weston-drm-fourcc.h"
|
||||
#include "output-capture.h"
|
||||
#include "weston-trace.h"
|
||||
#include "pixman-renderer.h"
|
||||
#include "pixel-formats.h"
|
||||
#include "libbacklight.h"
|
||||
|
|
@ -189,6 +190,64 @@ drm_output_pageflip_timer_create(struct drm_output *output)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
pageflip_timer_counter_handler(void *data)
|
||||
{
|
||||
struct drm_backend *b = data;
|
||||
struct weston_compositor *ec = b->compositor;
|
||||
struct weston_output *output_base;
|
||||
|
||||
wl_list_for_each(output_base, &ec->output_list, link) {
|
||||
struct drm_output *output = to_drm_output(output_base);
|
||||
char desc[1024];
|
||||
|
||||
output->page_flips_per_timer_interval =
|
||||
(float) (output->page_flips_counted /
|
||||
b->perf_page_flips_stats.frame_counter_interval);
|
||||
|
||||
snprintf(desc, sizeof(desc),
|
||||
"output %s KMS page flips", output_base->name);
|
||||
|
||||
WESTON_TRACE_SET_COUNTER(desc,
|
||||
output->page_flips_per_timer_interval);
|
||||
|
||||
output->page_flips_counted = 0;
|
||||
}
|
||||
|
||||
|
||||
wl_event_source_timer_update(b->perf_page_flips_stats.pageflip_timer_counter,
|
||||
1000 * b->perf_page_flips_stats.frame_counter_interval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
drm_backend_pageflip_timer_create(struct drm_backend *b, uint32_t interval)
|
||||
{
|
||||
struct wl_event_loop *loop = NULL;
|
||||
struct weston_compositor *ec = b->compositor;
|
||||
|
||||
loop = wl_display_get_event_loop(ec->wl_display);
|
||||
assert(loop);
|
||||
|
||||
b->perf_page_flips_stats.pageflip_timer_counter =
|
||||
wl_event_loop_add_timer(loop, pageflip_timer_counter_handler, b);
|
||||
|
||||
if (b->perf_page_flips_stats.pageflip_timer_counter == NULL) {
|
||||
weston_log("creating drm pageflip counter timer failed: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
b->perf_page_flips_stats.frame_counter_interval = interval;
|
||||
|
||||
/* arm it w/ interval */
|
||||
wl_event_source_timer_update(b->perf_page_flips_stats.pageflip_timer_counter,
|
||||
1000 * b->perf_page_flips_stats.frame_counter_interval);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the plane can be used on the given output for its current
|
||||
* repaint cycle.
|
||||
|
|
@ -3478,6 +3537,7 @@ drm_shutdown(struct weston_backend *backend)
|
|||
|
||||
wl_event_source_remove(b->udev_drm_source);
|
||||
wl_event_source_remove(b->drm_source);
|
||||
wl_event_source_remove(b->perf_page_flips_stats.pageflip_timer_counter);
|
||||
|
||||
/* We are shutting down. This function destroy the planes with
|
||||
* destroy_sprites() and then calls weston_compositor_shutdown(), which
|
||||
|
|
@ -4267,6 +4327,8 @@ drm_backend_create(struct weston_compositor *compositor,
|
|||
goto err_udev_monitor;
|
||||
}
|
||||
|
||||
drm_backend_pageflip_timer_create(b, DEFAULT_FRAME_RATE_INTERVAL);
|
||||
|
||||
return b;
|
||||
|
||||
err_udev_monitor:
|
||||
|
|
|
|||
|
|
@ -1884,6 +1884,7 @@ page_flip_handler(int fd, unsigned int frame,
|
|||
assert(output->page_flip_pending);
|
||||
output->page_flip_pending = false;
|
||||
|
||||
output->page_flips_counted++;
|
||||
drm_output_update_complete(output, flags, sec, usec);
|
||||
}
|
||||
|
||||
|
|
@ -1905,6 +1906,7 @@ atomic_flip_handler(int fd, unsigned int frame, unsigned int sec,
|
|||
assert(crtc);
|
||||
|
||||
output = crtc->output;
|
||||
output->page_flips_counted++;
|
||||
|
||||
/* During the initial modeset, we can disable CRTCs which we don't
|
||||
* actually handle during normal operation; this will give us events
|
||||
|
|
@ -1932,6 +1934,9 @@ atomic_flip_handler(int fd, unsigned int frame, unsigned int sec,
|
|||
|
||||
drm_output_update_complete(output, flags, sec, usec);
|
||||
drm_debug(b, "[atomic][CRTC:%u] flip processing completed\n", crtc_id);
|
||||
drm_debug(b, "[atomic][CRTC:%u] %.2f page flips computed in %d seconds\n",
|
||||
crtc_id, output->page_flips_per_timer_interval,
|
||||
output->backend->perf_page_flips_stats.frame_counter_interval);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@
|
|||
*/
|
||||
|
||||
#define DEFAULT_REPAINT_WINDOW 7 /* milliseconds */
|
||||
#define DEFAULT_FRAME_RATE_INTERVAL 1 /* seconds */
|
||||
|
||||
static void
|
||||
weston_output_transform_scale_init(struct weston_output *output,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
#include <assert.h>
|
||||
#include "color.h"
|
||||
|
||||
#define DEFAULT_FRAME_RATE_INTERVAL 1 /* seconds */
|
||||
|
||||
/* compositor <-> renderer interface */
|
||||
|
||||
/** Opaque pointer to renderbuffer data.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue