diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2015-01-07 09:58:37 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-01-07 09:58:37 +0000 |
commit | 362d455947701dcb8ce4a01100282e56821be401 (patch) | |
tree | aad1685c0a2c5d3d8fc32e950b85f5a03ae4e02e /src | |
parent | 5d4b00032c262284904fcbfe3a6303c6d7e7939c (diff) |
sna/video: Provide fallback support for filling the colorkey
If the GPU is wedged, we cannot use the blitter for filling the
colorkey, so provide an interface to write the value using the GTT
instead.
Reported-by: Zdenek Kabelac <zkabelac@redhat.com>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src')
-rw-r--r-- | src/sna/sna_video_overlay.c | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/src/sna/sna_video_overlay.c b/src/sna/sna_video_overlay.c index ac81f1a0..ee986fe3 100644 --- a/src/sna/sna_video_overlay.c +++ b/src/sna/sna_video_overlay.c @@ -449,6 +449,70 @@ sna_video_overlay_show(struct sna *sna, return true; } +static bool fill_colorkey(struct sna_video *video, const RegionRec *clip) +{ + struct sna *sna = video->sna; + PixmapPtr front = sna->front; + struct kgem_bo *bo = __sna_pixmap_get_bo(front); + uint8_t *dst, *tmp; + int w, width; + bool ret; + + assert(bo); + + if (!wedged(sna) && + sna_blt_fill_boxes(sna, GXcopy, bo, + front->drawable.bitsPerPixel, + video->color_key, + region_rects(clip), + region_num_rects(clip))) + return true; + + dst = kgem_bo_map__gtt(&sna->kgem, bo); + if (dst == NULL) + return false; + + w = front->drawable.bitsPerPixel/8; + width = (clip->extents.x2 - clip->extents.x1) * w; + tmp = malloc(width); + if (tmp == NULL) + return false; + + memcpy(tmp, &video->color_key, w); + while (2 * w < width) { + memcpy(tmp + w, tmp, w); + w *= 2; + } + if (w < width) + memcpy(tmp + w, tmp, width - w); + + ret = false; + if (sigtrap_get() == 0) { + const BoxRec *box = region_rects(clip); + int n = region_num_rects(clip); + + w = front->drawable.bitsPerPixel/8; + do { + int y = box->y1; + uint8_t *row = dst + y*bo->pitch + w*box->x1; + + width = (box->x2 - box->x1) * w; + while (y < box->y2) { + memcpy(row, tmp, width); + row += bo->pitch; + y++; + } + box++; + } while (--n); + sigtrap_put(); + + ret = true; + } + + free(tmp); + return ret; +} + static int sna_video_overlay_put_image(ddPutImage_ARGS) { @@ -552,13 +616,9 @@ sna_video_overlay_put_image(ddPutImage_ARGS) if (sna_video_overlay_show (sna, video, &frame, crtc, &dstBox, src_w, src_h, drw_w, drw_h)) { //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, - region_rects(&clip), - region_num_rects(&clip))) + if (!video->AlwaysOnTop && + !RegionEqual(&video->clip, &clip) && + fill_colorkey(video, &clip)) RegionCopy(&video->clip, &clip); sna_window_set_port((WindowPtr)draw, port); } else { |