[Intel-gfx] [PATCH xf86-video-intel] sna: Use correct struct sna in sna_mode_wakeup
Thomas Preston
thomas.preston at codethink.co.uk
Tue Jan 21 10:28:58 UTC 2020
When deciding if we should defer_vblanks we should reference the event's
struct sna, rather than the caller's struct sna. In order to do this, we
must grab a new struct sna for each event in the buffer. Move this logic
out of `case DRM_EVENT_FLIP_COMPLETE` and create a new variable
sna_event, so that it is clear which struct sna we are referring to.
Also add another ZaphodHead comment by the struct sna argument, in case
someone misses the comment below.
Fixes issue #184 with ZaphodHead and TearFree, introduced in this commit:
12db28ab sna: Reorder vblank/flip event handling to avoid TearFree recursion
Signed-off-by: Thomas Preston <thomas.preston at codethink.co.uk>
---
src/sna/sna_display.c | 48 +++++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 22 deletions(-)
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 874292bc..b40a6c4a 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -9711,9 +9711,12 @@ fixup_flip:
RegionEmpty(region);
}
+/* In the case of ZaphodHead, there is only one event queue in the main
+ * struct sna. Only refer to this struct sna when dealing with the event queue.
+ * Otherwise, extract the struct sna from the event user_data.
+ */
int sna_mode_wakeup(struct sna *sna)
{
- bool defer_vblanks = sna->mode.flip_active && sna->mode.shadow_enabled;
char buffer[1024];
int len, i;
int ret = 0;
@@ -9733,34 +9736,35 @@ again:
if (len < (int)sizeof(struct drm_event))
goto done;
- /* Note that we cannot rely on the passed in struct sna matching
- * the struct sna used for the vblank event (in case it was submitted
- * by a different ZaphodHead). When processing the event, we must
- * ensure that we only use the pointer passed along with the event.
- */
-
DBG(("%s: len=%d\n", __FUNCTION__, len));
i = 0;
while (i < len) {
struct drm_event *e = (struct drm_event *)&buffer[i];
+
+ /* Note that we cannot rely on the passed in struct sna
+ * matching the struct sna used for the vblank event (in case
+ * it was submitted by a different ZaphodHead). When processing
+ * the event, we must ensure that we only use the pointer
+ * passed along with the event.
+ */
+ struct drm_event_vblank *vbl = (struct drm_event_vblank *)e;
+ struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data;
+ struct sna *sna_event = to_sna(crtc->base->scrn);
+
switch (e->type) {
case DRM_EVENT_VBLANK:
- if (defer_vblanks)
+ if (sna_event->mode.flip_active && sna_event->mode.shadow_enabled)
defer_event(sna, e);
- else if (((uintptr_t)((struct drm_event_vblank *)e)->user_data) & 2)
- sna_present_vblank_handler((struct drm_event_vblank *)e);
+ else if (((uintptr_t)crtc) & 2)
+ sna_present_vblank_handler(vbl);
else
- sna_dri2_vblank_handler((struct drm_event_vblank *)e);
+ sna_dri2_vblank_handler(vbl);
break;
case DRM_EVENT_FLIP_COMPLETE:
{
- struct drm_event_vblank *vbl = (struct drm_event_vblank *)e;
- struct sna_crtc *crtc = (void *)(uintptr_t)vbl->user_data;
uint64_t msc;
- /* Beware Zaphod! */
- sna = to_sna(crtc->base->scrn);
if (msc64(crtc, vbl->sequence, &msc)) {
DBG(("%s: recording last swap on pipe=%d, frame %d [%08llx], time %d.%06d\n",
@@ -9784,26 +9788,26 @@ again:
assert(crtc->bo->refcnt >= crtc->bo->active_scanout);
crtc->bo->active_scanout--;
- kgem_bo_destroy(&sna->kgem, crtc->bo);
+ kgem_bo_destroy(&sna_event->kgem, crtc->bo);
if (crtc->shadow_bo) {
- kgem_bo_destroy(&sna->kgem, crtc->shadow_bo);
+ kgem_bo_destroy(&sna_event->kgem, crtc->shadow_bo);
crtc->shadow_bo = NULL;
}
crtc->bo = crtc->flip_bo;
crtc->flip_bo = NULL;
- assert_crtc_fb(sna, crtc);
+ assert_crtc_fb(sna_event, crtc);
} else {
crtc->flip_bo->active_scanout--;
- kgem_bo_destroy(&sna->kgem, crtc->flip_bo);
+ kgem_bo_destroy(&sna_event->kgem, crtc->flip_bo);
crtc->flip_bo = NULL;
}
- DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna->mode.flip_active));
- assert(sna->mode.flip_active);
- if (--sna->mode.flip_active == 0) {
+ DBG(("%s: flip complete, pending? %d\n", __FUNCTION__, sna_event->mode.flip_active));
+ assert(sna_event->mode.flip_active);
+ if (--sna_event->mode.flip_active == 0) {
assert(crtc->flip_handler);
crtc->flip_handler(vbl, crtc->flip_data);
}
--
2.24.1
More information about the Intel-gfx
mailing list