From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/src/gfx/generic/generic.c | 9161 +++++++++++++++++++++++++++++ 1 file changed, 9161 insertions(+) create mode 100755 Source/DirectFB/src/gfx/generic/generic.c (limited to 'Source/DirectFB/src/gfx/generic/generic.c') diff --git a/Source/DirectFB/src/gfx/generic/generic.c b/Source/DirectFB/src/gfx/generic/generic.c new file mode 100755 index 0000000..9b7cdeb --- /dev/null +++ b/Source/DirectFB/src/gfx/generic/generic.c @@ -0,0 +1,9161 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp , + Andreas Hundt , + Sven Neumann , + Ville Syrjälä and + Claudio Ciccani . + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "generic.h" +#include "duffs_device.h" + + +/* lookup tables for 2/3bit to 8bit color conversion */ +static const u8 lookup3to8[] = { 0x00, 0x24, 0x49, 0x6d, 0x92, 0xb6, 0xdb, 0xff}; +static const u8 lookup2to8[] = { 0x00, 0x55, 0xaa, 0xff}; + +#define EXPAND_1to8(v) ((v) ? 0xff : 0x00) +#define EXPAND_2to8(v) (lookup2to8[v]) +#define EXPAND_3to8(v) (lookup3to8[v]) +#define EXPAND_4to8(v) (((v) << 4) | ((v) )) +#define EXPAND_5to8(v) (((v) << 3) | ((v) >> 2)) +#define EXPAND_6to8(v) (((v) << 2) | ((v) >> 4)) +#define EXPAND_7to8(v) (((v) << 1) | ((v) >> 6)) + + +static int use_mmx = 0; + +#ifdef USE_MMX +static void gInit_MMX( void ); +#endif + +#if SIZEOF_LONG == 8 +static void gInit_64bit( void ); +#endif + +/* RGB16 */ +#define RGB_MASK 0xffff +#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_16 +#define Bop_PFI_OP_Aop_PFI( op ) Bop_16_##op##_Aop +#include "template_colorkey_16.h" + +/* ARGB1555 / RGB555 / BGR555 */ +#define RGB_MASK 0x7fff +#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_15 +#define Bop_PFI_OP_Aop_PFI( op ) Bop_15_##op##_Aop +#include "template_colorkey_16.h" + +/* ARGB2554 */ +#define RGB_MASK 0x3fff +#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_14 +#define Bop_PFI_OP_Aop_PFI( op ) Bop_14_##op##_Aop +#include "template_colorkey_16.h" + +/* ARGB4444 / RGB444*/ +#define RGB_MASK 0x0fff +#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_12 +#define Bop_PFI_OP_Aop_PFI( op ) Bop_12_##op##_Aop +#include "template_colorkey_16.h" + +/* RGBA4444 */ +#define RGB_MASK 0xfff0 +#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_12vv +#define Bop_PFI_OP_Aop_PFI( op ) Bop_12vv_##op##_Aop +#include "template_colorkey_16.h" + +/* ARGB/RGB32/AiRGB */ +#define RGB_MASK 0x00ffffff +#define Cop_OP_Aop_PFI( op ) Cop_##op##_Aop_32 +#define Bop_PFI_OP_Aop_PFI( op ) Bop_32_##op##_Aop +#include "template_colorkey_32.h" + +/* RGB16 */ +#define EXPAND_Ato8( a ) 0xFF +#define EXPAND_Rto8( r ) EXPAND_5to8( r ) +#define EXPAND_Gto8( g ) EXPAND_6to8( g ) +#define EXPAND_Bto8( b ) EXPAND_5to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB16( r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_rgb16_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_rgb16 +#define A_SHIFT 0 +#define R_SHIFT 11 +#define G_SHIFT 5 +#define B_SHIFT 0 +#define A_MASK 0 +#define R_MASK 0xf800 +#define G_MASK 0x07e0 +#define B_MASK 0x001f +#include "template_acc_16.h" + +/* ARGB1555 */ +#define EXPAND_Ato8( a ) EXPAND_1to8( a ) +#define EXPAND_Rto8( r ) EXPAND_5to8( r ) +#define EXPAND_Gto8( g ) EXPAND_5to8( g ) +#define EXPAND_Bto8( b ) EXPAND_5to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB1555( a, r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_argb1555_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb1555 +#define A_SHIFT 15 +#define R_SHIFT 10 +#define G_SHIFT 5 +#define B_SHIFT 0 +#define A_MASK 0x8000 +#define R_MASK 0x7c00 +#define G_MASK 0x03e0 +#define B_MASK 0x001f +#include "template_acc_16.h" + +/* RGB555 */ +#define EXPAND_Ato8( a ) 0xFF +#define EXPAND_Rto8( r ) EXPAND_5to8( r ) +#define EXPAND_Gto8( g ) EXPAND_5to8( g ) +#define EXPAND_Bto8( b ) EXPAND_5to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB555( r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_xrgb1555_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_xrgb1555 +#define A_SHIFT 0 +#define R_SHIFT 10 +#define G_SHIFT 5 +#define B_SHIFT 0 +#define A_MASK 0 +#define R_MASK 0x7c00 +#define G_MASK 0x03e0 +#define B_MASK 0x001f +#include "template_acc_16.h" + +/* BGR555 */ +#define EXPAND_Ato8( a ) 0xFF +#define EXPAND_Rto8( r ) EXPAND_5to8( r ) +#define EXPAND_Gto8( g ) EXPAND_5to8( g ) +#define EXPAND_Bto8( b ) EXPAND_5to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_BGR555( r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_xbgr1555_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_xbgr1555 +#define A_SHIFT 0 +#define B_SHIFT 10 +#define G_SHIFT 5 +#define R_SHIFT 0 +#define A_MASK 0 +#define B_MASK 0x7c00 +#define G_MASK 0x03e0 +#define R_MASK 0x001f +#include "template_acc_16.h" + +/* ARGB2554 */ +#define EXPAND_Ato8( a ) EXPAND_2to8( a ) +#define EXPAND_Rto8( r ) EXPAND_5to8( r ) +#define EXPAND_Gto8( g ) EXPAND_5to8( g ) +#define EXPAND_Bto8( b ) EXPAND_4to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB2554( a, r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_argb2554_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb2554 +#define A_SHIFT 14 +#define R_SHIFT 9 +#define G_SHIFT 4 +#define B_SHIFT 0 +#define A_MASK 0xc000 +#define R_MASK 0x3e00 +#define G_MASK 0x01f0 +#define B_MASK 0x000f +#include "template_acc_16.h" + +/* ARGB4444 */ +#define EXPAND_Ato8( a ) EXPAND_4to8( a ) +#define EXPAND_Rto8( r ) EXPAND_4to8( r ) +#define EXPAND_Gto8( g ) EXPAND_4to8( g ) +#define EXPAND_Bto8( b ) EXPAND_4to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB4444( a, r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_argb4444_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb4444 +#define A_SHIFT 12 +#define R_SHIFT 8 +#define G_SHIFT 4 +#define B_SHIFT 0 +#define A_MASK 0xf000 +#define R_MASK 0x0f00 +#define G_MASK 0x00f0 +#define B_MASK 0x000f +#include "template_acc_16.h" + +/* ARGB4444 */ +#define EXPAND_Ato8( a ) EXPAND_4to8( a ) +#define EXPAND_Rto8( r ) EXPAND_4to8( r ) +#define EXPAND_Gto8( g ) EXPAND_4to8( g ) +#define EXPAND_Bto8( b ) EXPAND_4to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_RGBA4444( a, r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_rgba4444_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_rgba4444 +#define A_SHIFT 0 +#define R_SHIFT 12 +#define G_SHIFT 8 +#define B_SHIFT 4 +#define A_MASK 0x000f +#define R_MASK 0xf000 +#define G_MASK 0x0f00 +#define B_MASK 0x00f0 +#include "template_acc_16.h" + +/* RGB444 */ +#define EXPAND_Ato8( a ) 0xFF +#define EXPAND_Rto8( r ) EXPAND_4to8( r ) +#define EXPAND_Gto8( g ) EXPAND_4to8( g ) +#define EXPAND_Bto8( b ) EXPAND_4to8( b ) +#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB444( r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_xrgb4444_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_xrgb4444 +#define A_SHIFT 0 +#define R_SHIFT 8 +#define G_SHIFT 4 +#define B_SHIFT 0 +#define A_MASK 0 +#define R_MASK 0x0f00 +#define G_MASK 0x00f0 +#define B_MASK 0x000f +#include "template_acc_16.h" + +/* ARGB */ +#define EXPAND_Ato8( a ) (a) +#define EXPAND_Rto8( r ) (r) +#define EXPAND_Gto8( g ) (g) +#define EXPAND_Bto8( b ) (b) +#define PIXEL_OUT( a, r, g, b ) PIXEL_ARGB( a, r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_argb_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_argb +#define A_SHIFT 24 +#define R_SHIFT 16 +#define G_SHIFT 8 +#define B_SHIFT 0 +#define A_MASK 0xff000000 +#define R_MASK 0x00ff0000 +#define G_MASK 0x0000ff00 +#define B_MASK 0x000000ff +#include "template_acc_32.h" + +/* RGB32 */ +#define EXPAND_Ato8( a ) 0xFF +#define EXPAND_Rto8( r ) (r) +#define EXPAND_Gto8( g ) (g) +#define EXPAND_Bto8( b ) (b) +#define PIXEL_OUT( a, r, g, b ) PIXEL_RGB32( r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_rgb32_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_rgb32 +#define A_SHIFT 0 +#define R_SHIFT 16 +#define G_SHIFT 8 +#define B_SHIFT 0 +#define A_MASK 0 +#define R_MASK 0x00ff0000 +#define G_MASK 0x0000ff00 +#define B_MASK 0x000000ff +#include "template_acc_32.h" + +/* AiRGB */ +#define EXPAND_Ato8( a ) ((a) ^ 0xff) +#define EXPAND_Rto8( r ) (r) +#define EXPAND_Gto8( g ) (g) +#define EXPAND_Bto8( b ) (b) +#define PIXEL_OUT( a, r, g, b ) PIXEL_AiRGB( a, r, g, b ) +#define Sop_PFI_OP_Dacc( op ) Sop_airgb_##op##_Dacc +#define Sacc_OP_Aop_PFI( op ) Sacc_##op##_Aop_airgb +#define A_SHIFT 24 +#define R_SHIFT 16 +#define G_SHIFT 8 +#define B_SHIFT 0 +#define A_MASK 0xff000000 +#define R_MASK 0x00ff0000 +#define G_MASK 0x0000ff00 +#define B_MASK 0x000000ff +#include "template_acc_32.h" + +/********************************* Cop_to_Aop_PFI *****************************/ + +static void Cop_to_Aop_8( GenefxState *gfxs ) +{ + memset( gfxs->Aop[0], gfxs->Cop, gfxs->length ); +} + +static void Cop_to_Aop_16( GenefxState *gfxs ) +{ + int w; + int l = gfxs->length; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + + u32 DCop = ((Cop << 16) | Cop); + + if (((long)D)&2) { /* align */ + u16* tmp = (u16*) D; + --l; + *tmp = Cop; + D = (u32*)(tmp+1); + } + + w = (l >> 1); + while (w) { + *D = DCop; + --w; + ++D; + } + + if (l & 1) /* do the last ential pixel */ + *((u16*)D) = (u16)Cop; +} + +static void Cop_to_Aop_18( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + + while (w) { + D[0] = Cop; + D[1] = Cop >> 8; + D[2] = Cop >> 16; + D += 3; + --w; + } +} + +static void Cop_to_Aop_24( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + + while (w) { + D[0] = gfxs->color.b; + D[1] = gfxs->color.g; + D[2] = gfxs->color.r; + + D += 3; + --w; + } +} + +static void Cop_to_Aop_32( GenefxState *gfxs ) +{ + int w = gfxs->length; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + + while (w--) + *D++ = Cop; +} + +static void Cop_to_Aop_yuv422( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + u16 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + + if ((long)D & 2) { +#ifdef WORDS_BIGENDIAN + *D++ = Cop & 0xffff; +#else + *D++ = Cop >> 16; +#endif + w--; + } + + for (l = w>>1; l--;) { + *((u32*)D) = Cop; + D += 2; + } + + if (w & 1) { +#ifdef WORDS_BIGENDIAN + *D = Cop >> 16; +#else + *D = Cop & 0xffff; +#endif + } +} + +static void Cop_to_Aop_i420( GenefxState *gfxs ) +{ + memset( gfxs->Aop[0], gfxs->YCop, gfxs->length ); + if (gfxs->AopY & 1) { + memset( gfxs->Aop[1], gfxs->CbCop, gfxs->length>>1 ); + memset( gfxs->Aop[2], gfxs->CrCop, gfxs->length>>1 ); + } +} + +static void Cop_to_Aop_nv12( GenefxState *gfxs ) +{ + memset( gfxs->Aop[0], gfxs->YCop, gfxs->length ); + + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) { + u16 *D = gfxs->Aop[1]; + int w = gfxs->length>>1; + u16 Cop = gfxs->CbCop | (gfxs->CrCop << 8); + + while (w--) + *D++ = Cop; + } +} + +static void Cop_to_Aop_nv21( GenefxState *gfxs ) +{ + memset( gfxs->Aop[0], gfxs->YCop, gfxs->length ); + + if (gfxs->AopY & 1) { + u16 *D = gfxs->Aop[1]; + int w = gfxs->length>>1; + u16 Cop = gfxs->CrCop | (gfxs->CbCop << 8); + + while (w--) + *D++ = Cop; + } +} + +static GenefxFunc Cop_to_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Cop_to_Aop_16, /* DSPF_ARGB1555 */ + Cop_to_Aop_16, /* DSPF_RGB16 */ + Cop_to_Aop_24, /* DSPF_RGB24 */ + Cop_to_Aop_32, /* DSPF_RGB32 */ + Cop_to_Aop_32, /* DSPF_ARGB */ + Cop_to_Aop_8, /* DSPF_A8 */ + Cop_to_Aop_yuv422, /* DSPF_YUY2 */ + Cop_to_Aop_8, /* DSPF_RGB332 */ + Cop_to_Aop_yuv422, /* DSPF_UYVY */ + Cop_to_Aop_i420, /* DSPF_I420 */ + Cop_to_Aop_i420, /* DSPF_YV12 */ + Cop_to_Aop_8, /* DSPF_LUT8 */ + Cop_to_Aop_8, /* DSPF_ALUT44 */ + Cop_to_Aop_32, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Cop_to_Aop_nv12, /* DSPF_NV12 */ + Cop_to_Aop_nv12, /* DSPF_NV16 */ + Cop_to_Aop_16, /* DSPF_ARGB2554 */ + Cop_to_Aop_16, /* DSPF_ARGB4444 */ + Cop_to_Aop_16, /* DSPF_RGBA4444 */ + Cop_to_Aop_nv21, /* DSPF_NV21 */ + Cop_to_Aop_32, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Cop_to_Aop_18, /* DSPF_ARGB1666 */ + Cop_to_Aop_18, /* DSPF_ARGB6666 */ + Cop_to_Aop_18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Cop_to_Aop_16, /* DSPF_RGB444 */ + Cop_to_Aop_16, /* DSPF_RGB555 */ + Cop_to_Aop_16 /* DSPF_BGR555 */ +}; + +/********************************* Cop_toK_Aop_PFI ****************************/ + +static void Cop_toK_Aop_8( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (Dkey == *D) + *D = Cop; + + D++; + } +} + +static void Cop_toK_Aop_18( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + u32 Cop = gfxs->Cop; + + while (w) { + if (Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) { + D[0] = Cop; + D[1] = Cop >> 8; + D[2] = Cop >> 16; + } + D += 3; + --w; + } + +} + +static void Cop_toK_Aop_24( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u8 Dkr = (gfxs->Dkey & 0xff0000) >> 16; + u8 Dkg = (gfxs->Dkey & 0x00ff00) >> 8; + u8 Dkb = (gfxs->Dkey & 0x0000ff); + + while (w--) { + if (D[0] == Dkb && D[1] == Dkg && D[2] == Dkr) { + D[0] = gfxs->color.b; + D[1] = gfxs->color.g; + D[2] = gfxs->color.r; + } + + D += 3; + } +} + +static void Cop_toK_Aop_yuv422( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + u16 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 Dkey = gfxs->Dkey; + + if ((long)D & 2) { +#ifdef WORDS_BIGENDIAN + if (*D == (Dkey & 0xffff)) + *D = Cop & 0xffff; +#else + if (*D == (Dkey >> 16)) + *D = Cop >> 16; +#endif + D++; + w--; + } + + for (l = w>>1; l--;) { + if (*((u32*)D) == Dkey) + *((u32*)D) = Cop; + D += 2; + } + + if (w & 1) { +#ifdef WORDS_BIGENDIAN + if (*D == (Dkey >> 16)) + *D = Cop >> 16; +#else + if (*D == (Dkey & 0xffff)) + *D = Cop & 0xffff; +#endif + } +} + +static void Cop_toK_Aop_alut44( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (Dkey == (*D & 0x0F)) + *D = Cop; + + D++; + } +} + +static GenefxFunc Cop_toK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Cop_toK_Aop_15, /* DSPF_ARGB1555 */ + Cop_toK_Aop_16, /* DSPF_RGB16 */ + Cop_toK_Aop_24, /* DSPF_RGB24 */ + Cop_toK_Aop_32, /* DSPF_RGB32 */ + Cop_toK_Aop_32, /* DSPF_ARGB */ + Cop_toK_Aop_8, /* DSPF_A8 */ + Cop_toK_Aop_yuv422, /* DSPF_YUY2 */ + Cop_toK_Aop_8, /* DSPF_RGB332 */ + Cop_toK_Aop_yuv422, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Cop_toK_Aop_8, /* DSPF_LUT8 */ + Cop_toK_Aop_alut44, /* DSPF_ALUT44 */ + Cop_toK_Aop_32, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Cop_toK_Aop_14, /* DSPF_ARGB2554 */ + Cop_toK_Aop_12, /* DSPF_ARGB4444 */ + Cop_toK_Aop_12vv, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + Cop_toK_Aop_32, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Cop_toK_Aop_18, /* DSPF_ARGB1666 */ + Cop_toK_Aop_18, /* DSPF_ARGB6666 */ + Cop_toK_Aop_18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Cop_toK_Aop_12, /* DSPF_RGB444 */ + Cop_toK_Aop_15, /* DSPF_RGB555 */ + Cop_toK_Aop_15 /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_to_Aop_PFI *************************/ + +static void Bop_4_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length>>1 ); +} + +static void Bop_8_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length ); +} + +static void Bop_16_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length*2 ); +} + +static void Bop_24_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length*3 ); +} + +static void Bop_32_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length*4 ); +} + +static void Bop_i420_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length ); + if (gfxs->AopY & 1) { + direct_memmove( gfxs->Aop[1], gfxs->Bop[1], gfxs->length>>1 ); + direct_memmove( gfxs->Aop[2], gfxs->Bop[2], gfxs->length>>1 ); + } +} + +static void Bop_NV_to_Aop( GenefxState *gfxs ) +{ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length ); + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) + direct_memmove( gfxs->Aop[1], gfxs->Bop[1], gfxs->length&~1 ); +} + +static GenefxFunc Bop_PFI_to_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_16_to_Aop, /* DSPF_ARGB1555 */ + Bop_16_to_Aop, /* DSPF_RGB16 */ + Bop_24_to_Aop, /* DSPF_RGB24 */ + Bop_32_to_Aop, /* DSPF_RGB32 */ + Bop_32_to_Aop, /* DSPF_ARGB */ + Bop_8_to_Aop, /* DSPF_A8 */ + Bop_16_to_Aop, /* DSPF_YUY2 */ + Bop_8_to_Aop, /* DSPF_RGB332 */ + Bop_16_to_Aop, /* DSPF_UYVY */ + Bop_i420_to_Aop, /* DSPF_I420 */ + Bop_i420_to_Aop, /* DSPF_YV12 */ + Bop_8_to_Aop, /* DSPF_LUT8 */ + Bop_8_to_Aop, /* DSPF_ALUT44 */ + Bop_32_to_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Bop_NV_to_Aop, /* DSPF_NV12 */ + Bop_NV_to_Aop, /* DSPF_NV16 */ + Bop_16_to_Aop, /* DSPF_ARGB2554 */ + Bop_16_to_Aop, /* DSPF_ARGB4444 */ + Bop_16_to_Aop, /* DSPF_RGBA4444 */ + Bop_NV_to_Aop, /* DSPF_NV21 */ + Bop_32_to_Aop, /* DSPF_AYUV */ + Bop_4_to_Aop, /* DSPF_A4 */ + Bop_24_to_Aop, /* DSPF_ARGB1666 */ + Bop_24_to_Aop, /* DSPF_ARGB6666 */ + Bop_24_to_Aop, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_16_to_Aop, /* DSPF_RGB444 */ + Bop_16_to_Aop, /* DSPF_RGB555 */ + Bop_16_to_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_toR_Aop_PFI *************************/ + +static void Bop_4_toR_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + int Dstep = gfxs->Astep; + u8 * S = gfxs->Bop[0]; + u8 * D = gfxs->Aop[0]; + while(w--) + { + *D = *S; + D += Dstep; + S++; + } +} + +static void Bop_8_toR_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int Dstep = gfxs->Astep; + u8 * S = gfxs->Bop[0]; + u8 * D = gfxs->Aop[0]; + while(w--) + { + *D = *S; + D += Dstep; + S++; + } +} + +static void Bop_16_toR_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int Dstep = gfxs->Astep; + u16 * S = gfxs->Bop[0]; + u16 * D = gfxs->Aop[0]; + while(w--) + { + *D = *S; + D += Dstep; + S++; + } +} + +static void Bop_24_toR_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int Dstep = gfxs->Astep; + u8 * S = gfxs->Bop[0]; + u8 * D = gfxs->Aop[0]; + while(w--) + { + D[0] = S[0]; + D[1] = S[1]; + D[2] = S[2]; + + D += Dstep * 3; + S += 3; + } +} + +static void Bop_32_toR_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int Dstep = gfxs->Astep; + u32 * S = gfxs->Bop[0]; + u32 * D = gfxs->Aop[0]; + while(w--) + { + *D = *S; + D += Dstep; + S++; + } +} + +static void Bop_i420_toR_Aop( GenefxState *gfxs ) +{ + Bop_8_toR_Aop( gfxs ); + if (gfxs->AopY & 1) { + int w = gfxs->length>>1; + int Dstep = gfxs->Astep>>1; + u8 * S1 = gfxs->Bop[1]; + u8 * D1 = gfxs->Aop[1]; + u8 * S2 = gfxs->Bop[2]; + u8 * D2 = gfxs->Aop[2]; + while(w--) + { + *D1 = *S1++; + *D2 = *S2++; + D1 += Dstep; + D2 += Dstep; + } + } +} + +static void Bop_NV_toR_Aop( GenefxState *gfxs ) +{ + Bop_8_toR_Aop( gfxs ); + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) { + int w = gfxs->length&~1; + int Dstep = gfxs->Astep; + u8 * S = gfxs->Bop[1]; + u8 * D = gfxs->Aop[1]; + while(w--) + { + *D = *S++; + D += Dstep; + } + } +} + +static GenefxFunc Bop_PFI_toR_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_16_toR_Aop, /* DSPF_ARGB1555 */ + Bop_16_toR_Aop, /* DSPF_RGB16 */ + Bop_24_toR_Aop, /* DSPF_RGB24 */ + Bop_32_toR_Aop, /* DSPF_RGB32 */ + Bop_32_toR_Aop, /* DSPF_ARGB */ + Bop_8_toR_Aop, /* DSPF_A8 */ + Bop_16_toR_Aop, /* DSPF_YUY2 */ + Bop_8_toR_Aop, /* DSPF_RGB332 */ + Bop_16_toR_Aop, /* DSPF_UYVY */ + Bop_i420_toR_Aop, /* DSPF_I420 */ + Bop_i420_toR_Aop, /* DSPF_YV12 */ + Bop_8_toR_Aop, /* DSPF_LUT8 */ + Bop_8_toR_Aop, /* DSPF_ALUT44 */ + Bop_32_toR_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Bop_NV_toR_Aop, /* DSPF_NV12 */ + Bop_NV_toR_Aop, /* DSPF_NV16 */ + Bop_16_toR_Aop, /* DSPF_ARGB2554 */ + Bop_16_toR_Aop, /* DSPF_ARGB4444 */ + Bop_16_toR_Aop, /* DSPF_RGBA4444 */ + Bop_NV_toR_Aop, /* DSPF_NV21 */ + Bop_32_toR_Aop, /* DSPF_AYUV */ + Bop_4_toR_Aop, /* DSPF_A4 */ + Bop_24_toR_Aop, /* DSPF_ARGB1666 */ + Bop_24_toR_Aop, /* DSPF_ARGB6666 */ + Bop_24_toR_Aop, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_16_toR_Aop, /* DSPF_RGB444 */ + Bop_16_toR_Aop, /* DSPF_RGB555 */ + Bop_16_toR_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_Kto_Aop_PFI ************************/ + +static void Bop_rgb18_Kto_Aop( GenefxState *gfxs ) +{ + + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int Ostep = gfxs->Ostep; + + if (Ostep < 0) { + D += (gfxs->length - 1) * 3; + S += (gfxs->length - 1) * 3; + } + + while (w--) { + u8 s0 = S[0]; + u8 s1 = S[1]; + u8 s2 = S[2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + D[0] = s0; + D[1] = s1; + D[2] = s2; + } + + S += Ostep * 3; + D += Ostep * 3; + } +} + +static void Bop_rgb24_Kto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int Ostep = gfxs->Ostep; + + if (Ostep < 0) { + D += (gfxs->length - 1) * 3; + S += (gfxs->length - 1) * 3; + } + + while (w--) { + u8 b = *S; + u8 g = *(S+1); + u8 r = *(S+2); + + if (Skey != (u32)(r<<16 | g<<8 | b)) { + *D = b; + *(D+1) = g; + *(D+2) = r; + } + + S += Ostep * 3; + D += Ostep * 3; + } +} + +static void Bop_a8_Kto_Aop( GenefxState *gfxs ) +{ + /* no color to key */ + direct_memmove( gfxs->Aop[0], gfxs->Bop[0], gfxs->length ); +} + +static void Bop_yuv422_Kto_Aop( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + u16 *D = gfxs->Aop[0]; + u16 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int Ostep = gfxs->Ostep; + + if (Ostep < 0) { + D += gfxs->length - 1; + S += gfxs->length - 1; + } + + if ((long)D & 2) { + u16 s = *S; +#ifdef WORDS_BIGENDIAN + if (s != (Skey >> 16)) + *D = s; +#else + if (s != (Skey & 0xffff)) + *D = s; +#endif + S += Ostep; + D += Ostep; + w--; + } + + if (Ostep < 0) { + S--; + D--; + } + + for (l = w>>1; l--;) { + u32 s = *((u32*)S); + + if (s != Skey) + *((u32*)D) = s; + + S += Ostep << 1; + D += Ostep << 1; + } + + if (w & 1) { + u16 s = *S; +#ifdef WORDS_BIGENDIAN + if (s != (Skey & 0xffff)) + *D = s; +#else + if (s != (Skey >> 16)) + *D = s; +#endif + } +} + + +/* change the last value to adjust the size of the device (1-4) */ +#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \ + SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 4 ) + +#define SET_PIXEL( D, S ) \ + do { \ + register u32 s = S; \ + \ + if (s != Skey) \ + D = s; \ + } while (0) + +static void Bop_8_Kto_Aop( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + + if (gfxs->Ostep > 0) { + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + } + else { + for (i=w-1; i>=0; i--) + if (S[i] != Skey) + D[i] = S[i]; + } +} + +#undef SET_PIXEL_DUFFS_DEVICE +#undef SET_PIXEL + +static void Bop_alut44_Kto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int Ostep = gfxs->Ostep; + + if (Ostep < 0) { + D += gfxs->length - 1; + S += gfxs->length - 1; + } + + while (w--) { + u8 spixel = *S; + + if ((spixel & 0x0F) != Skey) + *D = spixel; + + S += Ostep; + D += Ostep; + } +} + +static GenefxFunc Bop_PFI_Kto_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_15_Kto_Aop, /* DSPF_ARGB1555 */ + Bop_16_Kto_Aop, /* DSPF_RGB16 */ + Bop_rgb24_Kto_Aop, /* DSPF_RGB24 */ + Bop_32_Kto_Aop, /* DSPF_RGB32 */ + Bop_32_Kto_Aop, /* DSPF_ARGB */ + Bop_a8_Kto_Aop, /* DSPF_A8 */ + Bop_yuv422_Kto_Aop, /* DSPF_YUY2 */ + Bop_8_Kto_Aop, /* DSPF_RGB332 */ + Bop_yuv422_Kto_Aop, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Bop_8_Kto_Aop, /* DSPF_LUT8 */ + Bop_alut44_Kto_Aop, /* DSPF_ALUT44 */ + Bop_32_Kto_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_14_Kto_Aop, /* DSPF_ARGB2554 */ + Bop_12_Kto_Aop, /* DSPF_ARGB4444 */ + Bop_12vv_Kto_Aop, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + Bop_32_Kto_Aop, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Bop_rgb18_Kto_Aop, /* DSPF_ARGB1666 */ + Bop_rgb18_Kto_Aop, /* DSPF_ARGB6666 */ + Bop_rgb18_Kto_Aop, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_12_Kto_Aop, /* DSPF_RGB444 */ + Bop_15_Kto_Aop, /* DSPF_RGB555 */ + Bop_15_Kto_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_toK_Aop_PFI ************************/ + +static void Bop_rgb18_toK_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) { + D[0] = S[0]; + D[1] = S[1]; + D[2] = S[2]; + } + S += 3; + D += 3; + } +} + +static void Bop_rgb24_toK_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u8 Dkr = (gfxs->Dkey & 0xff0000) >> 16; + u8 Dkg = (gfxs->Dkey & 0x00ff00) >> 8; + u8 Dkb = (gfxs->Dkey & 0x0000ff); + + while (w--) { + if (D[0] == Dkb && D[1] == Dkg && D[2] == Dkr) { + D[0] = S[0]; + D[1] = S[1]; + D[2] = S[2]; + } + S += 3; + D += 3; + } +} + +static void Bop_yuv422_toK_Aop( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + u16 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + int Ostep = gfxs->Ostep; + + if (Ostep < 0) { + D += gfxs->length - 1; + S += gfxs->length - 1; + } + + if ((long)D & 2) { +#ifdef WORDS_BIGENDIAN + if (*D == (Dkey & 0xffff)) + *D = *S; +#else + if (*D == (Dkey >> 16)) + *D = *S; +#endif + D += Ostep; + S += Ostep; + w--; + } + + if (Ostep < 0) { + S--; + D--; + } + + for (l = w>>1; l--;) { + if (*D == Dkey) + *D = *S; + D += Ostep << 1; + S += Ostep << 1; + } + + if (w & 1) { +#ifdef WORDS_BIGENDIAN + if (*D == (Dkey >> 16)) + *D = *S; +#else + if (*D == (Dkey & 0xffff)) + *D = *S; +#endif + } +} + +static void Bop_rgb332_toK_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u8 Dkey = gfxs->Dkey; + + while (w--) { + if (*D == Dkey) { + *D = *S; + } + D++; + S++; + } +} + +static GenefxFunc Bop_PFI_toK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_15_toK_Aop, /* DSPF_ARGB1555 */ + Bop_16_toK_Aop, /* DSPF_RGB16 */ + Bop_rgb24_toK_Aop, /* DSPF_RGB24 */ + Bop_32_toK_Aop, /* DSPF_RGB32 */ + Bop_32_toK_Aop, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + Bop_yuv422_toK_Aop, /* DSPF_YUY2 */ + Bop_rgb332_toK_Aop, /* DSPF_RGB332 */ + Bop_yuv422_toK_Aop, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + Bop_32_toK_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_14_toK_Aop, /* DSPF_ARGB2554 */ + Bop_12_toK_Aop, /* DSPF_ARGB4444 */ + Bop_12vv_toK_Aop, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + Bop_32_toK_Aop, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Bop_rgb18_toK_Aop, /* DSPF_ARGB1666 */ + Bop_rgb18_toK_Aop, /* DSPF_ARGB6666 */ + Bop_rgb18_toK_Aop, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_12_toK_Aop, /* DSPF_RGB444 */ + Bop_15_toK_Aop, /* DSPF_RGB555 */ + Bop_15_toK_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_KtoK_Aop_PFI ***********************/ + +static GenefxFunc Bop_PFI_KtoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_15_KtoK_Aop, /* DSPF_ARGB1555 */ + Bop_16_KtoK_Aop, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + Bop_32_KtoK_Aop, /* DSPF_RGB32 */ + Bop_32_KtoK_Aop, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + Bop_32_KtoK_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_14_KtoK_Aop, /* DSPF_ARGB2554 */ + Bop_12_KtoK_Aop, /* DSPF_ARGB4444 */ + Bop_12vv_KtoK_Aop, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_12_KtoK_Aop, /* DSPF_RGB444 */ + Bop_15_KtoK_Aop, /* DSPF_RGB555 */ + Bop_15_KtoK_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_Sto_Aop_PFI ************************/ + +static void Bop_16_Sto_Aop( GenefxState *gfxs ) +{ + int w2; + int w = gfxs->length; + int i = gfxs->Xphase; + u32 *D = gfxs->Aop[0]; + u16 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + int SperD2 = SperD << 1; + + if (((long)D)&2) { + *(u16*)D = *S; + i += SperD; + w--; + D = gfxs->Aop[0] + 2; + } + + w2 = (w >> 1); + while (w2--) { +#ifdef WORDS_BIGENDIAN + *D++ = S[i>>16] << 16 | S[(i+SperD)>>16]; +#else + *D++ = (S[(i+SperD)>>16] << 16) | S[i>>16]; +#endif + i += SperD2; + } + if (w&1) { + *(u16*)D = S[i>>16]; + } +} + +static void Bop_24_Sto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + while (w--) { + int pixelstart = (i>>16)*3; + + *D++ = S[pixelstart+0]; + *D++ = S[pixelstart+1]; + *D++ = S[pixelstart+2]; + + i += SperD; + } +} + +static void Bop_32_Sto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u32 *D = gfxs->Aop[0]; + u32 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + while (w--) { + *D++ = S[i>>16]; + + i += SperD; + } +} + +static void Bop_yuy2_Sto_Aop( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + int i = gfxs->Xphase; + u16 *D = gfxs->Aop[0]; + u16 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + if ((long)D & 2) { + *D++ = *S; + i = SperD; + w--; + } + + for (l = w>>1; l--;) { + register u32 d; + + d = ((u32*)S)[i>>17] & 0xff00ff00; +#ifdef WORDS_BIGENDIAN + d |= (S[i>>16] & 0x00ff) << 16; + d |= (S[(i+SperD)>>16] & 0x00ff); +#else + d |= (S[i>>16] & 0x00ff); + d |= (S[(i+SperD)>>16] & 0x00ff) << 16; +#endif + *((u32*)D) = d; + D += 2; + + i += SperD << 1; + } + + if (w & 1) + *D = S[i>>16]; +} + +static void Bop_8_Sto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + while (w--) { + *D++ = S[i>>16]; + + i += SperD; + } +} + +static void Bop_uyvy_Sto_Aop( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + int i = gfxs->Xphase; + u16 *D = gfxs->Aop[0]; + u16 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + if ((long)D & 2) { + *D++ = *S; + i = SperD; + w--; + } + + for (l = w>>1; l--;) { + register u32 d; + + d = ((u32*)S)[i>>17] & 0x00ff00ff; +#ifdef WORDS_BIGENDIAN + d |= (S[i>>16] & 0xff00) << 16; + d |= (S[(i+SperD)>>16] & 0xff00); +#else + d |= (S[i>>16] & 0xff00); + d |= (S[(i+SperD)>>16] & 0xff00) << 16; +#endif + *((u32*)D) = d; + D += 2; + + i += SperD << 1; + } + + if (w & 1) + *D = S[i>>16]; +} + +static void Bop_i420_Sto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *Dy = gfxs->Aop[0]; + u8 *Sy = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + while (w--) { + *Dy++ = Sy[i>>16]; + + i += SperD; + } + + if (gfxs->AopY & 1) { + u8 *Du = gfxs->Aop[1]; + u8 *Dv = gfxs->Aop[2]; + u8 *Su = gfxs->Bop[1]; + u8 *Sv = gfxs->Bop[2]; + + for (w = gfxs->length>>1, i = 0; w--;) { + *Du++ = Su[i>>16]; + + i += SperD; + } + + for (w = gfxs->length>>1, i = 0; w--;) { + *Dv++ = Sv[i>>16]; + + i += SperD; + } + } +} + +static void Bop_NV_Sto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *Dy = gfxs->Aop[0]; + u8 *Sy = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + while (w--) { + *Dy++ = Sy[i>>16]; + + i += SperD; + } + + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) { + u16 *Duv = gfxs->Aop[1]; + u16 *Suv = gfxs->Bop[1]; + + for (w = gfxs->length>>1, i = 0; w--;) { + *Duv++ = Suv[i>>16]; + + i += SperD; + } + } +} + +static GenefxFunc Bop_PFI_Sto_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_16_Sto_Aop, /* DSPF_ARGB1555 */ + Bop_16_Sto_Aop, /* DSPF_RGB16 */ + Bop_24_Sto_Aop, /* DSPF_RGB24 */ + Bop_32_Sto_Aop, /* DSPF_RGB32 */ + Bop_32_Sto_Aop, /* DSPF_ARGB */ + Bop_8_Sto_Aop, /* DSPF_A8 */ + Bop_yuy2_Sto_Aop, /* DSPF_YUY2 */ + Bop_8_Sto_Aop, /* DSPF_RGB332 */ + Bop_uyvy_Sto_Aop, /* DSPF_UYVY */ + Bop_i420_Sto_Aop, /* DSPF_I420 */ + Bop_i420_Sto_Aop, /* DSPF_YV12 */ + Bop_8_Sto_Aop, /* DSPF_LUT8 */ + Bop_8_Sto_Aop, /* DSPF_ALUT44 */ + Bop_32_Sto_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Bop_NV_Sto_Aop, /* DSPF_NV12 */ + Bop_NV_Sto_Aop, /* DSPF_NV16 */ + Bop_16_Sto_Aop, /* DSPF_ARGB2554 */ + Bop_16_Sto_Aop, /* DSPF_ARGB4444 */ + Bop_16_Sto_Aop, /* DSPF_RGBA4444 */ + Bop_NV_Sto_Aop, /* DSPF_NV21 */ + Bop_32_Sto_Aop, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Bop_24_Sto_Aop, /* DSPF_ARGB1666 */ + Bop_24_Sto_Aop, /* DSPF_ARGB6666 */ + Bop_24_Sto_Aop, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_16_Sto_Aop, /* DSPF_ARGB4444 */ + Bop_16_Sto_Aop, /* DSPF_ARGB1555 */ + Bop_16_Sto_Aop /* DSPF_ARGB1555 */ +}; + +/********************************* Bop_PFI_SKto_Aop_PFI ***********************/ + +static void Bop_rgb18_SKto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int SperD = gfxs->SperD; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 s0 = S[pixelstart+0]; + u8 s1 = S[pixelstart+1]; + u8 s2 = S[pixelstart+2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + D[0] = s0; + D[1] = s1; + D[2] = s2; + } + i += SperD; + D += 3; + } +} + +static void Bop_rgb24_SKto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int SperD = gfxs->SperD; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 b = S[pixelstart+0]; + u8 g = S[pixelstart+1]; + u8 r = S[pixelstart+2]; + + if (Skey != (u32)(r<<16 | g<<8 | b)) { + *D = b; + *(D+1) = g; + *(D+2) = r; + } + + D += 3; + i += SperD; + } +} + +static void Bop_a8_SKto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + int SperD = gfxs->SperD; + + /* no color to key */ + while (w--) { + *D++ = S[i>>16]; + + i += SperD; + } +} + +static void Bop_yuy2_SKto_Aop( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + int i = gfxs->Xphase; + u16 *D = gfxs->Aop[0]; + u16 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; +#ifdef WORDS_BIGENDIAN + u16 Skey0 = gfxs->Skey >> 16; + u16 Skey1 = gfxs->Skey & 0xffff; +#else + u16 Skey0 = gfxs->Skey & 0xffff; + u16 Skey1 = gfxs->Skey >> 16; +#endif + int SperD = gfxs->SperD; + + if ((long)D & 2) { + u16 s = *S; + if (s != Skey0) + *D = s; + D++; + i = SperD; + w--; + } + + for (l = w>>1; l--;) { + register u32 s; + + s = ((u32*)S)[i>>17] & 0xff00ff00; +#ifdef WORDS_BIGENDIAN + s |= (S[i>>16] & 0x00ff) << 16; + s |= (S[(i+SperD)>>16] & 0x00ff); +#else + s |= (S[i>>16] & 0x00ff); + s |= (S[(i+SperD)>>16] & 0x00ff) << 16; +#endif + if (s != Skey) + *((u32*)D) = s; + D += 2; + + i += SperD << 1; + } + + if (w & 1) { + u16 s = S[i>>16]; + if (i & 0x20000) { + if (s != Skey1) + *D = s; + } else { + if (s != Skey0) + *D = s; + } + } +} + +static void Bop_8_SKto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int SperD = gfxs->SperD; + + while (w--) { + u8 s = S[i>>16]; + + if (s != Skey) + *D = s; + + D++; + i += SperD; + } +} + +static void Bop_uyvy_SKto_Aop( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + int i = gfxs->Xphase; + u16 *D = gfxs->Aop[0]; + u16 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; +#ifdef WORDS_BIGENDIAN + u16 Skey0 = gfxs->Skey >> 16; + u16 Skey1 = gfxs->Skey & 0xffff; +#else + u16 Skey0 = gfxs->Skey & 0xffff; + u16 Skey1 = gfxs->Skey >> 16; +#endif + int SperD = gfxs->SperD; + + if ((long)D & 2) { + u16 s = *S; + if (s != Skey0) + *D = s; + D++; + i = SperD; + w--; + } + + for (l = w>>1; l--;) { + register u32 s; + + s = ((u32*)S)[i>>17] & 0x00ff00ff; +#ifdef WORDS_BIGENDIAN + s |= (S[i>>16] & 0xff00) << 16; + s |= (S[(i+SperD)>>16] & 0xff00); +#else + s |= (S[i>>16] & 0xff00); + s |= (S[(i+SperD)>>16] & 0xff00) << 16; +#endif + if (s != Skey) + *((u32*)D) = s; + D += 2; + + i += SperD << 1; + } + + if (w & 1) { + u16 s = S[i>>16]; + if (i & 0x20000) { + if (s != Skey1) + *D = s; + } else { + if (s != Skey0) + *D = s; + } + } +} + +static void Bop_alut44_SKto_Aop( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + u8 *D = gfxs->Aop[0]; + u8 *S = gfxs->Bop[0]; + u32 Skey = gfxs->Skey; + int SperD = gfxs->SperD; + + while (w--) { + u8 s = S[i>>16]; + + if ((s & 0x0f) != Skey) + *D = s; + + D++; + i += SperD; + } +} + +static GenefxFunc Bop_PFI_SKto_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_15_SKto_Aop, /* DSPF_ARGB1555 */ + Bop_16_SKto_Aop, /* DSPF_RGB16 */ + Bop_rgb24_SKto_Aop, /* DSPF_RGB24 */ + Bop_32_SKto_Aop, /* DSPF_RGB32 */ + Bop_32_SKto_Aop, /* DSPF_ARGB */ + Bop_a8_SKto_Aop, /* DSPF_A8 */ + Bop_yuy2_SKto_Aop, /* DSPF_YUY2 */ + Bop_8_SKto_Aop, /* DSPF_RGB332 */ + Bop_uyvy_SKto_Aop, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Bop_8_SKto_Aop, /* DSPF_LUT8 */ + Bop_alut44_SKto_Aop, /* DSPF_ALUT44 */ + Bop_32_SKto_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_14_SKto_Aop, /* DSPF_ARGB2554 */ + Bop_12_SKto_Aop, /* DSPF_ARGB4444 */ + Bop_12vv_SKto_Aop, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + Bop_32_SKto_Aop, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Bop_rgb18_SKto_Aop, /* DSPF_ARGB1666 */ + Bop_rgb18_SKto_Aop, /* DSPF_ARGB6666 */ + Bop_rgb18_SKto_Aop, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_12_SKto_Aop, /* DSPF_RGB444 */ + Bop_15_SKto_Aop, /* DSPF_RGB555 */ + Bop_15_SKto_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_StoK_Aop_PFI ***********************/ + +static GenefxFunc Bop_PFI_StoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_15_StoK_Aop, /* DSPF_ARGB1555 */ + Bop_16_StoK_Aop, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + Bop_32_StoK_Aop, /* DSPF_RGB32 */ + Bop_32_StoK_Aop, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + Bop_32_StoK_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_14_StoK_Aop, /* DSPF_ARGB2554 */ + Bop_12_StoK_Aop, /* DSPF_ARGB4444 */ + Bop_12vv_StoK_Aop, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_12_StoK_Aop, /* DSPF_RGB444 */ + Bop_15_StoK_Aop, /* DSPF_RGB555 */ + Bop_15_StoK_Aop /* DSPF_BGR555 */ +}; + +/********************************* Bop_PFI_SKtoK_Aop_PFI **********************/ + +static GenefxFunc Bop_PFI_SKtoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_15_SKtoK_Aop, /* DSPF_ARGB1555 */ + Bop_16_SKtoK_Aop, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + Bop_32_SKtoK_Aop, /* DSPF_RGB32 */ + Bop_32_SKtoK_Aop, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + Bop_32_SKtoK_Aop, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_14_SKtoK_Aop, /* DSPF_ARGB2554 */ + Bop_12_SKtoK_Aop, /* DSPF_ARGB4444 */ + Bop_12vv_SKtoK_Aop, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Bop_12_SKtoK_Aop, /* DSPF_RGB444 */ + Bop_15_SKtoK_Aop, /* DSPF_RGB555 */ + Bop_15_SKtoK_Aop /* DSPF_BGR555 */ +}; + +/********************************* Sop_PFI_Sto_Dacc ***************************/ + +static void Sop_argb6666_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 b = S[pixelstart+0] & 0x3F; + u8 g = ((S[pixelstart+0] & 0xC0) >> 6) | ((S[pixelstart+1] & 0x0F) << 2); + u8 r = ((S[pixelstart+1] & 0xF0) >> 4) | ((S[pixelstart+2] & 0x03) << 4); + u8 a = (S[pixelstart+2] & 0xFC) >> 2; + + D->RGB.a = EXPAND_6to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + i += SperD; + D++; + } +} + +static void Sop_argb1666_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 b = S[pixelstart+0] & 0x3F; + u8 g = ((S[pixelstart+0] & 0xC0) >> 6) | ((S[pixelstart+1] & 0x0F) << 2); + u8 r = ((S[pixelstart+1] & 0xF0) >> 4) | ((S[pixelstart+2] & 0x03) << 4); + u8 a = (S[pixelstart+2] & 0x04) >> 2; + + D->RGB.a = EXPAND_1to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + i += SperD; + D++; + } +} + +static void Sop_rgb18_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 b = S[pixelstart+0] & 0x3F; + u8 g = ((S[pixelstart+0] & 0xC0) >> 6) | ((S[pixelstart+1] & 0x0F) << 2); + u8 r = ((S[pixelstart+1] & 0xF0) >> 4) | ((S[pixelstart+2] & 0x03) << 4); + + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + i += SperD; + D++; + } +} + +static void Sop_rgb24_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + int pixelstart = (i>>16)*3; + + D->RGB.a = 0xFF; + D->RGB.r = S[pixelstart+2]; + D->RGB.g = S[pixelstart+1]; + D->RGB.b = S[pixelstart+0]; + + i += SperD; + + D++; + } +} + +static void Sop_a8_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + u8 s = S[i>>16]; + + D->RGB.a = s; + D->RGB.r = 0xFF; + D->RGB.g = 0xFF; + D->RGB.b = 0xFF; + + i += SperD; + + D++; + } +} + +static void Sop_yuy2_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = S[i>>17]; + + D[0].YUV.a = D[1].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[0].YUV.u = D[1].YUV.u = (s & 0xFF000000) >> 24; + D[0].YUV.v = D[1].YUV.v = (s & 0x0000FF00) >> 8; +#else + D[0].YUV.u = D[1].YUV.u = (s & 0x0000FF00) >> 8; + D[0].YUV.v = D[1].YUV.v = (s & 0xFF000000) >> 24; +#endif + D[0].YUV.y = ((u16*)S)[i>>16] & 0x00FF; + D[1].YUV.y = ((u16*)S)[(i+SperD)>>16] & 0x00FF; + + D += 2; + i += SperD << 1; + } + + if (gfxs->length & 1) { + u16 s = ((u16*)S)[i>>17]; + + D->YUV.a = 0xFF; + D->YUV.y = s & 0xFF; + D->YUV.u = s >> 8; + D->YUV.v = 0x00; + } +} + +static void Sop_rgb332_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + u8 s = S[i>>16]; + + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_3to8(s >> 5); + D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2); + D->RGB.b = EXPAND_2to8(s & 0x03); + + i += SperD; + + D++; + } +} + +static void Sop_uyvy_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = S[i>>17]; + + D[0].YUV.a = D[1].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[0].YUV.u = D[1].YUV.u = (s & 0x00FF0000) >> 16; + D[0].YUV.v = D[1].YUV.v = (s & 0x000000FF); +#else + D[0].YUV.u = D[1].YUV.u = (s & 0x000000FF); + D[0].YUV.v = D[1].YUV.v = (s & 0x00FF0000) >> 16; +#endif + D[0].YUV.y = (((u16*)S)[i>>16] & 0xFF00) >> 8; + D[1].YUV.y = (((u16*)S)[(i+SperD)>>16] & 0xFF00) >> 8; + + D += 2; + i += SperD << 1; + } + + if (gfxs->length & 1) { + u16 s = ((u16*)S)[i>>16]; + + D->YUV.a = 0xFF; + D->YUV.y = s >> 8; + D->YUV.u = s & 0xFF; + D->YUV.v = 0x00; + } +} + +static void Sop_lut8_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = S[i>>16]; + + D->RGB.a = entries[s].a; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + + i += SperD; + + D++; + } +} + +static void Sop_alut44_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = S[i>>16]; + + D->RGB.a = s & 0xF0; + s &= 0x0F; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + + i += SperD; + + D++; + } +} + +static void Sop_i420_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *Sy = gfxs->Sop[0]; + u8 *Su = gfxs->Sop[1]; + u8 *Sv = gfxs->Sop[2]; + + while (w--) { + D->YUV.a = 0xFF; + D->YUV.y = Sy[i>>16]; + D->YUV.u = Su[i>>17]; + D->YUV.v = Sv[i>>17]; + + i += SperD; + + D++; + } +} + +static void Sop_nv12_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *Sy = gfxs->Sop[0]; + u16 *Suv = gfxs->Sop[1]; + + while (w--) { + D->YUV.a = 0xFF; + D->YUV.y = Sy[i>>16]; + D->YUV.u = Suv[i>>17] & 0xFF; + D->YUV.v = Suv[i>>17] >> 8; + + i += SperD; + + D++; + } +} + +static void Sop_nv21_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *Sy = gfxs->Sop[0]; + u16 *Svu = gfxs->Sop[1]; + + while (w--) { + D->YUV.a = 0xFF; + D->YUV.y = Sy[i>>16]; + D->YUV.u = Svu[i>>17] >> 8; + D->YUV.v = Svu[i>>17] & 0xFF; + + i += SperD; + + D++; + } +} + +static void Sop_ayuv_Sto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = S[i>>16]; + + D->YUV.a = (s >> 24); + D->YUV.y = (s >> 16) & 0xff; + D->YUV.u = (s >> 8) & 0xff; + D->YUV.v = (s ) & 0xff; + + i += SperD; + + D++; + } +} + +static GenefxFunc Sop_PFI_Sto_Dacc[DFB_NUM_PIXELFORMATS] = { + Sop_argb1555_Sto_Dacc, /* DSPF_ARGB1555 */ + Sop_rgb16_Sto_Dacc, /* DSPF_RGB16 */ + Sop_rgb24_Sto_Dacc, /* DSPF_RGB24 */ + Sop_rgb32_Sto_Dacc, /* DSPF_RGB32 */ + Sop_argb_Sto_Dacc, /* DSPF_ARGB */ + Sop_a8_Sto_Dacc, /* DSPF_A8 */ + Sop_yuy2_Sto_Dacc, /* DSPF_YUY2 */ + Sop_rgb332_Sto_Dacc, /* DSPF_RGB332 */ + Sop_uyvy_Sto_Dacc, /* DSPF_UYVY */ + Sop_i420_Sto_Dacc, /* DSPF_I420 */ + Sop_i420_Sto_Dacc, /* DSPF_YV12 */ + Sop_lut8_Sto_Dacc, /* DSPF_LUT8 */ + Sop_alut44_Sto_Dacc, /* DSPF_ALUT44 */ + Sop_airgb_Sto_Dacc, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Sop_nv12_Sto_Dacc, /* DSPF_NV12 */ + Sop_nv12_Sto_Dacc, /* DSPF_NV16 */ + Sop_argb2554_Sto_Dacc, /* DSPF_ARGB2554 */ + Sop_argb4444_Sto_Dacc, /* DSPF_ARGB4444 */ + Sop_rgba4444_Sto_Dacc, /* DSPF_RGBA4444 */ + Sop_nv21_Sto_Dacc, /* DSPF_NV21 */ + Sop_ayuv_Sto_Dacc, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Sop_argb1666_Sto_Dacc, /* DSPF_ARGB1666 */ + Sop_argb6666_Sto_Dacc, /* DSPF_ARGB6666 */ + Sop_rgb18_Sto_Dacc, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sop_xrgb4444_Sto_Dacc, /* DSPF_RGB444 */ + Sop_xrgb1555_Sto_Dacc, /* DSPF_RGB555 */ + Sop_xbgr1555_Sto_Dacc /* DSPF_BGR555 */ +}; + +/********************************* Sop_PFI_SKto_Dacc **************************/ + +static void Sop_argb6666_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + u32 Skey = gfxs->Skey; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 s0 = S[pixelstart+0]; + u8 s1 = S[pixelstart+1]; + u8 s2 = S[pixelstart+2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + u8 b = s0 & 0x3F; + u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2); + u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4); + u8 a = (s2 & 0xFC) >> 2; + + D->RGB.a = EXPAND_6to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + } + else + D->RGB.a = 0xFF00; + + i += SperD; + D++; + } +} + +static void Sop_argb1666_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 s0 = S[pixelstart+0]; + u8 s1 = S[pixelstart+1]; + u8 s2 = S[pixelstart+2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + u8 b = s0 & 0x3F; + u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2); + u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4); + u8 a = (s2 & 0x04) >> 2; + + D->RGB.a = EXPAND_1to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + } + else + D->RGB.a = 0xFF00; + i += SperD; + D++; + } +} + +static void Sop_rgb18_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + u32 Skey = gfxs->Skey; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 s0 = S[pixelstart+0]; + u8 s1 = S[pixelstart+1]; + u8 s2 = S[pixelstart+2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + u8 b = s0 & 0x3F; + u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2); + u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4); + + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + } + else + D->RGB.a = 0xFF00; + + i += SperD; + D++; + } +} + +static void Sop_rgb24_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + int pixelstart = (i>>16)*3; + + u8 b = S[pixelstart+0]; + u8 g = S[pixelstart+1]; + u8 r = S[pixelstart+2]; + + if (Skey != (u32)(r<<16 | g<<8 | b)) { + D->RGB.a = 0xFF; + D->RGB.r = r; + D->RGB.g = g; + D->RGB.b = b; + } + else + D->RGB.a = 0xFF00; + + i += SperD; + + D++; + } +} + +static void Sop_a8_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + /* no color to key */ + while (w--) { + u8 s = S[i>>16]; + + D->RGB.a = s; + D->RGB.r = 0xFF; + D->RGB.g = 0xFF; + D->RGB.b = 0xFF; + + i += SperD; + + D++; + } +} + +static void Sop_lut8_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = S[i>>16]; + + if (s != Skey) { + D->RGB.a = entries[s].a; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + } + else + D->RGB.a = 0xF000; + + i += SperD; + + D++; + } +} + +static void Sop_alut44_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = S[i>>16]; + + if ((s & 0x0F) != Skey) { + D->RGB.a = ((s & 0xF0) >> 4) | (s & 0xF0); + s &= 0x0F; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + } + else + D->RGB.a = 0xF000; + + i += SperD; + + D++; + } +} + +static void Sop_yuy2_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + u32 Ky = (gfxs->Skey & 0x000000FF); +#ifdef WORDS_BIGENDIAN + u32 Kcb = (gfxs->Skey & 0xFF000000) >> 24; + u32 Kcr = (gfxs->Skey & 0x0000FF00) >> 8; +#else + u32 Kcb = (gfxs->Skey & 0x0000FF00) >> 8; + u32 Kcr = (gfxs->Skey & 0xFF000000) >> 24; +#endif + + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = S[i>>17]; + u32 y0, cb, y1, cr; + +#ifdef WORDS_BIGENDIAN + cb = (s & 0xFF000000) >> 24; + cr = (s & 0x0000FF00) >> 8; +#else + cb = (s & 0x0000FF00) >> 8; + cr = (s & 0xFF000000) >> 24; +#endif + y0 = ((u16*)S)[i>>16] & 0x00FF; + y1 = ((u16*)S)[(i+SperD)>>16] & 0x00FF; + + if (y0 != Ky || cb != Kcb || cr != Kcr) { + D[0].YUV.a = 0xFF; + D[0].YUV.y = y0; + D[0].YUV.u = cb; + D[0].YUV.v = cr; + } + else + D[0].YUV.a = 0xF000; + + if (y0 != Ky || cb != Kcb || cr != Kcr) { + D[1].YUV.a = 0xFF; + D[1].YUV.y = y1; + D[1].YUV.u = cb; + D[1].YUV.v = cr; + } + else + D[1].YUV.a = 0xF000; + + D += 2; + i += SperD << 1; + } + + if (gfxs->length & 1) { + u16 s = ((u16*)S)[i>>16]; + + if (s != (Ky | (Kcb << 8))) { + D->YUV.a = 0xFF; + D->YUV.y = s & 0xFF; + D->YUV.u = s >> 8; + D->YUV.v = 0x00; + } + else + D->YUV.a = 0xF000; + } +} + +static void Sop_rgb332_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u8 Skey = gfxs->Skey; + + while (w--) { + u8 s = S[i>>16]; + + if (s != Skey) { + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_3to8(s >> 5); + D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2); + D->RGB.b = EXPAND_2to8(s & 0x03); + } + else + D->RGB.a = 0xF000; + + i += SperD; + + D++; + } +} + +static void Sop_uyvy_SKto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + int i = gfxs->Xphase; + int SperD = gfxs->SperD; + u32 Ky = (gfxs->Skey & 0x0000FF00) >> 8; +#ifdef WORDS_BIGENDIAN + u32 Kcb = (gfxs->Skey & 0x00FF0000) >> 16; + u32 Kcr = (gfxs->Skey & 0x000000FF); +#else + u32 Kcb = (gfxs->Skey & 0x000000FF); + u32 Kcr = (gfxs->Skey & 0x00FF0000) >> 16; +#endif + + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = S[i>>17]; + u32 cb, y0, cr, y1; + +#ifdef WORDS_BIGENDIAN + cb = (s & 0x00FF0000) >> 16; + cr = (s & 0x000000FF); +#else + cb = (s & 0x000000FF); + cr = (s & 0x00FF0000) >> 16; +#endif + y0 = (((u16*)S)[i>>16] & 0xFF00) >> 8; + y1 = (((u16*)S)[(i+SperD)>>16] & 0xFF00) >> 8; + + if (y0 != Ky || cb != Kcb || cr != Kcr) { + D[0].YUV.a = 0xFF; + D[0].YUV.y = y0; + D[0].YUV.u = cb; + D[0].YUV.v = cr; + } + else + D[0].YUV.a = 0xF000; + + if (y0 != Ky || cb != Kcb || cr != Kcr) { + D[1].YUV.a = 0xFF; + D[1].YUV.y = y1; + D[1].YUV.u = cb; + D[1].YUV.v = cr; + } + else + D[1].YUV.a = 0xF000; + + D += 2; + i += SperD << 1; + } + + if (gfxs->length & 1) { + u16 s = ((u16*)S)[i>>16]; + + if (s != (Kcb | (Ky << 8))) { + D->YUV.a = 0xFF; + D->YUV.y = s >> 8; + D->YUV.u = s & 0xFF; + D->YUV.v = 0x00; + } + else + D->YUV.a = 0xF000; + } +} + +static GenefxFunc Sop_PFI_SKto_Dacc[DFB_NUM_PIXELFORMATS] = { + Sop_argb1555_SKto_Dacc, /* DSPF_ARGB1555 */ + Sop_rgb16_SKto_Dacc, /* DSPF_RGB16 */ + Sop_rgb24_SKto_Dacc, /* DSPF_RGB24 */ + Sop_rgb32_SKto_Dacc, /* DSPF_RGB32 */ + Sop_argb_SKto_Dacc, /* DSPF_ARGB */ + Sop_a8_SKto_Dacc, /* DSPF_A8 */ + Sop_yuy2_SKto_Dacc, /* DSPF_YUY2 */ + Sop_rgb332_SKto_Dacc, /* DSPF_RGB332 */ + Sop_uyvy_SKto_Dacc, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Sop_lut8_SKto_Dacc, /* DSPF_LUT8 */ + Sop_alut44_SKto_Dacc, /* DSPF_ALUT44 */ + Sop_airgb_SKto_Dacc, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Sop_argb2554_SKto_Dacc, /* DSPF_ARGB2554 */ + Sop_argb4444_SKto_Dacc, /* DSPF_ARGB4444 */ + Sop_rgba4444_SKto_Dacc, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Sop_argb1666_SKto_Dacc, /* DSPF_ARGB1666 */ + Sop_argb6666_SKto_Dacc, /* DSPF_ARGB6666 */ + Sop_rgb18_SKto_Dacc, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sop_xrgb4444_SKto_Dacc, /* DSPF_RGB444 */ + Sop_xrgb1555_SKto_Dacc, /* DSPF_RGB555 */ + Sop_xbgr1555_SKto_Dacc /* DSPF_BGR555 */ +}; + +/********************************* Sop_PFI_to_Dacc ****************************/ + +static void Sop_argb6666_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + u8 b = S[0] & 0x3F; + u8 g = ((S[0] & 0xC0) >> 6) | ((S[1] & 0x0F) << 2); + u8 r = ((S[1] & 0xF0) >> 4) | ((S[2] & 0x03) << 4); + u8 a = (S[2] & 0xFC) >> 2; + + D->RGB.a = EXPAND_6to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + + S +=3; + D++; + } +} + +static void Sop_argb1666_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + u8 b = S[0] & 0x3F; + u8 g = ((S[0] & 0xC0) >> 6) | ((S[1] & 0x0F) << 2); + u8 r = ((S[1] & 0xF0) >> 4) | ((S[2] & 0x03) << 4); + u8 a = (S[2] & 0x04) >> 2; + + D->RGB.a = EXPAND_1to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + + S +=3; + D++; + } +} + +static void Sop_rgb18_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + u8 b = S[0] & 0x3F; + u8 g = ((S[0] & 0xC0) >> 6) | ((S[1] & 0x0F) << 2); + u8 r = ((S[1] & 0xF0) >> 4) | ((S[2] & 0x03) << 4); + + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + + S +=3; + D++; + } +} + +static void Sop_rgb24_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + D->RGB.a = 0xFF; + D->RGB.b = *S++; + D->RGB.g = *S++; + D->RGB.r = *S++; + + D++; + } +} + +static void Sop_a8_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + D->RGB.a = *S++; + D->RGB.r = 0xFF; + D->RGB.g = 0xFF; + D->RGB.b = 0xFF; + + D++; + } +} + +static void Sop_a4_to_Dacc( GenefxState *gfxs ) +{ + int i, n; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + for (i=0, n=0; ilength; i+=2, n++) { + register int left = S[n] & 0xF0; + register int right = S[n] & 0x0F; + + D[i].RGB.a = left | (left >> 4); + D[i].RGB.r = 0xFF; + D[i].RGB.g = 0xFF; + D[i].RGB.b = 0xFF; + + D[i+1].RGB.a = right | (right << 4); + D[i+1].RGB.r = 0xFF; + D[i+1].RGB.g = 0xFF; + D[i+1].RGB.b = 0xFF; + } +} + +static void Sop_yuy2_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = *S++; + + D[0].YUV.a = D[1].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[0].YUV.y = (s & 0x00FF0000) >> 16; + D[1].YUV.y = (s & 0x000000FF); + D[0].YUV.u = D[1].YUV.u = (s & 0xFF000000) >> 24; + D[0].YUV.v = D[1].YUV.v = (s & 0x0000FF00) >> 8; +#else + D[0].YUV.y = (s & 0x000000FF); + D[1].YUV.y = (s & 0x00FF0000) >> 16; + D[0].YUV.u = D[1].YUV.u = (s & 0x0000FF00) >> 8; + D[0].YUV.v = D[1].YUV.v = (s & 0xFF000000) >> 24; +#endif + + D += 2; + } + + if (gfxs->length & 1) { + u16 s = *((u16*)S); + + D->YUV.a = 0xFF; + D->YUV.y = s & 0xFF; + D->YUV.u = s >> 8; + D->YUV.v = 0x00; + } +} + +static void Sop_rgb332_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + while (w--) { + u8 s = *S++; + + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_3to8(s >> 5); + D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2); + D->RGB.b = EXPAND_2to8(s & 0x03); + + D++; + } +} + +static void Sop_uyvy_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = *S++; + + D[0].YUV.a = D[1].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[0].YUV.y = (s & 0xFF000000) >> 24; + D[1].YUV.y = (s & 0x0000FF00) >> 8; + D[0].YUV.u = D[1].YUV.u = (s & 0x00FF0000) >> 16; + D[0].YUV.v = D[1].YUV.v = (s & 0x000000FF); +#else + D[0].YUV.y = (s & 0x0000FF00) >> 8; + D[1].YUV.y = (s & 0xFF000000) >> 24; + D[0].YUV.u = D[1].YUV.u = (s & 0x000000FF); + D[0].YUV.v = D[1].YUV.v = (s & 0x00FF0000) >> 16; +#endif + + D += 2; + } + + if (gfxs->length & 1) { + u16 s = *((u16*)S); + + D->YUV.a = 0xFF; + D->YUV.y = s >> 8; + D->YUV.u = s & 0xFF; + D->YUV.v = 0x00; + } +} + +static void Sop_lut8_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = *S++; + + D->RGB.a = entries[s].a; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + + D++; + } +} + +static void Sop_alut44_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = *S++; + + D->RGB.a = s & 0xF0; + s &= 0x0F; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + + D++; + } +} + +static void Sop_i420_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u8 *Sy = gfxs->Sop[0]; + u8 *Su = gfxs->Sop[1]; + u8 *Sv = gfxs->Sop[2]; + + while (w--) { + D[1].YUV.a = D[0].YUV.a = 0xFF; + D[0].YUV.y = Sy[0]; + D[1].YUV.y = Sy[1]; + D[1].YUV.u = D[0].YUV.u = Su[0]; + D[1].YUV.v = D[0].YUV.v = Sv[0]; + + Sy += 2; + Su++; + Sv++; + + D += 2; + } +} + +static void Sop_nv12_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u8 *Sy = gfxs->Sop[0]; + u16 *Suv = gfxs->Sop[1]; + + while (w--) { + D[1].YUV.a = D[0].YUV.a = 0xFF; + D[0].YUV.y = Sy[0]; + D[1].YUV.y = Sy[1]; + D[1].YUV.u = D[0].YUV.u = Suv[0] & 0xFF; + D[1].YUV.v = D[0].YUV.v = Suv[0] >> 8; + + Sy += 2; + Suv++; + + D += 2; + } +} + +static void Sop_nv21_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u8 *Sy = gfxs->Sop[0]; + u16 *Svu = gfxs->Sop[1]; + + while (w--) { + D[1].YUV.a = D[0].YUV.a = 0xFF; + D[0].YUV.y = Sy[0]; + D[1].YUV.y = Sy[1]; + D[1].YUV.u = D[0].YUV.u = Svu[0] >> 8; + D[1].YUV.v = D[0].YUV.v = Svu[0] & 0xFF; + + Sy += 2; + Svu++; + + D += 2; + } +} + +static void Sop_ayuv_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + + while (w--) { + u32 s = *S++; + + D->YUV.a = (s >> 24); + D->YUV.y = (s >> 16) & 0xff; + D->YUV.u = (s >> 8) & 0xff; + D->YUV.v = (s ) & 0xff; + + D++; + } +} + +static GenefxFunc Sop_PFI_to_Dacc[DFB_NUM_PIXELFORMATS] = { + Sop_argb1555_to_Dacc, /* DSPF_ARGB1555 */ + Sop_rgb16_to_Dacc, /* DSPF_RGB16 */ + Sop_rgb24_to_Dacc, /* DSPF_RGB24 */ + Sop_rgb32_to_Dacc, /* DSPF_RGB32 */ + Sop_argb_to_Dacc, /* DSPF_ARGB */ + Sop_a8_to_Dacc, /* DSPF_A8 */ + Sop_yuy2_to_Dacc, /* DSPF_YUY2 */ + Sop_rgb332_to_Dacc, /* DSPF_RGB332 */ + Sop_uyvy_to_Dacc, /* DSPF_UYVY */ + Sop_i420_to_Dacc, /* DSPF_I420 */ + Sop_i420_to_Dacc, /* DSPF_YV12 */ + Sop_lut8_to_Dacc, /* DSPF_LUT8 */ + Sop_alut44_to_Dacc, /* DSPF_ALUT44 */ + Sop_airgb_to_Dacc, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Sop_nv12_to_Dacc, /* DSPF_NV12 */ + Sop_nv12_to_Dacc, /* DSPF_NV16 */ + Sop_argb2554_to_Dacc, /* DSPF_ARGB2554 */ + Sop_argb4444_to_Dacc, /* DSPF_ARGB4444 */ + Sop_rgba4444_to_Dacc, /* DSPF_RGBA4444 */ + Sop_nv21_to_Dacc, /* DSPF_NV21 */ + Sop_ayuv_to_Dacc, /* DSPF_AYUV */ + Sop_a4_to_Dacc, /* DSPF_A4 */ + Sop_argb1666_to_Dacc, /* DSPF_ARGB1666 */ + Sop_argb6666_to_Dacc, /* DSPF_ARGB6666 */ + Sop_rgb18_to_Dacc, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sop_xrgb4444_to_Dacc, /* DSPF_RGB444 */ + Sop_xrgb1555_to_Dacc, /* DSPF_RGB555 */ + Sop_xbgr1555_to_Dacc, /* DSPF_BGR555 */ +}; + +/********************************* Sop_PFI_Kto_Dacc ***************************/ + +static void Sop_argb6666_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + u8 s0 = S[0]; + u8 s1 = S[1]; + u8 s2 = S[2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + u8 b = s0 & 0x3F; + u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2); + u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4); + u8 a = (s2 & 0xFC) >> 2; + + D->RGB.a = EXPAND_6to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + } + else + D->RGB.a = 0xF000; + + S += 3; + D++; + } +} + +static void Sop_argb1666_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + u8 s0 = S[0]; + u8 s1 = S[1]; + u8 s2 = S[2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3FFFF)) { + u8 b = s0 & 0x3F; + u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2); + u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4); + u8 a = (s2 & 0x04) >> 2; + + D->RGB.a = EXPAND_1to8( a ); + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + } + else + D->RGB.a = 0xF000; + + S += 3; + D++; + } +} + +static void Sop_rgb18_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + u8 s0 = S[0]; + u8 s1 = S[1]; + u8 s2 = S[2]; + + if (Skey != ((u32)(s2<<16 | s1<<8 | s0) & 0x3ffff)) { + u8 b = s0 & 0x3F; + u8 g = ((s0 & 0xC0) >> 6) | ((s1 & 0x0F) << 2); + u8 r = ((s1 & 0xF0) >> 4) | ((s2 & 0x03) << 4); + + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_6to8( r ); + D->RGB.g = EXPAND_6to8( g ); + D->RGB.b = EXPAND_6to8( b ); + } + else + D->RGB.a = 0xF000; + + S += 3; + D++; + } +} + +static void Sop_rgb24_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + u8 b = *S++; + u8 g = *S++; + u8 r = *S++; + + if (Skey != (u32)(r<<16 | g<<8 | b)) { + D->RGB.a = 0xFF; + D->RGB.r = r; + D->RGB.g = g; + D->RGB.b = b; + } + else + D->RGB.a = 0xF000; + + D++; + } +} + +static void Sop_a8_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + + /* no color to key */ + while (w--) { + D->RGB.a = *S++; + D->RGB.r = 0xFF; + D->RGB.g = 0xFF; + D->RGB.b = 0xFF; + + D++; + } +} + +static void Sop_yuy2_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + u32 Skey0 = gfxs->Skey & 0xFF00FFFF; + u32 Skey1 = gfxs->Skey & 0xFFFFFF00; + +#ifdef WORDS_BIGENDIAN +#define S0_MASK 0xFFFFFF00 +#define S1_MASK 0xFF00FFFF +#else +#define S0_MASK 0xFF00FFFF +#define S1_MASK 0xFFFFFF00 +#endif + + while (w--) { + u32 s = *S++; + + if (s != Skey) { + u32 cb, cr; + +#ifdef WORDS_BIGENDIAN + cb = (s & 0xFF000000) >> 24; + cr = (s & 0x0000FF00) >> 8; +#else + cb = (s & 0x0000FF00) >> 8; + cr = (s & 0xFF000000) >> 24; +#endif + + if ((s & S0_MASK) != Skey0) { + D[0].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[0].YUV.y = (s & 0x00FF0000) >> 16; +#else + D[0].YUV.y = (s & 0x000000FF); +#endif + D[0].YUV.u = cb; + D[0].YUV.v = cr; + } + else + D[0].YUV.a = 0xF000; + + if ((s & S1_MASK) != Skey1) { + D[1].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[1].YUV.y = (s & 0x000000FF); +#else + D[1].YUV.y = (s & 0x00FF0000) >> 16; +#endif + D[1].YUV.u = cb; + D[1].YUV.v = cr; + } + else + D[1].YUV.a = 0xF000; + } + + D += 2; + } + + if (gfxs->length & 1) { + u16 s = *((u16*)S); + + if (s != Skey0) { + D->YUV.a = 0xFF; + D->YUV.y = s & 0xFF; + D->YUV.u = s >> 8; + D->YUV.v = 0x00; + } + else + D->YUV.a = 0xF000; + } +#undef S0_MASK +#undef S1_MASK +} + +static void Sop_rgb332_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + while (w--) { + u8 s = *S++; + + if (s != Skey) { + D->RGB.a = 0xFF; + D->RGB.r = EXPAND_3to8(s >> 5); + D->RGB.g = EXPAND_3to8((s & 0x1C) >> 2); + D->RGB.b = EXPAND_2to8(s & 0x03); + } + else + D->RGB.a = 0xF000; + + D++; + } +} + +static void Sop_uyvy_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *D = gfxs->Dacc; + u32 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + u32 Skey0 = gfxs->Skey & 0x00FFFFFF; + u32 Skey1 = gfxs->Skey & 0xFFFF00FF; + +#ifdef WORDS_BIGENDIAN +#define S0_MASK 0xFFFF00FF +#define S1_MASK 0x00FFFFFF +#else +#define S0_MASK 0x00FFFFFF +#define S1_MASK 0xFFFF00FF +#endif + + while (w--) { + u32 s = *S++; + + if (s != Skey) { + u32 cb, cr; + +#ifdef WORDS_BIGENDIAN + cb = (s & 0x00FF0000) >> 16; + cr = (s & 0x000000FF); +#else + cb = (s & 0x000000FF); + cr = (s & 0x00FF0000) >> 16; +#endif + + if ((s & S0_MASK) != Skey0) { + D[0].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[0].YUV.y = (s & 0xFF000000) >> 24; +#else + D[0].YUV.y = (s & 0x0000FF00) >> 8; +#endif + D[0].YUV.u = cb; + D[0].YUV.v = cr; + } + else + D[0].YUV.a = 0xF000; + + if ((s & S1_MASK) != Skey1) { + D[1].YUV.a = 0xFF; +#ifdef WORDS_BIGENDIAN + D[1].YUV.y = (s & 0x0000FF00) >> 8; +#else + D[1].YUV.y = (s & 0xFF000000) >>24; +#endif + D[1].YUV.u = cb; + D[1].YUV.v = cr; + } + else + D[1].YUV.a = 0xF000; + } + + D += 2; + } + + if (gfxs->length & 1) { + u16 s = *((u16*)S); + + if (s != Skey0) { + D->YUV.a = 0xFF; + D->YUV.y = s >> 8; + D->YUV.u = s & 0xFF; + D->YUV.v = 0x00; + } + else + D->YUV.a = 0xF000; + } +#undef S0_MASK +#undef S1_MASK +} + +static void Sop_lut8_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = *S++; + + if (s != Skey) { + D->RGB.a = entries[s].a; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + } + else + D->RGB.a = 0xF000; + + D++; + } +} + +static void Sop_alut44_Kto_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + u8 *S = gfxs->Sop[0]; + u32 Skey = gfxs->Skey; + + DFBColor *entries = gfxs->Slut->entries; + + while (w--) { + u8 s = *S++; + + if ((s & 0x0F) != Skey) { + D->RGB.a = ((s & 0xF0) >> 4) | (s & 0xF0); + s &= 0x0F; + D->RGB.r = entries[s].r; + D->RGB.g = entries[s].g; + D->RGB.b = entries[s].b; + } + else + D->RGB.a = 0xF000; + + D++; + } +} + +static GenefxFunc Sop_PFI_Kto_Dacc[DFB_NUM_PIXELFORMATS] = { + Sop_argb1555_Kto_Dacc, /* DSPF_ARGB1555 */ + Sop_rgb16_Kto_Dacc, /* DSPF_RGB16 */ + Sop_rgb24_Kto_Dacc, /* DSPF_RGB24 */ + Sop_rgb32_Kto_Dacc, /* DSPF_RGB32 */ + Sop_argb_Kto_Dacc, /* DSPF_ARGB */ + Sop_a8_Kto_Dacc, /* DSPF_A8 */ + Sop_yuy2_Kto_Dacc, /* DSPF_YUY2 */ + Sop_rgb332_Kto_Dacc, /* DSPF_RGB332 */ + Sop_uyvy_Kto_Dacc, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Sop_lut8_Kto_Dacc, /* DSPF_LUT8 */ + Sop_alut44_Kto_Dacc, /* DSPF_ALUT44 */ + Sop_airgb_Kto_Dacc, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Sop_argb2554_Kto_Dacc, /* DSPF_ARGB2554 */ + Sop_argb4444_Kto_Dacc, /* DSPF_ARGB4444 */ + Sop_rgba4444_Kto_Dacc, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Sop_argb6666_Kto_Dacc, /* DSPF_ARGB1666 */ + Sop_argb1666_Kto_Dacc, /* DSPF_ARGB6666 */ + Sop_rgb18_Kto_Dacc, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sop_xrgb4444_Kto_Dacc, /* DSPF_RGB444 */ + Sop_xrgb1555_Kto_Dacc, /* DSPF_RGB555 */ + Sop_xbgr1555_Kto_Dacc, /* DSPF_BGR555 */ +}; + +/********************************* Sacc_to_Aop_PFI ****************************/ + +static void Sacc_to_Aop_argb6666( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + u32 pixel = PIXEL_ARGB6666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + S++; + } +} + +static void Sacc_to_Aop_argb1666( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + u32 pixel = PIXEL_ARGB1666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + S++; + } +} + +static void Sacc_to_Aop_rgb18( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + u32 pixel = PIXEL_RGB18( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + S++; + } +} + +static void Sacc_to_Aop_rgb24( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + *D++ = (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b; + *D++ = (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g; + *D++ = (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r; + } + else + D += 3; + + S++; + } +} + +static void Sacc_to_Aop_a8( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) + *D = (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a; + + D++; + S++; + } +} + +static void Sacc_to_Aop_yuy2( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u16 *D = gfxs->Aop[0]; + + if ((long)D & 2) { + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) | + ((S->YUV.v & 0xFF00) ? 0XFF00 : (S->YUV.v<<8)); + } + S++; + D++; + w--; + } + + for (l = w>>1; l--;) { + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + u32 y0, cb, y1, cr; + + y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y; + y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y; + + cb = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *((u32*)D) = y1 | (cr << 8) | (y0 << 16) | (cb << 24); +#else + *((u32*)D) = y0 | (cb << 8) | (y1 << 16) | (cr << 24); +#endif + } + else if (!(S[0].YUV.a & 0xF000)) { + D[0] = ((S[0].YUV.y & 0xFF00) ? 0x00FF : S[0].YUV.y) | + ((S[0].YUV.u & 0xFF00) ? 0xFF00 : (S[0].YUV.u<<8)); + } + else if (!(S[1].YUV.a & 0xF000)) { + D[1] = ((S[1].YUV.y & 0xFF00) ? 0x00FF : S[1].YUV.y) | + ((S[1].YUV.v & 0xFF00) ? 0xFF00 : (S[1].YUV.v<<8)); + } + + D += 2; + S += 2; + } + + if (w & 1) { + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) | + ((S->YUV.u & 0xFF00) ? 0xFF00 : (S->YUV.u<<8)); + } + } +} + +static void Sacc_to_Aop_rgb332( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + *D = PIXEL_RGB332( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + } + + D++; + S++; + } +} + +static void Sacc_to_Aop_uyvy( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u16 *D = gfxs->Aop[0]; + + if ((long)D & 2) { + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.v & 0xFF00) ? 0x00FF : S->YUV.v) | + ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8)); + } + S++; + D++; + w--; + } + + for (l = w>>1; l--;) { + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + u32 cb, y0, cr, y1; + + y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y; + y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y; + + cb = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *((u32*)D) = cr | (y1 << 8) | (cb << 16) | (y0 << 24); +#else + *((u32*)D) = cb | (y0 << 8) | (cr << 16) | (y1 << 24); +#endif + } + else if (!(S[0].YUV.a & 0xF000)) { + D[0] = ((S[0].YUV.u & 0xFF00) ? 0x00FF : S[0].YUV.u) | + ((S[0].YUV.y & 0xFF00) ? 0xFF00 : (S[0].YUV.y<<8)); + } + else if (!(S[1].YUV.a & 0xF000)) { + D[1] = ((S[1].YUV.v & 0xFF00) ? 0x00FF : S[1].YUV.v) | + ((S[1].YUV.y & 0xFF00) ? 0xFF00 : (S[1].YUV.y<<8)); + } + + D += 2; + S += 2; + } + + if (w & 1) { + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.u & 0xFF00) ? 0x00FF : S->YUV.u) | + ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8)); + } + } +} + +static void Sacc_to_Aop_lut8( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + *D = dfb_palette_search( gfxs->Alut, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b, + (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a ); + } + + D++; + S++; + } +} + +static void Sacc_to_Aop_alut44( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->RGB.a & 0xF000)) { + *D = (S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0) + + dfb_palette_search( gfxs->Alut, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b, + 0x80 ); + } + + D++; + S++; + } +} + +static void Sacc_to_Aop_i420( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *Dy = gfxs->Aop[0]; + + while (w--) { + if (!(S->YUV.a & 0xF000)) + *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y; + + S++; + Dy++; + } + + if (gfxs->AopY & 1) { + u8 *Du = gfxs->Aop[1]; + u8 *Dv = gfxs->Aop[2]; + + w = gfxs->length>>1; + S = gfxs->Sacc; + + while (w--) { + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + u32 tmp; + + tmp = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (tmp & 0xFF00) + tmp = 0xFF; + *Du = tmp; + + tmp = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (tmp & 0xFF00) + tmp = 0xFF; + *Dv = tmp; + + } + else if (!(S[0].YUV.a & 0xF000)) { + *Du = (*Du + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1; + *Dv = (*Dv + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1; + } + else if (!(S[1].YUV.a & 0xF000)) { + *Du = (*Du + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1; + *Dv = (*Dv + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1; + } + + S += 2; + Du++; + Dv++; + } + } +} + +static void Sacc_to_Aop_nv12( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *Dy = gfxs->Aop[0]; + + while (w--) { + if (!(S->YUV.a & 0xF000)) + *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y; + + S++; + Dy++; + } + + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) { + u16 *Duv = gfxs->Aop[1]; + + w = gfxs->length>>1; + S = gfxs->Sacc; + + while (w--) { + u32 cb, cr; + + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + cb = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *Duv = cr | (cb << 8); + } + else if (!(S[0].YUV.a & 0xF000)) { + cb = ((*Duv >> 8) + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1; + cr = ((*Duv & 0xFF) + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1; + *Duv = cr | (cb << 8); + } + else if (!(S[1].YUV.a & 0xF000)) { + cb = ((*Duv >> 8) + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1; + cr = ((*Duv & 0xFF) + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1; + *Duv = cr | (cb << 8); + } +#else + *Duv = cb | (cr << 8); + } + else if (!(S[0].YUV.a & 0xF000)) { + cb = ((*Duv & 0xFF) + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1; + cr = ((*Duv >> 8) + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1; + *Duv = cb | (cr << 8); + } + else if (!(S[1].YUV.a & 0xF000)) { + cb = ((*Duv & 0xFF) + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1; + cr = ((*Duv >> 8) + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1; + *Duv = cb | (cr << 8); + } +#endif + + S += 2; + Duv++; + } + } +} + +static void Sacc_to_Aop_nv21( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *Dy = gfxs->Aop[0]; + + while (w--) { + if (!(S->YUV.a & 0xF000)) + *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y; + + S++; + Dy++; + } + + if (gfxs->AopY & 1) { + u16 *Dvu = gfxs->Aop[1]; + + w = gfxs->length>>1; + S = gfxs->Sacc; + + while (w--) { + u32 cb, cr; + + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + cb = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + + *Dvu = cr | (cb << 8); + } + else if (!(S[0].YUV.a & 0xF000)) { + cb = ((*Dvu >> 8) + ((S[0].YUV.u & 0xFF00) ? 0xFF : S[0].YUV.u)) >> 1; + cr = ((*Dvu & 0xFF) + ((S[0].YUV.v & 0xFF00) ? 0xFF : S[0].YUV.v)) >> 1; + *Dvu = cr | (cb << 8); + } + else if (!(S[1].YUV.a & 0xF000)) { + cb = ((*Dvu >> 8) + ((S[1].YUV.u & 0xFF00) ? 0xFF : S[1].YUV.u)) >> 1; + cr = ((*Dvu & 0xFF) + ((S[1].YUV.v & 0xFF00) ? 0xFF : S[1].YUV.v)) >> 1; + *Dvu = cr | (cb << 8); + } + + S += 2; + Dvu++; + } + } +} + +static void Sacc_to_Aop_ayuv( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u32 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S->YUV.a & 0xF000)) { + *D = PIXEL_AYUV( (S->YUV.a & 0xFF00) ? 0xFF : S->YUV.a, + (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y, + (S->YUV.u & 0xFF00) ? 0xFF : S->YUV.u, + (S->YUV.v & 0xFF00) ? 0xFF : S->YUV.v ); + } + + D++; + S++; + } +} + +static void Sacc_to_Aop_a4( GenefxState *gfxs ) +{ + int w = gfxs->length>>1; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + while (w--) { + if (!(S[0].RGB.a & 0xF000) && !(S[1].RGB.a & 0xF000)) { + *D = ((S[0].RGB.a & 0xFF00) ? 0xF0 : (S[0].RGB.a & 0xF0)) | + ((S[1].RGB.a & 0XFF00) ? 0x0F : (S[1].RGB.a >> 4)); + } + else if (!(S[0].RGB.a & 0xF000)) { + *D = (*D & 0x0F) | ((S[0].RGB.a & 0xFF00) ? 0xF0 : (S[0].RGB.a & 0xF0)); + } + else if (!(S[1].RGB.a & 0xF000)) { + *D = (*D & 0xF0) | ((S[1].RGB.a & 0XFF00) ? 0x0F : (S[1].RGB.a >> 4)); + } + + D++; + S += 2; + } + + if (gfxs->length & 1) { + if (!(S->RGB.a & 0xF000)) + *D = (*D & 0x0F) | ((S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0)); + } +} + +static GenefxFunc Sacc_to_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Sacc_to_Aop_argb1555, /* DSPF_ARGB1555 */ + Sacc_to_Aop_rgb16, /* DSPF_RGB16 */ + Sacc_to_Aop_rgb24, /* DSPF_RGB24 */ + Sacc_to_Aop_rgb32, /* DSPF_RGB32 */ + Sacc_to_Aop_argb, /* DSPF_ARGB */ + Sacc_to_Aop_a8, /* DSPF_A8 */ + Sacc_to_Aop_yuy2, /* DSPF_YUY2 */ + Sacc_to_Aop_rgb332, /* DSPF_RGB332 */ + Sacc_to_Aop_uyvy, /* DSPF_UYVY */ + Sacc_to_Aop_i420, /* DSPF_I420 */ + Sacc_to_Aop_i420, /* DSPF_YV12 */ + Sacc_to_Aop_lut8, /* DSPF_LUT8 */ + Sacc_to_Aop_alut44, /* DSPF_ALUT44 */ + Sacc_to_Aop_airgb, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Sacc_to_Aop_nv12, /* DSPF_NV12 */ + Sacc_to_Aop_nv12, /* DSPF_NV16 */ + Sacc_to_Aop_argb2554, /* DSPF_ARGB2554 */ + Sacc_to_Aop_argb4444, /* DSPF_ARGB4444 */ + Sacc_to_Aop_rgba4444, /* DSPF_RGBA4444 */ + Sacc_to_Aop_nv21, /* DSPF_NV21 */ + Sacc_to_Aop_ayuv, /* DSPF_AYUV */ + Sacc_to_Aop_a4, /* DSPF_A4 */ + Sacc_to_Aop_argb1666, /* DSPF_ARGB1666 */ + Sacc_to_Aop_argb6666, /* DSPF_ARGB6666 */ + Sacc_to_Aop_rgb18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sacc_to_Aop_xrgb4444, /* DSPF_RGB444 */ + Sacc_to_Aop_xrgb1555, /* DSPF_RGB555 */ + Sacc_to_Aop_xbgr1555, /* DSPF_BGR555 */ +}; + +/********************************* Sacc_Sto_Aop_PFI ***************************/ + +static void Sacc_Sto_Aop_argb6666( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + u32 pixel = PIXEL_ARGB6666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + i += SperD; + } +} + +static void Sacc_Sto_Aop_argb1666( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + u32 pixel = PIXEL_ARGB1666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + i += SperD; + } +} + +static void Sacc_Sto_Aop_rgb18( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + u32 pixel = PIXEL_RGB18( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + i += SperD; + } +} + +static void Sacc_Sto_Aop_rgb24( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + *D++ = (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b; + *D++ = (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g; + *D++ = (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r; + } + else + D += 3; + + i += SperD; + } +} + +static void Sacc_Sto_Aop_a8( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) + *D = (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a; + + D++; + i += SperD; + } +} + +static void Sacc_Sto_Aop_yuy2( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u16 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + int SperD2 = gfxs->SperD << 1; + + if ((long)D & 2) { + GenefxAccumulator *S = Sacc; + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) | + ((S->YUV.v & 0xFF00) ? 0XFF00 : (S->YUV.v<<8)); + } + D++; + w--; + i = SperD; + } + + for (l = w>>1; l--;) { + GenefxAccumulator *S0 = &Sacc[i>>16]; + GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16]; + + if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) { + u32 y0, cb, y1, cr; + + y0 = (S0->YUV.y & 0xFF00) ? 0xFF : S0->YUV.y; + y1 = (S1->YUV.y & 0xFF00) ? 0xFF : S1->YUV.y; + + cb = (S0->YUV.u + S1->YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S0->YUV.v + S1->YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *((u32*)D) = y1 | (cr << 8) | (y0 << 16) | (cb << 24); +#else + *((u32*)D) = y0 | (cb << 8) | (y1 << 16) | (cr << 24); +#endif + } + else if (!(S0->YUV.a & 0xF000)) { + D[0] = ((S0->YUV.y & 0xFF00) ? 0x00FF : S0->YUV.y) | + ((S0->YUV.u & 0xFF00) ? 0xFF00 : (S0->YUV.u<<8)); + } + else if (!(S1->YUV.a & 0xF000)) { + D[1] = ((S1->YUV.y & 0xFF00) ? 0x00FF : S1->YUV.y) | + ((S1->YUV.v & 0xFF00) ? 0xFF00 : (S1->YUV.v<<8)); + } + + D += 2; + i += SperD2; + } + + if (w & 1) { + GenefxAccumulator *S = &Sacc[i>>16]; + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) | + ((S->YUV.u & 0xFF00) ? 0xFF00 : (S->YUV.u<<8)); + } + } +} + +static void Sacc_Sto_Aop_rgb332( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + *D = PIXEL_RGB332( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + } + + D++; + i += SperD; + } +} + +static void Sacc_Sto_Aop_uyvy( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u16 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + int SperD2 = gfxs->SperD << 1; + + if ((long)D & 2) { + GenefxAccumulator *S = Sacc; + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.v & 0xFF00) ? 0x00FF : S->YUV.v) | + ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8)); + } + D++; + w--; + i = SperD; + } + + for (l = w>>1; l--;) { + GenefxAccumulator *S0 = &Sacc[i>>16]; + GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16]; + + if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) { + u32 cb, y0, cr, y1; + + y0 = (S0->YUV.y & 0xFF00) ? 0xFF : S0->YUV.y; + y1 = (S1->YUV.y & 0xFF00) ? 0xFF : S1->YUV.y; + + cb = (S0->YUV.u + S1->YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S0->YUV.v + S1->YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *((u32*)D) = cr | (y1 << 8) | (cb << 16) | (y0 << 24); +#else + *((u32*)D) = cb | (y0 << 8) | (cr << 16) | (y1 << 24); +#endif + } + else if (!(S0->YUV.a & 0xF000)) { + D[0] = ((S0->YUV.u & 0xFF00) ? 0x00FF : S0->YUV.u) | + ((S0->YUV.y & 0xFF00) ? 0xFF00 : (S0->YUV.y<<8)); + } + else if (!(S1->YUV.a & 0xF000)) { + D[1] = ((S1->YUV.v & 0xFF00) ? 0x00FF : S1->YUV.v) | + ((S1->YUV.y & 0xFF00) ? 0xFF00 : (S1->YUV.y<<8)); + } + + D += 2; + i += SperD2; + } + + if (w & 1) { + GenefxAccumulator *S = &Sacc[i>>16]; + if (!(S->YUV.a & 0xF00)) { + *D = ((S->YUV.u & 0xFF00) ? 0x00FF : S->YUV.u) | + ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8)); + } + } +} + +static void Sacc_Sto_Aop_lut8( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + *D = dfb_palette_search( gfxs->Alut, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b, + (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a ); + } + + D++; + i += SperD; + } +} + +static void Sacc_Sto_Aop_alut44( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->RGB.a & 0xF000)) { + *D = (S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0) + + dfb_palette_search( gfxs->Alut, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b, + 0x80 ); + } + + D++; + i += SperD; + } +} + +static void Sacc_Sto_Aop_i420( GenefxState *gfxs ) +{ + int i = gfxs->Xphase; + int w = gfxs->length; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *Dy = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->YUV.a & 0xF000)) + *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y; + + Dy++; + i += SperD; + } + + if (gfxs->AopY & 1) { + u8 *Du = gfxs->Aop[1]; + u8 *Dv = gfxs->Aop[2]; + + w = gfxs->length>>1; + i = gfxs->Xphase>>1; + + while (w--) { + GenefxAccumulator *S0 = &Sacc[i>>16]; + GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16]; + + if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) { + u32 tmp; + + tmp = (S0->YUV.u + S1->YUV.u) >> 1; + if (tmp & 0xFF00) + tmp = 0xFF; + *Du = tmp; + + tmp = (S0->YUV.v + S1->YUV.v) >> 1; + if (tmp & 0xFF00) + tmp = 0xFF; + *Dv = tmp; + + } + else if (!(S0->YUV.a & 0xF000)) { + *Du = (*Du + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1; + *Dv = (*Dv + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1; + } + else if (!(S1->YUV.a & 0xF000)) { + *Du = (*Du + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1; + *Dv = (*Dv + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1; + } + + Du++; + Dv++; + i += SperD << 1; + } + } +} + +static void Sacc_Sto_Aop_nv12( GenefxState *gfxs ) +{ + int i = gfxs->Xphase; + int w = gfxs->length; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *Dy = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->YUV.a & 0xF000)) + *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y; + + Dy++; + i += SperD; + } + + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) { + u16 *Duv = gfxs->Aop[1]; + + w = gfxs->length>>1; + i = gfxs->Xphase>>1; + + while (w--) { + GenefxAccumulator *S0 = &Sacc[i>>16]; + GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16]; + u32 cb, cr; + + if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) { + cb = (S0->YUV.u + S1->YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S0->YUV.v + S1->YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *Duv = cr | (cb << 8); + } + else if (!(S0->YUV.a & 0xF000)) { + cb = ((*Duv >> 8) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1; + cr = ((*Duv & 0xFF) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1; + *Duv = cr | (cb << 8); + } + else if (!(S1->YUV.a & 0xF000)) { + cb = ((*Duv >> 8) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1; + cr = ((*Duv & 0xFF) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1; + *Duv = cr | (cb << 8); + } +#else + *Duv = cb | (cr << 8); + } + else if (!(S0->YUV.a & 0xF000)) { + cb = ((*Duv & 0xFF) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1; + cr = ((*Duv >> 8) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1; + *Duv = cb | (cr << 8); + } + else if (!(S1->YUV.a & 0xF000)) { + cb = ((*Duv & 0xFF) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1; + cr = ((*Duv >> 8) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1; + *Duv = cb | (cr << 8); + } +#endif + + Duv++; + + i += SperD << 1; + } + } +} + +static void Sacc_Sto_Aop_nv21( GenefxState *gfxs ) +{ + int i = gfxs->Xphase; + int w = gfxs->length; + GenefxAccumulator *Sacc = gfxs->Sacc; + u8 *Dy = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->YUV.a & 0xF000)) + *Dy = (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y; + + Dy++; + i += SperD; + } + + if (gfxs->dst_format == DSPF_NV16 || gfxs->AopY & 1) { + u16 *Dvu = gfxs->Aop[1]; + + w = gfxs->length>>1; + i = gfxs->Xphase>>1; + + while (w--) { + GenefxAccumulator *S0 = &Sacc[i>>16]; + GenefxAccumulator *S1 = &Sacc[(i+SperD)>>16]; + u32 cb, cr; + + if (!(S0->YUV.a & 0xF000) && !(S1->YUV.a & 0xF000)) { + cb = (S0->YUV.u + S1->YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S0->YUV.v + S1->YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *Dvu = cb | (cr << 8); + } + else if (!(S0->YUV.a & 0xF000)) { + cb = ((*Dvu & 0xFF) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1; + cr = ((*Dvu >> 8) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1; + *Dvu = cb | (cr << 8); + } + else if (!(S1->YUV.a & 0xF000)) { + cb = ((*Dvu & 0xFF) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1; + cr = ((*Dvu >> 8) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1; + *Dvu = cb | (cr << 8); + } +#else + *Dvu = cr | (cb << 8); + } + else if (!(S0->YUV.a & 0xF000)) { + cb = ((*Dvu >> 8) + ((S0->YUV.u & 0xFF00) ? 0xFF : S0->YUV.u)) >> 1; + cr = ((*Dvu & 0xFF) + ((S0->YUV.v & 0xFF00) ? 0xFF : S0->YUV.v)) >> 1; + *Dvu = cr | (cb << 8); + } + else if (!(S1->YUV.a & 0xF000)) { + cb = ((*Dvu >> 8) + ((S1->YUV.u & 0xFF00) ? 0xFF : S1->YUV.u)) >> 1; + cr = ((*Dvu & 0xFF) + ((S1->YUV.v & 0xFF00) ? 0xFF : S1->YUV.v)) >> 1; + *Dvu = cr | (cb << 8); + } +#endif + + Dvu++; + + i += SperD << 1; + } + } +} + +static void Sacc_Sto_Aop_ayuv( GenefxState *gfxs ) +{ + int w = gfxs->length; + int i = gfxs->Xphase; + GenefxAccumulator *Sacc = gfxs->Sacc; + u32 *D = gfxs->Aop[0]; + int SperD = gfxs->SperD; + + while (w--) { + GenefxAccumulator *S = &Sacc[i>>16]; + + if (!(S->YUV.a & 0xF000)) { + *D = PIXEL_AYUV( (S->YUV.a & 0xFF00) ? 0xFF : S->YUV.a, + (S->YUV.y & 0xFF00) ? 0xFF : S->YUV.y, + (S->YUV.u & 0xFF00) ? 0xFF : S->YUV.u, + (S->YUV.v & 0xFF00) ? 0xFF : S->YUV.v ); + } + + D++; + i += SperD; + } +} + + +static GenefxFunc Sacc_Sto_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Sacc_Sto_Aop_argb1555, /* DSPF_ARGB1555 */ + Sacc_Sto_Aop_rgb16, /* DSPF_RGB16 */ + Sacc_Sto_Aop_rgb24, /* DSPF_RGB24 */ + Sacc_Sto_Aop_rgb32, /* DSPF_RGB32 */ + Sacc_Sto_Aop_argb, /* DSPF_ARGB */ + Sacc_Sto_Aop_a8, /* DSPF_A8 */ + Sacc_Sto_Aop_yuy2, /* DSPF_YUY2 */ + Sacc_Sto_Aop_rgb332, /* DSPF_RGB332 */ + Sacc_Sto_Aop_uyvy, /* DSPF_UYVY */ + Sacc_Sto_Aop_i420, /* DSPF_I420 */ + Sacc_Sto_Aop_i420, /* DSPF_YV12 */ + Sacc_Sto_Aop_lut8, /* DSPF_LUT8 */ + Sacc_Sto_Aop_alut44, /* DSPF_ALUT44 */ + Sacc_Sto_Aop_airgb, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + Sacc_Sto_Aop_nv12, /* DSPF_NV12 */ + Sacc_Sto_Aop_nv12, /* DSPF_NV16 */ + Sacc_Sto_Aop_argb2554, /* DSPF_ARGB2554 */ + Sacc_Sto_Aop_argb4444, /* DSPF_ARGB4444 */ + Sacc_Sto_Aop_rgba4444, /* DSPF_RGBA4444 */ + Sacc_Sto_Aop_nv21, /* DSPF_NV21 */ + Sacc_Sto_Aop_ayuv, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Sacc_Sto_Aop_argb1666, /* DSPF_ARGB1666 */ + Sacc_Sto_Aop_argb6666, /* DSPF_ARGB6666 */ + Sacc_Sto_Aop_rgb18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sacc_Sto_Aop_xrgb4444, /* DSPF_RGB444 */ + Sacc_Sto_Aop_xrgb1555, /* DSPF_RGB555 */ + Sacc_Sto_Aop_xbgr1555, /* DSPF_BGR555 */ +}; + +/********************************* Sacc_toK_Aop_PFI ***************************/ + +static void Sacc_toK_Aop_argb6666( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (!(S->RGB.a & 0xF000) && Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) { + u32 pixel = PIXEL_ARGB6666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + S++; + } +} + +static void Sacc_toK_Aop_argb1666( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (!(S->RGB.a & 0xF000) && Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) { + u32 pixel = PIXEL_ARGB1666( (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + S++; + } +} + +static void Sacc_toK_Aop_rgb18( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (!(S->RGB.a & 0xF000) && Dkey == ((u32)(D[2]<<16 | D[1]<<8 | D[0]) & 0x3FFFF)) { + u32 pixel = PIXEL_RGB18( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D +=3; + S++; + } +} + +static void Sacc_toK_Aop_rgb24( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u8 r = (gfxs->Dkey >> 16); + u8 g = (gfxs->Dkey >> 8) & 0xff; + u8 b = (gfxs->Dkey ) & 0xff; + + while (w--) { + if (!(S->RGB.a & 0xF000) && D[0] == b && D[1] == g && D[2] == r) { + *D++ = (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b; + *D++ = (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g; + *D++ = (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r; + } + else + D += 3; + + S++; + } +} + +static void Sacc_toK_Aop_a8( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + + /* FIXME: do all or do none? */ + while (w--) { + if (!(S->RGB.a & 0xF000)) + *D = (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a; + + D++; + S++; + } +} + +static void Sacc_toK_Aop_yuy2( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u16 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; +#ifdef WORDS_BIGENDIAN + u16 Dkey0 = gfxs->Dkey >> 16; + u16 Dkey1 = gfxs->Dkey & 0xFFFF; +#else + u16 Dkey0 = gfxs->Dkey & 0xFFFF; + u16 Dkey1 = gfxs->Dkey >> 16; +#endif + + if ((long)D & 2) { + if (!(S->YUV.a & 0xF000) && (*D == Dkey1)) { + *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) | + ((S->YUV.v & 0xFF00) ? 0xFF00 : (S->YUV.v<<8)); + } + S++; + D++; + w--; + } + + for (l = w>>1; l--;) { + if (*D == Dkey) { + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + u32 y0, cb, y1, cr; + + y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y; + y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y; + + cb = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *((u32*)D) = y1 | (cr << 8) | (y0 << 16) | (cb << 24); +#else + *((u32*)D) = y0 | (cb << 8) | (y1 << 16) | (cr << 24); +#endif + } + else if (!(S[0].YUV.a & 0xF000)) { + D[0] = ((S[0].YUV.y & 0xFF00) ? 0x00FF : S[0].YUV.y) | + ((S[0].YUV.u & 0xFF00) ? 0xFF00 : (S[0].YUV.u<<8)); + } + else if (!(S[1].YUV.a & 0xF000)) { + D[1] = ((S[1].YUV.y & 0xFF00) ? 0x00FF : S[1].YUV.y) | + ((S[1].YUV.v & 0xFF00) ? 0xFF00 : (S[1].YUV.v<<8)); + } + } + + D += 2; + S += 2; + } + + if (w & 1) { + if (!(S->YUV.a & 0xF000) && (*D == Dkey0)) { + *D = ((S->YUV.y & 0xFF00) ? 0x00FF : S->YUV.y) | + ((S->YUV.u & 0xFF00) ? 0xFF00 : (S->YUV.u<<8)); + } + } +} + +static void Sacc_toK_Aop_rgb332( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (!(S->RGB.a & 0xF000) && (*D == Dkey)) { + *D = PIXEL_RGB332( (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b ); + } + + D++; + S++; + } +} + +static void Sacc_toK_Aop_uyvy( GenefxState *gfxs ) +{ + int l; + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u16 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; +#ifdef WORDS_BIGENDIAN + u16 Dkey0 = gfxs->Dkey >> 16; + u16 Dkey1 = gfxs->Dkey & 0xFFFF; +#else + u16 Dkey0 = gfxs->Dkey & 0xFFFF; + u16 Dkey1 = gfxs->Dkey >> 16; +#endif + + if ((long)D & 2) { + if (!(S->YUV.a & 0xF000) && (*D == Dkey1)) { + *D = ((S->YUV.v & 0xFF00) ? 0x00FF : S->YUV.v) | + ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8)); + } + S++; + D++; + w--; + } + + for (l = w>>1; l--;) { + if (*D == Dkey) { + if (!(S[0].YUV.a & 0xF000) && !(S[1].YUV.a & 0xF000)) { + u32 cb, y0, cr, y1; + + y0 = (S[0].YUV.y & 0xFF00) ? 0xFF : S[0].YUV.y; + y1 = (S[1].YUV.y & 0xFF00) ? 0xFF : S[1].YUV.y; + + cb = (S[0].YUV.u + S[1].YUV.u) >> 1; + if (cb & 0xFF00) + cb = 0xFF; + + cr = (S[0].YUV.v + S[1].YUV.v) >> 1; + if (cr & 0xFF00) + cr = 0xFF; + +#ifdef WORDS_BIGENDIAN + *((u32*)D) = cr | (y1 << 8) | (cb << 16) | (y0 << 24); +#else + *((u32*)D) = cb | (y0 << 8) | (cr << 16) | (y1 << 24); +#endif + } + else if (!(S[0].YUV.a & 0xF000)) { + D[0] = ((S[0].YUV.u & 0xFF00) ? 0x00FF : S[0].YUV.u) | + ((S[0].YUV.y & 0xFF00) ? 0xFF00 : (S[0].YUV.y<<8)); + } + else if (!(S[1].YUV.a & 0xF000)) { + D[1] = ((S[1].YUV.v & 0xFF00) ? 0x00FF : S[1].YUV.v) | + ((S[1].YUV.y & 0xFF00) ? 0xFF00 : (S[1].YUV.y<<8)); + } + } + + D += 2; + S += 2; + } + + if (w & 1) { + if (!(S->YUV.a & 0xF000) && (*D == Dkey0)) { + *D = ((S->YUV.u & 0xFF00) ? 0x00FF : S->YUV.u) | + ((S->YUV.y & 0xFF00) ? 0xFF00 : (S->YUV.y<<8)); + } + } +} + +static void Sacc_toK_Aop_lut8( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (!(S->RGB.a & 0xF000) && (*D == Dkey)) { + *D = dfb_palette_search( gfxs->Alut, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b, + (S->RGB.a & 0xFF00) ? 0xFF : S->RGB.a ); + } + + D++; + S++; + } +} + +static void Sacc_toK_Aop_alut44( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + u8 *D = gfxs->Aop[0]; + u32 Dkey = gfxs->Dkey; + + while (w--) { + if (!(S->RGB.a & 0xF000) && ((*D & 0x0F) == Dkey)) { + *D = (S->RGB.a & 0xFF00) ? 0xF0 : (S->RGB.a & 0xF0) + + dfb_palette_search( gfxs->Alut, + (S->RGB.r & 0xFF00) ? 0xFF : S->RGB.r, + (S->RGB.g & 0xFF00) ? 0xFF : S->RGB.g, + (S->RGB.b & 0xFF00) ? 0xFF : S->RGB.b, + 0x80 ); + } + + D++; + S++; + } +} + +static GenefxFunc Sacc_toK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Sacc_toK_Aop_argb1555, /* DSPF_ARGB1555 */ + Sacc_toK_Aop_rgb16, /* DSPF_RGB16 */ + Sacc_toK_Aop_rgb24, /* DSPF_RGB24 */ + Sacc_toK_Aop_rgb32, /* DSPF_RGB32 */ + Sacc_toK_Aop_argb, /* DSPF_ARGB */ + Sacc_toK_Aop_a8, /* DSPF_A8 */ + Sacc_toK_Aop_yuy2, /* DSPF_YUY2 */ + Sacc_toK_Aop_rgb332, /* DSPF_RGB332 */ + Sacc_toK_Aop_uyvy, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Sacc_toK_Aop_lut8, /* DSPF_LUT8 */ + Sacc_toK_Aop_alut44, /* DSPF_ALUT44 */ + Sacc_toK_Aop_airgb, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Sacc_toK_Aop_argb2554, /* DSPF_ARGB2554 */ + Sacc_toK_Aop_argb4444, /* DSPF_ARGB4444 */ + Sacc_toK_Aop_rgba4444, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Sacc_toK_Aop_argb1666, /* DSPF_ARGB1666 */ + Sacc_toK_Aop_argb6666, /* DSPF_ARGB6666 */ + Sacc_toK_Aop_rgb18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sacc_toK_Aop_xrgb4444, /* DSPF_RGB444 */ + Sacc_toK_Aop_xrgb1555, /* DSPF_RGB555 */ + Sacc_toK_Aop_xbgr1555, /* DSPF_BGR555 */ +}; + +/********************************* Sacc_StoK_Aop_PFI **************************/ + +static GenefxFunc Sacc_StoK_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Sacc_StoK_Aop_argb1555, /* DSPF_ARGB1555 */ + Sacc_StoK_Aop_rgb16, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + Sacc_StoK_Aop_rgb32, /* DSPF_RGB32 */ + Sacc_StoK_Aop_argb, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + Sacc_StoK_Aop_airgb, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Sacc_StoK_Aop_argb2554, /* DSPF_ARGB2554 */ + Sacc_StoK_Aop_argb4444, /* DSPF_ARGB4444 */ + Sacc_StoK_Aop_rgba4444, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + Sacc_StoK_Aop_xrgb4444, /* DSPF_RGB444 */ + Sacc_StoK_Aop_xrgb1555, /* DSPF_RGB555 */ + Sacc_StoK_Aop_xbgr1555, /* DSPF_BGR555 */ +}; + +/************** Bop_a8_set_alphapixel_Aop_PFI *********************************/ + +/* change the last value to adjust the size of the device (1-4) */ +#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \ + SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 ) + + +static void Bop_a8_set_alphapixel_Aop_argb1555( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0x7c1f; + u32 g = Cop & 0x03e0; + +#define SET_PIXEL(d,a) \ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = (a>>3)+1;\ + register u32 t1 = (d & 0x7c1f);\ + register u32 t2 = (d & 0x03e0);\ + d = ((d) & 0x8000) | ((a & 0x80) << 8) | \ + ((((rb-t1)*s+(t1<<5)) & 0x000f83e0) + \ + ((( g-t2)*s+(t2<<5)) & 0x00007c00)) >> 5;\ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + + +static void Bop_a8_set_alphapixel_Aop_rgb16( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0xf81f; + u32 g = Cop & 0x07e0; + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = (a>>2)+1;\ + register u32 t1 = (d & 0xf81f);\ + register u32 t2 = (d & 0x07e0);\ + d = ((((rb-t1)*s+(t1<<6)) & 0x003e07c0) + \ + ((( g-t2)*s+(t2<<6)) & 0x0001f800)) >> 6;\ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_argb6666( GenefxState *gfxs ) +{ + + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0x3f03f; + u32 g = Cop & 0xfc0; + + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = (a>>2)+1;\ + register u32 t1 = (d & 0x3f03f);\ + register u32 t2 = (d & 0xfc0);\ + d = ((((rb-t1)*s+(t1<<6)) & 0xfc0fc0) + \ + ((( g-t2)*s+(t2<<6)) & 0xfc000)) >> 6;\ + }\ + } + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL + +} + +static void Bop_a8_set_alphapixel_Aop_argb1666( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0x3f03f; + u32 g = Cop & 0xfc0; + + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = (a>>2)+1;\ + register u32 t1 = (d & 0x3f03f);\ + register u32 t2 = (d & 0xfc0);\ + d = ((((rb-t1)*s+(t1<<6)) & 0xfc0fc0) + \ + ((( g-t2)*s+(t2<<6)) & 0xfc000)) >> 6;\ + }\ + } + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_rgb18( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0x3f03f; + u32 g = Cop & 0xfc0; + + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = (a>>2)+1;\ + register u32 t1 = (d & 0x3f03f);\ + register u32 t2 = (d & 0xfc0);\ + d = ((((rb-t1)*s+(t1<<6)) & 0xfc0fc0) + \ + ((( g-t2)*s+(t2<<6)) & 0xfc000)) >> 6;\ + }\ + } + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL + +} + +static void Bop_a8_set_alphapixel_Aop_rgb24( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + DFBColor color = gfxs->color; + +#define SET_PIXEL(d,r,g,b,a)\ + switch (a) {\ + case 0xff:\ + d[0] = b;\ + d[1] = g;\ + d[2] = r;\ + case 0: break;\ + default: {\ + register u16 s = a+1;\ + d[0] = ((b-d[0]) * s + (d[0] << 8)) >> 8;\ + d[1] = ((g-d[1]) * s + (d[1] << 8)) >> 8;\ + d[2] = ((r-d[2]) * s + (d[2] << 8)) >> 8;\ + }\ + } + + while (w>4) { + SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++; + SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++; + SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++; + SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3; S++; + w-=4; + } + while (w--) { + SET_PIXEL( D, color.r, color.g, color.b, *S ); D+=3, S++; + } + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_rgb32( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0xff00ff; + u32 g = Cop & 0x00ff00; + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = a+1;\ + register u32 t1 = (d & 0x00ff00ff);\ + register u32 t2 = (d & 0x0000ff00);\ + d = ((((rb-t1)*s+(t1<<8)) & 0xff00ff00) + \ + ((( g-t2)*s+(t2<<8)) & 0x00ff0000)) >> 8;\ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + + +/* saturating alpha blend */ + +static void Bop_a8_set_alphapixel_Aop_argb( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop | 0xff000000; + u32 rb = Cop & 0x00ff00ff; + u32 g = gfxs->color.g; + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = a+1;\ + register u32 s1 = 256-a;\ + register u32 sa = (((d >> 24) * s1) >> 8) + a;\ + d = (sa << 24) + \ + (((((d & 0x00ff00ff) * s1) + (rb * s)) >> 8) & 0x00ff00ff) + \ + (((((d & 0x0000ff00) >> 8) * s1) + ((g) * s)) & 0x0000ff00); \ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_airgb( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 rb = Cop & 0x00ff00ff; + u32 g = gfxs->color.g; + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = a+1;\ + register u32 s1 = 256-s;\ + register s32 sa = (d >> 24) - a;\ + if (sa < 0) sa = 0;\ + d = (sa << 24) + \ + (((((d & 0x00ff00ff) * s1) + (rb * s)) >> 8) & 0x00ff00ff) + \ + (((((d & 0x0000ff00) >> 8) * s1) + ((g) * s)) & 0x0000ff00); \ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_a8( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = 0xff;\ + case 0: break; \ + default: {\ + register u16 s1 = 255-a;\ + d = ((d * s1) >> 8) + a;\ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_yuy2( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u32 y = gfxs->YCop; + u32 u = gfxs->CbCop; + u32 v = gfxs->CrCop; + +#ifdef WORDS_BIGENDIAN + u16 Cop0 = u | (y << 8); + u16 Cop1 = v | (y << 8); + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff:\ + d = ((long)&(d) & 2) ? Cop1 : Cop0;\ + case 0x00: break;\ + default: {\ + register u32 s = a+1;\ + register u32 t1 = d & 0xff;\ + register u32 t2 = d >> 8;\ + if ((long)&(d) & 2)\ + d = (((v-t1)*s+(t1<<8)) >> 8) |\ + (((y-t2)*s+(t2<<8)) & 0xff00);\ + else\ + d = (((u-t1)*s+(t1<<8)) >> 8) |\ + (((y-t2)*s+(t2<<8)) & 0xff00);\ + } break;\ + } +#else + u16 Cop0 = y | (u << 8); + u16 Cop1 = y | (v << 8); + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff:\ + d = ((long)&(d) & 2) ? Cop1 : Cop0;\ + case 0x00: break;\ + default: {\ + register u32 s = a+1;\ + register u32 t1 = d & 0xff;\ + register u32 t2 = d >> 8;\ + if ((long)&(d) & 2)\ + d = (((y-t1)*s+(t1<<8)) >> 8) |\ + (((v-t2)*s+(t2<<8)) & 0xff00);\ + else\ + d = (((y-t1)*s+(t1<<8)) >> 8) |\ + (((u-t2)*s+(t2<<8)) & 0xff00);\ + } break;\ + } +#endif + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_rgb332( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + u32 rgb = ((Cop & 0xe0) << 16) | ((Cop & 0x1c) << 8) | (Cop & 0x03); + +#define SET_PIXEL(d,a) \ + switch (a) {\ + case 0xff: d = Cop;\ + case 0: break;\ + default: {\ + register u32 s = a + 1;\ + register u32 t = ((d & 0xe0) << 16) | ((d & 0x1c) << 8) | (d & 0x03);\ + register u32 c = ((rgb-t)*s + (t<<8)) & 0xe01c0300;\ + d = (c >> 24) | ((c >> 16) & 0xff) | ((c >> 8) & 0xff);\ + }\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_uyvy( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u32 y = gfxs->YCop; + u32 u = gfxs->CbCop; + u32 v = gfxs->CrCop; + u16 Cop0 = u | (y << 8); + u16 Cop1 = v | (y << 8); + +#define SET_PIXEL(d,a)\ + switch (a) {\ + case 0xff: d = ((long)&(d) & 2) ? Cop1 : Cop0;\ + case 0x00: break;\ + default: {\ + register u32 s = a+1;\ + register u32 t1 = d & 0xff;\ + register u32 t2 = d >> 8;\ + if ((long)&(d) & 2)\ + d = (((v-t1)*s+(t1<<8)) >> 8) |\ + (((y-t2)*s+(t2<<8)) & 0xff00);\ + else\ + d = (((u-t1)*s+(t1<<8)) >> 8) |\ + (((y-t2)*s+(t2<<8)) & 0xff00);\ + } break;\ + } + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_lut8( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + +#if 0 + DFBColor color = gfxs->color; + DFBColor *entries = gfxs->Alut->entries; + +# define SET_PIXEL(d,alpha) \ + switch (alpha) {\ + case 0xff: d = Cop;\ + case 0: break; \ + default: {\ + register u16 s = alpha+1;\ + DFBColor dc = entries[d];\ + u16 sa = alpha + dc.a;\ + dc.r = ((color.r - dc.r) * s + (dc.r << 8)) >> 8;\ + dc.g = ((color.g - dc.g) * s + (dc.g << 8)) >> 8;\ + dc.b = ((color.b - dc.b) * s + (dc.b << 8)) >> 8;\ + d = dfb_palette_search( gfxs->Alut, dc.r, dc.g, dc.b,\ + sa & 0xff00 ? 0xff : sa );\ + }\ + } +#else +# define SET_PIXEL(d,a) \ + if (a & 0x80) \ + d = Cop; +#endif + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); + +#undef SET_PIXEL +} + +static void Bop_a8_set_alphapixel_Aop_alut44( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + + DFBColor color = gfxs->color; + DFBColor *entries = gfxs->Alut->entries; + +#define SET_PIXEL(d,alpha) \ + switch (alpha) {\ + case 0xff: d = Cop;\ + case 0: break; \ + default: {\ + register u16 s = alpha+1;\ + DFBColor dc = entries[d & 0x0f];\ + u16 sa = (d & 0xf0) + alpha;\ + dc.r = ((color.r - dc.r) * s + (dc.r << 8)) >> 8;\ + dc.g = ((color.g - dc.g) * s + (dc.g << 8)) >> 8;\ + dc.b = ((color.b - dc.b) * s + (dc.b << 8)) >> 8;\ + if (sa & 0xff00) sa = 0xf0;\ + d = (sa & 0xf0) + \ + dfb_palette_search( gfxs->Alut, dc.r, dc.g, dc.b, 0x80 );\ + }\ + } + + while (w--) { + SET_PIXEL( *D, *S ); + D++, S++; + } + +#undef SET_PIXEL +} + +#undef SET_PIXEL_DUFFS_DEVICE + +static GenefxFunc Bop_a8_set_alphapixel_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_a8_set_alphapixel_Aop_argb1555, /* DSPF_ARGB1555 */ + Bop_a8_set_alphapixel_Aop_rgb16, /* DSPF_RGB16 */ + Bop_a8_set_alphapixel_Aop_rgb24, /* DSPF_RGB24 */ + Bop_a8_set_alphapixel_Aop_rgb32, /* DSPF_RGB32 */ + Bop_a8_set_alphapixel_Aop_argb, /* DSPF_ARGB */ + Bop_a8_set_alphapixel_Aop_a8, /* DSPF_A8 */ + Bop_a8_set_alphapixel_Aop_yuy2, /* DSPF_YUY2 */ + Bop_a8_set_alphapixel_Aop_rgb332, /* DSPF_RGB332 */ + Bop_a8_set_alphapixel_Aop_uyvy, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Bop_a8_set_alphapixel_Aop_lut8, /* DSPF_LUT8 */ + Bop_a8_set_alphapixel_Aop_alut44, /* DSPF_ALUT44 */ + Bop_a8_set_alphapixel_Aop_airgb, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + NULL, /* DSPF_ARGB2554 */ + NULL, /* DSPF_ARGB4444 */ + NULL, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + Bop_a8_set_alphapixel_Aop_argb, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Bop_a8_set_alphapixel_Aop_argb1666, /* DSPF_ARGB1666 */ + Bop_a8_set_alphapixel_Aop_argb6666, /* DSPF_ARGB6666 */ + Bop_a8_set_alphapixel_Aop_rgb18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + NULL, /* DSPF_ARGB4444 */ + NULL, /* DSPF_ARGB1555 */ + NULL /* DSPF_ARGB1555 */ +}; + +/************** Bop_a1_set_alphapixel_Aop_PFI *********************************/ + +static void Bop_a1_set_alphapixel_Aop_argb1555( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop = gfxs->Cop | 0x8000; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_rgb16( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop = gfxs->Cop; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_argb6666( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + DFBColor color = gfxs->color; + + for (i=0; i>3] & (0x80 >> (i&7))) { + u32 pixel = PIXEL_ARGB6666( color.a, color.r, color.g, color.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D += 3; + } + +} + +static void Bop_a1_set_alphapixel_Aop_argb1666( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + DFBColor color = gfxs->color; + + for (i=0; i>3] & (0x80 >> (i&7))) { + u32 pixel = PIXEL_ARGB1666( color.a, color.r, color.g, color.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D += 3; + } + +} + +static void Bop_a1_set_alphapixel_Aop_rgb18( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + DFBColor color = gfxs->color; + + for (i=0; i>3] & (0x80 >> (i&7))) { + u32 pixel = PIXEL_RGB18( color.r, color.g, color.b ); + + D[0] = pixel; + D[1] = pixel >> 8; + D[2] = pixel >> 16; + } + D += 3; + } + +} + +static void Bop_a1_set_alphapixel_Aop_rgb24( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + DFBColor color = gfxs->color; + + for (i=0; i>3] & (0x80 >> (i&7))) { + D[0] = color.b; + D[1] = color.g; + D[2] = color.r; + } + + D += 3; + } +} + +static void Bop_a1_set_alphapixel_Aop_rgb32( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_argb( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop | 0xFF000000; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_airgb( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + u32 Cop = gfxs->Cop & 0x00FFFFFF; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_a8( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = 0xff; + } +} + +static void Bop_a1_set_alphapixel_Aop_yuy2( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop0 = gfxs->YCop | (gfxs->CbCop << 8); + u16 Cop1 = gfxs->YCop | (gfxs->CrCop << 8); + + for (i=0; i>3] & (0x80 >> (i&7))) { + D[i] = ((long)&D[i] & 2) ? Cop1 : Cop0; + } + } +} + +static void Bop_a1_set_alphapixel_Aop_rgb332( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u8 Cop = gfxs->Cop; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_uyvy( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop0 = gfxs->CbCop | (gfxs->YCop << 8); + u16 Cop1 = gfxs->CrCop | (gfxs->YCop << 8); + + for (i=0; i>3] & (0x80 >> (i&7))) { + D[i] = ((long)&D[i] & 2) ? Cop1 : Cop0; + } + } +} + +static void Bop_a1_set_alphapixel_Aop_lut8( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u8 Cop = gfxs->Cop; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_alut44( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + u8 Cop = gfxs->Cop; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_argb2554( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop = gfxs->Cop | 0xC000; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_argb4444( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop = gfxs->Cop | 0xF000; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static void Bop_a1_set_alphapixel_Aop_rgba4444( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + u16 Cop = gfxs->Cop | 0x000F; + + for (i=0; i>3] & (0x80 >> (i&7))) + D[i] = Cop; + } +} + +static GenefxFunc Bop_a1_set_alphapixel_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + Bop_a1_set_alphapixel_Aop_argb1555, /* DSPF_ARGB1555 */ + Bop_a1_set_alphapixel_Aop_rgb16, /* DSPF_RGB16 */ + Bop_a1_set_alphapixel_Aop_rgb24, /* DSPF_RGB24 */ + Bop_a1_set_alphapixel_Aop_rgb32, /* DSPF_RGB32 */ + Bop_a1_set_alphapixel_Aop_argb, /* DSPF_ARGB */ + Bop_a1_set_alphapixel_Aop_a8, /* DSPF_A8 */ + Bop_a1_set_alphapixel_Aop_yuy2, /* DSPF_YUY2 */ + Bop_a1_set_alphapixel_Aop_rgb332, /* DSPF_RGB332 */ + Bop_a1_set_alphapixel_Aop_uyvy, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + Bop_a1_set_alphapixel_Aop_lut8, /* DSPF_LUT8 */ + Bop_a1_set_alphapixel_Aop_alut44, /* DSPF_ALUT44 */ + Bop_a1_set_alphapixel_Aop_airgb, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + Bop_a1_set_alphapixel_Aop_argb2554, /* DSPF_ARGB2554 */ + Bop_a1_set_alphapixel_Aop_argb4444, /* DSPF_ARGB4444 */ + Bop_a1_set_alphapixel_Aop_rgba4444, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + Bop_a1_set_alphapixel_Aop_argb, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + Bop_a1_set_alphapixel_Aop_argb1666, /* DSPF_ARGB1666 */ + Bop_a1_set_alphapixel_Aop_argb6666, /* DSPF_ARGB6666 */ + Bop_a1_set_alphapixel_Aop_rgb18, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + NULL, /* DSPF_RGB444 */ + NULL, /* DSPF_RGB555 */ + NULL, /* DSPF_BGR555 */ +}; + + +/**************************** Bop_translate_to_Aop ****************************/ + +static void Bop_lut2_translate_to_Aop_lut8( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + int W = (w + 3) / 4; + u8 *S = gfxs->Bop[0]; + u8 *D = gfxs->Aop[0]; + + for (i=0; inum_trans && gfxs->trans[index] >= 0) + D[3] = gfxs->trans[index]; + + case 3: + index = (pixels >> 2) & 3; + if (index < gfxs->num_trans && gfxs->trans[index] >= 0) + D[2] = gfxs->trans[index]; + + case 2: + index = (pixels >> 4) & 3; + if (index < gfxs->num_trans && gfxs->trans[index] >= 0) + D[1] = gfxs->trans[index]; + + case 1: + index = (pixels >> 6); + if (index < gfxs->num_trans && gfxs->trans[index] >= 0) + D[0] = gfxs->trans[index]; + } + } +} + +/********************************* Xacc_blend *********************************/ + +static void Xacc_blend_zero( GenefxState *gfxs ) +{ + int i; + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + + for (i=0; ilength; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + + for (i=0; ilength; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + + if (gfxs->Sacc) { + GenefxAccumulator *S = gfxs->Sacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = ((S->RGB.r + 1) * Y->RGB.r) >> 8; + X->RGB.g = ((S->RGB.g + 1) * Y->RGB.g) >> 8; + X->RGB.b = ((S->RGB.b + 1) * Y->RGB.b) >> 8; + X->RGB.a = ((S->RGB.a + 1) * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + S++; + } + } + else { + GenefxAccumulator Cacc = gfxs->Cacc; + Cacc.RGB.r = Cacc.RGB.r + 1; + Cacc.RGB.g = Cacc.RGB.g + 1; + Cacc.RGB.b = Cacc.RGB.b + 1; + Cacc.RGB.a = Cacc.RGB.a + 1; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = (Cacc.RGB.r * Y->RGB.r) >> 8; + X->RGB.g = (Cacc.RGB.g * Y->RGB.g) >> 8; + X->RGB.b = (Cacc.RGB.b * Y->RGB.b) >> 8; + X->RGB.a = (Cacc.RGB.a * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + } + } +} + +static void Xacc_blend_invsrccolor( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + + if (gfxs->Sacc) { + GenefxAccumulator *S = gfxs->Sacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = ((0x100 - S->RGB.r) * Y->RGB.r) >> 8; + X->RGB.g = ((0x100 - S->RGB.g) * Y->RGB.g) >> 8; + X->RGB.b = ((0x100 - S->RGB.b) * Y->RGB.b) >> 8; + X->RGB.a = ((0x100 - S->RGB.a) * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + S++; + } + } + else { + GenefxAccumulator Cacc = gfxs->Cacc; + Cacc.RGB.r = 0x100 - Cacc.RGB.r; + Cacc.RGB.g = 0x100 - Cacc.RGB.g; + Cacc.RGB.b = 0x100 - Cacc.RGB.b; + Cacc.RGB.a = 0x100 - Cacc.RGB.a; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = (Cacc.RGB.r * Y->RGB.r) >> 8; + X->RGB.g = (Cacc.RGB.g * Y->RGB.g) >> 8; + X->RGB.b = (Cacc.RGB.b * Y->RGB.b) >> 8; + X->RGB.a = (Cacc.RGB.a * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + } + } +} + +static void Xacc_blend_srcalpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + + if (gfxs->Sacc) { + GenefxAccumulator *S = gfxs->Sacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + register u16 Sa = S->RGB.a + 1; + + X->RGB.r = (Sa * Y->RGB.r) >> 8; + X->RGB.g = (Sa * Y->RGB.g) >> 8; + X->RGB.b = (Sa * Y->RGB.b) >> 8; + X->RGB.a = (Sa * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + S++; + } + } + else { + register u16 Sa = gfxs->color.a + 1; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = (Sa * Y->RGB.r) >> 8; + X->RGB.g = (Sa * Y->RGB.g) >> 8; + X->RGB.b = (Sa * Y->RGB.b) >> 8; + X->RGB.a = (Sa * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + } + } +} + +static void Xacc_blend_invsrcalpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + + if (gfxs->Sacc) { + GenefxAccumulator *S = gfxs->Sacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + register u16 Sa = 0x100 - S->RGB.a; + + X->RGB.r = (Sa * Y->RGB.r) >> 8; + X->RGB.g = (Sa * Y->RGB.g) >> 8; + X->RGB.b = (Sa * Y->RGB.b) >> 8; + X->RGB.a = (Sa * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + S++; + } + } + else { + register u16 Sa = 0x100 - gfxs->color.a; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.a = (Sa * Y->RGB.a) >> 8; + X->RGB.r = (Sa * Y->RGB.r) >> 8; + X->RGB.g = (Sa * Y->RGB.g) >> 8; + X->RGB.b = (Sa * Y->RGB.b) >> 8; + } else + *X = *Y; + + X++; + Y++; + } + } +} + +static void Xacc_blend_dstalpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + register u16 Da = D->RGB.a + 1; + + X->RGB.r = (Da * Y->RGB.r) >> 8; + X->RGB.g = (Da * Y->RGB.g) >> 8; + X->RGB.b = (Da * Y->RGB.b) >> 8; + X->RGB.a = (Da * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + D++; + } +} + +static void Xacc_blend_invdstalpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + register u16 Da = 0x100 - D->RGB.a; + + X->RGB.r = (Da * Y->RGB.r) >> 8; + X->RGB.g = (Da * Y->RGB.g) >> 8; + X->RGB.b = (Da * Y->RGB.b) >> 8; + X->RGB.a = (Da * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + D++; + } +} + +static void Xacc_blend_destcolor( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = ((D->RGB.r + 1) * Y->RGB.r) >> 8; + X->RGB.g = ((D->RGB.g + 1) * Y->RGB.g) >> 8; + X->RGB.b = ((D->RGB.b + 1) * Y->RGB.b) >> 8; + X->RGB.a = ((D->RGB.a + 1) * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + D++; + } +} + +static void Xacc_blend_invdestcolor( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + X->RGB.r = ((0x100 - D->RGB.r) * Y->RGB.r) >> 8; + X->RGB.g = ((0x100 - D->RGB.g) * Y->RGB.g) >> 8; + X->RGB.b = ((0x100 - D->RGB.b) * Y->RGB.b) >> 8; + X->RGB.a = ((0x100 - D->RGB.a) * Y->RGB.a) >> 8; + } else + *X = *Y; + + X++; + Y++; + D++; + } +} + +static void Xacc_blend_srcalphasat( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *X = gfxs->Xacc; + GenefxAccumulator *Y = gfxs->Yacc; + GenefxAccumulator *D = gfxs->Dacc; + + if (gfxs->Sacc) { + GenefxAccumulator *S = gfxs->Sacc; + + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + register u16 Sa = MIN( S->RGB.a + 1, 0x100 - D->RGB.a ); + + X->RGB.a = Y->RGB.a; + X->RGB.r = (Sa * Y->RGB.r) >> 8; + X->RGB.g = (Sa * Y->RGB.g) >> 8; + X->RGB.b = (Sa * Y->RGB.b) >> 8; + } else + *X = *Y; + + X++; + Y++; + D++; + S++; + } + } + else { + while (w--) { + if (!(Y->RGB.a & 0xF000)) { + register u16 Sa = MIN( gfxs->color.a + 1, 0x100 - D->RGB.a ); + + X->RGB.a = Y->RGB.a; + X->RGB.r = (Sa * Y->RGB.r) >> 8; + X->RGB.g = (Sa * Y->RGB.g) >> 8; + X->RGB.b = (Sa * Y->RGB.b) >> 8; + } else + *X = *Y; + + X++; + Y++; + D++; + } + } +} + +static GenefxFunc Xacc_blend[] = { + Xacc_blend_zero, /* DSBF_ZERO */ + Xacc_blend_one, /* DSBF_ONE */ + Xacc_blend_srccolor, /* DSBF_SRCCOLOR */ + Xacc_blend_invsrccolor, /* DSBF_INVSRCCOLOR */ + Xacc_blend_srcalpha, /* DSBF_SRCALPHA */ + Xacc_blend_invsrcalpha, /* DSBF_INVSRCALPHA */ + Xacc_blend_dstalpha, /* DSBF_DESTALPHA */ + Xacc_blend_invdstalpha, /* DSBF_INVDESTALPHA */ + Xacc_blend_destcolor, /* DSBF_DESTCOLOR */ + Xacc_blend_invdestcolor, /* DSBF_INVDESTCOLOR */ + Xacc_blend_srcalphasat /* DSBF_SRCALPHASAT */ +}; + +/********************************* Dacc_modulation ****************************/ + +static void Dacc_set_alpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + int a = gfxs->color.a; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a = a; + } + + D++; + } +} + +static void Dacc_modulate_alpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + int a = gfxs->Cacc.RGB.a; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a = (a * D->RGB.a) >> 8; + } + + D++; + } +} + +static void Dacc_modulate_rgb( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator Cacc = gfxs->Cacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8; + D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8; + D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8; + } + + D++; + } +} + +static void Dacc_modulate_rgb_set_alpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator Cacc = gfxs->Cacc; + int a = gfxs->color.a; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a = a; + D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8; + D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8; + D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8; + } + + D++; + } +} + +static void Dacc_modulate_argb( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator Cacc = gfxs->Cacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a = (Cacc.RGB.a * D->RGB.a) >> 8; + D->RGB.r = (Cacc.RGB.r * D->RGB.r) >> 8; + D->RGB.g = (Cacc.RGB.g * D->RGB.g) >> 8; + D->RGB.b = (Cacc.RGB.b * D->RGB.b) >> 8; + } + + D++; + } +} + +static GenefxFunc Dacc_modulation[] = { + NULL, + NULL, + Dacc_set_alpha, + Dacc_modulate_alpha, + Dacc_modulate_rgb, + Dacc_modulate_rgb, + Dacc_modulate_rgb_set_alpha, + Dacc_modulate_argb +}; + +/********************************* misc accumulator operations ****************/ + +static void Dacc_premultiply( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + register u16 Da = D->RGB.a + 1; + + D->RGB.r = (Da * D->RGB.r) >> 8; + D->RGB.g = (Da * D->RGB.g) >> 8; + D->RGB.b = (Da * D->RGB.b) >> 8; + } + + D++; + } +} + +static void Dacc_premultiply_color_alpha( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + register u16 Ca = gfxs->Cacc.RGB.a; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.r = (Ca * D->RGB.r) >> 8; + D->RGB.g = (Ca * D->RGB.g) >> 8; + D->RGB.b = (Ca * D->RGB.b) >> 8; + } + + D++; + } +} + +static void Dacc_demultiply( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + register u16 Da = D->RGB.a + 1; + + D->RGB.r = (D->RGB.r << 8) / Da; + D->RGB.g = (D->RGB.g << 8) / Da; + D->RGB.b = (D->RGB.b << 8) / Da; + } + + D++; + } +} + +static void Dacc_xor_C( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + DFBColor color = gfxs->color; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a ^= color.a; + D->RGB.r ^= color.r; + D->RGB.g ^= color.g; + D->RGB.b ^= color.b; + } + + D++; + } +} + +static GenefxFunc Dacc_xor = Dacc_xor_C; + +static void Sacc_xor_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a ^= S->RGB.a; + D->RGB.r ^= S->RGB.r; + D->RGB.g ^= S->RGB.g; + D->RGB.b ^= S->RGB.b; + } + D++; + S++; + } +} + +static void Cacc_to_Dacc( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator Cacc = gfxs->Cacc; + + while (w--) + *D++ = Cacc; +} + +static void SCacc_add_to_Dacc_C( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator SCacc = gfxs->SCacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a += SCacc.RGB.a; + D->RGB.r += SCacc.RGB.r; + D->RGB.g += SCacc.RGB.g; + D->RGB.b += SCacc.RGB.b; + } + D++; + } +} + +static GenefxFunc SCacc_add_to_Dacc = SCacc_add_to_Dacc_C; + +static void Sacc_add_to_Dacc_C( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *S = gfxs->Sacc; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->RGB.a += S->RGB.a; + D->RGB.r += S->RGB.r; + D->RGB.g += S->RGB.g; + D->RGB.b += S->RGB.b; + } + D++; + S++; + } +} + +static GenefxFunc Sacc_add_to_Dacc = Sacc_add_to_Dacc_C; + +/**********************************************************************************************************************/ + +/* change the last value to adjust the size of the device (1-4) */ +#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \ + SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 ) + +#define SET_PIXEL( D, S ) \ + if (!(S.RGB.a & 0xF000)) { \ + RGB_TO_YCBCR( S.RGB.r, S.RGB.g, S.RGB.b, \ + D.YUV.y, D.YUV.u, D.YUV.v ); \ + } + +static void Dacc_RGB_to_YCbCr_C( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator *S = gfxs->Dacc; + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); +} + +#undef SET_PIXEL_DUFFS_DEVICE +#undef SET_PIXEL + +static GenefxFunc Dacc_RGB_to_YCbCr = Dacc_RGB_to_YCbCr_C; + +/**********************************************************************************************************************/ + +/* change the last value to adjust the size of the device (1-4) */ +#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \ + SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 2 ) + +#define SET_PIXEL( D, S ) \ + if (!(S.YUV.a & 0xF000)) { \ + YCBCR_TO_RGB( S.YUV.y, S.YUV.u, S.YUV.v, \ + D.RGB.r, D.RGB.g, D.RGB.b ); \ + } + +static void Dacc_YCbCr_to_RGB_C( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + GenefxAccumulator *S = gfxs->Dacc; + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); +} + +#undef SET_PIXEL_DUFFS_DEVICE +#undef SET_PIXEL + +static GenefxFunc Dacc_YCbCr_to_RGB = Dacc_YCbCr_to_RGB_C; + +/**********************************************************************************************************************/ + +/* change the last value to adjust the size of the device (1-4) */ +#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \ + SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 ) + +#define SET_PIXEL( D, S ) \ + switch (S >> 26) { \ + case 0: \ + break; \ + case 0x3f: \ + D = RGB32_TO_RGB16( S ); \ + break; \ + default: \ + D = (((( (((S>>8) & 0xf800) | ((S>>3) & 0x001f)) \ + - (D & 0xf81f)) * ((S>>26)+1) + ((D & 0xf81f)<<6)) & 0x003e07c0) \ + + \ + ((( ((S>>5) & 0x07e0) \ + - (D & 0x07e0)) * ((S>>26)+1) + ((D & 0x07e0)<<6)) & 0x0001f800)) >> 6; \ + } while (0) + +static void Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb16( GenefxState *gfxs ) +{ + int w = gfxs->length; + u32 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); +} + +#undef SET_PIXEL_DUFFS_DEVICE +#undef SET_PIXEL + +static void Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb32( GenefxState *gfxs ) +{ + int w = gfxs->length; + int Dstep = gfxs->Astep; + u32 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + + while (w--) { + u32 dp32 = *D; + u32 sp32 = *S++; + int salpha = (sp32 >> 25) + 1; + +#define rb (sp32 & 0xff00ff) +#define g (sp32 & 0x00ff00) + + *D = ((((rb-(dp32 & 0xff00ff))*salpha+((dp32 & 0xff00ff)<<7)) & 0x7f807f80) + + ((( g-(dp32 & 0x00ff00))*salpha+((dp32 & 0x00ff00)<<7)) & 0x007f8000)) >> 7; + D += Dstep; + +#undef rb +#undef g + } +} + +static GenefxFunc Bop_argb_blend_alphachannel_src_invsrc_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + NULL, /* DSPF_ARGB1555 */ + Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb16, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + Bop_argb_blend_alphachannel_src_invsrc_Aop_rgb32, /* DSPF_RGB32 */ + NULL, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + NULL, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + NULL, /* DSPF_ARGB2554 */ + NULL, /* DSPF_ARGB4444 */ + NULL, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + NULL, /* DSPF_RGB444 */ + NULL, /* DSPF_RGB555 */ + NULL /* DSPF_BGR555 */ +}; + +/**********************************************************************************************************************/ + +/* change the last value to adjust the size of the device (1-4) */ +#define SET_PIXEL_DUFFS_DEVICE( D, S, w ) \ + SET_PIXEL_DUFFS_DEVICE_N( D, S, w, 3 ) + +#define SET_PIXEL( D, S ) \ +do { \ + int invsrc = 256 - (S >> 24); \ + \ + u32 Drb = ((D & 0x00ff00ff) * invsrc) >> 8; \ + u32 Dag = ((D & 0xff00ff00) >> 8) * invsrc; \ + \ + D = S + (Drb & 0x00ff00ff) + (Dag & 0xff00ff00); \ +} while (0) + +static void Bop_argb_blend_alphachannel_one_invsrc_Aop_argb( GenefxState *gfxs ) +{ + int w = gfxs->length; + u32 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + + SET_PIXEL_DUFFS_DEVICE( D, S, w ); +} + +#undef SET_PIXEL_DUFFS_DEVICE +#undef SET_PIXEL + +static GenefxFunc Bop_argb_blend_alphachannel_one_invsrc_Aop_PFI[DFB_NUM_PIXELFORMATS] = { + NULL, /* DSPF_ARGB1555 */ + NULL, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + Bop_argb_blend_alphachannel_one_invsrc_Aop_argb, /* DSPF_RGB32 */ + Bop_argb_blend_alphachannel_one_invsrc_Aop_argb, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + NULL, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + NULL, /* DSPF_ARGB2554 */ + NULL, /* DSPF_ARGB4444 */ + NULL, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + NULL, /* DSPF_RGB444 */ + NULL, /* DSPF_RGB555 */ + NULL /* DSPF_BGR555 */ +}; + +/**********************************************************************************************************************/ + +/* A8/A1 to YCbCr */ +static void Dacc_Alpha_to_YCbCr( GenefxState *gfxs ) +{ + int w = gfxs->length; + GenefxAccumulator *D = gfxs->Dacc; + + while (w--) { + if (!(D->RGB.a & 0xF000)) { + D->YUV.y = 235; + D->YUV.u = 128; + D->YUV.v = 128; + } + + D++; + } +} + +/**********************************************************************************************************************/ + +static void Sop_is_Aop( GenefxState *gfxs ) { gfxs->Sop = gfxs->Aop; gfxs->Ostep = gfxs->Astep; } +static void Sop_is_Bop( GenefxState *gfxs ) { gfxs->Sop = gfxs->Bop; gfxs->Ostep = gfxs->Bstep; } + +static void Slut_is_Alut( GenefxState *gfxs ) { gfxs->Slut = gfxs->Alut;} +static void Slut_is_Blut( GenefxState *gfxs ) { gfxs->Slut = gfxs->Blut;} + +static void Sacc_is_NULL( GenefxState *gfxs ) { gfxs->Sacc = NULL;} +static void Sacc_is_Aacc( GenefxState *gfxs ) { gfxs->Sacc = gfxs->Aacc;} +static void Sacc_is_Bacc( GenefxState *gfxs ) { gfxs->Sacc = gfxs->Bacc;} +static void Sacc_is_Tacc( GenefxState *gfxs ) { gfxs->Sacc = gfxs->Tacc;} + +static void Dacc_is_Aacc( GenefxState *gfxs ) { gfxs->Dacc = gfxs->Aacc;} +static void Dacc_is_Bacc( GenefxState *gfxs ) { gfxs->Dacc = gfxs->Bacc;} + +static void Xacc_is_Aacc( GenefxState *gfxs ) { gfxs->Xacc = gfxs->Aacc;} +static void Xacc_is_Bacc( GenefxState *gfxs ) { gfxs->Xacc = gfxs->Bacc;} +static void Xacc_is_Tacc( GenefxState *gfxs ) { gfxs->Xacc = gfxs->Tacc;} + +static void Yacc_is_Aacc( GenefxState *gfxs ) { gfxs->Yacc = gfxs->Aacc;} +static void Yacc_is_Bacc( GenefxState *gfxs ) { gfxs->Yacc = gfxs->Bacc;} + +static void Len_is_Slen( GenefxState *gfxs ) { gfxs->length = gfxs->Slen;} +static void Len_is_Dlen( GenefxState *gfxs ) { gfxs->length = gfxs->Dlen;} + +/******************************************************************************/ + +#ifdef USE_MMX +static bool has_mmx( void ) +{ +#ifdef ARCH_X86_64 + return true; +#else + u32 a, b, c, d; + + asm( "pushfl \n" + "pushfl \n" + "popl %0 \n" + "movl %0, %1 \n" + "xorl $0x200000, %0 \n" + "pushl %0 \n" + "popfl \n" + "pushfl \n" + "popl %0 \n" + "popfl" + : "=a" (a), "=r" (b) + : + : "cc" ); + + if (a == b) + return false; + + asm( "pushl %%ebx \n" + "cpuid \n" + "movl %%ebx, %1 \n" + "popl %%ebx" + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) + : "a" (0) + : "cc" ); + + if (!a) + return false; + + asm( "pushl %%ebx \n" + "cpuid \n" + "movl %%ebx, %1 \n" + "popl %%ebx" + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) + : "a" (1) + : "cc" ); + + return (d & 0x800000) ? true : false; +#endif /* !ARCH_X86_64 */ +} +#endif + +void gGetDriverInfo( GraphicsDriverInfo *info ) +{ + snprintf( info->name, + DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, "Software Driver" ); + +#if SIZEOF_LONG == 8 + gInit_64bit(); +#endif + +#ifdef USE_MMX + if (has_mmx()) { + if (!dfb_config->mmx) { + D_INFO( "DirectFB/Genefx: MMX detected, but disabled by option 'no-mmx'\n"); + } + else { + gInit_MMX(); + + snprintf( info->name, DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH, + "MMX Software Driver" ); + + D_INFO( "DirectFB/Genefx: MMX detected and enabled\n"); + } + } + else { + D_INFO( "DirectFB/Genefx: No MMX detected\n" ); + } +#endif + + snprintf( info->vendor, DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH, "directfb.org" ); + + info->version.major = 0; + info->version.minor = 6; +} + +void gGetDeviceInfo( GraphicsDeviceInfo *info ) +{ + snprintf( info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, + "Software Rasterizer" ); + + snprintf( info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, + use_mmx ? "MMX" : "Generic" ); + + info->caps.accel = DFXL_NONE; + info->caps.flags = 0; + info->caps.drawing = DSDRAW_NOFX; + info->caps.blitting = DSBLIT_NOFX; +} + +#define MODULATION_FLAGS (DSBLIT_BLEND_ALPHACHANNEL | \ + DSBLIT_BLEND_COLORALPHA | \ + DSBLIT_COLORIZE | \ + DSBLIT_DST_PREMULTIPLY | \ + DSBLIT_SRC_PREMULTIPLY | \ + DSBLIT_SRC_PREMULTCOLOR | \ + DSBLIT_DEMULTIPLY | \ + DSBLIT_XOR) + +#ifndef WORDS_BIGENDIAN +#define BGR_TO_RGB16(pixel) ( (((pixel) << 8) & 0xF800) | \ + (((pixel) >> 5) & 0x07E0) | \ + (((pixel) >> 19) & 0x001F) ) + +/* + * Fast RGB24 to RGB16 conversion. + */ +static void +Bop_rgb24_to_Aop_rgb16_LE( GenefxState *gfxs ) +{ + int w = gfxs->length; + u8 *S = gfxs->Bop[0]; + u16 *D = gfxs->Aop[0]; + + while ((unsigned long)S & 3) { + *D++ = PIXEL_RGB16( S[0], S[1], S[2] ); + + S += 3; + w -= 1; + } + + if ((unsigned long)D & 2) { + *D++ = PIXEL_RGB16( S[0], S[1], S[2] ); + + w -= 1; + S += 3; + + while (w > 1) { + *(u32*)D = PIXEL_RGB16( S[0], S[1], S[2] ) | (PIXEL_RGB16( S[3], S[4], S[5] ) << 16); + + w -= 2; + D += 2; + S += 6; + } + } + else { + u32 *S32 = (u32*)S; + u32 *D32 = (u32*)D; + + while (w > 3) { + D32[0] = BGR_TO_RGB16( S32[0] ) | (BGR_TO_RGB16( (S32[0] >> 24) | (S32[1] << 8) ) << 16); + D32[1] = BGR_TO_RGB16( (S32[1] >> 16) | (S32[2] << 16) ) | (BGR_TO_RGB16( S32[2] >> 8 ) << 16); + + D32 += 2; + S32 += 3; + w -= 4; + } + + S = (u8*) S32; + D = (u16*) D32; + } + + while (w > 0) { + *D++ = PIXEL_RGB16( S[0], S[1], S[2] ); + + w -= 1; + S += 3; + } +} + +/* + * Fast RGB32 to RGB16 conversion. + */ +static void +Bop_rgb32_to_Aop_rgb16_LE( GenefxState *gfxs ) +{ + int w = gfxs->length; + u32 *S = gfxs->Bop[0]; + u32 *D = gfxs->Aop[0]; + + if ((unsigned long)D & 2) { + u16 *d = (u16*)D; + + d[0] = RGB32_TO_RGB16( S[0] ); + + w--; + S++; + + D = (u32*)(d+1); + } + + while (w > 1) { + D[0] = RGB32_TO_RGB16( S[0] ) | (RGB32_TO_RGB16( S[1] ) << 16); + + w -= 2; + S += 2; + D += 1; + } + + if (w > 0) { + u16 *d = (u16*)D; + + d[0] = RGB32_TO_RGB16( S[0] ); + } +} +#endif /* #ifndef WORDS_BIGENDIAN */ + +bool gAcquire( CardState *state, DFBAccelerationMask accel ) +{ + DFBResult ret; + GenefxState *gfxs; + GenefxFunc *funcs; + int dst_pfi; + int src_pfi = 0; + CoreSurface *destination = state->destination; + CoreSurface *source = state->source; + DFBColor color = state->color; + bool src_ycbcr = false; + bool dst_ycbcr = false; + + CoreSurfaceAccessFlags access = CSAF_WRITE; + + if (dfb_config->hardware_only) { + if (dfb_config->software_warn) { + if (DFB_BLITTING_FUNCTION( accel )) + D_WARN( "Ignoring blit (%x) from %s to %s, flags 0x%08x, funcs %d %d", accel, + source ? dfb_pixelformat_name(source->config.format) : "NULL SOURCE", + destination ? dfb_pixelformat_name(destination->config.format) : "NULL DESTINATION", + state->blittingflags, state->src_blend, state->dst_blend ); + else + D_WARN( "Ignoring draw (%x) to %s, flags 0x%08x", accel, + destination ? dfb_pixelformat_name(destination->config.format) : "NULL DESTINATION", + state->drawingflags ); + } + + return false; + } + + if (!state->gfxs) { + gfxs = D_CALLOC( 1, sizeof(GenefxState) ); + if (!gfxs) { + D_ERROR( "DirectFB/Genefx: Couldn't allocate state struct!\n" ); + return false; + } + + state->gfxs = gfxs; + } + + gfxs = state->gfxs; + funcs = gfxs->funcs; + + /* Destination may have been destroyed. */ + if (!destination) + return false; + + /* Source may have been destroyed. */ + if (DFB_BLITTING_FUNCTION( accel ) && !source) + return false; + + /* + * Destination setup + */ + + if (DFB_BLITTING_FUNCTION( accel )) { + if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | + DSBLIT_BLEND_COLORALPHA | + DSBLIT_DST_COLORKEY)) + access |= CSAF_READ; + } + else if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_DST_COLORKEY)) + access |= CSAF_READ; + + /* Lock destination */ + ret = dfb_surface_lock_buffer( destination, state->to, CSAID_CPU, access, &state->dst ); + if (ret) { + D_DERROR( ret, "DirectFB/Genefx: Could not lock destination!\n" ); + return false; + } + + gfxs->dst_caps = destination->config.caps; + gfxs->dst_height = destination->config.size.h; + gfxs->dst_format = destination->config.format; + gfxs->dst_bpp = DFB_BYTES_PER_PIXEL( gfxs->dst_format ); + dst_pfi = DFB_PIXELFORMAT_INDEX( gfxs->dst_format ); + + gfxs->dst_org[0] = state->dst.addr; + gfxs->dst_pitch = state->dst.pitch; + + switch (gfxs->dst_format) { + case DSPF_I420: + gfxs->dst_org[1] = gfxs->dst_org[0] + gfxs->dst_height * gfxs->dst_pitch; + gfxs->dst_org[2] = gfxs->dst_org[1] + gfxs->dst_height/2 * gfxs->dst_pitch/2; + break; + case DSPF_YV12: + gfxs->dst_org[2] = gfxs->dst_org[0] + gfxs->dst_height * gfxs->dst_pitch; + gfxs->dst_org[1] = gfxs->dst_org[2] + gfxs->dst_height/2 * gfxs->dst_pitch/2; + break; + case DSPF_NV12: + case DSPF_NV21: + case DSPF_NV16: + gfxs->dst_org[1] = gfxs->dst_org[0] + gfxs->dst_height * gfxs->dst_pitch; + break; + default: + break; + } + + gfxs->dst_field_offset = gfxs->dst_height/2 * gfxs->dst_pitch; + + + /* + * Source setup + */ + + if (DFB_BLITTING_FUNCTION( accel )) { +#if FIXME_SC_3 + DFBSurfaceLockFlags flags = DSLF_READ; + + if (accel == DFXL_STRETCHBLIT) + flags |= CSLF_FORCE; +#endif + + /* Lock source */ + ret = dfb_surface_lock_buffer( source, state->from, CSAID_CPU, CSAF_READ, &state->src ); + if (ret) { + D_DERROR( ret, "DirectFB/Genefx: Could not lock source!\n" ); + dfb_surface_unlock_buffer( destination, &state->dst ); + return false; + } + + gfxs->src_caps = source->config.caps; + gfxs->src_height = source->config.size.h; + gfxs->src_format = source->config.format; + gfxs->src_bpp = DFB_BYTES_PER_PIXEL( gfxs->src_format ); + src_pfi = DFB_PIXELFORMAT_INDEX( gfxs->src_format ); + + gfxs->src_org[0] = state->src.addr; + gfxs->src_pitch = state->src.pitch; + + switch (gfxs->src_format) { + case DSPF_I420: + gfxs->src_org[1] = gfxs->src_org[0] + gfxs->src_height * gfxs->src_pitch; + gfxs->src_org[2] = gfxs->src_org[1] + gfxs->src_height/2 * gfxs->src_pitch/2; + break; + case DSPF_YV12: + gfxs->src_org[2] = gfxs->src_org[0] + gfxs->src_height * gfxs->src_pitch; + gfxs->src_org[1] = gfxs->src_org[2] + gfxs->src_height/2 * gfxs->src_pitch/2; + break; + case DSPF_NV12: + case DSPF_NV21: + case DSPF_NV16: + gfxs->src_org[1] = gfxs->src_org[0] + gfxs->src_height * gfxs->src_pitch; + break; + default: + break; + } + + gfxs->src_field_offset = gfxs->src_height/2 * gfxs->src_pitch; + + state->flags |= CSF_SOURCE_LOCKED; + } + + + /* premultiply source (color) */ + if (DFB_DRAWING_FUNCTION(accel) && (state->drawingflags & DSDRAW_SRC_PREMULTIPLY)) { + u16 ca = color.a + 1; + + color.r = (color.r * ca) >> 8; + color.g = (color.g * ca) >> 8; + color.b = (color.b * ca) >> 8; + } + + + gfxs->color = color; + + + switch (gfxs->dst_format) { + case DSPF_ARGB1555: + gfxs->Cop = PIXEL_ARGB1555( color.a, color.r, color.g, color.b ); + break; + case DSPF_RGB16: + gfxs->Cop = PIXEL_RGB16( color.r, color.g, color.b ); + break; + case DSPF_RGB18: + gfxs->Cop = PIXEL_RGB18( color.r, color.g, color.b ); + break; + case DSPF_RGB24: + gfxs->Cop = PIXEL_RGB32( color.r, color.g, color.b ); + break; + case DSPF_RGB32: + gfxs->Cop = PIXEL_RGB32( color.r, color.g, color.b ); + break; + case DSPF_ARGB: + gfxs->Cop = PIXEL_ARGB( color.a, color.r, color.g, color.b ); + break; + case DSPF_AiRGB: + gfxs->Cop = PIXEL_AiRGB( color.a, color.r, color.g, color.b ); + break; + case DSPF_ARGB6666: + gfxs->Cop = PIXEL_ARGB6666( color.a, color.r, color.g, color.b ); + break; + case DSPF_ARGB1666: + gfxs->Cop = PIXEL_ARGB1666( color.a, color.r, color.g, color.b ); + break; + case DSPF_A1: + gfxs->Cop = color.a >> 7; + break; + case DSPF_A4: + gfxs->Cop = color.a >> 4; + break; + case DSPF_A8: + gfxs->Cop = color.a; + break; + case DSPF_YUY2: + RGB_TO_YCBCR( color.r, color.g, color.b, + gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + gfxs->Cop = PIXEL_YUY2( gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + dst_ycbcr = true; + break; + case DSPF_RGB332: + gfxs->Cop = PIXEL_RGB332( color.r, color.g, color.b ); + break; + case DSPF_UYVY: + RGB_TO_YCBCR( color.r, color.g, color.b, + gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + gfxs->Cop = PIXEL_UYVY( gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + dst_ycbcr = true; + break; + case DSPF_I420: + case DSPF_YV12: + case DSPF_NV12: + case DSPF_NV16: + RGB_TO_YCBCR( color.r, color.g, color.b, + gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + gfxs->Cop = gfxs->YCop; + dst_ycbcr = true; + break; + case DSPF_NV21: + RGB_TO_YCBCR( color.r, color.g, color.b, + gfxs->YCop, gfxs->CrCop, gfxs->CbCop ); + gfxs->Cop = gfxs->YCop; + dst_ycbcr = true; + break; + case DSPF_LUT2: + case DSPF_LUT8: + gfxs->Cop = state->color_index; + gfxs->Alut = destination->palette; + break; + case DSPF_ALUT44: + gfxs->Cop = (color.a & 0xF0) + state->color_index; + gfxs->Alut = destination->palette; + break; + case DSPF_ARGB2554: + gfxs->Cop = PIXEL_ARGB2554( color.a, color.r, color.g, color.b ); + break; + case DSPF_ARGB4444: + gfxs->Cop = PIXEL_ARGB4444( color.a, color.r, color.g, color.b ); + break; + case DSPF_RGBA4444: + gfxs->Cop = PIXEL_RGBA4444( color.a, color.r, color.g, color.b ); + break; + case DSPF_AYUV: + RGB_TO_YCBCR( color.r, color.g, color.b, + gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + gfxs->Cop = PIXEL_AYUV( color.a, gfxs->YCop, gfxs->CbCop, gfxs->CrCop ); + dst_ycbcr = true; + break; + case DSPF_RGB444: + gfxs->Cop = PIXEL_RGB444( color.r, color.g, color.b ); + break; + case DSPF_RGB555: + gfxs->Cop = PIXEL_RGB555( color.r, color.g, color.b ); + break; + case DSPF_BGR555: + gfxs->Cop = PIXEL_BGR555( color.r, color.g, color.b ); + break; + default: + D_ONCE("unsupported destination format"); + return false; + } + + if (DFB_BLITTING_FUNCTION( accel )) { + switch (gfxs->src_format) { + case DSPF_LUT2: + case DSPF_LUT8: + case DSPF_ALUT44: + gfxs->Blut = source->palette; + case DSPF_ARGB1555: + case DSPF_ARGB2554: + case DSPF_ARGB4444: + case DSPF_RGBA4444: + case DSPF_ARGB1666: + case DSPF_ARGB6666: + case DSPF_RGB16: + case DSPF_RGB18: + case DSPF_RGB24: + case DSPF_RGB32: + case DSPF_ARGB: + case DSPF_AiRGB: + case DSPF_RGB332: + case DSPF_RGB444: + case DSPF_RGB555: + case DSPF_BGR555: + if (dst_ycbcr && + state->blittingflags & (DSBLIT_COLORIZE | + DSBLIT_SRC_PREMULTCOLOR)) + return false; + case DSPF_A1: + case DSPF_A4: + case DSPF_A8: + if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format) && + state->blittingflags & DSBLIT_DST_COLORKEY) + return false; + break; + case DSPF_I420: + case DSPF_YV12: + case DSPF_NV12: + case DSPF_NV21: + case DSPF_NV16: + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + return false; + case DSPF_YUY2: + case DSPF_UYVY: + case DSPF_AYUV: + if (dst_ycbcr) { + if (state->blittingflags & (DSBLIT_COLORIZE | + DSBLIT_SRC_PREMULTCOLOR)) + return false; + + if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format) && + state->blittingflags & DSBLIT_DST_COLORKEY) + return false; + } + src_ycbcr = true; + break; + default: + D_ONCE("unsupported source format"); + return false; + } + } + + gfxs->need_accumulator = true; + + /* Initialization */ + gfxs->Astep = gfxs->Bstep = gfxs->Ostep = 1; + + switch (accel) { + case DFXL_FILLRECTANGLE: + case DFXL_DRAWRECTANGLE: + case DFXL_DRAWLINE: + case DFXL_FILLTRIANGLE: + if (state->drawingflags & ~(DSDRAW_DST_COLORKEY | DSDRAW_SRC_PREMULTIPLY)) { + GenefxAccumulator Cacc, SCacc; + + /* not yet completed optimizing checks */ + if (state->drawingflags & DSDRAW_BLEND) { + if (state->src_blend == DSBF_ZERO) { + if (state->dst_blend == DSBF_ZERO) { + gfxs->Cop = 0; + if (state->drawingflags & DSDRAW_DST_COLORKEY) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Cop_toK_Aop_PFI[dst_pfi]; + } + else + *funcs++ = Cop_to_Aop_PFI[dst_pfi]; + break; + } + else if (state->dst_blend == DSBF_ONE) { + break; + } + } + else if (state->src_blend == DSBF_ONE && state->dst_blend == DSBF_ZERO) { + if (state->drawingflags & DSDRAW_DST_COLORKEY) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Cop_toK_Aop_PFI[dst_pfi]; + } + else + *funcs++ = Cop_to_Aop_PFI[dst_pfi]; + break; + } + } + + /* load from destination */ + *funcs++ = Sop_is_Aop; + if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->dst_format)) + *funcs++ = Slut_is_Alut; + *funcs++ = Dacc_is_Aacc; + *funcs++ = Sop_PFI_to_Dacc[dst_pfi]; + + /* premultiply destination */ + if (state->drawingflags & DSDRAW_DST_PREMULTIPLY) + *funcs++ = Dacc_premultiply; + + /* xor destination */ + if (state->drawingflags & DSDRAW_XOR) + *funcs++ = Dacc_xor; + + /* load source (color) */ + Cacc.RGB.a = color.a; + if (!dst_ycbcr) { + Cacc.RGB.r = color.r; + Cacc.RGB.g = color.g; + Cacc.RGB.b = color.b; + } else { + Cacc.YUV.y = gfxs->YCop; + Cacc.YUV.u = gfxs->CbCop; + Cacc.YUV.v = gfxs->CrCop; + } + + /* premultiply source (color) */ + /*if (state->drawingflags & DSDRAW_SRC_PREMULTIPLY) { + u16 ca = color.a + 1; + + Cacc.r = (Cacc.r * ca) >> 8; + Cacc.g = (Cacc.g * ca) >> 8; + Cacc.b = (Cacc.b * ca) >> 8; + }*/ + + if (state->drawingflags & DSDRAW_BLEND) { + /* source blending */ + switch (state->src_blend) { + case DSBF_ZERO: + break; + case DSBF_ONE: + SCacc = Cacc; + break; + case DSBF_SRCCOLOR: + SCacc.RGB.a = (Cacc.RGB.a * (Cacc.RGB.a + 1)) >> 8; + SCacc.RGB.r = (Cacc.RGB.r * (Cacc.RGB.r + 1)) >> 8; + SCacc.RGB.g = (Cacc.RGB.g * (Cacc.RGB.g + 1)) >> 8; + SCacc.RGB.b = (Cacc.RGB.b * (Cacc.RGB.b + 1)) >> 8; + break; + case DSBF_INVSRCCOLOR: + SCacc.RGB.a = (Cacc.RGB.a * (0x100 - Cacc.RGB.a)) >> 8; + SCacc.RGB.r = (Cacc.RGB.r * (0x100 - Cacc.RGB.r)) >> 8; + SCacc.RGB.g = (Cacc.RGB.g * (0x100 - Cacc.RGB.g)) >> 8; + SCacc.RGB.b = (Cacc.RGB.b * (0x100 - Cacc.RGB.b)) >> 8; + break; + case DSBF_SRCALPHA: { + u16 ca = color.a + 1; + + SCacc.RGB.a = (Cacc.RGB.a * ca) >> 8; + SCacc.RGB.r = (Cacc.RGB.r * ca) >> 8; + SCacc.RGB.g = (Cacc.RGB.g * ca) >> 8; + SCacc.RGB.b = (Cacc.RGB.b * ca) >> 8; + break; + } + case DSBF_INVSRCALPHA: { + u16 ca = 0x100 - color.a; + + SCacc.RGB.a = (Cacc.RGB.a * ca) >> 8; + SCacc.RGB.r = (Cacc.RGB.r * ca) >> 8; + SCacc.RGB.g = (Cacc.RGB.g * ca) >> 8; + SCacc.RGB.b = (Cacc.RGB.b * ca) >> 8; + break; + } + case DSBF_SRCALPHASAT: + *funcs++ = Sacc_is_NULL; + case DSBF_DESTALPHA: + case DSBF_INVDESTALPHA: + case DSBF_DESTCOLOR: + case DSBF_INVDESTCOLOR: + *funcs++ = Dacc_is_Bacc; + *funcs++ = Cacc_to_Dacc; + + *funcs++ = Dacc_is_Aacc; + *funcs++ = Xacc_is_Bacc; + *funcs++ = Yacc_is_Bacc; + *funcs++ = Xacc_blend[state->src_blend - 1]; + + break; + + default: + D_BUG( "unknown src_blend %d", state->src_blend ); + } + + + /* destination blending */ + *funcs++ = Sacc_is_NULL; + *funcs++ = Xacc_is_Aacc; + *funcs++ = Yacc_is_Aacc; + + if (state->dst_blend > D_ARRAY_SIZE(Xacc_blend) || state->dst_blend < 1) + D_BUG( "unknown dst_blend %d", state->dst_blend ); + else + *funcs++ = Xacc_blend[state->dst_blend - 1]; + + /* add source to destination accumulator */ + switch (state->src_blend) { + case DSBF_ZERO: + break; + case DSBF_ONE: + case DSBF_SRCCOLOR: + case DSBF_INVSRCCOLOR: + case DSBF_SRCALPHA: + case DSBF_INVSRCALPHA: + if (SCacc.RGB.a || SCacc.RGB.r || + SCacc.RGB.g || SCacc.RGB.b) + *funcs++ = SCacc_add_to_Dacc; + break; + case DSBF_DESTALPHA: + case DSBF_INVDESTALPHA: + case DSBF_DESTCOLOR: + case DSBF_INVDESTCOLOR: + case DSBF_SRCALPHASAT: + *funcs++ = Sacc_is_Bacc; + *funcs++ = Sacc_add_to_Dacc; + break; + + default: + D_BUG( "unknown src_blend %d", state->src_blend ); + } + } + + /* demultiply result */ + if (state->drawingflags & DSDRAW_DEMULTIPLY) + *funcs++ = Dacc_demultiply; + + /* write to destination */ + *funcs++ = Sacc_is_Aacc; + if (state->drawingflags & DSDRAW_DST_COLORKEY) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Sacc_toK_Aop_PFI[dst_pfi]; + } + else + *funcs++ = Sacc_to_Aop_PFI[dst_pfi]; + + /* store computed Cacc */ + gfxs->Cacc = Cacc; + gfxs->SCacc = SCacc; + } + else { + gfxs->need_accumulator = false; + + if (state->drawingflags & DSDRAW_DST_COLORKEY) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Cop_toK_Aop_PFI[dst_pfi]; + } + else + *funcs++ = Cop_to_Aop_PFI[dst_pfi]; + } + break; + case DFXL_BLIT: + if (state->blittingflags == DSBLIT_BLEND_ALPHACHANNEL && + state->src_blend == DSBF_SRCALPHA && + state->dst_blend == DSBF_INVSRCALPHA) + { + if (gfxs->src_format == DSPF_ARGB && + Bop_argb_blend_alphachannel_src_invsrc_Aop_PFI[dst_pfi]) + { + *funcs++ = Bop_argb_blend_alphachannel_src_invsrc_Aop_PFI[dst_pfi]; + break; + } + } + if (state->blittingflags == DSBLIT_BLEND_ALPHACHANNEL && + state->src_blend == DSBF_ONE && + state->dst_blend == DSBF_INVSRCALPHA) + { + if (gfxs->src_format == DSPF_ARGB && + Bop_argb_blend_alphachannel_one_invsrc_Aop_PFI[dst_pfi]) + { + *funcs++ = Bop_argb_blend_alphachannel_one_invsrc_Aop_PFI[dst_pfi]; + break; + } + } + if (((state->blittingflags == (DSBLIT_COLORIZE | DSBLIT_BLEND_ALPHACHANNEL | + DSBLIT_SRC_PREMULTIPLY) && + state->src_blend == DSBF_ONE) + || + (state->blittingflags == (DSBLIT_COLORIZE | DSBLIT_BLEND_ALPHACHANNEL) && + state->src_blend == DSBF_SRCALPHA)) + && + state->dst_blend == DSBF_INVSRCALPHA) + { + if (gfxs->src_format == DSPF_A8 && Bop_a8_set_alphapixel_Aop_PFI[dst_pfi]) { + *funcs++ = Bop_a8_set_alphapixel_Aop_PFI[dst_pfi]; + break; + } + if (gfxs->src_format == DSPF_A1 && Bop_a1_set_alphapixel_Aop_PFI[dst_pfi]) { + *funcs++ = Bop_a1_set_alphapixel_Aop_PFI[dst_pfi]; + break; + } + } +#ifndef WORDS_BIGENDIAN + if (state->blittingflags == DSBLIT_NOFX && + source->config.format == DSPF_RGB24 && + destination->config.format == DSPF_RGB16) + { + *funcs++ = Bop_rgb24_to_Aop_rgb16_LE; + break; + } + if (state->blittingflags == DSBLIT_NOFX && + (source->config.format == DSPF_RGB32 || source->config.format == DSPF_ARGB) && + destination->config.format == DSPF_RGB16) + { + *funcs++ = Bop_rgb32_to_Aop_rgb16_LE; + break; + } +#endif + /* fallthru */ + case DFXL_STRETCHBLIT: { + int modulation = state->blittingflags & MODULATION_FLAGS; + + if (modulation) { + bool read_destination = false; + bool source_needs_destination = false; + bool scale_from_accumulator; + + /* check if destination has to be read */ + if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | + DSBLIT_BLEND_COLORALPHA)) { + switch (state->src_blend) { + case DSBF_DESTALPHA: + case DSBF_DESTCOLOR: + case DSBF_INVDESTALPHA: + case DSBF_INVDESTCOLOR: + case DSBF_SRCALPHASAT: + source_needs_destination = true; + default: + ; + } + + read_destination = source_needs_destination || + (state->dst_blend != DSBF_ZERO) || + (state->blittingflags & DSBLIT_XOR); + } + else if (state->blittingflags & DSBLIT_XOR) { + read_destination = true; + } + + scale_from_accumulator = !read_destination && + (accel == DFXL_STRETCHBLIT); + + /* read the destination if needed */ + if (read_destination) { + *funcs++ = Sop_is_Aop; + if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->dst_format)) + *funcs++ = Slut_is_Alut; + *funcs++ = Dacc_is_Aacc; + *funcs++ = Sop_PFI_to_Dacc[dst_pfi]; + + if (state->blittingflags & DSBLIT_DST_PREMULTIPLY) + *funcs++ = Dacc_premultiply; + } + else if (scale_from_accumulator) { + *funcs++ = Len_is_Slen; + } + + /* read the source */ + *funcs++ = Sop_is_Bop; + if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format)) + *funcs++ = Slut_is_Blut; + *funcs++ = Dacc_is_Bacc; + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + gfxs->Skey = state->src_colorkey; + if (accel == DFXL_BLIT || scale_from_accumulator) + *funcs++ = Sop_PFI_Kto_Dacc[src_pfi]; + else + *funcs++ = Sop_PFI_SKto_Dacc[src_pfi]; + } + else { + if (accel == DFXL_BLIT || scale_from_accumulator) + *funcs++ = Sop_PFI_to_Dacc[src_pfi]; + else + *funcs++ = Sop_PFI_Sto_Dacc[src_pfi]; + } + + if (!src_ycbcr && dst_ycbcr) { + if (DFB_COLOR_BITS_PER_PIXEL(gfxs->src_format)) + *funcs++ = Dacc_RGB_to_YCbCr; + /*else + *funcs++ = Dacc_Alpha_to_YCbCr;*/ + } + else if (src_ycbcr && !dst_ycbcr) { + if (DFB_COLOR_BITS_PER_PIXEL(gfxs->dst_format)) + *funcs++ = Dacc_YCbCr_to_RGB; + } + + /* Premultiply color alpha? */ + if (state->blittingflags & DSBLIT_SRC_PREMULTCOLOR) { + gfxs->Cacc.RGB.a = color.a + 1; + *funcs++ = Dacc_premultiply_color_alpha; + } + + /* modulate the source if requested */ + if (Dacc_modulation[modulation & 0x7]) { + /* modulation source */ + gfxs->Cacc.RGB.a = color.a + 1; + if (!dst_ycbcr) { + gfxs->Cacc.RGB.r = color.r + 1; + gfxs->Cacc.RGB.g = color.g + 1; + gfxs->Cacc.RGB.b = color.b + 1; + } else { + gfxs->Cacc.YUV.y = gfxs->YCop + 1; + gfxs->Cacc.YUV.u = gfxs->CbCop + 1; + gfxs->Cacc.YUV.v = gfxs->CrCop + 1; + } + + *funcs++ = Dacc_modulation[modulation & 0x7]; + } + + /* Premultiply (modulated) source alpha? */ + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) + *funcs++ = Dacc_premultiply; + + /* Xor source with destination */ + if (state->blittingflags & DSBLIT_XOR) { + *funcs++ = Sacc_is_Aacc; + *funcs++ = Dacc_is_Bacc; + *funcs++ = Sacc_xor_Dacc; + } + + /* do blend functions and combine both accumulators */ + if (state->blittingflags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) { + /* Xacc will be blended and written to while + Sacc and Dacc point to the SRC and DST + as referenced by the blending functions */ + *funcs++ = Sacc_is_Bacc; + *funcs++ = Dacc_is_Aacc; + + if (source_needs_destination && + state->dst_blend != DSBF_ONE) { + /* blend the destination */ + *funcs++ = Yacc_is_Aacc; + *funcs++ = Xacc_is_Tacc; + *funcs++ = Xacc_blend[state->dst_blend - 1]; + + /* blend the source */ + *funcs++ = Xacc_is_Bacc; + *funcs++ = Yacc_is_Bacc; + *funcs++ = Xacc_blend[state->src_blend - 1]; + } + else { + /* blend the destination if needed */ + if (read_destination) { + *funcs++ = Yacc_is_Aacc; + *funcs++ = Xacc_is_Tacc; + *funcs++ = Xacc_blend[state->dst_blend - 1]; + } + + /* blend the source */ + *funcs++ = Xacc_is_Bacc; + *funcs++ = Yacc_is_Bacc; + *funcs++ = Xacc_blend[state->src_blend - 1]; + } + + /* add the destination to the source */ + if (read_destination) { + *funcs++ = Sacc_is_Tacc; + *funcs++ = Dacc_is_Bacc; + *funcs++ = Sacc_add_to_Dacc; + } + } + + if (state->blittingflags & DSBLIT_DEMULTIPLY) { + *funcs++ = Dacc_is_Bacc; + *funcs++ = Dacc_demultiply; + } + + /* write source to destination */ + *funcs++ = Sacc_is_Bacc; + if (scale_from_accumulator) { + *funcs++ = Len_is_Dlen; + if (state->blittingflags & DSBLIT_DST_COLORKEY ) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Sacc_StoK_Aop_PFI[dst_pfi]; + } else + *funcs++ = Sacc_Sto_Aop_PFI[dst_pfi]; + } else { + if (state->blittingflags & DSBLIT_DST_COLORKEY ) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Sacc_toK_Aop_PFI[dst_pfi]; + } else + *funcs++ = Sacc_to_Aop_PFI[dst_pfi]; + } + } + else if (state->blittingflags == DSBLIT_INDEX_TRANSLATION && + DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format) && + DFB_PIXELFORMAT_IS_INDEXED(gfxs->dst_format)) + { + gfxs->trans = state->index_translation; + gfxs->num_trans = state->num_translation; + + switch (gfxs->src_format) { + case DSPF_LUT2: + switch (gfxs->dst_format) { + case DSPF_LUT8: + *funcs++ = Bop_lut2_translate_to_Aop_lut8; + break; + + default: + D_ONCE( "no index translation to %s implemented", + dfb_pixelformat_name( gfxs->dst_format ) ); + break; + } + break; + + default: + D_ONCE( "no index translation from %s implemented", + dfb_pixelformat_name( gfxs->src_format ) ); + break; + } + } + else if ((gfxs->src_format == gfxs->dst_format && + (!DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format) || + dfb_palette_equal( gfxs->Alut, gfxs->Blut ))) || + ((gfxs->src_format == DSPF_I420 || gfxs->src_format == DSPF_YV12) && + (gfxs->dst_format == DSPF_I420 || gfxs->dst_format == DSPF_YV12))) + { + gfxs->need_accumulator = false; + + if (accel == DFXL_BLIT) { + if (state->blittingflags & DSBLIT_SRC_COLORKEY && + state->blittingflags & DSBLIT_DST_COLORKEY) { + gfxs->Skey = state->src_colorkey; + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Bop_PFI_KtoK_Aop_PFI[dst_pfi]; + } else if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + gfxs->Skey = state->src_colorkey; + *funcs++ = Bop_PFI_Kto_Aop_PFI[dst_pfi]; + } else if (state->blittingflags & DSBLIT_DST_COLORKEY) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Bop_PFI_toK_Aop_PFI[dst_pfi]; + } else if (state->blittingflags & (DSBLIT_ROTATE90 | + DSBLIT_ROTATE180 | + DSBLIT_ROTATE270)) { + *funcs++ = Bop_PFI_toR_Aop_PFI[dst_pfi]; + } else + *funcs++ = Bop_PFI_to_Aop_PFI[dst_pfi]; + } + else { + if (state->blittingflags & DSBLIT_SRC_COLORKEY && + state->blittingflags & DSBLIT_DST_COLORKEY) { + gfxs->Skey = state->src_colorkey; + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Bop_PFI_SKtoK_Aop_PFI[dst_pfi]; + } else if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + gfxs->Skey = state->src_colorkey; + *funcs++ = Bop_PFI_SKto_Aop_PFI[dst_pfi]; + } else if (state->blittingflags & DSBLIT_DST_COLORKEY) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Bop_PFI_StoK_Aop_PFI[dst_pfi]; + } else + *funcs++ = Bop_PFI_Sto_Aop_PFI[dst_pfi]; + } + } + else { + bool scale_from_accumulator = (src_ycbcr != dst_ycbcr) && + (accel == DFXL_STRETCHBLIT); + + if (scale_from_accumulator) + *funcs++ = Len_is_Slen; + + gfxs->Sop = gfxs->Bop; + + if (DFB_PIXELFORMAT_IS_INDEXED(gfxs->src_format)) + *funcs++ = Slut_is_Blut; + + if (accel == DFXL_BLIT || scale_from_accumulator) { + if (state->blittingflags & DSBLIT_SRC_COLORKEY ) { + gfxs->Skey = state->src_colorkey; + *funcs++ = Sop_PFI_Kto_Dacc[src_pfi]; + } + else + *funcs++ = Sop_PFI_to_Dacc[src_pfi]; + } + else { /* DFXL_STRETCHBLIT */ + + if (state->blittingflags & DSBLIT_SRC_COLORKEY ) { + gfxs->Skey = state->src_colorkey; + *funcs++ = Sop_PFI_SKto_Dacc[src_pfi]; + } + else + *funcs++ = Sop_PFI_Sto_Dacc[src_pfi]; + + } + + if (!src_ycbcr && dst_ycbcr) { + if (DFB_COLOR_BITS_PER_PIXEL(gfxs->src_format)) + *funcs++ = Dacc_RGB_to_YCbCr; + else + *funcs++ = Dacc_Alpha_to_YCbCr; + } + else if (src_ycbcr && !dst_ycbcr) { + if (DFB_COLOR_BITS_PER_PIXEL(gfxs->dst_format)) + *funcs++ = Dacc_YCbCr_to_RGB; + } + + if (scale_from_accumulator) { + *funcs++ = Len_is_Dlen; + if (state->blittingflags & DSBLIT_DST_COLORKEY ) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Sacc_StoK_Aop_PFI[dst_pfi]; + } else + *funcs++ = Sacc_Sto_Aop_PFI[dst_pfi]; + } else { + if (state->blittingflags & DSBLIT_DST_COLORKEY ) { + gfxs->Dkey = state->dst_colorkey; + *funcs++ = Sacc_toK_Aop_PFI[dst_pfi]; + } else + *funcs++ = Sacc_to_Aop_PFI[dst_pfi]; + } + } + break; + } + default: + D_ONCE("unimplemented drawing/blitting function"); + gRelease( state ); + return false; + } + + *funcs = NULL; + + dfb_state_update( state, state->flags & CSF_SOURCE_LOCKED ); + + return true; +} + +void gRelease( CardState *state ) +{ + dfb_surface_unlock_buffer( state->destination, &state->dst ); + + if (state->flags & CSF_SOURCE_LOCKED) { + dfb_surface_unlock_buffer( state->source, &state->src ); + state->flags &= ~CSF_SOURCE_LOCKED; + } +} + +#define CHECK_PIPELINE() \ + { \ + if (!gfxs->funcs[0]) \ + return; \ + \ + if (dfb_config->software_trace) { \ + int i; \ + GenefxFunc *funcs = gfxs->funcs; \ + \ + direct_log_lock( NULL ); \ + direct_log_printf( NULL, " Software Fallback Pipeline:\n" ); \ + \ + for (i=0; funcs[i]; ++i) \ + direct_log_printf( NULL, " [%2d] %s\n", i, \ + direct_trace_lookup_symbol_at( funcs[i] ) ); \ + \ + direct_log_printf( NULL, "\n" ); \ + direct_log_unlock( NULL ); \ + } \ + } + +#define RUN_PIPELINE() \ + { \ + int i; \ + GenefxFunc *funcs = gfxs->funcs; \ + \ + for (i=0; funcs[i]; ++i) \ + funcs[i]( gfxs ); \ + } + + +static inline void Aop_xy( GenefxState *gfxs, int x, int y ) +{ + int pitch = gfxs->dst_pitch; + + gfxs->Aop[0] = gfxs->dst_org[0]; + gfxs->AopY = y; + + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + gfxs->Aop_field = y & 1; + if (gfxs->Aop_field) + gfxs->Aop[0] += gfxs->dst_field_offset; + + y /= 2; + } + + D_ASSUME( !(x & DFB_PIXELFORMAT_ALIGNMENT(gfxs->dst_format)) ); + + gfxs->Aop[0] += y * pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, x ); + + if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) { + int dst_field_offset = gfxs->dst_field_offset; + + switch (gfxs->dst_format) { + case DSPF_YV12: + case DSPF_I420: + dst_field_offset /= 4; + pitch /= 2; + y /= 2; + x /= 2; + break; + case DSPF_NV12: + case DSPF_NV21: + dst_field_offset /= 2; + y /= 2; + case DSPF_NV16: + x &= ~1; + break; + default: + break; + } + + gfxs->Aop[1] = gfxs->dst_org[1]; + gfxs->Aop[2] = gfxs->dst_org[2]; + + if (gfxs->dst_caps & DSCAPS_SEPARATED && gfxs->Aop_field) { + gfxs->Aop[1] += dst_field_offset; + gfxs->Aop[2] += dst_field_offset; + } + + gfxs->Aop[1] += y * pitch + x; + gfxs->Aop[2] += y * pitch + x; + } +} + +static inline void Aop_crab( GenefxState *gfxs ) +{ + gfxs->Aop[0] += gfxs->dst_bpp; + gfxs->AopY++; +} + +static inline void Aop_next( GenefxState *gfxs ) +{ + int pitch = gfxs->dst_pitch; + + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + gfxs->Aop_field++; + + if (gfxs->Aop_field & 1) + gfxs->Aop[0] += gfxs->dst_field_offset; + else + gfxs->Aop[0] += pitch - gfxs->dst_field_offset; + } + else + gfxs->Aop[0] += pitch; + + if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) { + if (gfxs->dst_format == DSPF_YV12 || gfxs->dst_format == DSPF_I420) { + if (gfxs->AopY & 1) { + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + if (gfxs->Aop_field & 2) { + gfxs->Aop[1] += gfxs->dst_field_offset/4; + gfxs->Aop[2] += gfxs->dst_field_offset/4; + } + else { + gfxs->Aop[1] += pitch/2 - gfxs->dst_field_offset/4; + gfxs->Aop[2] += pitch/2 - gfxs->dst_field_offset/4; + } + } + else { + gfxs->Aop[1] += pitch/2; + gfxs->Aop[2] += pitch/2; + } + } + } + else if (gfxs->dst_format == DSPF_NV12 || gfxs->dst_format == DSPF_NV21) { + if (gfxs->AopY & 1) { + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + if (gfxs->Aop_field & 2) + gfxs->Aop[1] += gfxs->dst_field_offset/2; + else + gfxs->Aop[1] += pitch - gfxs->dst_field_offset/2; + } + else { + gfxs->Aop[1] += pitch; + } + } + } + else { /* NV16 */ + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + if (gfxs->Aop_field & 1) + gfxs->Aop[1] += gfxs->dst_field_offset; + else + gfxs->Aop[1] += pitch - gfxs->dst_field_offset; + } + else { + gfxs->Aop[1] += pitch; + } + } + } + + gfxs->AopY++; +} + +static inline void Aop_prev( GenefxState *gfxs ) +{ + int pitch = gfxs->dst_pitch; + + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + gfxs->Aop_field++; + + if (gfxs->Aop_field & 1) + gfxs->Aop[0] += gfxs->dst_field_offset - pitch; + else + gfxs->Aop[0] -= gfxs->dst_field_offset; + } + else + gfxs->Aop[0] -= pitch; + + if (DFB_PLANAR_PIXELFORMAT(gfxs->dst_format)) { + if (gfxs->dst_format == DSPF_YV12 || gfxs->dst_format == DSPF_I420) { + if (gfxs->AopY & 1) { + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + if (gfxs->Aop_field & 2) { + gfxs->Aop[1] += gfxs->dst_field_offset/4 - pitch/2; + gfxs->Aop[2] += gfxs->dst_field_offset/4 - pitch/2; + } + else { + gfxs->Aop[1] -= gfxs->dst_field_offset/4; + gfxs->Aop[2] -= gfxs->dst_field_offset/4; + } + } + else { + gfxs->Aop[1] -= pitch/2; + gfxs->Aop[2] -= pitch/2; + } + } + } + else if (gfxs->dst_format == DSPF_NV12 || gfxs->dst_format == DSPF_NV21) { + if (gfxs->AopY & 1) { + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + if (gfxs->Aop_field & 2) + gfxs->Aop[1] += gfxs->dst_field_offset/2 - pitch; + else + gfxs->Aop[1] -= gfxs->dst_field_offset/2; + } + else { + gfxs->Aop[1] -= pitch; + } + } + } + else { /* NV16 */ + if (gfxs->dst_caps & DSCAPS_SEPARATED) { + if (gfxs->Aop_field & 1) + gfxs->Aop[1] += gfxs->dst_field_offset - pitch; + else + gfxs->Aop[1] -= gfxs->dst_field_offset; + } + else { + gfxs->Aop[1] -= pitch; + } + } + } + + gfxs->AopY--; +} + + +static inline void Bop_xy( GenefxState *gfxs, int x, int y ) +{ + int pitch = gfxs->src_pitch; + + gfxs->Bop[0] = gfxs->src_org[0]; + gfxs->BopY = y; + + if (gfxs->src_caps & DSCAPS_SEPARATED) { + gfxs->Bop_field = y & 1; + if (gfxs->Bop_field) + gfxs->Bop[0] += gfxs->src_field_offset; + + y /= 2; + } + + D_ASSUME( !(x & DFB_PIXELFORMAT_ALIGNMENT(gfxs->src_format)) ); + + gfxs->Bop[0] += y * pitch + DFB_BYTES_PER_LINE( gfxs->src_format, x ); + + if (DFB_PLANAR_PIXELFORMAT(gfxs->src_format)) { + int src_field_offset = gfxs->src_field_offset; + + switch (gfxs->src_format) { + case DSPF_YV12: + case DSPF_I420: + src_field_offset /= 4; + pitch /= 2; + y /= 2; + x /= 2; + break; + case DSPF_NV12: + case DSPF_NV21: + src_field_offset /= 2; + y /= 2; + case DSPF_NV16: + x &= ~1; + break; + default: + break; + } + + gfxs->Bop[1] = gfxs->src_org[1]; + gfxs->Bop[2] = gfxs->src_org[2]; + + if (gfxs->src_caps & DSCAPS_SEPARATED && gfxs->Bop_field) { + gfxs->Bop[1] += src_field_offset; + gfxs->Bop[2] += src_field_offset; + } + + gfxs->Bop[1] += y * pitch + x; + gfxs->Bop[2] += y * pitch + x; + } +} + +static inline void Bop_next( GenefxState *gfxs ) +{ + int pitch = gfxs->src_pitch; + + if (gfxs->src_caps & DSCAPS_SEPARATED) { + gfxs->Bop_field++; + + if (gfxs->Bop_field & 1) + gfxs->Bop[0] += gfxs->src_field_offset; + else + gfxs->Bop[0] += pitch - gfxs->src_field_offset; + } + else + gfxs->Bop[0] += pitch; + + if (DFB_PLANAR_PIXELFORMAT(gfxs->src_format)) { + if (gfxs->src_format == DSPF_YV12 || gfxs->src_format == DSPF_I420) { + if (gfxs->BopY & 1) { + if (gfxs->src_caps & DSCAPS_SEPARATED) { + if (gfxs->Bop_field & 2) { + gfxs->Bop[1] += gfxs->src_field_offset/4; + gfxs->Bop[2] += gfxs->src_field_offset/4; + } + else { + gfxs->Bop[1] += pitch/2 - gfxs->src_field_offset/4; + gfxs->Bop[2] += pitch/2 - gfxs->src_field_offset/4; + } + } + else { + gfxs->Bop[1] += pitch/2; + gfxs->Bop[2] += pitch/2; + } + } + } + else if (gfxs->src_format == DSPF_NV12 || gfxs->src_format == DSPF_NV21) { + if (gfxs->BopY & 1) { + if (gfxs->src_caps & DSCAPS_SEPARATED) { + if (gfxs->Bop_field & 2) + gfxs->Bop[1] += gfxs->src_field_offset/2; + else + gfxs->Bop[1] += pitch - gfxs->src_field_offset/2; + } + else { + gfxs->Bop[1] += pitch; + } + } + } + else { /* NV16 */ + if (gfxs->src_caps & DSCAPS_SEPARATED) { + if (gfxs->Bop_field & 1) + gfxs->Bop[1] += gfxs->src_field_offset; + else + gfxs->Bop[1] += pitch - gfxs->src_field_offset; + } + else { + gfxs->Bop[1] += pitch; + } + } + } + + gfxs->BopY++; +} + +static inline void Bop_prev( GenefxState *gfxs ) +{ + int pitch = gfxs->src_pitch; + + if (gfxs->src_caps & DSCAPS_SEPARATED) { + gfxs->Bop_field++; + + if (gfxs->Bop_field & 1) + gfxs->Bop[0] += gfxs->src_field_offset - pitch; + else + gfxs->Bop[0] -= gfxs->src_field_offset; + } + else + gfxs->Bop[0] -= pitch; + + if (DFB_PLANAR_PIXELFORMAT(gfxs->src_format)) { + if (gfxs->src_format == DSPF_YV12 || gfxs->src_format == DSPF_I420) { + if (gfxs->BopY & 1) { + if (gfxs->src_caps & DSCAPS_SEPARATED) { + if (gfxs->Bop_field & 2) { + gfxs->Bop[1] += gfxs->src_field_offset/4 - pitch/2; + gfxs->Bop[2] += gfxs->src_field_offset/4 - pitch/2; + } + else { + gfxs->Bop[1] -= gfxs->src_field_offset/4; + gfxs->Bop[2] -= gfxs->src_field_offset/4; + } + } + else { + gfxs->Bop[1] -= pitch/2; + gfxs->Bop[2] -= pitch/2; + } + } + } + else if (gfxs->src_format == DSPF_NV12 || gfxs->src_format == DSPF_NV21) { + if (gfxs->BopY & 1) { + if (gfxs->src_caps & DSCAPS_SEPARATED) { + if (gfxs->Bop_field & 2) + gfxs->Bop[1] += gfxs->src_field_offset/2 - pitch; + else + gfxs->Bop[1] -= gfxs->src_field_offset/2; + } + else { + gfxs->Bop[1] -= pitch; + } + } + } + else { /* NV16 */ + if (gfxs->src_caps & DSCAPS_SEPARATED) { + if (gfxs->Bop_field & 1) + gfxs->Bop[1] += gfxs->src_field_offset - pitch; + else + gfxs->Bop[1] -= gfxs->src_field_offset; + } + else { + gfxs->Bop[1] -= pitch; + } + } + } + + gfxs->BopY--; +} + +static bool +ABacc_prepare( GenefxState *gfxs, int width ) +{ + int size; + + if (!gfxs->need_accumulator) + return true; + + size = (width + 31) & ~31; + + if (gfxs->ABsize < size) { + void *ABstart = D_MALLOC( size * sizeof(GenefxAccumulator) * 3 + 31 ); + + if (!ABstart) { + D_WARN( "out of memory" ); + return false; + } + + if (gfxs->ABstart) + D_FREE( gfxs->ABstart ); + + gfxs->ABstart = ABstart; + gfxs->ABsize = size; + gfxs->Aacc = (GenefxAccumulator*) (((unsigned long)ABstart+31) & ~31); + gfxs->Bacc = gfxs->Aacc + size; + gfxs->Tacc = gfxs->Aacc + size + size; + } + + gfxs->Sacc = gfxs->Dacc = gfxs->Aacc; + + return true; +} + +static void +ABacc_flush( GenefxState *gfxs ) +{ + if (dfb_config->keep_accumulators >= 0 && gfxs->ABsize > dfb_config->keep_accumulators) { + D_FREE( gfxs->ABstart ); + + gfxs->ABsize = 0; + gfxs->ABstart = NULL; + gfxs->Aacc = NULL; + gfxs->Bacc = NULL; + gfxs->Sacc = NULL; + gfxs->Dacc = NULL; + } +} + +void gFillRectangle( CardState *state, DFBRectangle *rect ) +{ + int h; + GenefxState *gfxs = state->gfxs; + + D_ASSERT( gfxs != NULL ); + + if (dfb_config->software_warn) { + D_WARN( "FillRectangle (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, color 0x%02x%02x%02x%02x", + DFB_RECTANGLE_VALS(rect), dfb_pixelformat_name(gfxs->dst_format), state->drawingflags, + state->color.a, state->color.r, state->color.g, state->color.b ); + } + + D_ASSERT( state->clip.x1 <= rect->x ); + D_ASSERT( state->clip.y1 <= rect->y ); + D_ASSERT( state->clip.x2 >= (rect->x + rect->w - 1) ); + D_ASSERT( state->clip.y2 >= (rect->y + rect->h - 1) ); + + CHECK_PIPELINE(); + + if (!ABacc_prepare( gfxs, rect->w )) + return; + + gfxs->length = rect->w; + + Aop_xy( gfxs, rect->x, rect->y ); + + h = rect->h; + while (h--) { + RUN_PIPELINE(); + + Aop_next( gfxs ); + } + + ABacc_flush( gfxs ); +} + +void gDrawLine( CardState *state, DFBRegion *line ) +{ + GenefxState *gfxs = state->gfxs; + + int i,dx,dy,sdy,dxabs,dyabs,x,y,px,py; + + D_ASSERT( gfxs != NULL ); + + CHECK_PIPELINE(); + + /* the horizontal distance of the line */ + dx = line->x2 - line->x1; + dxabs = abs(dx); + + if (!ABacc_prepare( gfxs, dxabs )) + return; + + /* the vertical distance of the line */ + dy = line->y2 - line->y1; + dyabs = abs(dy); + + if (!dx || !dy) { /* draw horizontal/vertical line */ + DFBRectangle rect = { + MIN (line->x1, line->x2), + MIN (line->y1, line->y2), + dxabs + 1, dyabs + 1}; + + gFillRectangle( state, &rect ); + return; + } + + if (dfb_config->software_warn) { + D_WARN( "DrawLine (%4d,%4d-%4d,%4d) %6s, flags 0x%08x, color 0x%02x%02x%02x%02x", + DFB_RECTANGLE_VALS_FROM_REGION(line), dfb_pixelformat_name(gfxs->dst_format), state->drawingflags, + state->color.a, state->color.r, state->color.g, state->color.b ); + } + + sdy = SIGN(dy) * SIGN(dx); + x = dyabs >> 1; + y = dxabs >> 1; + + if (dx > 0) { + px = line->x1; + py = line->y1; + } + else { + px = line->x2; + py = line->y2; + } + + if (dxabs >= dyabs) { /* the line is more horizontal than vertical */ + + for (i=0, gfxs->length=1; ilength++) { + y += dyabs; + if (y >= dxabs) { + Aop_xy( gfxs, px, py ); + RUN_PIPELINE(); + px += gfxs->length; + gfxs->length = 0; + y -= dxabs; + py += sdy; + } + } + Aop_xy( gfxs, px, py ); + RUN_PIPELINE(); + } + else { /* the line is more vertical than horizontal */ + + gfxs->length = 1; + Aop_xy( gfxs, px, py ); + RUN_PIPELINE(); + + for (i=0; i= dyabs) { + x -= dyabs; + px++; + } + py += sdy; + + Aop_xy( gfxs, px, py ); + RUN_PIPELINE(); + } + } + + ABacc_flush( gfxs ); +} + +void gBlit( CardState *state, DFBRectangle *rect, int dx, int dy ) +{ + GenefxState *gfxs = state->gfxs; + int x, h; + + D_ASSERT( gfxs != NULL ); + + if (dfb_config->software_warn) { + D_WARN( "Blit (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, funcs %d/%d, color 0x%02x%02x%02x%02x, source (%4d,%4d) %6s", + dx, dy, rect->w, rect->h, dfb_pixelformat_name(gfxs->dst_format), state->blittingflags, + state->src_blend, state->dst_blend, + state->color.a, state->color.r, state->color.g, state->color.b, rect->x, rect->y, + dfb_pixelformat_name(gfxs->src_format) ); + } + + D_ASSERT( state->clip.x1 <= dx ); + D_ASSERT( state->clip.y1 <= dy ); + D_ASSERT( (state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.x2 >= (dx + rect->w - 1) ); + D_ASSERT( (state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.y2 >= (dy + rect->h - 1) ); + D_ASSERT( !(state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.x2 >= (dx + rect->h - 1) ); + D_ASSERT( !(state->blittingflags & (DSBLIT_ROTATE90 | DSBLIT_ROTATE270)) || state->clip.y2 >= (dy + rect->w - 1) ); + + CHECK_PIPELINE(); + + if (!ABacc_prepare( gfxs, rect->w )) + return; + + if (gfxs->src_org[0] == gfxs->dst_org[0] && dy == rect->y && dx > rect->x) + /* we must blit from right to left */ + gfxs->Astep = gfxs->Bstep = -1; + else + /* we must blit from left to right*/ + gfxs->Astep = gfxs->Bstep = 1; + + if (state->blittingflags & DSBLIT_ROTATE90) + gfxs->Astep *= -gfxs->dst_pitch / gfxs->dst_bpp; + else if (state->blittingflags & DSBLIT_ROTATE180) + gfxs->Astep *= -1; + else if (state->blittingflags & DSBLIT_ROTATE270) + gfxs->Astep *= gfxs->dst_pitch / gfxs->dst_bpp; + + switch (gfxs->src_format) { + case DSPF_A4: + case DSPF_YUY2: + case DSPF_UYVY: + rect->x &= ~1; + break; + default: + break; + } + + switch (gfxs->dst_format) { + case DSPF_A4: + case DSPF_YUY2: + case DSPF_UYVY: + dx &= ~1; + break; + default: + break; + } + + gfxs->length = rect->w; + + if (state->blittingflags == DSBLIT_ROTATE180 && gfxs->src_format == gfxs->dst_format) { + Aop_xy( gfxs, dx, dy ); + Bop_xy( gfxs, rect->x + rect->w - 1, rect->y + rect->h - 1 ); + + switch (DFB_BYTES_PER_PIXEL(gfxs->dst_format)) { + case 4: { + for (h = rect->h; h; h--) { + u32 *src = gfxs->Bop[0]; + u32 *dst = gfxs->Aop[0]; + + for (x=0; xw; x++) + dst[x] = src[-x]; + + Aop_next( gfxs ); + Bop_prev( gfxs ); + } + return; + } + case 2: { + for (h = rect->h; h; h--) { + u16 *src = gfxs->Bop[0]; + u16 *dst = gfxs->Aop[0]; + + for (x=0; xw; x++) + dst[x] = src[-x]; + + Aop_next( gfxs ); + Bop_prev( gfxs ); + } + return; + } + case 1: { + for (h = rect->h; h; h--) { + u8 *src = gfxs->Bop[0]; + u8 *dst = gfxs->Aop[0]; + + for (x=0; xw; x++) + dst[x] = src[-x]; + + Aop_next( gfxs ); + Bop_prev( gfxs ); + } + return; + } + + default: + break; + } + } + + if (state->blittingflags & DSBLIT_ROTATE180) { + Aop_xy( gfxs, dx + rect->w - 1, dy ); + Bop_xy( gfxs, rect->x, rect->y + rect->h - 1 ); + + for (h = rect->h; h; h--) { + RUN_PIPELINE(); + + Aop_next( gfxs ); + Bop_prev( gfxs ); + } + return; + } + else if( state->blittingflags & DSBLIT_ROTATE270 ) + { + Aop_xy( gfxs, dx, dy ); + Bop_xy( gfxs, rect->x, rect->y + rect->h - 1 ); + + for( h = rect->h; h; h-- ) + { + RUN_PIPELINE(); + + Aop_crab( gfxs ); + Bop_prev( gfxs ); + } + return; + } + else if( state->blittingflags & DSBLIT_ROTATE90 ) + { + Aop_xy( gfxs, dx, dy + rect->w - 1 ); + Bop_xy( gfxs, rect->x, rect->y ); + + for( h = rect->h; h; h-- ) + { + RUN_PIPELINE(); + + Aop_crab( gfxs ); + Bop_next( gfxs ); + } + return; + } + + if (gfxs->src_org[0] == gfxs->dst_org[0] && dy > rect->y && + !(state->blittingflags & DSBLIT_DEINTERLACE)) { + /* we must blit from bottom to top */ + Aop_xy( gfxs, dx, dy + rect->h - 1 ); + Bop_xy( gfxs, rect->x, rect->y + rect->h - 1 ); + + for (h = rect->h; h; h--) { + RUN_PIPELINE(); + + Aop_prev( gfxs ); + Bop_prev( gfxs ); + } + } + else { + /* we must blit from top to bottom */ + Aop_xy( gfxs, dx, dy ); + Bop_xy( gfxs, rect->x, rect->y ); + + if (state->blittingflags & DSBLIT_DEINTERLACE) { + if (state->source->field) { + Aop_next( gfxs ); + Bop_next( gfxs ); + rect->h--; + } + + for (h = rect->h/2; h; h--) { + RUN_PIPELINE(); + + Aop_next( gfxs ); + + RUN_PIPELINE(); + + Aop_next( gfxs ); + + Bop_next( gfxs ); + Bop_next( gfxs ); + } + } /* ! DSBLIT_DEINTERLACE */ + else { + for (h = rect->h; h; h--) { + RUN_PIPELINE(); + + Aop_next( gfxs ); + Bop_next( gfxs ); + } + } + } + + ABacc_flush( gfxs ); +} + +/**********************************************************************************************************************/ +/********* **************************************************************************************************/ +/*** Smooth scaling routines ******************************************************************************************/ +/********* **************************************************************************************************/ +/**********************************************************************************************************************/ + +#if DFB_SMOOTH_SCALING + +typedef struct { + DFBRegion clip; + const void *colors; + ulong protect; + ulong key; +} StretchCtx; + +typedef void (*StretchHVx)( void *dst, + int dpitch, + const void *src, + int spitch, + int width, + int height, + int dst_width, + int dst_height, + const StretchCtx *ctx ); + +#define STRETCH_NONE 0 +#define STRETCH_SRCKEY 1 +#define STRETCH_PROTECT 2 +#define STRETCH_SRCKEY_PROTECT 3 +#define STRETCH_NUM 4 + +typedef struct { + struct { + StretchHVx up[STRETCH_NUM]; + StretchHVx down[STRETCH_NUM]; + } f[DFB_NUM_PIXELFORMATS]; +} StretchFunctionTable; + +/**********************************************************************************************************************/ +/*** 16 bit RGB 565 scalers *******************************************************************************************/ +/**********************************************************************************************************************/ + +#define DST_FORMAT DSPF_RGB16 +#define TABLE_NAME stretch_hvx_RGB16 +#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGB16_ ## UPDOWN ## _ ## K ## P ## _ ## F +#define SHIFT_R5 5 +#define SHIFT_R6 6 +#define X_F81F 0xf81f +#define X_07E0 0x07e0 +#define MASK_RGB 0xffff + +#define FORMAT_RGB16 +#include "stretch_up_down_16.h" +#undef FORMAT_RGB16 + +#undef DST_FORMAT +#undef TABLE_NAME +#undef FUNC_NAME +#undef SHIFT_R5 +#undef SHIFT_R6 +#undef X_F81F +#undef X_07E0 +#undef MASK_RGB + +/**********************************************************************************************************************/ +/*** 16 bit ARGB 4444 scalers *****************************************************************************************/ +/**********************************************************************************************************************/ + +#define DST_FORMAT DSPF_ARGB4444 +#define TABLE_NAME stretch_hvx_ARGB4444 +#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_ARGB4444_ ## UPDOWN ## _ ## K ## P ## _ ## F +#define SHIFT_R5 4 +#define SHIFT_R6 4 +#define X_F81F 0x0f0f +#define X_07E0 0xf0f0 +#define MASK_RGB 0x0fff +#define HAS_ALPHA + +#define FORMAT_ARGB4444 +#include "stretch_up_down_16.h" +#undef FORMAT_ARGB4444 + +#undef DST_FORMAT +#undef TABLE_NAME +#undef FUNC_NAME +#undef SHIFT_R5 +#undef SHIFT_R6 +#undef X_F81F +#undef X_07E0 +#undef MASK_RGB +#undef HAS_ALPHA + +/**********************************************************************************************************************/ +/*** 16 bit RGBA 4444 scalers *****************************************************************************************/ +/**********************************************************************************************************************/ + +#define DST_FORMAT DSPF_RGBA4444 +#define TABLE_NAME stretch_hvx_RGBA4444 +#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGBA4444_ ## UPDOWN ## _ ## K ## P ## _ ## F +#define SHIFT_R5 4 +#define SHIFT_R6 4 +#define X_F81F 0x0f0f +#define X_07E0 0xf0f0 +#define MASK_RGB 0xfff0 +#define HAS_ALPHA + +#define FORMAT_RGBA4444 +#include "stretch_up_down_16.h" +#undef FORMAT_RGBA4444 + +#undef DST_FORMAT +#undef TABLE_NAME +#undef FUNC_NAME +#undef SHIFT_R5 +#undef SHIFT_R6 +#undef X_F81F +#undef X_07E0 +#undef MASK_RGB +#undef HAS_ALPHA + +/**********************************************************************************************************************/ +/*** 32 bit ARGB 8888 scalers *****************************************************************************************/ +/**********************************************************************************************************************/ + +#define DST_FORMAT DSPF_ARGB +#define TABLE_NAME stretch_hvx_ARGB +#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_ARGB_ ## UPDOWN ## _ ## K ## P ## _ ## F +#define SHIFT_R8 8 +#define SHIFT_L8 8 +#define X_00FF00FF 0x00ff00ff +#define X_FF00FF00 0xff00ff00 +#define MASK_RGB 0x00ffffff +#define HAS_ALPHA + +#include "stretch_up_down_32.h" + +#undef DST_FORMAT +#undef TABLE_NAME +#undef FUNC_NAME +#undef SHIFT_R8 +#undef SHIFT_L8 +#undef X_00FF00FF +#undef X_FF00FF00 +#undef MASK_RGB +#undef HAS_ALPHA + +/**********************************************************************************************************************/ +/*** 32 bit RGB 888 scalers *******************************************************************************************/ +/**********************************************************************************************************************/ + +#define DST_FORMAT DSPF_RGB32 +#define TABLE_NAME stretch_hvx_RGB32 +#define FUNC_NAME(UPDOWN,K,P,F) stretch_hvx_RGB32_ ## UPDOWN ## _ ## K ## P ## _ ## F +#define SHIFT_R8 8 +#define SHIFT_L8 8 +#define X_00FF00FF 0x00ff00ff +#define X_FF00FF00 0x0000ff00 +#define MASK_RGB 0x00ffffff + +#include "stretch_up_down_32.h" + +#undef DST_FORMAT +#undef TABLE_NAME +#undef FUNC_NAME +#undef SHIFT_R8 +#undef SHIFT_L8 +#undef X_00FF00FF +#undef X_FF00FF00 +#undef MASK_RGB + +#if 0 +/**********************************************************************************************************************/ +/*** 16 bit YUV 422 scalers *******************************************************************************************/ +/**********************************************************************************************************************/ + +#define FUNC_NAME(UPDOWN) stretch_hvx_nv16_ ## UPDOWN + +#include "stretch_up_down_8.h" + +#undef FUNC_NAME + +/**********************************************************************************************************************/ + +#define FUNC_NAME(UPDOWN) stretch_hvx_nv16_uv_ ## UPDOWN + +#include "stretch_up_down_88.h" + +#undef FUNC_NAME + +#endif +/**********************************************************************************************************************/ +/**********************************************************************************************************************/ + +static const StretchFunctionTable *stretch_tables[DFB_NUM_PIXELFORMATS] = { + NULL, /* DSPF_ARGB1555 */ + &stretch_hvx_RGB16, /* DSPF_RGB16 */ + NULL, /* DSPF_RGB24 */ + &stretch_hvx_RGB32, /* DSPF_RGB32 */ + &stretch_hvx_ARGB, /* DSPF_ARGB */ + NULL, /* DSPF_A8 */ + NULL, /* DSPF_YUY2 */ + NULL, /* DSPF_RGB332 */ + NULL, /* DSPF_UYVY */ + NULL, /* DSPF_I420 */ + NULL, /* DSPF_YV12 */ + NULL, /* DSPF_LUT8 */ + NULL, /* DSPF_ALUT44 */ + NULL, /* DSPF_AiRGB */ + NULL, /* DSPF_A1 */ + NULL, /* DSPF_NV12 */ + NULL, /* DSPF_NV16 */ + NULL, /* DSPF_ARGB2554 */ + &stretch_hvx_ARGB4444, /* DSPF_ARGB4444 */ + &stretch_hvx_RGBA4444, /* DSPF_RGBA4444 */ + NULL, /* DSPF_NV21 */ + NULL, /* DSPF_AYUV */ + NULL, /* DSPF_A4 */ + NULL, /* DSPF_ARGB1666 */ + NULL, /* DSPF_ARGB6666 */ + NULL, /* DSPF_RGB18 */ + NULL, /* DSPF_LUT2 */ + NULL, /* DSPF_RGB444 */ + NULL, /* DSPF_RGB555 */ + NULL /* DSPF_BGR555 */ +}; + +/**********************************************************************************************************************/ + +__attribute__((noinline)) +static bool +stretch_hvx( CardState *state, DFBRectangle *srect, DFBRectangle *drect ) +{ + GenefxState *gfxs; + const StretchFunctionTable *table; + StretchHVx stretch; + bool down = false; + void *dst; + void *src; + StretchCtx ctx; + int idx = STRETCH_NONE; + u32 colors[256]; + + D_ASSERT( state != NULL ); + DFB_RECTANGLE_ASSERT( srect ); + DFB_RECTANGLE_ASSERT( drect ); + + gfxs = state->gfxs; + + if (state->blittingflags & ~(DSBLIT_COLORKEY_PROTECT | DSBLIT_SRC_COLORKEY | DSBLIT_SRC_PREMULTIPLY)) + return false; + + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY && !DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) + return false; + + if (DFB_PIXELFORMAT_INDEX(gfxs->dst_format) >= D_ARRAY_SIZE(stretch_tables)) + return false; + + if (DFB_PIXELFORMAT_INDEX(gfxs->src_format) >= D_ARRAY_SIZE((stretch_tables[0])->f)) + return false; + + table = stretch_tables[DFB_PIXELFORMAT_INDEX(gfxs->dst_format)]; + if (!table) + return false; + + if (srect->w > drect->w && srect->h > drect->h) + down = true; + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) + idx |= STRETCH_SRCKEY; + + if (state->blittingflags & DSBLIT_COLORKEY_PROTECT) + idx |= STRETCH_PROTECT; + + if (down) { + if (!(state->render_options & DSRO_SMOOTH_DOWNSCALE)) + return false; + + stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].down[idx]; + } + else { + if (!(state->render_options & DSRO_SMOOTH_UPSCALE)) + return false; + + stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].up[idx]; + } + + if (!stretch) + return false; + + ctx.clip = state->clip; + + if (!dfb_region_rectangle_intersect( &ctx.clip, drect )) + return false; + + dfb_region_translate( &ctx.clip, - drect->x, - drect->y ); + + if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) { + int i; + const DFBColor *entries; + u16 *colors16 = (void*) colors; + + D_ASSERT( gfxs->Blut != NULL ); + + entries = gfxs->Blut->entries; + + switch (gfxs->dst_format) { + case DSPF_ARGB: + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + for (i=0; iBlut->num_entries; i++) { + int alpha = entries[i].a + 1; + + switch (alpha) { + case 0: + colors[i] = 0; + break; + + case 255: + colors[i] = PIXEL_ARGB( entries[i].a, + entries[i].r, + entries[i].g, + entries[i].b ); + break; + + default: + colors[i] = PIXEL_ARGB( entries[i].a, + (alpha * entries[i].r) >> 8, + (alpha * entries[i].g) >> 8, + (alpha * entries[i].b) >> 8 ); + } + } + } + else { + for (i=0; iBlut->num_entries; i++) + colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); + } + break; + + case DSPF_RGB32: + for (i=0; iBlut->num_entries; i++) + colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b ); + break; + + case DSPF_RGB16: + for (i=0; iBlut->num_entries; i++) + colors16[i] = PIXEL_RGB16( entries[i].r, entries[i].g, entries[i].b ); + break; + + case DSPF_ARGB4444: + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + for (i=0; iBlut->num_entries; i++) { + int alpha = entries[i].a + 1; + + switch (alpha) { + case 0: + colors16[i] = 0; + break; + + case 255: + colors16[i] = PIXEL_ARGB4444( entries[i].a, + entries[i].r, + entries[i].g, + entries[i].b ); + break; + + default: + colors16[i] = PIXEL_ARGB4444( entries[i].a, + (alpha * entries[i].r) >> 8, + (alpha * entries[i].g) >> 8, + (alpha * entries[i].b) >> 8 ); + } + } + } + else { + for (i=0; iBlut->num_entries; i++) + colors16[i] = PIXEL_ARGB4444( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); + } + break; + + case DSPF_RGBA4444: + if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) { + for (i=0; iBlut->num_entries; i++) { + int alpha = entries[i].a + 1; + + switch (alpha) { + case 0: + colors16[i] = 0; + break; + + case 255: + colors16[i] = PIXEL_RGBA4444( entries[i].a, + entries[i].r, + entries[i].g, + entries[i].b ); + break; + + default: + colors16[i] = PIXEL_RGBA4444( entries[i].a, + (alpha * entries[i].r) >> 8, + (alpha * entries[i].g) >> 8, + (alpha * entries[i].b) >> 8 ); + } + } + } + else { + for (i=0; iBlut->num_entries; i++) + colors16[i] = PIXEL_RGBA4444( entries[i].a, entries[i].r, entries[i].g, entries[i].b ); + } + break; + + case DSPF_RGB444: + for (i=0; iBlut->num_entries; i++) + colors16[i] = PIXEL_RGB444( entries[i].r, entries[i].g, entries[i].b ); + break; + + default: + D_UNIMPLEMENTED(); + } + + ctx.colors = colors; + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->dst_format )) + ctx.key = state->src_colorkey; + else { + const DFBColor *color = &entries[state->src_colorkey % gfxs->Blut->num_entries]; + + ctx.key = dfb_color_to_pixel( gfxs->dst_format, color->r, color->g, color->b ); + } + } + } + else { + ctx.colors = NULL; + + if (state->blittingflags & DSBLIT_SRC_COLORKEY) { + DFBColor color; + + dfb_pixel_to_color( gfxs->src_format, state->src_colorkey, &color ); + + ctx.key = dfb_color_to_pixel( gfxs->dst_format, color.r, color.g, color.b ); + } + } + + if (state->blittingflags & DSBLIT_COLORKEY_PROTECT) { + if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->dst_format )) + ctx.protect = state->colorkey.index; + else + ctx.protect = dfb_color_to_pixel( gfxs->dst_format, + state->colorkey.r, + state->colorkey.g, + state->colorkey.b ); + } + + dst = gfxs->dst_org[0] + drect->y * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x ); + src = gfxs->src_org[0] + srect->y * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x ); + + stretch( dst, gfxs->dst_pitch, src, gfxs->src_pitch, + srect->w, srect->h, drect->w, drect->h, &ctx ); + +#if 0 /* FIXME: repair */ + switch (gfxs->dst_format) { + case DSPF_NV16: + ctx.clip.x1 /= 2; + ctx.clip.x2 /= 2; + if (srect->w < drect->w || srect->h < drect->h) { + stretch_hvx_nv16_uv_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch, + srect->w/2, srect->h, drect->w/2, drect->h, &ctx ); + } + else { + stretch_hvx_nv16_uv_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch, + srect->w/2, srect->h, drect->w/2, drect->h, &ctx ); + } + break; + + default: + break; + } +#endif + + return true; +} +#endif /* DFB_SMOOTH_SCALING */ + +void gStretchBlit( CardState *state, DFBRectangle *srect, DFBRectangle *drect ) +{ + GenefxState *gfxs = state->gfxs; + DFBRectangle orect = *drect; + + int fx, fy; + int ix, iy; + int h; + + D_ASSERT( gfxs != NULL ); + + if (dfb_config->software_warn) { + D_WARN( "StretchBlit (%4d,%4d-%4dx%4d) %6s, flags 0x%08x, color 0x%02x%02x%02x%02x, source (%4d,%4d-%4dx%4d) %6s", + drect->x, drect->y, drect->w, drect->h, dfb_pixelformat_name(gfxs->dst_format), state->blittingflags, + state->color.a, state->color.r, state->color.g, state->color.b, srect->x, srect->y, srect->w, srect->h, + dfb_pixelformat_name(gfxs->src_format) ); + } + + CHECK_PIPELINE(); + +#if DFB_SMOOTH_SCALING + if (state->render_options & (DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE) && + stretch_hvx( state, srect, drect )) + return; +#endif + + /* Clip destination rectangle. */ + if (!dfb_rectangle_intersect_by_region( drect, &state->clip )) + return; + + /* Calculate fractions. */ + fx = (srect->w << 16) / orect.w; + fy = (srect->h << 16) / orect.h; + + /* Calculate horizontal phase and offset. */ + ix = fx * (drect->x - orect.x); + srect->x += ix >> 16; + ix &= 0xFFFF; + + /* Calculate vertical phase and offset. */ + iy = fy * (drect->y - orect.y); + srect->y += iy >> 16; + iy &= 0xFFFF; + + /* Adjust source size. */ + srect->w = ((drect->w * fx + ix) + 0xFFFF) >> 16; + srect->h = ((drect->h * fy + iy) + 0xFFFF) >> 16; + + D_ASSERT( srect->x + srect->w <= state->source->config.size.w ); + D_ASSERT( srect->y + srect->h <= state->source->config.size.h ); + D_ASSERT( drect->x + drect->w <= state->clip.x2 + 1 ); + D_ASSERT( drect->y + drect->h <= state->clip.y2 + 1 ); + + + if (!ABacc_prepare( gfxs, MAX( srect->w, drect->w ) )) + return; + + + switch (gfxs->src_format) { + case DSPF_A4: + case DSPF_YUY2: + case DSPF_UYVY: + srect->x &= ~1; + break; + default: + break; + } + + switch (gfxs->dst_format) { + case DSPF_A4: + case DSPF_YUY2: + case DSPF_UYVY: + drect->x &= ~1; + break; + default: + break; + } + + gfxs->Slen = srect->w; + gfxs->Dlen = drect->w; + gfxs->length = gfxs->Dlen; + gfxs->SperD = fx; + gfxs->Xphase = ix; + + h = drect->h; + + Aop_xy( gfxs, drect->x, drect->y ); + Bop_xy( gfxs, srect->x, srect->y ); + + while (h--) { + RUN_PIPELINE(); + + Aop_next( gfxs ); + + iy += fy; + + while (iy > 0xFFFF) { + iy -= 0x10000; + Bop_next( gfxs ); + } + } + + ABacc_flush( gfxs ); +} + + +#ifdef USE_MMX + +#include "generic_mmx.h" + +/* + * patches function pointers to MMX functions + */ +static void gInit_MMX( void ) +{ + use_mmx = 1; + +/********************************* Sop_PFI_Sto_Dacc ***************************/ +// Sop_PFI_Sto_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Sop_argb_Sto_Dacc_MMX; +/********************************* Sop_PFI_to_Dacc ****************************/ +// Sop_PFI_to_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = Sop_rgb16_to_Dacc_MMX; +// Sop_PFI_to_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Sop_rgb32_to_Dacc_MMX; +// Sop_PFI_to_Dacc[DFB_PIXELFORMAT_INDEX(DSPF_ARGB )] = Sop_argb_to_Dacc_MMX; +/********************************* Sacc_to_Aop_PFI ****************************/ +// Sacc_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB16)] = Sacc_to_Aop_rgb16_MMX; +// Sacc_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Sacc_to_Aop_rgb32_MMX; +/********************************* Xacc_blend *********************************/ + Xacc_blend[DSBF_SRCALPHA-1] = Xacc_blend_srcalpha_MMX; + Xacc_blend[DSBF_INVSRCALPHA-1] = Xacc_blend_invsrcalpha_MMX; +/********************************* Dacc_modulation ****************************/ + Dacc_modulation[DSBLIT_BLEND_ALPHACHANNEL | + DSBLIT_BLEND_COLORALPHA | + DSBLIT_COLORIZE] = Dacc_modulate_argb_MMX; +/********************************* misc accumulator operations ****************/ + SCacc_add_to_Dacc = SCacc_add_to_Dacc_MMX; + Sacc_add_to_Dacc = Sacc_add_to_Dacc_MMX; + Dacc_YCbCr_to_RGB = Dacc_YCbCr_to_RGB_MMX; + Dacc_RGB_to_YCbCr = Dacc_RGB_to_YCbCr_MMX; +} + +#endif + + +#if SIZEOF_LONG == 8 + +#include "generic_64.h" + +/* + * patches function pointers to 64bit functions + */ +static void gInit_64bit( void ) +{ +/********************************* Cop_to_Aop_PFI ********************************/ + Cop_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Cop_to_Aop_32_64; + Cop_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Cop_to_Aop_32_64; + Cop_to_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Cop_to_Aop_32_64; +/********************************* Bop_PFI_Kto_Aop_PFI ***************************/ + Bop_PFI_Kto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Bop_rgb32_Kto_Aop_64; + Bop_PFI_Kto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Bop_rgb32_Kto_Aop_64; + Bop_PFI_Kto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Bop_rgb32_Kto_Aop_64; +/********************************* Bop_PFI_tKo_Aop_PFI ***************************/ + Bop_PFI_toK_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Bop_rgb32_toK_Aop_64; + Bop_PFI_toK_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Bop_rgb32_toK_Aop_64; + Bop_PFI_toK_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Bop_rgb32_toK_Aop_64; +/********************************* Bop_PFI_Sto_Aop_PFI ***************************/ + Bop_PFI_Sto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_RGB32)] = Bop_32_Sto_Aop_64; + Bop_PFI_Sto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_ARGB)] = Bop_32_Sto_Aop_64; + Bop_PFI_Sto_Aop_PFI[DFB_PIXELFORMAT_INDEX(DSPF_AiRGB)] = Bop_32_Sto_Aop_64; +/********************************* misc accumulator operations *******************/ + Dacc_xor = Dacc_xor_64; +} + +#endif -- cgit