diff options
-rw-r--r-- | src/sna/sna.h | 4 | ||||
-rw-r--r-- | src/sna/sna_display.c | 69 | ||||
-rw-r--r-- | src/sna/sna_video_sprite.c | 12 |
3 files changed, 63 insertions, 22 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h index fdfefe17..033781e1 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -611,8 +611,8 @@ static inline void sna_present_vblank_handler(struct drm_event_vblank *event) { static inline void sna_present_cancel_flip(struct sna *sna) { } #endif -extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation); -extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc); +extern bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, unsigned idx, uint32_t rotation); +extern uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx); extern bool sna_crtc_is_transformed(xf86CrtcPtr crtc); #define CRTC_VBLANK 0x3 diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 0cf2bdbf..2f54ff12 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -221,7 +221,9 @@ struct sna_crtc { uint32_t supported; uint32_t current; } rotation; - } primary, sprite; + struct list link; + } primary; + struct list sprites; uint32_t mode_serial, flip_serial; @@ -443,10 +445,25 @@ static inline uint32_t fb_id(struct kgem_bo *bo) return bo->delta; } -uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc) +static struct plane *lookup_sprite(struct sna_crtc *crtc, unsigned idx) { + struct plane *sprite; + + list_for_each_entry(sprite, &crtc->sprites, link) + if (idx-- == 0) + return sprite; + + return NULL; +} + +uint32_t sna_crtc_to_sprite(xf86CrtcPtr crtc, unsigned idx) +{ + struct plane *sprite; + assert(to_sna_crtc(crtc)); - return to_sna_crtc(crtc)->sprite.id; + + sprite = lookup_sprite(to_sna_crtc(crtc), idx); + return sprite ? sprite->id : 0; } bool sna_crtc_is_transformed(xf86CrtcPtr crtc) @@ -1253,17 +1270,23 @@ rotation_reset(struct plane *p) p->rotation.current = 0; } -bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, uint32_t rotation) +bool sna_crtc_set_sprite_rotation(xf86CrtcPtr crtc, + unsigned idx, + uint32_t rotation) { + struct plane *sprite; assert(to_sna_crtc(crtc)); DBG(("%s: CRTC:%d [pipe=%d], sprite=%u set-rotation=%x\n", __FUNCTION__, sna_crtc_id(crtc), sna_crtc_pipe(crtc), to_sna_crtc(crtc)->sprite.id, rotation)); - return rotation_set(to_sna(crtc->scrn), - &to_sna_crtc(crtc)->sprite, - rotation_reduce(&to_sna_crtc(crtc)->sprite, rotation)); + sprite = lookup_sprite(to_sna_crtc(crtc), idx); + if (!sprite) + return false; + + return rotation_set(to_sna(crtc->scrn), sprite, + rotation_reduce(sprite, rotation)); } #if HAS_DEBUG_FULL @@ -3005,10 +3028,14 @@ static void sna_crtc_destroy(xf86CrtcPtr crtc) { struct sna_crtc *sna_crtc = to_sna_crtc(crtc); + struct plane *sprite, *sn; if (sna_crtc == NULL) return; + list_for_each_entry_safe(sprite, sn, &sna_crtc->sprites, link) + free(sprite); + free(sna_crtc); crtc->driver_private = NULL; } @@ -3158,6 +3185,17 @@ static int plane_details(struct sna *sna, struct plane *p) return type; } +static void add_sprite_plane(struct sna_crtc *crtc, + struct plane *details) +{ + struct plane *sprite = malloc(sizeof(*sprite)); + if (!sprite) + return; + + memcpy(sprite, details, sizeof(*sprite)); + list_add(&sprite->link, &crtc->sprites); +} + static void sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc) { @@ -3231,8 +3269,7 @@ sna_crtc_find_planes(struct sna *sna, struct sna_crtc *crtc) break; case DRM_PLANE_TYPE_OVERLAY: - if (crtc->sprite.id == 0) - crtc->sprite = details; + add_sprite_plane(crtc, &details); break; } } @@ -3247,7 +3284,6 @@ sna_crtc_init__rotation(struct sna *sna, struct sna_crtc *crtc) crtc->rotation = RR_Rotate_0; crtc->primary.rotation.supported = RR_Rotate_0; crtc->primary.rotation.current = RR_Rotate_0; - crtc->sprite.rotation = crtc->primary.rotation; } static void @@ -3299,8 +3335,8 @@ sna_crtc_add(ScrnInfoPtr scrn, unsigned id) return true; } + list_init(&sna_crtc->sprites); sna_crtc_init__rotation(sna, sna_crtc); - sna_crtc_find_planes(sna, sna_crtc); DBG(("%s: CRTC:%d [pipe=%d], primary id=%x: supported-rotations=%x, current-rotation=%x, sprite id=%x: supported-rotations=%x, current-rotation=%x\n", @@ -8084,6 +8120,7 @@ static bool sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc) { struct local_mode_set_plane s; + struct plane *plane; if (crtc->primary.id == 0) return false; @@ -8093,8 +8130,10 @@ sna_crtc_hide_planes(struct sna *sna, struct sna_crtc *crtc) if (drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) return false; - s.plane_id = crtc->sprite.id; - (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s); + list_for_each_entry(plane, &crtc->sprites, link) { + s.plane_id = plane->id; + (void)drmIoctl(sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s); + } __sna_crtc_disable(sna, crtc); return true; @@ -8118,12 +8157,14 @@ void sna_mode_reset(struct sna *sna) for (i = 0; i < sna->mode.num_real_crtc; i++) { struct sna_crtc *sna_crtc = to_sna_crtc(config->crtc[i]); + struct plane *plane; assert(sna_crtc != NULL); /* Force the rotation property to be reset on next use */ rotation_reset(&sna_crtc->primary); - rotation_reset(&sna_crtc->sprite); + list_for_each_entry(plane, &sna_crtc->sprites, link) + rotation_reset(plane); } /* VT switching, likely to be fbcon so make the backlight usable */ diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c index 1498707d..17b272ca 100644 --- a/src/sna/sna_video_sprite.c +++ b/src/sna/sna_video_sprite.c @@ -91,7 +91,7 @@ static int sna_video_sprite_stop(ddStopVideo_ARGS) continue; memset(&s, 0, sizeof(s)); - s.plane_id = sna_crtc_to_sprite(crtc); + s.plane_id = sna_crtc_to_sprite(crtc, 0); if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR, "failed to disable plane\n"); @@ -224,7 +224,7 @@ sna_video_sprite_show(struct sna *sna, /* XXX handle video spanning multiple CRTC */ VG_CLEAR(s); - s.plane_id = sna_crtc_to_sprite(crtc); + s.plane_id = sna_crtc_to_sprite(crtc, 0); #define DRM_I915_SET_SPRITE_COLORKEY 0x2b #define LOCAL_IOCTL_I915_SET_SPRITE_COLORKEY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_SET_SPRITE_COLORKEY, struct local_intel_sprite_colorkey) @@ -422,7 +422,7 @@ off: if (video->bo[pipe]) { struct local_mode_set_plane s; memset(&s, 0, sizeof(s)); - s.plane_id = sna_crtc_to_sprite(crtc); + s.plane_id = sna_crtc_to_sprite(crtc, 0); if (drmIoctl(video->sna->kgem.fd, LOCAL_IOCTL_MODE_SETPLANE, &s)) xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR, "failed to disable plane\n"); @@ -461,8 +461,8 @@ off: /* if sprite can't handle rotation natively, store it for the copy func */ rotation = RR_Rotate_0; - if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) { - sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0); + if (!sna_crtc_set_sprite_rotation(crtc, 0, crtc->rotation)) { + sna_crtc_set_sprite_rotation(crtc, 0, RR_Rotate_0); rotation = crtc->rotation; } sna_video_frame_set_rotation(video, &frame, rotation); @@ -662,7 +662,7 @@ static bool sna_video_has_sprites(struct sna *sna) return false; for (i = 0; i < sna->mode.num_real_crtc; i++) { - if (!sna_crtc_to_sprite(config->crtc[i])) { + if (!sna_crtc_to_sprite(config->crtc[i], 0)) { DBG(("%s: no sprite found on pipe %d\n", __FUNCTION__, sna_crtc_pipe(config->crtc[i]))); return false; } |