summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sna/sna.h4
-rw-r--r--src/sna/sna_display.c69
-rw-r--r--src/sna/sna_video_sprite.c12
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;
}