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/davinci/davinci_osd.c | 681 +++++++++++++++++++++++ 1 file changed, 681 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/davinci/davinci_osd.c (limited to 'Source/DirectFB/gfxdrivers/davinci/davinci_osd.c') diff --git a/Source/DirectFB/gfxdrivers/davinci/davinci_osd.c b/Source/DirectFB/gfxdrivers/davinci/davinci_osd.c new file mode 100755 index 0000000..2effb2e --- /dev/null +++ b/Source/DirectFB/gfxdrivers/davinci/davinci_osd.c @@ -0,0 +1,681 @@ +/* + TI Davinci driver - Graphics Layer + + (c) Copyright 2007 Telio AG + + Written by Denis Oliver Kropp + + Code is derived from VMWare driver. + + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + 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. +*/ + +//#define DIRECT_ENABLE_DEBUG + +#include + +#include + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include "davincifb.h" + +#include "davinci_gfxdriver.h" +#include "davinci_osd.h" + + +#define D_OSDERROR(x...) do {} while (0) + + +D_DEBUG_DOMAIN( Davinci_OSD, "Davinci/OSD", "TI Davinci OSD" ); + +/**********************************************************************************************************************/ + +static int +osdLayerDataSize( void ) +{ + return sizeof(DavinciOSDLayerData); +} + +static DFBResult +osdInitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + int ret; + DavinciDriverData *ddrv = driver_data; + DavinciOSDLayerData *dosd = layer_data; + + D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ ); + + ret = ioctl( ddrv->fb[OSD0].fd, FBIOGET_VSCREENINFO, &dosd->var0 ); + if (ret) { + D_PERROR( "Davinci/OSD: FBIOGET_VSCREENINFO (fb%d) failed!\n", OSD0 ); + return DFB_INIT; + } + + ret = ioctl( ddrv->fb[OSD1].fd, FBIOGET_VSCREENINFO, &dosd->var1 ); + if (ret) { + D_PERROR( "Davinci/OSD: FBIOGET_VSCREENINFO (fb%d) failed!\n", OSD1 ); + return DFB_INIT; + } + + ret = ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 0 ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 0 ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, 0 ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, 0 ); + + /* set capabilities and type */ + description->caps = DLCAPS_SURFACE | DLCAPS_ALPHACHANNEL | DLCAPS_OPACITY | DLCAPS_SCREEN_POSITION | + DLCAPS_SRC_COLORKEY; + description->type = DLTF_GRAPHICS; + + /* set name */ + snprintf( description->name, DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "TI Davinci OSD" ); + + /* fill out the default configuration */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | DLCONF_OPTIONS; + config->width = 640; + config->height = 480; + config->pixelformat = DSPF_RGB16; + config->buffermode = DLBM_FRONTONLY; + config->options = DLOP_ALPHACHANNEL; + + return DFB_OK; +} + +static DFBResult +osdTestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + CoreLayerRegionConfigFlags fail = 0; + + D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ ); + + if (config->options & ~DAVINCI_OSD_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + switch (config->format) { + case DSPF_RGB444: + case DSPF_RGB555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB4444: + case DSPF_ARGB1555: + case DSPF_ARGB: + break; + + default: + fail |= CLRCF_FORMAT; + } + + if (config->width < 8 || config->width > 1920) + fail |= CLRCF_WIDTH; + + if (config->height < 8 || config->height > 1080) + fail |= CLRCF_HEIGHT; + + if (config->dest.x < 0 || config->dest.y < 0) + fail |= CLRCF_DEST; + + if (config->dest.x + config->dest.w > 1920) + fail |= CLRCF_DEST; + + if (config->dest.y + config->dest.h > 1080) + fail |= CLRCF_DEST; + + if (failed) + *failed = fail; + + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +osdSetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + int ret; + DavinciDriverData *ddrv = driver_data; + DavinciDeviceData *ddev = ddrv->ddev; + DavinciOSDLayerData *dosd = layer_data; + + D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ ); + + D_ASSERT( ddrv != NULL ); + D_ASSERT( ddev != NULL ); + D_ASSERT( dosd != NULL ); + + ret = ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 0 ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 0 ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, 0 ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, 0 ); + + ioctl( ddrv->fb[OSD0].fd, FBIO_WAITFORVSYNC ); + + /* Update blend parameters? */ + if (updated & (CLRCF_OPTIONS | CLRCF_OPACITY | CLRCF_SRCKEY | CLRCF_FORMAT)) { + vpbe_blink_option_t blink = {0}; + vpbe_bitmap_blend_params_t blend = {0}; + + D_DEBUG_AT( Davinci_OSD, " -> %s\n", dfb_pixelformat_name( config->format ) ); + + if (config->options & DLOP_SRC_COLORKEY) { + blend.enable_colorkeying = 1; + blend.colorkey = dfb_color_to_pixel( DSPF_RGB16, + config->src_key.r, + config->src_key.g, + config->src_key.b ); + + D_DEBUG_AT( Davinci_OSD, " -> color key 0x%02x (%02x %02x %02x)\n", + blend.colorkey, config->src_key.r, config->src_key.g, config->src_key.b ); + } + else if (config->options & DLOP_OPACITY) { + blend.bf = config->opacity >> 5; + + D_DEBUG_AT( Davinci_OSD, " -> opacity %d/7\n", blend.bf ); + } + else + blend.bf = 7; + + ret = ioctl( ddrv->fb[OSD0].fd, FBIO_SET_BITMAP_BLEND_FACTOR, &blend ); + if (ret) + D_PERROR( "Davinci/OSD: FBIO_SET_BITMAP_BLEND_FACTOR (fb%d)!\n", OSD0 ); + + if (config->options & DLOP_ALPHACHANNEL) + dosd->alpha = DFB_PIXELFORMAT_HAS_ALPHA( config->format ); + else + dosd->alpha = 0; + + D_DEBUG_AT( Davinci_OSD, " -> %salpha channel\n", dosd->alpha ? "" : "no " ); + + if (dosd->alpha) { + if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN, dosd->alpha )) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN (fb%d - %d)!\n", OSD0, dosd->alpha ); + } + + if (ioctl( ddrv->fb[OSD1].fd, FBIO_SET_BLINK_INTERVAL, &blink )) + D_OSDERROR( "Davinci/OSD: FBIO_SET_BLINK_INTERVAL (fb%d - disable)!\n", OSD1 ); + } + + /* Update size? */ + if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_BUFFERMODE)) { + vpbe_window_position_t win_pos; + + D_DEBUG_AT( Davinci_OSD, " -> %dx%d\n", config->width, config->height ); + +/*********************************** Start workaround ***********************************/ + win_pos.xpos = 0; + win_pos.ypos = 0; + + ret = ioctl( ddrv->fb[OSD0].fd, FBIO_SETPOS, &win_pos ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD0, win_pos.xpos, win_pos.ypos ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIO_SETPOS, &win_pos ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD1, win_pos.xpos, win_pos.ypos ); + + updated |= CLRCF_DEST; + + dosd->var0.yoffset = dosd->var1.yoffset = 0; +/*********************************** End workaround ***********************************/ + + /* Set width and height. */ + dosd->var0.xres = config->width; + dosd->var0.yres = config->height; + dosd->var1.xres = config->width; + dosd->var1.yres = config->height; + + dosd->var0.yres_virtual = ddrv->fb[OSD0].size / ddev->fix[OSD0].line_length; + + ret = ioctl( ddrv->fb[OSD0].fd, FBIOPUT_VSCREENINFO, &dosd->var0 ); + if (ret) + D_PERROR( "Davinci/OSD: FBIOPUT_VSCREENINFO (fb%d) failed!\n", OSD0 ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIOPUT_VSCREENINFO, &dosd->var1 ); + if (ret) + D_PERROR( "Davinci/OSD: FBIOPUT_VSCREENINFO (fb%d) failed!\n", OSD1 ); + } + + /* Update position? */ + if (updated & CLRCF_DEST) { + vpbe_window_position_t win_pos; + + D_DEBUG_AT( Davinci_OSD, " -> %d, %d\n", config->dest.x, config->dest.y ); + + /* Set horizontal and vertical offset. */ + win_pos.xpos = config->dest.x; + win_pos.ypos = config->dest.y; + + ret = ioctl( ddrv->fb[OSD0].fd, FBIO_SETPOS, &win_pos ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD0, config->dest.x, config->dest.y ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIO_SETPOS, &win_pos ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_SETPOS (fb%d - %d,%d) failed!\n", OSD1, config->dest.x, config->dest.y ); + } + + davincifb_pan_display( &ddrv->fb[OSD0], &dosd->var0, + (config->format == DSPF_RGB16) ? lock : NULL, DSFLIP_NONE, 0, 0 ); + + ret = ioctl( ddrv->fb[OSD0].fd, FBIOGET_FSCREENINFO, &ddev->fix[OSD0] ); + if (ret) + D_PERROR( "Davinci/OSD: FBIOGET_FSCREENINFO (fb%d) failed!\n", OSD0 ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIOGET_FSCREENINFO, &ddev->fix[OSD1] ); + if (ret) + D_PERROR( "Davinci/OSD: FBIOGET_FSCREENINFO (fb%d) failed!\n", OSD1 ); + + dosd->enable = true; + + if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN, 0 )) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN (fb%d - %d)!\n", OSD0, 0 ); + + return DFB_OK; +} + +static DFBResult +osdRemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + int ret; + DavinciDriverData *ddrv = driver_data; + DavinciOSDLayerData *dosd = layer_data; + + D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ ); + + D_ASSERT( ddrv != NULL ); + + ret = ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 0 ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 0 ); + + ret = ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, 0 ); + if (ret) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, 0 ); + + dosd->enable = false; + + return DFB_OK; +} + +static void +update_buffers( DavinciDriverData *ddrv, + DavinciDeviceData *ddev, + CoreSurface *surface, + CoreSurfaceBufferLock *lock, + const DFBRegion *update ) +{ + DFBRectangle rect; + CoreSurfaceBuffer *buffer; + + D_ASSERT( ddrv != NULL ); + D_ASSERT( ddev != NULL ); + D_ASSERT( surface != NULL ); + D_ASSERT( lock != NULL ); + DFB_REGION_ASSERT_IF( update ); + + buffer = lock->buffer; + D_ASSERT( buffer != NULL ); + + if (update) { + rect = DFB_RECTANGLE_INIT_FROM_REGION( update ); + + if (rect.x & 1) { + rect.x &= ~1; + rect.w++; + } + + if (rect.w & 1) + rect.w++; + } + else { + rect.x = 0; + rect.y = 0; + rect.w = surface->config.size.w; + rect.h = surface->config.size.h; + } + + /* Can we use the DSP? */ + if (ddrv->c64x_present) { + int i; + int lines = ddev->fix[OSD0].line_length == ddev->fix[OSD1].line_length ? rect.h : 1; + unsigned long rgb = ddev->fix[OSD0].smem_start + rect.x * 2 + rect.y * ddev->fix[OSD0].line_length; + unsigned long alpha = ddev->fix[OSD1].smem_start + rect.x / 2 + rect.y * ddev->fix[OSD1].line_length; + unsigned long src = lock->phys + rect.x * 4 + rect.y * lock->pitch; + + //D_ASSUME( ddev->fix[OSD0].line_length == ddev->fix[OSD1].line_length ); + + dfb_gfxcard_lock( GDLF_NONE ); + + /* Dither ARGB to RGB16+A3 using the DSP. */ + for (i=0; i rect.h - i) + lines = rect.h - i; + + davinci_c64x_dither_argb__L( &ddrv->tasks, rgb, alpha, + ddev->fix[OSD0].line_length, src, lock->pitch, rect.w, lines ); + + if (ddev->fix[OSD0].line_length != ddev->fix[OSD1].line_length && lines > 1) { + davinci_c64x_blit_32__L( &ddrv->tasks, + alpha + ddev->fix[OSD1].line_length, ddev->fix[OSD1].line_length, + alpha + ddev->fix[OSD0].line_length, ddev->fix[OSD0].line_length, + rect.w/2, lines - 1 ); + } + + rgb += lines * ddev->fix[OSD0].line_length; + alpha += lines * ddev->fix[OSD1].line_length; + src += lines * lock->pitch; + } + + /* Flush the write cache. */ + davinci_c64x_write_back_all( &ddrv->c64x ); + + + davinci_c64x_emit_tasks( &ddrv->c64x, &ddrv->tasks, C64X_TEF_RESET ); + + + dfb_gfxcard_unlock(); + } + else { + u32 *src32 = lock->addr + rect.y * lock->pitch + DFB_BYTES_PER_LINE( buffer->format, rect.x ); + int sp4 = lock->pitch / 4; + u32 *dst32 = ddrv->fb[OSD0].mem + rect.y * ddev->fix[OSD0].line_length + rect.x * 2; + int dp4 = ddev->fix[OSD0].line_length / 4; + u8 *dst8 = ddrv->fb[OSD1].mem + rect.y * ddev->fix[OSD1].line_length + rect.x / 2; + int dp = ddev->fix[OSD1].line_length; + int w2 = rect.w / 2; + u32 z = 0; + + switch (buffer->format) { + case DSPF_ARGB4444: + while (rect.h--) { + int x; + + for (x=0; x> 1) | + ((src32[x] & 0x000f000f) << 1) | ((src32[x] & 0x00080008) >> 3); + + dst8[x] = ((src32[x] & 0xe0000000) >> 29) | ((src32[x] & 0x0000e000) >> 9); + } + + src32 += sp4; + dst32 += dp4; + dst8 += dp; + } + break; + + case DSPF_ARGB1555: + while (rect.h--) { + int x; + + for (x=0; x> 8) | + ((s0 & 0x0000fc00) >> 5) | + ((s0 & 0x000000f8) >> 3) | + ((s1 & 0x00f80000) << 8) | + ((s1 & 0x0000fc00) << 11) | + ((s1 & 0x000000f8) << 13) ; + +#ifndef DAVINCI_NO_DITHER + if ((s0 & s1) >> 24 == 0xff) + dst8[x] = 0x77; + else { + register int pt, da; + + z ^= ((z << 13) | (z >> 19)); + z += 0x87654321; + pt = s0 - ((s0 & 0xf8000000) >> 3); + da = (((pt >> 29) & 0x07) + ( ((z&0x1f) - ((pt >> 24) & 0x1f))>>31 )) << 4; + + z ^= ((z << 13) | (z >> 19)); + z += 0x87654321; + pt = s1 - ((s1 & 0xf8000000) >> 3); + da |= (((pt >> 29) & 0x07) + ( ((z&0x1f) - ((pt >> 24) & 0x1f))>>31 )); + + + dst8[x] = da; + } +#else + dst8[x] = ((s0 & 0xe0000000) >> 25) | + ((s1 & 0xe0000000) >> 29) ; +#endif + } + + src32 += sp4; + dst32 += dp4; + dst8 += dp; + } + break; + + default: + D_ONCE( "unsupported format" ); + } + } +} + +static void +update_rgb( DavinciDriverData *ddrv, + DavinciDeviceData *ddev, + CoreSurface *surface, + CoreSurfaceBufferLock *lock, + const DFBRegion *update ) +{ + DFBRectangle rect; + CoreSurfaceBuffer *buffer; + + D_ASSERT( ddrv != NULL ); + D_ASSERT( ddev != NULL ); + D_ASSERT( surface != NULL ); + D_ASSERT( lock != NULL ); + DFB_REGION_ASSERT_IF( update ); + + buffer = lock->buffer; + D_ASSERT( buffer != NULL ); + + if (update) + rect = DFB_RECTANGLE_INIT_FROM_REGION( update ); + else { + rect.x = 0; + rect.y = 0; + rect.w = surface->config.size.w; + rect.h = surface->config.size.h; + } + + dfb_convert_to_rgb16( buffer->format, + lock->addr + rect.y * lock->pitch + DFB_BYTES_PER_LINE( buffer->format, rect.x ), + lock->pitch, + surface->config.size.h, + ddrv->fb[OSD0].mem + rect.y * ddev->fix[OSD0].line_length + rect.x * 2, + ddev->fix[OSD0].line_length, + rect.w, rect.h ); +} + +static void +enable_osd( DavinciDriverData *ddrv, + DavinciOSDLayerData *dosd ) +{ + if (!dosd->enable) + return; + + ioctl( ddrv->fb[OSD0].fd, FBIO_WAITFORVSYNC ); + + if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN, dosd->alpha )) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_ATTRIBUTE_WIN (fb%d - %d)!\n", OSD0, dosd->alpha ); + + if (ioctl( ddrv->fb[OSD0].fd, FBIO_ENABLE_DISABLE_WIN, 1 )) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD0, 1 ); + + if (ioctl( ddrv->fb[OSD1].fd, FBIO_ENABLE_DISABLE_WIN, dosd->alpha )) + D_OSDERROR( "Davinci/OSD: FBIO_ENABLE_DISABLE_WIN (fb%d - %d)!\n", OSD1, dosd->alpha ); + + dosd->enable = false; +} + +static DFBResult +osdFlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + CoreSurfaceBuffer *buffer; + DavinciDriverData *ddrv = driver_data; + DavinciDeviceData *ddev = ddrv->ddev; + DavinciOSDLayerData *dosd = layer_data; + + D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ ); + + D_ASSERT( surface != NULL ); + D_ASSERT( lock != NULL ); + D_ASSERT( ddrv != NULL ); + D_ASSERT( ddev != NULL ); + + buffer = lock->buffer; + D_ASSERT( buffer != NULL ); + + if (buffer->format != DSPF_RGB16) { + if (DFB_PIXELFORMAT_HAS_ALPHA( buffer->format )) + update_buffers( ddrv, ddev, surface, lock, NULL ); + else + update_rgb( ddrv, ddev, surface, lock, NULL ); + } + else + davincifb_pan_display( &ddrv->fb[OSD0], &dosd->var0, lock, flags, 0, 0 ); + + dfb_surface_flip( surface, false ); + + enable_osd( ddrv, dosd ); + + return DFB_OK; +} + +static DFBResult +osdUpdateRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + const DFBRegion *update, + CoreSurfaceBufferLock *lock ) +{ + CoreSurfaceBuffer *buffer; + DavinciDriverData *ddrv = driver_data; + DavinciDeviceData *ddev = ddrv->ddev; + DavinciOSDLayerData *dosd = layer_data; + + D_DEBUG_AT( Davinci_OSD, "%s()\n", __FUNCTION__ ); + + D_ASSERT( surface != NULL ); + D_ASSERT( lock != NULL ); + D_ASSERT( ddrv != NULL ); + D_ASSERT( ddev != NULL ); + + buffer = lock->buffer; + D_ASSERT( buffer != NULL ); + + if (buffer->format != DSPF_RGB16) { + if (DFB_PIXELFORMAT_HAS_ALPHA( buffer->format )) + update_buffers( ddrv, ddev, surface, lock, update ); + else + update_rgb( ddrv, ddev, surface, lock, update ); + } + + enable_osd( ddrv, dosd ); + + return DFB_OK; +} + +const DisplayLayerFuncs davinciOSDLayerFuncs = { + .LayerDataSize = osdLayerDataSize, + .InitLayer = osdInitLayer, + + .TestRegion = osdTestRegion, + .SetRegion = osdSetRegion, + .RemoveRegion = osdRemoveRegion, + .FlipRegion = osdFlipRegion, + .UpdateRegion = osdUpdateRegion, +}; + -- cgit