summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@armlinux.org.uk>2018-06-23 17:30:06 +0100
committerRussell King <rmk@armlinux.org.uk>2018-06-25 16:07:46 +0100
commit3d8cbe8c5a6a3b086b73e500edd92663337b5a05 (patch)
tree352ef8b1316df1a73973798fa20dbbcff85b5870
parentd52ffe9d313bfd2bf7dd26909f4de21827789453 (diff)
etnaviv: clean up drawable picture acquisition
Acquiring the source and mask drawable pictures are actually identical operations, so we should share this code rather than duplicating it. Provide etnaviv_acquire_drawable_picture() for this purpose. Signed-off-by: Russell King <rmk@armlinux.org.uk>
-rw-r--r--etnaviv/etnaviv_render.c160
1 files changed, 76 insertions, 84 deletions
diff --git a/etnaviv/etnaviv_render.c b/etnaviv/etnaviv_render.c
index c22e58d..3c1b65a 100644
--- a/etnaviv/etnaviv_render.c
+++ b/etnaviv/etnaviv_render.c
@@ -434,55 +434,33 @@ static Bool etnaviv_workaround_nonalpha(struct etnaviv_format *fmt)
}
/*
- * Acquire the source. If we're filling a solid surface, force it to have
- * alpha; it may be used in combination with a mask. Otherwise, we ask
- * for the plain source format, with or without alpha, and convert later
- * when copying. If force_vtemp is set, we ensure that the source is in
- * our temporary pixmap.
+ * Acquire a drawable picture. origin refers to the location in untransformed
+ * space of the origin, which will be updated for the underlying pixmap origin.
+ * rotation, if non-NULL, will take the GPU rotation. Returns NULL if GPU
+ * acceleration of this drawable is not possible.
*/
-static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
- PicturePtr pict, const BoxRec *clip, PixmapPtr *ppPixTemp,
- xPoint *src_topleft, unsigned *rotation, Bool force_vtemp)
+static struct etnaviv_pixmap *etnaviv_acquire_drawable_picture(
+ ScreenPtr pScreen, PicturePtr pict, const BoxRec *clip, xPoint *origin,
+ unsigned *rotation)
{
struct etnaviv *etnaviv = etnaviv_get_screen_priv(pScreen);
- struct etnaviv_pixmap *vSrc, *vTemp;
- struct etnaviv_blend_op copy_op;
- DrawablePtr drawable;
- uint32_t colour;
- xPoint src_offset;
-
- if (etnaviv_pict_solid_argb(pict, &colour)) {
- vTemp = etnaviv_get_scratch_argb(pScreen, ppPixTemp,
- clip->x2, clip->y2);
- if (!vTemp)
- return NULL;
-
- if (!etnaviv_fill_single(etnaviv, vTemp, clip, colour))
- return NULL;
-
- src_topleft->x = 0;
- src_topleft->y = 0;
-
- if (rotation)
- *rotation = DE_ROT_MODE_ROT0;
-
- return vTemp;
- }
+ DrawablePtr drawable = pict->pDrawable;
+ struct etnaviv_pixmap *vpix;
+ xPoint offset;
- drawable = pict->pDrawable;
- vSrc = etnaviv_drawable_offset(drawable, &src_offset);
- if (!vSrc)
- goto fallback;
+ vpix = etnaviv_drawable_offset(drawable, &offset);
+ if (!vpix)
+ return NULL;
- src_offset.x += drawable->x;
- src_offset.y += drawable->y;
+ offset.x += drawable->x;
+ offset.y += drawable->y;
- etnaviv_set_format(vSrc, pict);
- if (!etnaviv_src_format_valid(etnaviv, vSrc->pict_format))
- goto fallback;
+ etnaviv_set_format(vpix, pict);
+ if (!etnaviv_src_format_valid(etnaviv, vpix->pict_format))
+ return NULL;
- if (!picture_has_pixels(pict, *src_topleft, clip))
- goto fallback;
+ if (!picture_has_pixels(pict, *origin, clip))
+ return NULL;
if (pict->transform) {
struct transform_properties prop;
@@ -490,24 +468,24 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
struct pixman_vector vec;
if (!picture_transform(pict, &prop))
- goto fallback;
+ return NULL;
if (rotation) {
switch (prop.rot_mode) {
case DE_ROT_MODE_ROT180: /* 180°, aka inverted */
case DE_ROT_MODE_ROT270: /* 90° clockwise, aka right */
if (!VIV_FEATURE(etnaviv->conn, chipMinorFeatures0, 2DPE20))
- goto fallback;
+ return NULL;
/* fallthrough */
case DE_ROT_MODE_ROT0: /* no rotation, aka normal */
case DE_ROT_MODE_ROT90: /* 90° anti-clockwise, aka left */
break;
default:
- goto fallback;
+ return NULL;
}
*rotation = prop.rot_mode;
} else if (prop.rot_mode != DE_ROT_MODE_ROT0) {
- goto fallback;
+ return NULL;
}
/* Map the drawable source offsets to destination coords.
@@ -519,24 +497,66 @@ static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
* We need to do some fiddling here to calculate the source
* origin values.
*/
- vec.vector[0] = pixman_int_to_fixed(src_offset.x + prop.translation.x);
- vec.vector[1] = pixman_int_to_fixed(src_offset.y + prop.translation.y);
+ vec.vector[0] = pixman_int_to_fixed(offset.x + prop.translation.x);
+ vec.vector[1] = pixman_int_to_fixed(offset.y + prop.translation.y);
vec.vector[2] = pixman_int_to_fixed(0);
pixman_transform_invert(&inv, pict->transform);
pixman_transform_point(&inv, &vec);
- src_topleft->x += pixman_fixed_to_int(vec.vector[0]);
- src_topleft->y += pixman_fixed_to_int(vec.vector[1]);
+ origin->x += pixman_fixed_to_int(vec.vector[0]);
+ origin->y += pixman_fixed_to_int(vec.vector[1]);
} else {
/* No transform, simple case */
- src_topleft->x += src_offset.x;
- src_topleft->y += src_offset.y;
+ origin->x += offset.x;
+ origin->y += offset.y;
if (rotation)
*rotation = DE_ROT_MODE_ROT0;
}
+ return vpix;
+}
+
+/*
+ * Acquire the source. If we're filling a solid surface, force it to have
+ * alpha; it may be used in combination with a mask. Otherwise, we ask
+ * for the plain source format, with or without alpha, and convert later
+ * when copying. If force_vtemp is set, we ensure that the source is in
+ * our temporary pixmap.
+ */
+static struct etnaviv_pixmap *etnaviv_acquire_src(ScreenPtr pScreen,
+ PicturePtr pict, const BoxRec *clip, PixmapPtr *ppPixTemp,
+ xPoint *src_topleft, unsigned *rotation, Bool force_vtemp)
+{
+ struct etnaviv *etnaviv = etnaviv_get_screen_priv(pScreen);
+ struct etnaviv_pixmap *vSrc, *vTemp;
+ struct etnaviv_blend_op copy_op;
+ uint32_t colour;
+
+ if (etnaviv_pict_solid_argb(pict, &colour)) {
+ vTemp = etnaviv_get_scratch_argb(pScreen, ppPixTemp,
+ clip->x2, clip->y2);
+ if (!vTemp)
+ return NULL;
+
+ if (!etnaviv_fill_single(etnaviv, vTemp, clip, colour))
+ return NULL;
+
+ src_topleft->x = 0;
+ src_topleft->y = 0;
+
+ if (rotation)
+ *rotation = DE_ROT_MODE_ROT0;
+
+ return vTemp;
+ }
+
+ vSrc = etnaviv_acquire_drawable_picture(pScreen, pict, clip,
+ src_topleft, rotation);
+ if (!vSrc)
+ goto fallback;
+
if (force_vtemp)
goto copy_to_vtemp;
@@ -766,40 +786,12 @@ static int etnaviv_accel_composite_masked(PicturePtr pSrc, PicturePtr pMask,
mask_op.dst_mode = DE_BLENDMODE_COLOR;
}
- if (pMask->pDrawable) {
- xPoint mo;
- int tx, ty;
-
- /* We don't handle mask repeats (yet) */
- if (!picture_has_pixels(pMask, mask_offset, &clip_temp))
- goto fallback;
-
- if (!transform_is_integer_translation(pMask->transform, &tx, &ty))
- goto fallback;
-
- mask_offset.x += pMask->pDrawable->x + tx;
- mask_offset.y += pMask->pDrawable->y + ty;
-
- /*
- * Check whether the mask has a etna bo backing it. If not,
- * fallback to software for the mask operation.
- */
- vMask = etnaviv_drawable_offset(pMask->pDrawable, &mo);
- if (!vMask)
- goto fallback;
-
- if (vMask->width < clip_temp.x2 || vMask->height < clip_temp.y2)
- goto fallback;
-
- mask_offset.x += mo.x;
- mask_offset.y += mo.y;
- } else {
+ if (!pMask->pDrawable)
goto fallback;
- }
-
- etnaviv_set_format(vMask, pMask);
- if (!etnaviv_src_format_valid(etnaviv, vMask->pict_format))
+ vMask = etnaviv_acquire_drawable_picture(pScreen, pMask, &clip_temp,
+ &mask_offset, NULL);
+ if (!vMask)
goto fallback;
/*