[PATCH xf86-video-ati 2/2] kms: Move flip_count and co. to a per swap structure
Stéphane Marchesin
stephane.marchesin at gmail.com
Thu Jun 9 20:08:24 PDT 2011
On Wed, May 4, 2011 at 13:51, Ville Syrjala <syrjala at sci.fi> wrote:
> If multiple drawables are doing page flipping, the global drmmode
> structure can't be used to keep per swap information. For example
> flip_count can increase prematurely due to another swap request,
> and then the previous swap request never gets completed, leading to a
> stuck client. Move the relevant pieces of data to a strucuture that
> gets allocated once per swap request and shared by all involved CRTCs.
>
> Signed-off-by: Ville Syrjala <syrjala at sci.fi>
> ---
> src/drmmode_display.c | 45 ++++++++++++++++++++++++++-------------------
> src/drmmode_display.h | 10 +++++++---
> 2 files changed, 33 insertions(+), 22 deletions(-)
>
> diff --git a/src/drmmode_display.c b/src/drmmode_display.c
> index 7873d57..7dd5d86 100644
> --- a/src/drmmode_display.c
> +++ b/src/drmmode_display.c
> @@ -1331,31 +1331,34 @@ drmmode_flip_handler(int fd, unsigned int frame, unsigned int tv_sec,
> unsigned int tv_usec, void *event_data)
> {
> drmmode_flipevtcarrier_ptr flipcarrier = event_data;
> - drmmode_ptr drmmode = flipcarrier->drmmode;
> + drmmode_flipdata_ptr flipdata = flipcarrier->flipdata;
> + drmmode_ptr drmmode = flipdata->drmmode;
>
> /* Is this the event whose info shall be delivered to higher level? */
> if (flipcarrier->dispatch_me) {
> /* Yes: Cache msc, ust for later delivery. */
> - drmmode->fe_frame = frame;
> - drmmode->fe_tv_sec = tv_sec;
> - drmmode->fe_tv_usec = tv_usec;
> + flipdata->fe_frame = frame;
> + flipdata->fe_tv_sec = tv_sec;
> + flipdata->fe_tv_usec = tv_usec;
> }
> free(flipcarrier);
>
> /* Last crtc completed flip? */
> - drmmode->flip_count--;
> - if (drmmode->flip_count > 0)
> + flipdata->flip_count--;
> + if (flipdata->flip_count > 0)
> return;
>
> /* Release framebuffer */
> - drmModeRmFB(drmmode->fd, drmmode->old_fb_id);
> + drmModeRmFB(drmmode->fd, flipdata->old_fb_id);
>
> - if (drmmode->event_data == NULL)
> + if (flipdata->event_data == NULL)
> return;
>
> /* Deliver cached msc, ust from reference crtc to flip event handler */
> - radeon_dri2_flip_event_handler(drmmode->fe_frame, drmmode->fe_tv_sec,
> - drmmode->fe_tv_usec, drmmode->event_data);
> + radeon_dri2_flip_event_handler(flipdata->fe_frame, flipdata->fe_tv_sec,
> + flipdata->fe_tv_usec, flipdata->event_data);
> +
> + free(flipdata);
> }
>
>
> @@ -1399,12 +1402,10 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
>
> xf86InitialConfiguration(pScrn, TRUE);
>
> - drmmode->flip_count = 0;
> drmmode->event_context.version = DRM_EVENT_CONTEXT_VERSION;
> drmmode->event_context.vblank_handler = drmmode_vblank_handler;
> drmmode->event_context.page_flip_handler = drmmode_flip_handler;
> if (!pRADEONEnt->fd_wakeup_registered && info->dri->pKernelDRMVersion->version_minor >= 4) {
> - drmmode->flip_count = 0;
> AddGeneralSocket(drmmode->fd);
> RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
> drm_wakeup_handler, drmmode);
> @@ -1654,6 +1655,7 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *dat
> int i, old_fb_id;
> uint32_t tiling_flags = 0;
> int height;
> + drmmode_flipdata_ptr flipdata;
> drmmode_flipevtcarrier_ptr flipcarrier;
>
> if (info->allowColorTiling) {
> @@ -1676,6 +1678,12 @@ Bool radeon_do_pageflip(ScrnInfoPtr scrn, struct radeon_bo *new_front, void *dat
> new_front->handle, &drmmode->fb_id))
> goto error_out;
>
> + flipdata = calloc(1, sizeof(drmmode_flipdata_rec));
I think you leak that flipdata in the error_undo case.
Stéphane
More information about the xorg-devel
mailing list