xf86-video-intel: 3 commits - src/sna/kgem.c src/sna/sna_video.c src/sna/sna_video.h src/sna/sna_video_sprite.c

Chris Wilson ickle at kemper.freedesktop.org
Sun Sep 29 03:24:47 PDT 2013


 src/sna/kgem.c             |   47 +++++++++++++++++++++++++++++++++++++++++++--
 src/sna/sna_video.c        |    9 ++++++++
 src/sna/sna_video.h        |    1 
 src/sna/sna_video_sprite.c |    5 ++++
 4 files changed, 60 insertions(+), 2 deletions(-)

New commits:
commit 0dd20381364aabede2e1306945abe21d57c1d7b4
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 29 11:19:46 2013 +0100

    sna: Resize an existing framebuffer if possible
    
    Sometimes we may have a compatible scanout cached, but of the wrong
    size. Instead of throwing away the memory and creating a new scanout
    from scratch, allow us to just resize the old scanout by destroying and
    recreating its associated framebuffer.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 4bd12f6..215d607 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -3913,7 +3913,7 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 	bucket = cache_bucket(size);
 
 	if (flags & CREATE_SCANOUT) {
-		struct kgem_bo *last = NULL;
+		struct kgem_bo *last = NULL, *first = NULL;
 
 		list_for_each_entry_reverse(bo, &kgem->scanout, list) {
 			assert(bo->scanout);
@@ -3924,8 +3924,11 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			if (size > num_pages(bo) || num_pages(bo) > 2*size)
 				continue;
 
-			if (!check_scanout_size(kgem, bo, width, height))
+			if (!check_scanout_size(kgem, bo, width, height)) {
+				if (first == NULL)
+					first = bo;
 				continue;
+			}
 
 			if (bo->tiling != tiling ||
 			    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
@@ -3965,6 +3968,46 @@ struct kgem_bo *kgem_create_2d(struct kgem *kgem,
 			return last;
 		}
 
+		if (first) {
+			ScrnInfoPtr scrn =
+				container_of(kgem, struct sna, kgem)->scrn;
+
+			if (scrn->vtSema) {
+				DBG(("%s: recreate fb %dx%d@%d/%d\n",
+				     __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel));
+
+				if (bo->tiling != tiling ||
+				    (tiling != I915_TILING_NONE && bo->pitch != pitch)) {
+					if (gem_set_tiling(kgem->fd, bo->handle,
+							   tiling, pitch)) {
+						bo->tiling = tiling;
+						bo->pitch = pitch;
+					}
+				}
+
+				if (bo->tiling == tiling && bo->pitch == pitch) {
+					struct drm_mode_fb_cmd arg;
+
+					VG_CLEAR(arg);
+					arg.width = width;
+					arg.height = height;
+					arg.pitch = bo->pitch;
+					arg.bpp = scrn->bitsPerPixel;
+					arg.depth = scrn->depth;
+					arg.handle = bo->handle;
+
+					drmIoctl(kgem->fd, DRM_IOCTL_MODE_RMFB, &bo->delta);
+					if (drmIoctl(kgem->fd, DRM_IOCTL_MODE_ADDFB, &arg)) {
+						bo->scanout = false;
+						kgem_bo_free(kgem, bo);
+					} else {
+						bo->delta = arg.fb_id;
+						return bo;
+					}
+				}
+			}
+		}
+
 		bo = __kgem_bo_create_as_display(kgem, size, tiling, pitch);
 		if (bo)
 			return bo;
commit 902ce98df10c221e136c416f981c3a2730410415
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 29 11:08:19 2013 +0100

    sna/video: Don't allow caching of yuv scanouts
    
    We only want scanouts capable of being used for the front buffer in our
    cache, so make sure that YUV formatted fb are destroyed upon release.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video_sprite.c b/src/sna/sna_video_sprite.c
index 43cb5c4..b6e7b94 100644
--- a/src/sna/sna_video_sprite.c
+++ b/src/sna/sna_video_sprite.c
@@ -242,6 +242,7 @@ sna_video_sprite_show(struct sna *sna,
 	if (frame->bo->delta == 0) {
 		uint32_t offsets[4], pitches[4], handles[4];
 		uint32_t pixel_format;
+		bool purged = true;
 
 		handles[0] = frame->bo->handle;
 		pitches[0] = frame->pitch[0];
@@ -250,9 +251,11 @@ sna_video_sprite_show(struct sna *sna,
 		switch (frame->id) {
 		case FOURCC_RGB565:
 			pixel_format = DRM_FORMAT_RGB565;
+			purged = sna->scrn->depth != 16;
 			break;
 		case FOURCC_RGB888:
 			pixel_format = DRM_FORMAT_XRGB8888;
+			purged = sna->scrn->depth != 24;
 			break;
 		case FOURCC_UYVY:
 			pixel_format = DRM_FORMAT_UYVY;
@@ -277,6 +280,8 @@ sna_video_sprite_show(struct sna *sna,
 		}
 
 		frame->bo->scanout = true;
+		/* Don't allow the scanout to be cached if not suitable for front */
+		frame->bo->purged = purged;
 	}
 
 	assert(frame->bo->scanout);
commit 4a7587ca1c076f25eed67751f9a9e26c5dcd1692
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Sep 29 10:57:23 2013 +0100

    sna/video: Discard old video buffers when the frame size changes
    
    Back in the good old days of the overlay, we only needed to care about
    having a frame buffer large enough to hold the data. This changed with
    the sprite interface which encodes the width x height into the
    framebuffer and so we need to be careful when handing back a cached
    buffer that it does indeed match the required dimensions.
    
    Reported-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/sna/sna_video.c b/src/sna/sna_video.c
index 2083a22..61f6615 100644
--- a/src/sna/sna_video.c
+++ b/src/sna/sna_video.c
@@ -96,6 +96,12 @@ sna_video_buffer(struct sna_video *video,
 	if (video->buf && __kgem_bo_size(video->buf) < frame->size)
 		sna_video_free_buffers(video);
 
+	if (video->buf && video->buf->scanout) {
+		if (frame->width != video->width ||
+		    frame->height != video->height)
+			sna_video_free_buffers(video);
+	}
+
 	if (video->buf == NULL) {
 		if (video->tiled) {
 			video->buf = kgem_create_2d(&video->sna->kgem,
@@ -107,6 +113,9 @@ sna_video_buffer(struct sna_video *video,
 		}
 	}
 
+	video->width  = frame->width;
+	video->height = frame->height;
+
 	return video->buf;
 }
 
diff --git a/src/sna/sna_video.h b/src/sna/sna_video.h
index cbb3ea3..996377b 100644
--- a/src/sna/sna_video.h
+++ b/src/sna/sna_video.h
@@ -92,6 +92,7 @@ struct sna_video {
 	/** YUV data buffers */
 	struct kgem_bo *old_buf[2];
 	struct kgem_bo *buf;
+	int width, height;
 
 	int alignment;
 	bool tiled;


More information about the xorg-commit mailing list