summaryrefslogtreecommitdiff
path: root/Source/DirectFB/src/gfx/generic/generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/src/gfx/generic/generic.c')
-rwxr-xr-xSource/DirectFB/src/gfx/generic/generic.c9161
1 files changed, 9161 insertions, 0 deletions
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 <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ 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 <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <dfb_types.h>
+
+#include <pthread.h>
+
+#include <directfb.h>
+
+#include <core/core.h>
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/gfxcard.h>
+#include <core/state.h>
+#include <core/palette.h>
+
+#include <misc/gfx_util.h>
+#include <misc/util.h>
+#include <misc/conf.h>
+
+#include <direct/clock.h>
+#include <direct/mem.h>
+#include <direct/memcpy.h>
+#include <direct/messages.h>
+#include <direct/util.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#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; i<gfxs->length; 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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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<w; i++) {
+ if (S[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; i<W; i++, D+=4, w-=4) {
+ u8 index;
+ u8 pixels = S[i];
+
+ switch (w) {
+ default:
+ index = (pixels & 3);
+ if (index < gfxs->num_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; i<w; i++) {
+ if (!(Y[i].RGB.a & 0xF000))
+ X[i].RGB.a = X[i].RGB.r = X[i].RGB.g = X[i].RGB.b = 0;
+ else
+ X[i] = Y[i];
+ }
+}
+
+static void Xacc_blend_one( GenefxState *gfxs )
+{
+ int i;
+ int w = gfxs->length;
+ GenefxAccumulator *X = gfxs->Xacc;
+ GenefxAccumulator *Y = gfxs->Yacc;
+
+ for (i=0; i<w; i++) {
+ X[i] = Y[i];
+ }
+}
+
+static void Xacc_blend_srccolor( 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 = ((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; i<dxabs; i++, gfxs->length++) {
+ 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; i++) {
+ x += dxabs;
+ if (x >= 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; x<rect->w; 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; x<rect->w; 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; x<rect->w; 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; i<gfxs->Blut->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; i<gfxs->Blut->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; i<gfxs->Blut->num_entries; i++)
+ colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b );
+ break;
+
+ case DSPF_RGB16:
+ for (i=0; i<gfxs->Blut->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; i<gfxs->Blut->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; i<gfxs->Blut->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; i<gfxs->Blut->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; i<gfxs->Blut->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; i<gfxs->Blut->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