summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2014-04-23 11:34:06 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2014-04-23 11:54:58 +0100
commit5fbbfd4dd35c5e5381897b7e5d4c16c1f182ef2b (patch)
treefc553f215d32518987d1b75db839989e182183db
parent3508f809c40bc59d67deb7182807664bc0648639 (diff)
sna/video: Show sprites across all outputs
If an overlay video (using the sprite interface) is visible on multiple outputs, we have to create and show a sprite for each. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=77802 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r--src/sna/sna_display.c3
-rw-r--r--src/sna/sna_video.c39
-rw-r--r--src/sna/sna_video.h17
-rw-r--r--src/sna/sna_video_overlay.c21
-rw-r--r--src/sna/sna_video_sprite.c303
-rw-r--r--src/sna/sna_video_textured.c3
6 files changed, 239 insertions, 147 deletions
diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c
index 5e8ea627..b802cf7e 100644
--- a/src/sna/sna_display.c
+++ b/src/sna/sna_display.c
@@ -194,7 +194,8 @@ static inline uint32_t fb_id(struct kgem_bo *bo)
uint32_t sna_crtc_id(xf86CrtcPtr crtc)
{
- assert(to_sna_crtc(crtc));
+ if (to_sna_crtc(crtc) == NULL)
+ return 0;
return to_sna_crtc(crtc)->id;
}
diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 890ae490..7534fe32 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -200,8 +200,6 @@ sna_video_frame_init(struct sna_video *video,
int id, short width, short height,
struct sna_video_frame *frame)
{
- int align;
-
DBG(("%s: id=%d [planar? %d], width=%d, height=%d, align=%d\n",
__FUNCTION__, id, is_planar_fourcc(id), width, height, video->alignment));
assert(width && height);
@@ -210,21 +208,35 @@ sna_video_frame_init(struct sna_video *video,
frame->id = id;
frame->width = width;
frame->height = height;
+ frame->rotation = 0;
+}
+
+void
+sna_video_frame_set_rotation(struct sna_video *video,
+ struct sna_video_frame *frame,
+ Rotation rotation)
+{
+ unsigned width = frame->width;
+ unsigned height = frame->height;
+ unsigned align;
+
+ DBG(("%s: rotation=%d\n", __FUNCTION__, rotation));
+ frame->rotation = rotation;
align = video->alignment;
#if SNA_XVMC
/* for i915 xvmc, hw requires 1kb aligned surfaces */
- if (id == FOURCC_XVMC && video->sna->kgem.gen < 040 && align < 1024)
+ if (frame->id == FOURCC_XVMC && video->sna->kgem.gen < 040 && align < 1024)
align = 1024;
#endif
/* Determine the desired destination pitch (representing the
* chroma's pitch in the planar case).
*/
- if (is_planar_fourcc(id)) {
+ if (is_planar_fourcc(frame->id)) {
assert((width & 1) == 0);
assert((height & 1) == 0);
- if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
frame->pitch[0] = ALIGN((height / 2), align);
frame->pitch[1] = ALIGN(height, align);
frame->size = width;
@@ -235,7 +247,7 @@ sna_video_frame_init(struct sna_video *video,
}
frame->size *= frame->pitch[0] + frame->pitch[1];
- if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
frame->UBufOffset = (int)frame->pitch[1] * width;
frame->VBufOffset =
frame->UBufOffset + (int)frame->pitch[0] * width / 2;
@@ -247,7 +259,7 @@ sna_video_frame_init(struct sna_video *video,
} else {
switch (frame->id) {
case FOURCC_RGB888:
- if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
frame->pitch[0] = ALIGN((height << 2), align);
frame->size = (int)frame->pitch[0] * width;
} else {
@@ -257,7 +269,7 @@ sna_video_frame_init(struct sna_video *video,
frame->UBufOffset = frame->VBufOffset = 0;
break;
case FOURCC_RGB565:
- if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
frame->pitch[0] = ALIGN((height << 1), align);
frame->size = (int)frame->pitch[0] * width;
} else {
@@ -268,7 +280,7 @@ sna_video_frame_init(struct sna_video *video,
break;
default:
- if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ if (rotation & (RR_Rotate_90 | RR_Rotate_270)) {
frame->pitch[0] = ALIGN((height << 1), align);
frame->size = (int)frame->pitch[0] * width;
} else {
@@ -309,7 +321,7 @@ static void sna_memcpy_plane(struct sna_video *video,
if (!video->textured)
x = y = 0;
- switch (video->rotation) {
+ switch (frame->rotation) {
case RR_Rotate_0:
dst += y * dstPitch + x;
if (srcPitch == dstPitch && srcPitch == w)
@@ -399,7 +411,7 @@ sna_copy_packed_data(struct sna_video *video,
src = buf + (y * pitch) + (x << 1);
- switch (video->rotation) {
+ switch (frame->rotation) {
case RR_Rotate_0:
w <<= 1;
for (i = 0; i < h; i++) {
@@ -481,16 +493,17 @@ sna_video_copy_data(struct sna_video *video,
DBG(("%s: handle=%d, size=%dx%d [%d], pitch=[%d,%d] rotation=%d, is-texture=%d\n",
__FUNCTION__, frame->bo ? frame->bo->handle : 0,
frame->width, frame->height, frame->size, frame->pitch[0], frame->pitch[1],
- video->rotation, video->textured));
+ frame->rotation, video->textured));
DBG(("%s: image=(%d, %d), (%d, %d), source=(%d, %d), (%d, %d)\n",
__FUNCTION__,
frame->image.x1, frame->image.y1, frame->image.x2, frame->image.y2,
frame->src.x1, frame->src.y1, frame->src.x2, frame->src.y2));
assert(frame->width && frame->height);
+ assert(frame->rotation);
assert(frame->size);
/* In the common case, we can simply the upload in a single pwrite */
- if (video->rotation == RR_Rotate_0 && !video->tiled) {
+ if (frame->rotation == RR_Rotate_0 && !video->tiled) {
DBG(("%s: unrotated, untiled fast paths: is-planar?=%d\n",
__FUNCTION__, is_planar_fourcc(frame->id)));
if (is_planar_fourcc(frame->id)) {
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index 337f928e..d46c0159 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -77,8 +77,6 @@ struct sna_video {
int saturation;
xf86CrtcPtr desired_crtc;
- RegionRec clip;
-
uint32_t gamma0;
uint32_t gamma1;
uint32_t gamma2;
@@ -86,8 +84,8 @@ struct sna_video {
uint32_t gamma4;
uint32_t gamma5;
- int color_key;
- bool color_key_changed;
+ unsigned color_key;
+ unsigned color_key_changed;
bool has_color_key;
/** YUV data buffers */
@@ -98,9 +96,10 @@ struct sna_video {
int alignment;
bool tiled;
bool textured;
- Rotation rotation;
int plane;
- struct kgem_bo *bo;
+
+ struct kgem_bo *bo[4];
+ RegionRec clip;
int SyncToVblank; /* -1: auto, 0: off, 1: on */
int AlwaysOnTop;
@@ -112,6 +111,7 @@ struct sna_video_frame {
uint32_t size;
uint32_t UBufOffset;
uint32_t VBufOffset;
+ Rotation rotation;
uint16_t width, height;
uint16_t pitch[2];
@@ -179,6 +179,11 @@ sna_video_frame_init(struct sna_video *video,
int id, short width, short height,
struct sna_video_frame *frame);
+void
+sna_video_frame_set_rotation(struct sna_video *video,
+ struct sna_video_frame *frame,
+ Rotation rotation);
+
struct kgem_bo *
sna_video_buffer(struct sna_video *video,
struct sna_video_frame *frame);
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c
index 6f277342..72b290a5 100644
--- a/src/sna/sna_video_overlay.c
+++ b/src/sna/sna_video_overlay.c
@@ -139,9 +139,9 @@ static int sna_video_overlay_stop(ClientPtr client,
DRM_IOCTL_I915_OVERLAY_PUT_IMAGE,
&request);
- if (video->bo)
- kgem_bo_destroy(&sna->kgem, video->bo);
- video->bo = NULL;
+ if (video->bo[0])
+ kgem_bo_destroy(&sna->kgem, video->bo[0]);
+ video->bo[0] = NULL;
sna_video_free_buffers(video);
sna_window_set_port((WindowPtr)draw, NULL);
@@ -202,6 +202,7 @@ sna_video_overlay_set_attribute(ClientPtr client,
video->gamma5 = value;
} else if (attribute == xvColorKey) {
video->color_key = value;
+ RegionEmpty(&video->clip);
DBG(("COLORKEY\n"));
} else
return BadMatch;
@@ -218,9 +219,6 @@ sna_video_overlay_set_attribute(ClientPtr client,
if (!sna_video_overlay_update_attrs(video))
return BadValue;
- if (attribute == xvColorKey)
- RegionEmpty(&video->clip);
-
return Success;
}
@@ -455,10 +453,10 @@ sna_video_overlay_show(struct sna *sna,
return false;
}
- if (video->bo != frame->bo) {
- if (video->bo)
- kgem_bo_destroy(&sna->kgem, video->bo);
- video->bo = kgem_bo_reference(frame->bo);
+ if (video->bo[0] != frame->bo) {
+ if (video->bo[0])
+ kgem_bo_destroy(&sna->kgem, video->bo[0]);
+ video->bo[0] = kgem_bo_reference(frame->bo);
}
return true;
@@ -535,7 +533,7 @@ sna_video_overlay_put_image(ClientPtr client,
goto invisible;
/* overlay can't handle rotation natively, store it for the copy func */
- video->rotation = crtc->rotation;
+ sna_video_frame_set_rotation(video, &frame, crtc->rotation);
if (xvmc_passthrough(format->id)) {
DBG(("%s: using passthough, name=%d\n",
@@ -821,7 +819,6 @@ void sna_video_overlay_setup(struct sna *sna, ScreenPtr screen)
video->gamma2 = 0x202020;
video->gamma1 = 0x101010;
video->gamma0 = 0x080808;
- video->rotation = RR_Rotate_0;
RegionNull(&video->clip);
xvColorKey = MAKE_ATOM("XV_COLORKEY");
diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 6fcc7791..0a1c545f 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -35,6 +35,7 @@
#include <xf86drm.h>
#include <xf86xv.h>
+#include <xf86Crtc.h>
#include <X11/extensions/Xv.h>
#include <fourcc.h>
#include <i915_drm.h>
@@ -48,7 +49,7 @@
#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, true)
-static Atom xvColorKey, xvAlwaysOnTop;
+static Atom xvColorKey, xvAlwaysOnTop, xvSyncToVblank;
static XvFormatRec formats[] = { {15}, {16}, {24} };
static const XvImageRec images[] = { XVIMAGE_YUY2, XVIMAGE_UYVY, XVMC_RGB888, XVMC_RGB565 };
@@ -63,21 +64,31 @@ static int sna_video_sprite_stop(ClientPtr client,
{
struct sna_video *video = port->devPriv.ptr;
struct drm_mode_set_plane s;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(video->sna->scrn);
+ int i;
- if (video->plane == 0)
- return Success;
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+ int pipe;
- memset(&s, 0, sizeof(s));
- s.plane_id = video->plane;
- if (drmIoctl(video->sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s))
- xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
- "failed to disable plane\n");
+ if (sna_crtc_id(crtc) == 0)
+ break;
+
+ pipe = sna_crtc_to_pipe(crtc);
+ if (video->bo[pipe] == NULL)
+ continue;
- if (video->bo)
- kgem_bo_destroy(&video->sna->kgem, video->bo);
- video->bo = NULL;
+ memset(&s, 0, sizeof(s));
+ s.plane_id = sna_crtc_to_sprite(crtc);
+ if (drmIoctl(video->sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s))
+ xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
+ "failed to disable plane\n");
+
+ if (video->bo[pipe])
+ kgem_bo_destroy(&video->sna->kgem, video->bo[pipe]);
+ video->bo[pipe] = NULL;
+ }
- video->plane = 0;
sna_window_set_port((WindowPtr)draw, NULL);
return Success;
@@ -91,13 +102,18 @@ static int sna_video_sprite_set_attr(ClientPtr client,
struct sna_video *video = port->devPriv.ptr;
if (attribute == xvColorKey) {
- video->color_key_changed = true;
+ video->color_key_changed = ~0;
video->color_key = value;
+ RegionEmpty(&video->clip);
DBG(("COLORKEY = %ld\n", (long)value));
+ } else if (attribute == xvSyncToVblank) {
+ DBG(("%s: SYNC_TO_VBLANK: %d -> %d\n", __FUNCTION__,
+ video->SyncToVblank, !!value));
+ video->SyncToVblank = !!value;
} else if (attribute == xvAlwaysOnTop) {
DBG(("%s: ALWAYS_ON_TOP: %d -> %d\n", __FUNCTION__,
video->AlwaysOnTop, !!value));
- video->color_key_changed = true;
+ video->color_key_changed = ~0;
video->AlwaysOnTop = !!value;
} else
return BadMatch;
@@ -116,6 +132,8 @@ static int sna_video_sprite_get_attr(ClientPtr client,
*value = video->color_key;
else if (attribute == xvAlwaysOnTop)
*value = video->AlwaysOnTop;
+ else if (attribute == xvSyncToVblank)
+ *value = video->SyncToVblank;
else
return BadMatch;
@@ -201,22 +219,15 @@ sna_video_sprite_show(struct sna *sna,
BoxPtr dstBox)
{
struct drm_mode_set_plane s;
+ int pipe = sna_crtc_to_pipe(crtc);
/* XXX handle video spanning multiple CRTC */
VG_CLEAR(s);
s.plane_id = sna_crtc_to_sprite(crtc);
- update_dst_box_to_crtc_coords(sna, crtc, dstBox);
- if (video->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
- int tmp = frame->width;
- frame->width = frame->height;
- frame->height = tmp;
- }
-
#define DRM_I915_SET_SPRITE_COLORKEY 0x2b
- if ((video->color_key_changed || video->plane != s.plane_id) &&
- video->has_color_key) {
+ if (video->color_key_changed & (1 << pipe) && video->has_color_key) {
struct drm_intel_sprite_colorkey set;
DBG(("%s: updating color key: %x\n",
@@ -238,7 +249,17 @@ sna_video_sprite_show(struct sna *sna,
video->has_color_key = false;
}
- video->color_key_changed = false;
+ video->color_key_changed &= ~(1 << pipe);
+ }
+
+ if (video->bo[pipe] == frame->bo)
+ return true;
+
+ update_dst_box_to_crtc_coords(sna, crtc, dstBox);
+ if (frame->rotation & (RR_Rotate_90 | RR_Rotate_270)) {
+ int tmp = frame->width;
+ frame->width = frame->height;
+ frame->height = tmp;
}
if (frame->bo->delta == 0) {
@@ -308,28 +329,21 @@ sna_video_sprite_show(struct sna *sna,
if (drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s)) {
DBG(("SET_PLANE failed: ret=%d\n", errno));
+ memset(&s, 0, sizeof(s));
+ s.plane_id = video->plane;
+ (void)drmIoctl(sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s);
+ if (video->bo[pipe]) {
+ kgem_bo_destroy(&sna->kgem, video->bo[pipe]);
+ video->bo[pipe] = NULL;
+ }
return false;
}
frame->bo->domain = DOMAIN_NONE;
- if (video->plane != s.plane_id) {
- if (video->plane) {
- memset(&s, 0, sizeof(s));
- s.plane_id = video->plane;
- if (drmIoctl(video->sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s)) {
- DBG(("SET_PLANE failed to turn off existing sprite: ret=%d\n", errno));
- return false;
- }
- }
- video->plane = s.plane_id;
- }
-
- if (video->bo != frame->bo) {
- if (video->bo)
- kgem_bo_destroy(&sna->kgem, video->bo);
- video->bo = kgem_bo_reference(frame->bo);
- }
+ if (video->bo[pipe])
+ kgem_bo_destroy(&sna->kgem, video->bo[pipe]);
+ video->bo[pipe] = kgem_bo_reference(frame->bo);
return true;
}
@@ -348,11 +362,9 @@ static int sna_video_sprite_put_image(ClientPtr client,
{
struct sna_video *video = port->devPriv.ptr;
struct sna *sna = video->sna;
- struct sna_video_frame frame;
- xf86CrtcPtr crtc;
- BoxRec dst_box;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(sna->scrn);
RegionRec clip;
- int ret;
+ int ret, i;
clip.extents.x1 = draw->x + drw_x;
clip.extents.y1 = draw->y + drw_y;
@@ -363,8 +375,6 @@ static int sna_video_sprite_put_image(ClientPtr client,
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",
__FUNCTION__,
@@ -377,87 +387,151 @@ static int sna_video_sprite_put_image(ClientPtr client,
clip.extents.x1, clip.extents.y1,
clip.extents.x2, clip.extents.y2));
- sna_video_frame_init(video, format->id, width, height, &frame);
+ if (RegionNil(&clip)) {
+ ret = Success;
+ goto err;
+ }
- if (!sna_video_clip_helper(video, &frame, &crtc, &dst_box,
- src_x, src_y, draw->x + drw_x, draw->y + drw_y,
- src_w, src_h, drw_w, drw_h,
- &clip))
- goto invisible;
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+ struct sna_video_frame frame;
+ int pipe;
+ INT32 x1, x2, y1, y2;
+ BoxRec dst;
+ RegionRec reg;
+ Rotation rotation;
- if (!crtc || sna_crtc_to_sprite(crtc) == 0)
- goto invisible;
+ if (sna_crtc_id(crtc) == 0)
+ break;
- /* if sprite can't handle rotation natively, store it for the copy func */
- video->rotation = RR_Rotate_0;
- if (!sna_crtc_set_sprite_rotation(crtc, crtc->rotation)) {
- sna_crtc_set_sprite_rotation(crtc, RR_Rotate_0);
- video->rotation = crtc->rotation;
- }
+ pipe = sna_crtc_to_pipe(crtc);
+
+ sna_video_frame_init(video, format->id, width, height, &frame);
+
+ reg.extents = crtc->bounds;
+ reg.data = NULL;
+ RegionIntersect(&reg, &reg, &clip);
+ if (RegionNil(&reg)) {
+off:
+ if (video->bo[pipe]) {
+ struct drm_mode_set_plane s;
+ memset(&s, 0, sizeof(s));
+ s.plane_id = sna_crtc_to_sprite(crtc);
+ if (drmIoctl(video->sna->kgem.fd, DRM_IOCTL_MODE_SETPLANE, &s))
+ xf86DrvMsg(video->sna->scrn->scrnIndex, X_ERROR,
+ "failed to disable plane\n");
+ video->bo[pipe] = NULL;
+ }
+ continue;
+ }
+
+ x1 = src_x;
+ x2 = src_x + src_w;
+ y1 = src_y;
+ y2 = src_y + src_h;
+
+ dst = clip.extents;
+
+ ret = xf86XVClipVideoHelper(&dst, &x1, &x2, &y1, &y2,
+ &reg, frame.width, frame.height);
+ RegionUninit(&reg);
+ if (!ret)
+ goto off;
+
+ frame.src.x1 = x1 >> 16;
+ frame.src.y1 = y1 >> 16;
+ frame.src.x2 = (x2 + 0xffff) >> 16;
+ frame.src.y2 = (y2 + 0xffff) >> 16;
+
+ frame.image.x1 = frame.src.x1 & ~1;
+ frame.image.x2 = ALIGN(frame.src.x2, 2);
+ if (is_planar_fourcc(frame.id)) {
+ frame.image.y1 = frame.src.y1 & ~1;
+ frame.image.y2 = ALIGN(frame.src.y2, 2);
+ } else {
+ frame.image.y1 = frame.src.y1;
+ frame.image.y2 = frame.src.y2;
+ }
- if (xvmc_passthrough(format->id)) {
- DBG(("%s: using passthough, name=%d\n",
- __FUNCTION__, *(uint32_t *)buf));
+ /* 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);
+ rotation = crtc->rotation;
+ }
+ sna_video_frame_set_rotation(video, &frame, rotation);
- if (*(uint32_t*)buf == 0)
- goto invisible;
+ if (xvmc_passthrough(format->id)) {
+ DBG(("%s: using passthough, name=%d\n",
+ __FUNCTION__, *(uint32_t *)buf));
- frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf);
- if (frame.bo == NULL)
- return BadAlloc;
+ if (*(uint32_t*)buf == 0)
+ goto err;
- if (kgem_bo_size(frame.bo) < frame.size) {
- DBG(("%s: bo size=%d, expected=%d\n",
- __FUNCTION__, kgem_bo_size(frame.bo), frame.size));
- kgem_bo_destroy(&sna->kgem, frame.bo);
- return BadAlloc;
- }
+ frame.bo = kgem_create_for_name(&sna->kgem, *(uint32_t*)buf);
+ if (frame.bo == NULL) {
+ ret = BadAlloc;
+ goto err;
+ }
- frame.image.x1 = 0;
- frame.image.y1 = 0;
- frame.image.x2 = frame.width;
- frame.image.y2 = frame.height;
- } else {
- frame.bo = sna_video_buffer(video, &frame);
- if (frame.bo == NULL) {
- DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
- return BadAlloc;
+ if (kgem_bo_size(frame.bo) < frame.size) {
+ DBG(("%s: bo size=%d, expected=%d\n",
+ __FUNCTION__, kgem_bo_size(frame.bo), frame.size));
+ kgem_bo_destroy(&sna->kgem, frame.bo);
+ ret = BadAlloc;
+ goto err;
+ }
+
+ frame.image.x1 = 0;
+ frame.image.y1 = 0;
+ frame.image.x2 = frame.width;
+ frame.image.y2 = frame.height;
+ } else {
+ frame.bo = sna_video_buffer(video, &frame);
+ if (frame.bo == NULL) {
+ DBG(("%s: failed to allocate video bo\n", __FUNCTION__));
+ ret = BadAlloc;
+ goto err;
+ }
+
+ if (!sna_video_copy_data(video, &frame, buf)) {
+ DBG(("%s: failed to copy video data\n", __FUNCTION__));
+ ret = BadAlloc;
+ goto err;
+ }
}
- if (!sna_video_copy_data(video, &frame, buf)) {
- DBG(("%s: failed to copy video data\n", __FUNCTION__));
- return BadAlloc;
+ ret = Success;
+ if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst)) {
+ DBG(("%s: failed to show video frame\n", __FUNCTION__));
+ ret = BadAlloc;
}
- }
- ret = Success;
- if (!sna_video_sprite_show(sna, video, &frame, crtc, &dst_box)) {
- DBG(("%s: failed to show video frame\n", __FUNCTION__));
- ret = BadAlloc;
- } else {
- //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);
- sna_window_set_port((WindowPtr)draw, port);
+ frame.bo->domain = DOMAIN_NONE;
+ if (xvmc_passthrough(format->id))
+ kgem_bo_destroy(&sna->kgem, frame.bo);
+ else
+ sna_video_buffer_fini(video);
+
+ if (ret != Success)
+ goto err;
}
- frame.bo->domain = DOMAIN_NONE;
- if (xvmc_passthrough(format->id))
- kgem_bo_destroy(&sna->kgem, frame.bo);
- else
- sna_video_buffer_fini(video);
+ 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);
+ sna_window_set_port((WindowPtr)draw, port);
- return ret;
+ return Success;
-invisible:
- /* If the video isn't visible on any CRTC, turn it off */
- return sna_video_sprite_stop(client, port, draw);
+err:
+ (void)sna_video_sprite_stop(client, port, draw);
+ return ret;
}
static int sna_video_sprite_query(ClientPtr client,
@@ -604,7 +678,7 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
video->sna = sna;
video->alignment = 64;
video->color_key = sna_video_sprite_color_key(sna);
- video->color_key_changed = true;
+ video->color_key_changed = ~0;
video->has_color_key = true;
video->brightness = -19; /* (255/219) * -16 */
video->contrast = 75; /* 255/219 * 64 */
@@ -616,11 +690,12 @@ void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
video->gamma2 = 0x202020;
video->gamma1 = 0x101010;
video->gamma0 = 0x080808;
- video->rotation = RR_Rotate_0;
RegionNull(&video->clip);
+ video->SyncToVblank = 1;
xvColorKey = MAKE_ATOM("XV_COLORKEY");
xvAlwaysOnTop = MAKE_ATOM("XV_ALWAYS_ON_TOP");
+ xvSyncToVblank = MAKE_ATOM("XV_SYNC_TO_VBLANK");
}
#else
void sna_video_sprite_setup(struct sna *sna, ScreenPtr screen)
diff --git a/src/sna/sna_video_textured.c b/src/sna/sna_video_textured.c
index b7f4d4fc..c2a37bf1 100644
--- a/src/sna/sna_video_textured.c
+++ b/src/sna/sna_video_textured.c
@@ -211,6 +211,8 @@ sna_video_textured_put_image(ClientPtr client,
&clip))
return Success;
+ sna_video_frame_set_rotation(video, &frame, RR_Rotate_0);
+
if (xvmc_passthrough(format->id)) {
DBG(("%s: using passthough, name=%d\n",
__FUNCTION__, *(uint32_t *)buf));
@@ -403,7 +405,6 @@ void sna_video_textured_setup(struct sna *sna, ScreenPtr screen)
v->sna = sna;
v->textured = true;
v->alignment = 4;
- v->rotation = RR_Rotate_0;
v->SyncToVblank = (sna->flags & SNA_NO_WAIT) == 0;
RegionNull(&v->clip);