From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/mach64/mach64_overlay.c | 724 +++++++++++++++++++++ 1 file changed, 724 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/mach64/mach64_overlay.c (limited to 'Source/DirectFB/gfxdrivers/mach64/mach64_overlay.c') diff --git a/Source/DirectFB/gfxdrivers/mach64/mach64_overlay.c b/Source/DirectFB/gfxdrivers/mach64/mach64_overlay.c new file mode 100755 index 0000000..11cff28 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/mach64/mach64_overlay.c @@ -0,0 +1,724 @@ +/* + (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 "regs.h" +#include "mmio.h" +#include "mach64.h" + +typedef struct { + CoreLayerRegionConfig config; + bool visible; + + /* overlay registers */ + struct { + u32 overlay_Y_X_START; + u32 overlay_Y_X_END; + u32 overlay_GRAPHICS_KEY_CLR; + u32 overlay_GRAPHICS_KEY_MSK; + u32 overlay_VIDEO_KEY_CLR; + u32 overlay_VIDEO_KEY_MSK; + u32 overlay_KEY_CNTL; + u32 overlay_SCALE_INC; + u32 overlay_SCALE_CNTL; + u32 scaler_HEIGHT_WIDTH; + u32 scaler_BUF_PITCH; + u32 scaler_BUF0_OFFSET; + u32 scaler_BUF1_OFFSET; + u32 scaler_BUF0_OFFSET_U; + u32 scaler_BUF0_OFFSET_V; + u32 scaler_BUF1_OFFSET_U; + u32 scaler_BUF1_OFFSET_V; + u32 video_FORMAT; + u32 capture_CONFIG; + } regs; +} Mach64OverlayLayerData; + +static void ov_reset( Mach64DriverData *mdrv ); +static void ov_set_regs( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov ); +static void ov_calc_regs( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config, CoreSurface *surface, + CoreSurfaceBufferLock *lock ); +static void ov_set_buffer( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov ); +static void ov_calc_buffer( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config, CoreSurface *surface, + CoreSurfaceBufferLock *lock ); +static void ov_set_colorkey( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov ); +static void ov_calc_colorkey( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config ); +static void ov_set_opacity( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov ); +static void ov_calc_opacity( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config ); +static void ov_set_field( Mach64DriverData *mdrv, Mach64OverlayLayerData *mov ); + +#define OV_SUPPORTED_OPTIONS (DLOP_SRC_COLORKEY | DLOP_DST_COLORKEY | DLOP_DEINTERLACING) + +/**********************/ + +static int +ovLayerDataSize( void ) +{ + return sizeof(Mach64OverlayLayerData); +} + +static DFBResult +ovInitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64DeviceData *mdev = mdrv->device_data; + + /* set capabilities and type */ + description->caps = DLCAPS_SCREEN_LOCATION | DLCAPS_SURFACE | + DLCAPS_DST_COLORKEY | DLCAPS_DEINTERLACING; + + if (mdev->chip >= CHIP_264VT3) + description->caps |= DLCAPS_SRC_COLORKEY; + + description->type = DLTF_VIDEO | DLTF_STILL_PICTURE; + + /* set name */ + snprintf( description->name, + DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Mach64 Overlay" ); + + /* fill out the default configuration */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | + DLCONF_OPTIONS; + config->width = (mdev->chip >= CHIP_264VT3) ? 640 : 320; + config->height = (mdev->chip >= CHIP_264VT3) ? 480 : 240; + config->pixelformat = DSPF_YUY2; + config->buffermode = DLBM_FRONTONLY; + config->options = DLOP_NONE; + + adjustment->flags = DCAF_NONE; + + if (mdev->chip >= CHIP_3D_RAGE_PRO) { + description->caps |= DLCAPS_BRIGHTNESS | DLCAPS_SATURATION; + + /* fill out default color adjustment, + only fields set in flags will be accepted from applications */ + adjustment->flags |= DCAF_BRIGHTNESS | DCAF_SATURATION; + adjustment->brightness = 0x8000; + adjustment->saturation = 0x8000; + } + + return DFB_OK; +} + +static DFBResult +ovTestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64DeviceData *mdev = mdrv->device_data; + CoreLayerRegionConfigFlags fail = 0; + int max_width, max_height = 1024; + + switch (mdev->chip) { + case CHIP_264VT: /* 264VT2 verified */ + case CHIP_3D_RAGE: /* not verified */ + max_width = 384; + break; + case CHIP_264VT3: /* not verified */ + case CHIP_3D_RAGE_II: /* not verified */ + case CHIP_3D_RAGE_IIPLUS: + case CHIP_264VT4: /* not verified */ + case CHIP_3D_RAGE_IIC: + case CHIP_3D_RAGE_XLXC: + case CHIP_3D_RAGE_MOBILITY: + max_width = 720; + break; + case CHIP_3D_RAGE_PRO: /* not verified */ + case CHIP_3D_RAGE_LT_PRO: + max_width = 768; + break; + default: + D_BUG( "unknown chip" ); + return DFB_UNSUPPORTED; + } + + if (config->options & DLOP_DEINTERLACING) + max_height = 2048; + + /* check for unsupported options */ + if (config->options & ~OV_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + /* + * Video keying doesn't work the same way on 264VT2 as it does + * on later chips. If enabled the overlay goes completely black + * so clearly it does something but not what we want. + */ + if (mdev->chip < CHIP_264VT3 && config->options & DLOP_SRC_COLORKEY) + fail |= CLRCF_OPTIONS; + + /* check pixel format */ + switch (config->format) { + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_YUY2: + case DSPF_UYVY: + break; + case DSPF_I420: + case DSPF_YV12: + if (mdev->chip >= CHIP_3D_RAGE_PRO) + break; + default: + fail |= CLRCF_FORMAT; + } + + switch (config->format) { + case DSPF_I420: + case DSPF_YV12: + if (config->height & 1) + fail |= CLRCF_HEIGHT; + case DSPF_YUY2: + case DSPF_UYVY: + if (config->width & 1) + fail |= CLRCF_WIDTH; + default: + break; + } + + /* check width */ + if (config->width > max_width || config->width < 1) + fail |= CLRCF_WIDTH; + + /* check height */ + if (config->height > max_height || config->height < 1) + fail |= CLRCF_HEIGHT; + + /* write back failing fields */ + if (failed) + *failed = fail; + + /* return failure if any field failed */ + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +ovSetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64OverlayLayerData *mov = (Mach64OverlayLayerData*) layer_data; + + /* remember configuration */ + mov->config = *config; + + if (updated == CLRCF_ALL) + ov_reset( mdrv ); + + if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT | CLRCF_SOURCE | CLRCF_DEST | CLRCF_OPTIONS)) { + ov_calc_buffer( mdrv, mov, config, surface, lock ); + ov_calc_regs( mdrv, mov, config, surface, lock ); + ov_set_buffer( mdrv, mov ); + ov_set_regs( mdrv, mov ); + } + + if (updated & (CLRCF_OPTIONS | CLRCF_SRCKEY | CLRCF_DSTKEY)) { + ov_calc_colorkey( mdrv, mov, config ); + ov_set_colorkey( mdrv, mov ); + } + + if (updated & CLRCF_OPTIONS) + ov_set_field( mdrv, mov ); + + if (updated & (CLRCF_DEST | CLRCF_OPACITY)) { + ov_calc_opacity( mdrv, mov, config ); + ov_set_opacity( mdrv, mov ); + } + + return DFB_OK; +} + +static DFBResult +ovRemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + mach64_waitfifo( mdrv, mdev, 2 ); + + /* + * On 264VT2 the keyer sometimes remains active + * even after the overlay has been disabled. + */ + mach64_out32( mmio, OVERLAY_KEY_CNTL, + VIDEO_KEY_FN_FALSE | GRAPHICS_KEY_FN_FALSE | OVERLAY_CMP_MIX_OR ); + + mach64_out32( mmio, OVERLAY_SCALE_CNTL, 0 ); + + return DFB_OK; +} + +static DFBResult +ovFlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64OverlayLayerData *mov = (Mach64OverlayLayerData*) layer_data; + + ov_calc_buffer( mdrv, mov, &mov->config, surface, lock ); + ov_set_buffer( mdrv, mov ); + + dfb_surface_flip( surface, false ); + + return DFB_OK; +} + +static DFBResult +ovSetColorAdjustment( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBColorAdjustment *adj ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + if (mdev->chip < CHIP_3D_RAGE_PRO) + return DFB_UNSUPPORTED; + + mach64_waitfifo( mdrv, mdev, 1 ); + + mach64_out32( mmio, SCALER_COLOUR_CNTL, + (((adj->brightness >> 9) - 64) & 0x0000007F) | + ((adj->saturation >> 3) & 0x00001F00) | + ((adj->saturation << 5) & 0x001F0000) ); + + return DFB_OK; +} + +static DFBResult +ovSetInputField( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + int field ) +{ + Mach64DriverData *mdrv = (Mach64DriverData*) driver_data; + Mach64OverlayLayerData *mov = (Mach64OverlayLayerData*) layer_data; + + mov->regs.capture_CONFIG = OVL_BUF_MODE_SINGLE | (field ? OVL_BUF_NEXT_BUF1 : OVL_BUF_NEXT_BUF0); + + ov_set_field( mdrv, mov ); + + return DFB_OK; +} + +DisplayLayerFuncs mach64OverlayFuncs = { + .LayerDataSize = ovLayerDataSize, + .InitLayer = ovInitLayer, + + .TestRegion = ovTestRegion, + .SetRegion = ovSetRegion, + .RemoveRegion = ovRemoveRegion, + .FlipRegion = ovFlipRegion, + .SetColorAdjustment = ovSetColorAdjustment, + .SetInputField = ovSetInputField, +}; + +/* internal */ + +static void ov_reset( Mach64DriverData *mdrv ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + if (mdev->chip >= CHIP_3D_RAGE_PRO) { + mach64_waitfifo( mdrv, mdev, 6 ); + + mach64_out32( mmio, SCALER_H_COEFF0, 0x00002000 ); + mach64_out32( mmio, SCALER_H_COEFF1, 0x0D06200D ); + mach64_out32( mmio, SCALER_H_COEFF2, 0x0D0A1C0D ); + mach64_out32( mmio, SCALER_H_COEFF3, 0x0C0E1A0C ); + mach64_out32( mmio, SCALER_H_COEFF4, 0x0C14140C ); + mach64_out32( mmio, SCALER_COLOUR_CNTL, 0x00101000 ); + } + + if (mdev->chip >= CHIP_264VT3) { + mach64_waitfifo( mdrv, mdev, 2 ); + + mach64_out32( mmio, OVERLAY_EXCLUSIVE_HORZ, 0 ); + mach64_out32( mmio, OVERLAY_EXCLUSIVE_VERT, 0 ); + } + + mach64_waitfifo( mdrv, mdev, 2 ); + + mach64_out32( mmio, OVERLAY_SCALE_CNTL, 0 ); + mach64_out32( mmio, SCALER_TEST, 0 ); +} + +static void ov_set_regs( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + mach64_waitfifo( mdrv, mdev, (mdev->chip >= CHIP_264VT3) ? 6 : 7 ); + + mach64_out32( mmio, VIDEO_FORMAT, mov->regs.video_FORMAT ); + mach64_out32( mmio, OVERLAY_Y_X_START, mov->regs.overlay_Y_X_START ); + mach64_out32( mmio, OVERLAY_Y_X_END, mov->regs.overlay_Y_X_END ); + mach64_out32( mmio, OVERLAY_SCALE_INC, mov->regs.overlay_SCALE_INC ); + mach64_out32( mmio, SCALER_HEIGHT_WIDTH, mov->regs.scaler_HEIGHT_WIDTH ); + + if (mdev->chip >= CHIP_264VT3) { + mach64_out32( mmio, SCALER_BUF_PITCH, mov->regs.scaler_BUF_PITCH ); + } else { + mach64_out32( mmio, BUF0_PITCH, mov->regs.scaler_BUF_PITCH ); + mach64_out32( mmio, BUF1_PITCH, mov->regs.scaler_BUF_PITCH ); + } +} + +static void ov_set_buffer( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + mach64_waitfifo( mdrv, mdev, (mdev->chip >= CHIP_3D_RAGE_PRO) ? 6 : 2 ); + + if (mdev->chip >= CHIP_264VT3) { + mach64_out32( mmio, SCALER_BUF0_OFFSET, mov->regs.scaler_BUF0_OFFSET ); + mach64_out32( mmio, SCALER_BUF1_OFFSET, mov->regs.scaler_BUF1_OFFSET ); + } else { + mach64_out32( mmio, BUF0_OFFSET, mov->regs.scaler_BUF0_OFFSET ); + mach64_out32( mmio, BUF1_OFFSET, mov->regs.scaler_BUF1_OFFSET ); + } + + if (mdev->chip >= CHIP_3D_RAGE_PRO) { + mach64_out32( mmio, SCALER_BUF0_OFFSET_U, mov->regs.scaler_BUF0_OFFSET_U ); + mach64_out32( mmio, SCALER_BUF0_OFFSET_V, mov->regs.scaler_BUF0_OFFSET_V ); + mach64_out32( mmio, SCALER_BUF1_OFFSET_U, mov->regs.scaler_BUF1_OFFSET_U ); + mach64_out32( mmio, SCALER_BUF1_OFFSET_V, mov->regs.scaler_BUF1_OFFSET_V ); + } +} + +static void ov_set_colorkey( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + mach64_waitfifo( mdrv, mdev, 5 ); + + mach64_out32( mmio, OVERLAY_GRAPHICS_KEY_CLR, mov->regs.overlay_GRAPHICS_KEY_CLR ); + mach64_out32( mmio, OVERLAY_GRAPHICS_KEY_MSK, mov->regs.overlay_GRAPHICS_KEY_MSK ); + mach64_out32( mmio, OVERLAY_VIDEO_KEY_CLR, mov->regs.overlay_VIDEO_KEY_CLR ); + mach64_out32( mmio, OVERLAY_VIDEO_KEY_MSK, mov->regs.overlay_VIDEO_KEY_MSK ); + mach64_out32( mmio, OVERLAY_KEY_CNTL, mov->regs.overlay_KEY_CNTL ); +} + +static void ov_set_opacity( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + mach64_waitfifo( mdrv, mdev, 1 ); + + mach64_out32( mmio, OVERLAY_SCALE_CNTL, mov->regs.overlay_SCALE_CNTL ); +} + +static void ov_set_field( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + + mach64_waitfifo( mdrv, mdev, 1 ); + + mach64_out32( mmio, CAPTURE_CONFIG, mov->regs.capture_CONFIG ); +} + +static void ov_calc_regs( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ) +{ + Mach64DeviceData *mdev = mdrv->device_data; + volatile u8 *mmio = mdrv->mmio_base; + VideoMode *mode = dfb_system_current_mode(); + int yres = mode->yres; + unsigned int pitch = lock->pitch / DFB_BYTES_PER_PIXEL( surface->config.format ); + DFBRectangle source = config->source; + DFBRectangle dest = config->dest; + + DFBRegion dst; + int h_inc, v_inc; + u32 lcd_gen_ctrl, vert_stretching; + u8 ecp_div; + + if (mode->doubled) { + dest.y *= 2; + dest.h *= 2; + yres *= 2; + } + + if (config->options & DLOP_DEINTERLACING) { + source.y /= 2; + source.h /= 2; + pitch *= 2; + } else + mov->regs.capture_CONFIG = OVL_BUF_MODE_SINGLE | OVL_BUF_NEXT_BUF0; + + dst.x1 = dest.x; + dst.y1 = dest.y; + dst.x2 = dest.x + dest.w - 1; + dst.y2 = dest.y + dest.h - 1; + + mov->visible = dfb_region_intersect( &dst, 0, 0, mode->xres - 1, yres - 1 ); + + if (mode->laced) { + dest.y /= 2; + dest.h /= 2; + } + + ecp_div = (mach64_in_pll( mmio, PLL_VCLK_CNTL ) & ECP_DIV) >> 4; + h_inc = (source.w << (12 + ecp_div)) / dest.w; + + lcd_gen_ctrl = mach64_in_lcd( mdev, mmio, LCD_GEN_CTRL ); + vert_stretching = mach64_in_lcd( mdev, mmio, VERT_STRETCHING ); + if ((lcd_gen_ctrl & LCD_ON) && (vert_stretching & VERT_STRETCH_EN)) + v_inc = (source.h << 2) * (vert_stretching & VERT_STRETCH_RATIO0) / dest.h; + else + v_inc = (source.h << 12) / dest.h; + + switch (surface->config.format) { + case DSPF_RGB555: + case DSPF_ARGB1555: + mov->regs.video_FORMAT = SCALER_IN_RGB15; + break; + case DSPF_RGB16: + mov->regs.video_FORMAT = SCALER_IN_RGB16; + break; + case DSPF_RGB32: + mov->regs.video_FORMAT = SCALER_IN_RGB32; + break; + case DSPF_UYVY: + mov->regs.video_FORMAT = SCALER_IN_YVYU422; + break; + case DSPF_YUY2: + mov->regs.video_FORMAT = SCALER_IN_VYUY422; + break; + case DSPF_I420: + case DSPF_YV12: + mov->regs.video_FORMAT = SCALER_IN_YUV12; + break; + default: + D_BUG( "unexpected pixelformat" ); + } + + mov->regs.scaler_HEIGHT_WIDTH = (source.w << 16) | source.h; + mov->regs.scaler_BUF_PITCH = pitch; + + mov->regs.overlay_Y_X_START = (dst.x1 << 16) | dst.y1 | OVERLAY_LOCK_START; + mov->regs.overlay_Y_X_END = (dst.x2 << 16) | dst.y2; + mov->regs.overlay_SCALE_INC = (h_inc << 16) | v_inc; +} + +static void ov_calc_buffer( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ) +{ + unsigned int pitch = lock->pitch; + DFBRectangle source = config->source; + + u32 offset, offset_u, offset_v; + int cropleft, croptop; + + if (config->options & DLOP_DEINTERLACING) { + source.y /= 2; + source.h /= 2; + pitch *= 2; + } + + /* Source cropping */ + cropleft = source.x; + croptop = source.y; + + /* Add destination cropping */ + if (config->dest.x < 0) + cropleft += -config->dest.x * source.w / config->dest.w; + if (config->dest.y < 0) + croptop += -config->dest.y * source.h / config->dest.h; + + switch (surface->config.format) { + case DSPF_I420: + cropleft &= ~15; + croptop &= ~1; + + offset_u = lock->offset + surface->config.size.h * lock->pitch; + offset_v = offset_u + surface->config.size.h/2 * lock->pitch/2; + offset_u += croptop/2 * pitch/2 + cropleft/2; + offset_v += croptop/2 * pitch/2 + cropleft/2; + break; + + case DSPF_YV12: + cropleft &= ~15; + croptop &= ~1; + + offset_v = lock->offset + surface->config.size.h * lock->pitch; + offset_u = offset_v + surface->config.size.h/2 * lock->pitch/2; + offset_v += croptop/2 * pitch/2 + cropleft/2; + offset_u += croptop/2 * pitch/2 + cropleft/2; + break; + + default: + offset_u = 0; + offset_v = 0; + break; + } + + offset = lock->offset; + offset += croptop * pitch + cropleft * DFB_BYTES_PER_PIXEL( surface->config.format ); + + mov->regs.scaler_BUF0_OFFSET = offset; + mov->regs.scaler_BUF0_OFFSET_U = offset_u; + mov->regs.scaler_BUF0_OFFSET_V = offset_v; + + mov->regs.scaler_BUF1_OFFSET = offset + lock->pitch; + mov->regs.scaler_BUF1_OFFSET_U = offset_u + lock->pitch/2; + mov->regs.scaler_BUF1_OFFSET_V = offset_v + lock->pitch/2; +} + +static u32 ovColorKey[] = { + VIDEO_KEY_FN_TRUE | GRAPHICS_KEY_FN_TRUE | OVERLAY_CMP_MIX_OR, /* 0 */ + VIDEO_KEY_FN_NOT_EQUAL | GRAPHICS_KEY_FN_FALSE | OVERLAY_CMP_MIX_OR, /* DLOP_SRC_COLORKEY */ + VIDEO_KEY_FN_FALSE | GRAPHICS_KEY_FN_EQUAL | OVERLAY_CMP_MIX_OR, /* DLOP_DST_COLORKEY */ + VIDEO_KEY_FN_NOT_EQUAL | GRAPHICS_KEY_FN_EQUAL | OVERLAY_CMP_MIX_AND /* DLOP_SRC_COLORKEY | + DLOP_DST_COLORKEY */ +}; + +static void ov_calc_colorkey( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config ) +{ + DFBSurfacePixelFormat primary_format = dfb_primary_layer_pixelformat(); + + /* Video key is always RGB24 */ + mov->regs.overlay_VIDEO_KEY_CLR = PIXEL_RGB32( config->src_key.r, + config->src_key.g, + config->src_key.b ); + + /* The same mask is used for all three components */ + mov->regs.overlay_VIDEO_KEY_MSK = 0xFF; + + switch (primary_format) { + case DSPF_RGB332: + mov->regs.overlay_GRAPHICS_KEY_CLR = PIXEL_RGB332( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ); + break; + case DSPF_RGB555: + mov->regs.overlay_GRAPHICS_KEY_CLR = PIXEL_RGB555( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ); + break; + case DSPF_ARGB1555: + mov->regs.overlay_GRAPHICS_KEY_CLR = PIXEL_RGB555( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ); + break; + case DSPF_RGB16: + mov->regs.overlay_GRAPHICS_KEY_CLR = PIXEL_RGB16( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ); + break; + case DSPF_ARGB: + case DSPF_RGB32: + mov->regs.overlay_GRAPHICS_KEY_CLR = PIXEL_RGB32( config->dst_key.r, + config->dst_key.g, + config->dst_key.b ); + break; + default: + D_BUG( "unexpected pixelformat" ); + } + + mov->regs.overlay_GRAPHICS_KEY_MSK = (1 << DFB_COLOR_BITS_PER_PIXEL( primary_format )) - 1; + + mov->regs.overlay_KEY_CNTL = ovColorKey[(config->options >> 3) & 3]; +} + +static void ov_calc_opacity( Mach64DriverData *mdrv, + Mach64OverlayLayerData *mov, + CoreLayerRegionConfig *config ) +{ + mov->regs.overlay_SCALE_CNTL = SCALE_PIX_EXPAND | SCALE_Y2R_TEMP; + + if (config->opacity && mov->visible) + mov->regs.overlay_SCALE_CNTL |= OVERLAY_EN | SCALE_EN; +} -- cgit