summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2014-09-10 22:23:46 +0100
committerRussell King <rmk@arm.linux.org.uk>2014-09-12 11:03:43 +0100
commit36db458287cdd0e59d4f70ca784afd7fc3d03fd0 (patch)
treec89be3d1f5928b11083f2297aaa5546d8a8655e1
parentedf9d8321ae0b45480e295a4e6873a665b077009 (diff)
downloadxf86-video-armada-36db458287cdd0e59d4f70ca784afd7fc3d03fd0.tar.gz
xf86-video-armada-36db458287cdd0e59d4f70ca784afd7fc3d03fd0.tar.xz
vivante: fetch solid colour and convert to ARGB8888
When fetching the solid colour to fill the temporary composite pixmap, always ensure that it is formatted for ARGB8888 to match the destination format. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--src/vivante_accel.c91
1 files changed, 73 insertions, 18 deletions
diff --git a/src/vivante_accel.c b/src/vivante_accel.c
index 1e4a96d..83f4915 100644
--- a/src/vivante_accel.c
+++ b/src/vivante_accel.c
@@ -31,6 +31,16 @@
#include <gc_hal_enum.h>
#include <gc_hal.h>
+static inline uint32_t scale16(uint32_t val, int bits)
+{
+ val <<= (16 - bits);
+ while (bits < 16) {
+ val |= val >> bits;
+ bits <<= 1;
+ }
+ return val >> 8;
+}
+
static CARD32 get_first_pixel(DrawablePtr pDraw)
{
union { CARD32 c32; CARD16 c16; CARD8 c8; char c; } pixel;
@@ -1226,6 +1236,63 @@ static Bool vivante_picture_is_solid(PicturePtr pict, CARD32 *colour)
return FALSE;
}
+static Bool vivante_pict_solid_argb(PicturePtr pict, uint32_t *col)
+{
+ unsigned r, g, b, a, rbits, gbits, bbits, abits;
+ PictFormatPtr pFormat;
+ xRenderColor colour;
+ CARD32 pixel;
+ uint32_t argb;
+
+ if (!vivante_picture_is_solid(pict, &pixel))
+ return FALSE;
+
+ pFormat = pict->pFormat;
+ /* If no format (eg, source-only) assume it's the correct format */
+ if (!pFormat || pict->format == PICT_a8r8g8b8) {
+ *col = pixel;
+ return TRUE;
+ }
+
+ switch (pFormat->type) {
+ case PictTypeDirect:
+ r = (pixel >> pFormat->direct.red) & pFormat->direct.redMask;
+ g = (pixel >> pFormat->direct.green) & pFormat->direct.greenMask;
+ b = (pixel >> pFormat->direct.blue) & pFormat->direct.blueMask;
+ a = (pixel >> pFormat->direct.alpha) & pFormat->direct.alphaMask;
+ rbits = Ones(pFormat->direct.redMask);
+ gbits = Ones(pFormat->direct.greenMask);
+ bbits = Ones(pFormat->direct.blueMask);
+ abits = Ones(pFormat->direct.alphaMask);
+ if (abits)
+ argb = scale16(a, abits) << 24;
+ else
+ argb = 0xff000000;
+ if (rbits)
+ argb |= scale16(r, rbits) << 16;
+ if (gbits)
+ argb |= scale16(g, gbits) << 8;
+ if (bbits)
+ argb |= scale16(b, bbits);
+ break;
+ case PictTypeIndexed:
+ miRenderPixelToColor(pFormat, pixel, &colour);
+ argb = (colour.alpha >> 8) << 24;
+ argb |= (colour.red >> 8) << 16;
+ argb |= (colour.green >> 8) << 8;
+ argb |= (colour.blue >> 8);
+ break;
+ default:
+ /* unknown type, just assume pixel value */
+ argb = pixel;
+ break;
+ }
+
+ *col = argb;
+
+ return TRUE;
+}
+
/*
* If we're filling a solid
* surface, force it to have alpha; it may be used in combination
@@ -1240,14 +1307,12 @@ static struct vivante_pixmap *vivante_acquire_src(struct vivante *vivante,
PixmapPtr pPixmap;
struct vivante_pixmap *vSrc;
DrawablePtr drawable = pict->pDrawable;
- CARD32 colour;
+ uint32_t colour;
int tx, ty, ox, oy;
- if (vivante_picture_is_solid(pict, &colour)) {
+ if (vivante_pict_solid_argb(pict, &colour)) {
*xout = 0;
*yout = 0;
- if (PICT_FORMAT_A(pict->format) == 0)
- colour |= 0xff000000;
if (!vivante_fill_single(vivante, vTemp, clip, colour))
return NULL;
vivante_flush(vivante);
@@ -1405,7 +1470,7 @@ fprintf(stderr, "%s: i: op 0x%02x src=%p,%d,%d mask=%p,%d,%d dst=%p,%d,%d %ux%u\
/* Remove repeat on source or mask if useless */
adjust_repeat(pSrc, xSrc, ySrc, width, height);
if (pMask) {
- CARD32 colour;
+ uint32_t colour;
/*
* A PictOpOver with a mask looks like this:
@@ -1436,19 +1501,9 @@ fprintf(stderr, "%s: i: op 0x%02x src=%p,%d,%d mask=%p,%d,%d dst=%p,%d,%d %ux%u\
* format must not have an alpha channel.
*/
if (op == PictOpOver && !PICT_FORMAT_A(pDst->format) &&
- vivante_picture_is_solid(pMask, &colour)) {
- switch (pMask->format) {
- case PICT_a8:
- break;
- case PICT_a4:
- colour *= 0x11;
- break;
- case PICT_a1:
- colour *= 0xff;
- break;
- default:
- goto fallback;
- }
+ vivante_pict_solid_argb(pMask, &colour)) {
+ /* Convert the colour to A8 */
+ colour >>= 24;
special = vivante_composite_op[PictOpAtop];