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