[PATCH 1/7] etnaviv: always assume pixmap 3D usage if DRI2 is enabled

Russell King rmk at armlinux.org.uk
Tue Nov 22 19:20:09 UTC 2016


On Tue, Nov 22, 2016 at 12:44:14PM +0100, Lucas Stach wrote:
> The texture-from-pixmap extension allows to construct a GL
> texture from any pixmap. The GL textures can then be bound
> to an FBO for rendering, so all pixmaps must be properly
> aligned to be used with the 3D core if DRI2 is enabled.

Given that the number of pixmaps that get this treatment are likely
to be very low, it would be nice not to penalise every pixmap
allocation.  Something like this:

 etnaviv/etnaviv_dri2.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

diff --git a/etnaviv/etnaviv_dri2.c b/etnaviv/etnaviv_dri2.c
index 1ecd28b..0d6f206 100644
--- a/etnaviv/etnaviv_dri2.c
+++ b/etnaviv/etnaviv_dri2.c
@@ -38,6 +38,34 @@ struct etnaviv_dri2_info {
 	char *devname;
 };
 
+static Bool etnaviv_replace_drawable(DrawablePtr drawable, PixmapPtr pixmap)
+{
+	PixmapPtr old_pixmap = drawable_pixmap(drawable);
+	struct etnaviv_pixmap *opix;
+	GCPtr gc;
+
+	/* Copy the old drawable to the new buffer */
+
+	gc = GetScratchGC(pixmap->drawable.depth, drawable->pScreen);
+	if (!gc)
+		return FALSE;
+
+	ValidateGC(&pixmap->drawable, gc);
+	gc->ops->CopyArea(drawable, &pixmap->drawable, gc, 0, 0,
+			  drawable->width, drawable->height,
+			  0, 0);
+	FreeScratchGC(gc);
+
+	opix = etnaviv_get_pixmap_priv(old_pixmap);
+	if (opix) {
+		etnaviv_set_pixmap_priv(old_pixmap,
+					etnaviv_get_pixmap_priv(pixmap));
+		etnaviv_set_pixmap_priv(pixmap, opix);
+	}
+
+	return TRUE;
+}
+
 static DRI2Buffer2Ptr etnaviv_dri2_CreateBuffer(DrawablePtr drawable,
 	unsigned int attachment, unsigned int format)
 {
@@ -51,9 +79,15 @@ static DRI2Buffer2Ptr etnaviv_dri2_CreateBuffer(DrawablePtr drawable,
 		return NULL;
 
 	if (attachment == DRI2BufferFrontLeft) {
+		struct etnaviv_pixmap *vpix;
+		uint32_t pitch;
+
 		pixmap = drawable_pixmap(drawable);
+		vpix = etnaviv_get_pixmap_priv(pixmap);
+		pitch = etnaviv_3d_pitch(pixmap->drawable.width,
+					 pixmap->drawable.bitsPerPixel);
 
-		if (!etnaviv_get_pixmap_priv(pixmap)) {
+		if (!vpix || vpix->pitch < pitch) {
 			/* Force the backing buffer to be reallocated */
 			drawable = &pixmap->drawable;
 			pixmap = NULL;
@@ -68,6 +102,10 @@ static DRI2Buffer2Ptr etnaviv_dri2_CreateBuffer(DrawablePtr drawable,
 						   CREATE_PIXMAP_USAGE_3D);
 		if (!pixmap)
 			goto err;
+
+		if (attachment == DRI2BufferFrontLeft &&
+		    !etnaviv_replace_drawable(drawable, pixmap))
+			goto err;
 	}
 
 	if (!etnaviv_pixmap_flink(pixmap, &name))


-- 
Russell King


More information about the etnaviv mailing list