diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna.h | 5 | ||||
-rw-r--r-- | src/sna/sna_accel.c | 5 | ||||
-rw-r--r-- | src/sna/sna_video.h | 1 | ||||
-rw-r--r-- | src/sna/sna_video_overlay.c | 34 | ||||
-rw-r--r-- | src/sna/sna_video_sprite.c | 30 |
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) |