summaryrefslogtreecommitdiff
path: root/src/sna
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-16 18:22:45 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2013-08-16 18:22:45 +0100
commitc610d37dae7e025027fd09a6889bf94853af8b8c (patch)
tree3b1443a6edb3c62d9fd2a38732c6b5b2d3d8cfcd /src/sna
parent7a6bd55da90382459db072bffbd4aa36d18f9a17 (diff)
sna/video: Expose an attribute to keep the overlay always on top
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r--src/sna/sna.h5
-rw-r--r--src/sna/sna_accel.c5
-rw-r--r--src/sna/sna_video.h1
-rw-r--r--src/sna/sna_video_overlay.c34
-rw-r--r--src/sna/sna_video_sprite.c30
5 files changed, 53 insertions, 22 deletions
diff --git a/src/sna/sna.h b/src/sna/sna.h
index b5613bd9..14b3c145 100644
--- a/src/sna/sna.h
+++ b/src/sna/sna.h
@@ -548,6 +548,11 @@ inline static int16_t clamp(int16_t a, int16_t b)
return v;
}
+static inline bool box_empty(const BoxRec *box)
+{
+ return box->x2 <= box->x1 || box->y2 <= box->y1;
+}
+
static inline bool
box_inplace(PixmapPtr pixmap, const BoxRec *box)
{
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index c54c2547..8409d5ee 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -2217,11 +2217,6 @@ static inline bool region_inplace(struct sna *sna,
>= sna->kgem.half_cpu_cache_pages;
}
-static inline bool box_empty(const BoxRec *box)
-{
- return box->x2 <= box->x1 || box->y2 <= box->y1;
-}
-
bool
sna_drawable_move_region_to_cpu(DrawablePtr drawable,
RegionPtr region,
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index 593a8cc4..f0ad28f4 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -80,6 +80,7 @@ struct sna_video {
int plane;
int SyncToVblank; /* -1: auto, 0: off, 1: on */
+ int AlwaysOnTop;
};
struct sna_video_frame {
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index cfdc83d6..434d11f4 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -43,9 +43,8 @@
#define HAS_GAMMA(sna) ((sna)->kgem.gen >= 030)
-static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe;
+static Atom xvBrightness, xvContrast, xvSaturation, xvColorKey, xvPipe, xvAlwaysOnTop;
static Atom xvGamma0, xvGamma1, xvGamma2, xvGamma3, xvGamma4, xvGamma5;
-static Atom xvSyncToVblank;
/* Limits for the overlay/textured video source sizes. The documented hardware
* limits are 2048x2048 or better for overlay and both of our textured video
@@ -116,6 +115,9 @@ static bool sna_video_overlay_update_attrs(struct sna_video *video)
attrs.gamma4 = video->gamma4;
attrs.gamma5 = video->gamma5;
+ if (video->AlwaysOnTop)
+ attrs.flags |= 1<<2;
+
return drmIoctl(video->sna->kgem.fd, DRM_IOCTL_I915_OVERLAY_ATTRS, &attrs) == 0;
}
@@ -150,6 +152,7 @@ sna_video_overlay_set_attribute(ClientPtr client,
struct sna_video *video = port->devPriv.ptr;
struct sna *sna = video->sna;
+ DBG(("%s: set(%lx) to %d\n", __FUNCTION__, (long)attribute, (int)value));
if (attribute == xvBrightness) {
if ((value < -128) || (value > 127))
return BadValue;
@@ -176,6 +179,10 @@ sna_video_overlay_set_attribute(ClientPtr client,
video->desired_crtc = NULL;
else
video->desired_crtc = xf86_config->crtc[value];
+ } else if (attribute == xvAlwaysOnTop) {
+ DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__,
+ video->AlwaysOnTop, !!value));
+ video->AlwaysOnTop = !!value;
} else if (attribute == xvGamma0 && HAS_GAMMA(sna)) {
video->gamma0 = value;
} else if (attribute == xvGamma1 && HAS_GAMMA(sna)) {
@@ -236,6 +243,8 @@ sna_video_overlay_get_attribute(ClientPtr client,
if (c == xf86_config->num_crtc)
c = -1;
*value = c;
+ } else if (attribute == xvAlwaysOnTop) {
+ *value = video->AlwaysOnTop;
} else if (attribute == xvGamma0 && HAS_GAMMA(sna)) {
*value = video->gamma0;
} else if (attribute == xvGamma1 && HAS_GAMMA(sna)) {
@@ -250,8 +259,6 @@ sna_video_overlay_get_attribute(ClientPtr client,
*value = video->gamma5;
} else if (attribute == xvColorKey) {
*value = video->color_key;
- } else if (attribute == xvSyncToVblank) {
- *value = video->SyncToVblank;
} else
return BadMatch;
@@ -483,8 +490,10 @@ sna_video_overlay_put_image(ClientPtr client,
clip.extents.y2 = clip.extents.y1 + drw_h;
clip.data = NULL;
- RegionIntersect(&clip, &clip, gc->pCompositeClip);
- if (!RegionNotEmpty(&clip))
+ DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop));
+ if (!video->AlwaysOnTop)
+ RegionIntersect(&clip, &clip, gc->pCompositeClip);
+ if (box_empty(&clip.extents))
goto invisible;
DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
@@ -550,11 +559,15 @@ sna_video_overlay_put_image(ClientPtr client,
ret = Success;
if (sna_video_overlay_show
(sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) {
- if (!RegionEqual(&video->clip, &clip)) {
+ //xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
+ if (!video->AlwaysOnTop && !RegionEqual(&video->clip, &clip) &&
+ sna_blt_fill_boxes(sna, GXcopy,
+ __sna_pixmap_get_bo(sna->front),
+ sna->front->drawable.bitsPerPixel,
+ video->color_key,
+ RegionRects(&clip),
+ RegionNumRects(&clip)))
RegionCopy(&video->clip, &clip);
- xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
- }
-
sna_window_set_port((WindowPtr)draw, port);
} else {
DBG(("%s: failed to show video frame\n", __FUNCTION__));
@@ -791,6 +804,7 @@ void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen)
/* Allow the pipe to be switched from pipe A to B when in clone mode */
xvPipe = MAKE_ATOM("XV_PIPE");
+ xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
if (HAS_GAMMA(sna)) {
xvGamma0 = MAKE_ATOM("XV_GAMMA0");
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index cab2cdaa..a20e9b9c 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -48,7 +48,7 @@
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true)
-static Atom xvColorKey;
+static Atom xvColorKey, xvAlwaysOnTop;
static XvFormatRec formats[] = { {15}, {16}, {24} };
static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_YUV };
@@ -88,6 +88,10 @@ static int sna_video_sprite_set_attr(ClientPtr client,
video->color_key_changed = true;
video->color_key = value;
DBG(("COLORKEY = %ld\n", (long)value));
+ } else if (attribute == xvAlwaysOnTop) {
+ DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__,
+ video->AlwaysOnTop, !!value));
+ video->AlwaysOnTop = !!value;
} else
return BadMatch;
@@ -103,6 +107,8 @@ static int sna_video_sprite_get_attr(ClientPtr client,
if (attribute == xvColorKey)
*value = video->color_key;
+ else if (attribute == xvAlwaysOnTop)
+ *value = video->AlwaysOnTop;
else
return BadMatch;
@@ -208,6 +214,9 @@ sna_video_sprite_show(struct sna *sna,
set.plane_id = s.plane_id;
set.value = video->color_key;
+ set.flags = 0;
+ if (!video->AlwaysOnTop)
+ set.flags = I915_SET_COLORKEY_DESTINATION;
if (drmIoctl(sna->kgem.fd,
DRM_IOCTL_I915_SET_SPRITE_DESTKEY,
@@ -310,8 +319,10 @@ static int sna_video_sprite_put_image(ClientPtr client,
clip.extents.y2 = clip.extents.y1 + drw_h;
clip.data = NULL;
- RegionIntersect(&clip, &clip, gc->pCompositeClip);
- if (!RegionNotEmpty(&clip))
+ DBG(("%s: always_on_top=%d\n", __FUNCTION__, video->AlwaysOnTop));
+ if (!video->AlwaysOnTop)
+ RegionIntersect(&clip, &clip, gc->pCompositeClip);
+ if (box_empty(&clip.extents))
goto invisible;
DBG(("%s: src=(%d, %d),(%d, %d), dst=(%d, %d),(%d, %d), id=%d, sizep=%dx%d, sync?=%d\n",
@@ -377,10 +388,14 @@ static int sna_video_sprite_put_image(ClientPtr client,
DBG(("%s: failed to show video frame\n", __FUNCTION__));
ret = BadAlloc;
} else {
- if (!RegionEqual(&video->clip, &clip)) {
- RegionCopy(&video->clip, &clip);
- xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
- }
+ //xf86XVFillKeyHelperDrawable(draw, video->color_key, &clip);
+ if (!video->AlwaysOnTop && !RegionEqual(&video->clip, &clip) &&
+ sna_blt_fill_boxes(sna, GXcopy,
+ __sna_pixmap_get_bo(sna->front),
+ sna->front->drawable.bitsPerPixel,
+ video->color_key,
+ RegionRects(&clip),
+ RegionNumRects(&clip)))
sna_window_set_port((WindowPtr)draw, port);
}
@@ -549,6 +564,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
RegionNull(&video->clip);
xvColorKey = MAKE_ATOM("XV_COLORKEY");
+ xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
}
#else
void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)