/* * Called by vmwareSetState() to ensure that the color register is properly set * for execution of rendering functions. */ static inline void vmware_validate_COLOR( VMWareDeviceData *vdev, CardState *state ) { switch (vdev->dst_format) { case DSPF_ARGB: vdev->color_pixel = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); break; case DSPF_RGB32: vdev->color_pixel = PIXEL_RGB32( state->color.r, state->color.g, state->color.b ); break; case DSPF_RGB16: vdev->color_pixel = PIXEL_RGB16( state->color.r, state->color.g, state->color.b ); break; default: D_BUG( "unexpected format %s", dfb_pixelformat_name(vdev->dst_format) ); } /* Set the flag. */ VMWARE_VALIDATE( COLOR ); }
static DFBResult IDirectFBImageProvider_ANDROID_GetImageDescription( IDirectFBImageProvider *thiz, DFBImageDescription *desc ) { DFBResult ret; DIRECT_INTERFACE_GET_DATA(IDirectFBImageProvider_ANDROID) if (!desc) return DFB_INVARG; ret = decodeImage( data ); if (ret) return ret; desc->caps = DICAPS_NONE; if (data->alpha) desc->caps |= DICAPS_ALPHACHANNEL; D_DEBUG_AT( imageProviderANDROID, "GetImageDescription: width=%d height=%d pitch=%d has_alpha=%d pixelformat=%s\n", data->width, data->height, data->pitch, data->alpha, dfb_pixelformat_name(data->format) ); return DFB_OK; }
DFBResult dfb_surface_create_simple ( CoreDFB *core, int width, int height, DFBSurfacePixelFormat format, DFBSurfaceCapabilities caps, CoreSurfaceTypeFlags type, unsigned long resource_id, CorePalette *palette, CoreSurface **ret_surface ) { CoreSurfaceConfig config; D_DEBUG_AT( Core_Surface, "%s( %p, %dx%d %s, %p )\n", __FUNCTION__, core, width, height, dfb_pixelformat_name( format ), ret_surface ); D_ASSERT( core != NULL ); D_ASSERT( ret_surface != NULL ); config.flags = CSCONF_SIZE | CSCONF_FORMAT | CSCONF_CAPS; config.size.w = width; config.size.h = height; config.format = format; config.caps = caps; return CoreDFB_CreateSurface( core, &config, type, resource_id, palette, ret_surface ); }
static DFBResult IDirectFBImageProvider_ANDROID_GetSurfaceDescription( IDirectFBImageProvider *thiz, DFBSurfaceDescription *desc ) { DFBResult ret; DFBSurfacePixelFormat primary_format = dfb_primary_layer_pixelformat(); DIRECT_INTERFACE_GET_DATA (IDirectFBImageProvider_ANDROID) if (!desc) return DFB_INVARG; ret = decodeImage( data ); if (ret) return ret; desc->flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; if (data->alpha) desc->pixelformat = DFB_PIXELFORMAT_HAS_ALPHA(primary_format) ? primary_format : DSPF_ARGB; //desc->pixelformat = DSPF_ABGR; else desc->pixelformat = primary_format; desc->width = data->width; desc->height = data->height; D_DEBUG_AT( imageProviderANDROID, "GetSurfaceDescription: width=%d height=%d pitch=%d has_alpha=%d pixelformat=%s/%s\n", data->width, data->height, data->pitch, data->alpha, dfb_pixelformat_name(data->format), dfb_pixelformat_name(desc->pixelformat) ); 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 ); }
DFBResult dfb_x11_create_window_handler( DFBX11 *x11, SetModeData *setmode ) { XWindow *xw; DFBX11Shared *shared = x11->shared; CoreLayerRegionConfig *config; config = &setmode->config; xw = *(setmode->xw); D_DEBUG_AT( X11_Layer, "%s( %p )\n", __FUNCTION__, config ); D_DEBUG_AT( X11_Layer, " -> %4dx%4d %s\n", config->width, config->height, dfb_pixelformat_name(config->format) ); XLockDisplay( x11->display ); if (xw != NULL) { if (xw->width == config->width && xw->height == config->height) { XUnlockDisplay( x11->display ); return DFB_OK; } *(setmode->xw) = NULL; dfb_x11_close_window( x11, xw ); shared->window_count--; } bool bSucces = dfb_x11_open_window( x11, &xw, 0, 0, config->width, config->height, config->format ); /* Set video mode */ if ( !bSucces ) { D_ERROR( "DirectFB/X11: Couldn't open %dx%d window!\n", config->width, config->height ); XUnlockDisplay( x11->display ); return DFB_FAILURE; } else { *(setmode->xw) = xw; shared->window_count++; } XUnlockDisplay( x11->display ); return DFB_OK; }
DFBResult dfb_surface_client_create( CoreDFB *core, CoreSurface *surface, CoreSurfaceClient **ret_client ) { DFBResult ret; CoreSurfaceClient *client; CORE_SURFACE_ASSERT( surface ); D_ASSERT( ret_client != NULL ); D_DEBUG_AT( Core_SurfClient, "%s( %p %dx%d %s )\n", __FUNCTION__, surface, surface->config.size.w, surface->config.size.h, dfb_pixelformat_name( surface->config.format ) ); client = dfb_core_create_surface_client( core ); if (!client) return DFB_FUSION; ret = dfb_surface_link( &client->surface, surface ); if (ret) { fusion_object_destroy( &client->object ); return ret; } D_MAGIC_SET( client, CoreSurfaceClient ); *ret_client = client; CoreSurfaceClient_Init_Dispatch( core, client, &client->call ); dfb_surface_lock( surface ); client->flip_count = surface->flips; fusion_vector_add( &surface->clients, client ); dfb_surface_unlock( surface ); fusion_object_activate( &client->object ); return DFB_OK; }
static DFBResult x11TestConfig( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, const CoreSurfaceConfig *config ) { x11PoolLocalData *local = pool_local; DFBX11 *x11 = local->x11; D_DEBUG_AT( X11_Surfaces, "%s()\n", __FUNCTION__ ); if (!x11->visuals[DFB_PIXELFORMAT_INDEX(config->format)]) { D_DEBUG_AT( X11_Surfaces, " -> NO VISUAL for %s\n", dfb_pixelformat_name(config->format) ); return DFB_UNSUPPORTED; } return DFB_OK; }
/* * Called by davinciSetState() to ensure that the source ARGB modulation is properly set * for execution of blitting functions. */ static inline void davinci_validate_SOURCE_MULT( DavinciDeviceData *ddev, CardState *state ) { switch (ddev->dst_format) { case DSPF_ARGB: if (state->blittingflags & DSBLIT_COLORIZE) ddev->source_mult = 0xff000000 | ddev->color_argb; else ddev->source_mult = 0xffffffff; break; default: D_BUG( "unexpected format %s", dfb_pixelformat_name(ddev->dst_format) ); return; } D_DEBUG_AT( Davinci_2D, " => SOURCE_MULT: 0x%08lx\n", ddev->source_mult ); /* Set the flag. */ DAVINCI_VALIDATE( SOURCE_MULT ); }
DFBResult dfb_surface_lock_buffer( CoreSurface *surface, CoreSurfaceBufferRole role, CoreSurfaceAccessorID accessor, CoreSurfaceAccessFlags access, CoreSurfaceBufferLock *ret_lock ) { DFBResult ret; CoreSurfaceAllocation *allocation; D_MAGIC_ASSERT( surface, CoreSurface ); D_DEBUG_AT( Core_Surface, "%s( 0x%02x 0x%02x ) <- %dx%d %s [%d]\n", __FUNCTION__, accessor, access, surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format), role ); ret = CoreSurface_PreLockBuffer2( surface, role, accessor, access, true, &allocation ); if (ret) return ret; D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_DEBUG_AT( Core_Surface, " -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name ); /* Lock the allocation. */ dfb_surface_buffer_lock_init( ret_lock, accessor, access ); ret = dfb_surface_pool_lock( allocation->pool, allocation, ret_lock ); if (ret) { D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( ret_lock ); dfb_surface_allocation_unref( allocation ); return ret; } return DFB_OK; }
/* * Called by davinciSetState() to ensure that the color register is properly set * for execution of rendering functions. */ static inline void davinci_validate_FILLCOLOR( DavinciDeviceData *ddev, CardState *state ) { switch (ddev->dst_format) { case DSPF_ARGB: case DSPF_RGB32: ddev->fillcolor = ddev->color_argb; break; case DSPF_RGB16: ddev->fillcolor = PIXEL_RGB16( state->color.r, state->color.g, state->color.b ); ddev->fillcolor |= ddev->fillcolor << 16; break; case DSPF_UYVY: { int y, u, v; RGB_TO_YCBCR( state->color.r, state->color.g, state->color.b, y, u, v ); ddev->fillcolor = PIXEL_UYVY( y, u, v ); break; } default: D_BUG( "unexpected format %s", dfb_pixelformat_name(ddev->dst_format) ); return; } D_DEBUG_AT( Davinci_2D, " => FILLCOLOR: 0x%08lx\n", ddev->fillcolor ); /* Set the flag. */ DAVINCI_VALIDATE( FILLCOLOR ); }
DFBResult dfb_surface_reconfig( CoreSurface *surface, const CoreSurfaceConfig *config ) { int i, buffers; DFBResult ret; CoreSurfaceConfig new_config; D_DEBUG_AT( Core_Surface, "%s( %p, %dx%d %s -> %dx%d %s )\n", __FUNCTION__, surface, surface->config.size.w, surface->config.size.h, dfb_pixelformat_name( surface->config.format ), (config->flags & CSCONF_SIZE) ? config->size.w : surface->config.size.w, (config->flags & CSCONF_SIZE) ? config->size.h : surface->config.size.h, (config->flags & CSCONF_FORMAT) ? dfb_pixelformat_name( config->format ) : dfb_pixelformat_name( surface->config.format ) ); D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( config != NULL ); if (config->flags & CSCONF_PREALLOCATED) return DFB_UNSUPPORTED; if (fusion_skirmish_prevail( &surface->lock )) return DFB_FUSION; if (surface->type & CSTF_PREALLOCATED) { fusion_skirmish_dismiss( &surface->lock ); return DFB_UNSUPPORTED; } if ( (config->flags == CSCONF_SIZE || ((config->flags == (CSCONF_SIZE | CSCONF_FORMAT)) && (config->format == surface->config.format))) && config->size.w <= surface->config.min_size.w && config->size.h <= surface->config.min_size.h) { surface->config.size = config->size; fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; } new_config = surface->config; if (config->flags & CSCONF_SIZE) new_config.size = config->size; if (config->flags & CSCONF_FORMAT) new_config.format = config->format; if (config->flags & CSCONF_CAPS) { if (config->caps & DSCAPS_ROTATED) D_UNIMPLEMENTED(); new_config.caps = config->caps & ~DSCAPS_ROTATED; } if (new_config.caps & DSCAPS_SYSTEMONLY) surface->type = (surface->type & ~CSTF_EXTERNAL) | CSTF_INTERNAL; else if (new_config.caps & DSCAPS_VIDEOONLY) surface->type = (surface->type & ~CSTF_INTERNAL) | CSTF_EXTERNAL; else surface->type = surface->type & ~(CSTF_INTERNAL | CSTF_EXTERNAL); if (new_config.caps & DSCAPS_TRIPLE) buffers = 3; else if (new_config.caps & DSCAPS_DOUBLE) buffers = 2; else { buffers = 1; new_config.caps &= ~DSCAPS_ROTATED; } ret = Core_Resource_CheckSurfaceUpdate( surface, &new_config ); if (ret) return ret; /* Destroy the Surface Buffers. */ for (i=0; i<surface->num_buffers; i++) { dfb_surface_buffer_decouple( surface->buffers[i] ); surface->buffers[i] = NULL; } surface->num_buffers = 0; Core_Resource_UpdateSurface( surface, &new_config ); surface->config = new_config; /* Recreate the Surface Buffers. */ for (i=0; i<buffers; i++) { CoreSurfaceBuffer *buffer; ret = dfb_surface_buffer_create( core_dfb, surface, CSBF_NONE, &buffer ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } dfb_surface_buffer_globalize( buffer ); surface->buffers[surface->num_buffers++] = buffer; switch (i) { case 0: surface->buffer_indices[CSBR_FRONT] = i; case 1: surface->buffer_indices[CSBR_BACK] = i; case 2: surface->buffer_indices[CSBR_IDLE] = i; } } dfb_surface_notify( surface, CSNF_SIZEFORMAT ); fusion_skirmish_dismiss( &surface->lock ); return DFB_OK; error: D_UNIMPLEMENTED(); fusion_skirmish_dismiss( &surface->lock ); return ret; }
void gBlit( CardState *state, DFBRectangle *rect, int dx, int dy ) { GenefxState *gfxs = state->gfxs; int h; XopAdvanceFunc Aop_advance; XopAdvanceFunc Bop_advance; int Aop_X; int Aop_Y; int Bop_X; int Bop_Y; DFBSurfaceBlittingFlags rotflip_blittingflags = state->blittingflags; dfb_simplify_blittingflags( &rotflip_blittingflags ); rotflip_blittingflags &= (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL | DSBLIT_ROTATE90 ); 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( (rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.x2 >= (dx + rect->w - 1) ); D_ASSERT( (rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.y2 >= (dy + rect->h - 1) ); D_ASSERT( !(rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.x2 >= (dx + rect->h - 1) ); D_ASSERT( !(rotflip_blittingflags & DSBLIT_ROTATE90) || state->clip.y2 >= (dy + rect->w - 1) ); CHECK_PIPELINE(); if (!Genefx_ABacc_prepare( gfxs, rect->w )) return; 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 (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 (rotflip_blittingflags == (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL)) { // 180 deg gfxs->Astep *= -1; Aop_X = dx + rect->w - 1; Aop_Y = dy; Bop_X = rect->x; Bop_Y = rect->y + rect->h - 1; Aop_advance = Genefx_Aop_next; Bop_advance = Genefx_Bop_prev; } else if (rotflip_blittingflags == DSBLIT_FLIP_HORIZONTAL) { gfxs->Astep *= -1; Aop_X = dx + rect->w - 1; Aop_Y = dy; Bop_X = rect->x; Bop_Y = rect->y; Aop_advance = Genefx_Aop_next; Bop_advance = Genefx_Bop_next; } else if (rotflip_blittingflags == DSBLIT_FLIP_VERTICAL) { Aop_X = dx; Aop_Y = dy + rect->h - 1; Bop_X = rect->x; Bop_Y = rect->y; Aop_advance = Genefx_Aop_prev; Bop_advance = Genefx_Bop_next; } else if (rotflip_blittingflags == (DSBLIT_ROTATE90 | DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL)) { // 270 deg ccw if (gfxs->dst_bpp == 0) { D_UNIMPLEMENTED(); return; } gfxs->Astep *= gfxs->dst_pitch / gfxs->dst_bpp; Aop_X = dx; Aop_Y = dy; Bop_X = rect->x; Bop_Y = rect->y + rect->h - 1; Aop_advance = Genefx_Aop_crab; Bop_advance = Genefx_Bop_prev; } else if (rotflip_blittingflags == DSBLIT_ROTATE90) { // 90 deg ccw if (gfxs->dst_bpp == 0) { D_UNIMPLEMENTED(); return; } gfxs->Astep *= -gfxs->dst_pitch / gfxs->dst_bpp; Aop_X = dx; Aop_Y = dy + rect->w - 1; Bop_X = rect->x; Bop_Y = rect->y; Aop_advance = Genefx_Aop_crab; Bop_advance = Genefx_Bop_next; } else if (rotflip_blittingflags == (DSBLIT_ROTATE90 | DSBLIT_FLIP_VERTICAL)) { if (gfxs->dst_bpp == 0) { D_UNIMPLEMENTED(); return; } gfxs->Astep *= -gfxs->dst_pitch / gfxs->dst_bpp; Aop_X = dx + rect->h - 1; Aop_Y = dy + rect->w - 1; Bop_X = rect->x; Bop_Y = rect->y; Aop_advance = Genefx_Aop_prev_crab; Bop_advance = Genefx_Bop_next; } else if (rotflip_blittingflags == (DSBLIT_ROTATE90 | DSBLIT_FLIP_HORIZONTAL)) { if (gfxs->dst_bpp == 0) { D_UNIMPLEMENTED(); return; } gfxs->Astep *= gfxs->dst_pitch / gfxs->dst_bpp; Aop_X = dx; Aop_Y = dy; Bop_X = rect->x; Bop_Y = rect->y; Aop_advance = Genefx_Aop_crab; Bop_advance = Genefx_Bop_next; } else if (gfxs->src_org[0] == gfxs->dst_org[0] && dy > rect->y && !(state->blittingflags & DSBLIT_DEINTERLACE)) { /* we must blit from bottom to top */ Aop_X = dx; Aop_Y = dy + rect->h - 1; Bop_X = rect->x; Bop_Y = rect->y + rect->h - 1; Aop_advance = Genefx_Aop_prev; Bop_advance = Genefx_Bop_prev; } else { /* we must blit from top to bottom */ Aop_X = dx; Aop_Y = dy; Bop_X = rect->x; Bop_Y = rect->y; Aop_advance = Genefx_Aop_next; Bop_advance = Genefx_Bop_next; } Genefx_Aop_xy( gfxs, Aop_X, Aop_Y ); Genefx_Bop_xy( gfxs, Bop_X, Bop_Y ); if (state->blittingflags & DSBLIT_DEINTERLACE) { if (state->source->field) { Aop_advance( gfxs ); Bop_advance( gfxs ); rect->h--; } for (h = rect->h/2; h; h--) { RUN_PIPELINE(); Aop_advance( gfxs ); RUN_PIPELINE(); Aop_advance( gfxs ); Bop_advance( gfxs ); Bop_advance( gfxs ); } } /* ! DSBLIT_DEINTERLACE */ else { for (h = rect->h; h; h--) { RUN_PIPELINE(); Aop_advance( gfxs ); Bop_advance( gfxs ); } } Genefx_ABacc_flush( gfxs ); }
DFBResult dfb_surface_create( CoreDFB *core, const CoreSurfaceConfig *config, CoreSurfaceTypeFlags type, unsigned long resource_id, CorePalette *palette, CoreSurface **ret_surface ) { DFBResult ret = DFB_BUG; int i, data_size; int buffers; CoreSurface *surface; char buf[64]; D_ASSERT( core != NULL ); D_FLAGS_ASSERT( type, CSTF_ALL ); D_MAGIC_ASSERT_IF( palette, CorePalette ); D_ASSERT( ret_surface != NULL ); D_DEBUG_AT( Core_Surface, "dfb_surface_create( %p, %p, %p )\n", core, config, ret_surface ); surface = dfb_core_create_surface( core ); if (!surface) return DFB_FUSION; surface->data = NULL; if (config) { D_FLAGS_ASSERT( config->flags, CSCONF_ALL ); surface->config.flags = config->flags; if (config->flags & CSCONF_SIZE) { D_DEBUG_AT( Core_Surface, " -> %dx%d\n", config->size.w, config->size.h ); surface->config.size = config->size; } if (config->flags & CSCONF_FORMAT) { D_DEBUG_AT( Core_Surface, " -> %s\n", dfb_pixelformat_name( config->format ) ); surface->config.format = config->format; } if (config->flags & CSCONF_CAPS) { D_DEBUG_AT( Core_Surface, " -> caps 0x%08x\n", config->caps ); if (config->caps & DSCAPS_ROTATED) D_UNIMPLEMENTED(); surface->config.caps = config->caps & ~DSCAPS_ROTATED; } if (config->flags & CSCONF_PREALLOCATED) { D_DEBUG_AT( Core_Surface, " -> prealloc %p [%d]\n", config->preallocated[0].addr, config->preallocated[0].pitch ); direct_memcpy( surface->config.preallocated, config->preallocated, sizeof(config->preallocated) ); surface->config.preallocated_pool_id = config->preallocated_pool_id; type |= CSTF_PREALLOCATED; } } if (surface->config.caps & DSCAPS_SYSTEMONLY) surface->type = (type & ~CSTF_EXTERNAL) | CSTF_INTERNAL; else if (surface->config.caps & DSCAPS_VIDEOONLY) surface->type = (type & ~CSTF_INTERNAL) | CSTF_EXTERNAL; else surface->type = type & ~(CSTF_INTERNAL | CSTF_EXTERNAL); if (surface->config.caps & DSCAPS_SHARED) surface->type |= CSTF_SHARED; surface->resource_id = resource_id; if (surface->config.caps & DSCAPS_TRIPLE) buffers = 3; else if (surface->config.caps & DSCAPS_DOUBLE) buffers = 2; else { buffers = 1; surface->config.caps &= ~DSCAPS_ROTATED; } surface->notifications = CSNF_ALL & ~CSNF_FLIP; surface->alpha_ramp[0] = 0x00; surface->alpha_ramp[1] = 0x55; surface->alpha_ramp[2] = 0xaa; surface->alpha_ramp[3] = 0xff; if (surface->config.caps & DSCAPS_STATIC_ALLOC) surface->config.min_size = surface->config.size; surface->shmpool = dfb_core_shmpool( core ); direct_serial_init( &surface->serial ); snprintf( buf, sizeof(buf), "Surface %dx%d %s", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format) ); fusion_ref_set_name( &surface->object.ref, buf ); fusion_skirmish_init2( &surface->lock, buf, dfb_core_world(core), fusion_config->secure_fusion ); // fusion_skirmish_add_permissions( &surface->lock, 0, FUSION_SKIRMISH_PERMIT_PREVAIL | FUSION_SKIRMISH_PERMIT_DISMISS ); D_MAGIC_SET( surface, CoreSurface ); if (dfb_config->warn.flags & DCWF_CREATE_SURFACE && dfb_config->warn.create_surface.min_size.w <= surface->config.size.w && dfb_config->warn.create_surface.min_size.h <= surface->config.size.h) D_WARN( "create-surface %4dx%4d %6s, buffers %d, caps 0x%08x, type 0x%08x", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format), buffers, surface->config.caps, surface->type ); if (palette) { dfb_surface_set_palette( surface, palette ); } else if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) { ret = dfb_surface_init_palette( core, surface ); if (ret) goto error; } /* Create the system driver specific surface data information */ data_size = dfb_system_surface_data_size(); if (data_size) { surface->data = SHCALLOC( surface->shmpool, 1, data_size ); if (!surface->data) { ret = D_OOSHM(); goto error; } } dfb_system_surface_data_init(surface,surface->data); dfb_surface_lock( surface ); /* Create the Surface Buffers. */ for (i=0; i<buffers; i++) { ret = dfb_surface_buffer_create( core, surface, CSBF_NONE, &surface->buffers[i] ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } surface->num_buffers++; dfb_surface_buffer_globalize( surface->buffers[i] ); switch (i) { case 0: surface->buffer_indices[CSBR_FRONT] = i; case 1: surface->buffer_indices[CSBR_BACK] = i; case 2: surface->buffer_indices[CSBR_IDLE] = i; } } dfb_surface_unlock( surface ); CoreSurface_Init_Dispatch( core, surface, &surface->call ); fusion_object_activate( &surface->object ); *ret_surface = surface; return DFB_OK; error: for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_decouple( surface->buffers[i] ); } /* release the system driver specific surface data */ if (surface->data) { dfb_system_surface_data_destroy( surface, surface->data ); SHFREE( surface->shmpool, surface->data ); surface->data = NULL; } fusion_skirmish_destroy( &surface->lock ); direct_serial_deinit( &surface->serial ); D_MAGIC_CLEAR( surface ); fusion_object_destroy( &surface->object ); return ret; }
DFBResult dfb_surface_create( CoreDFB *core, const CoreSurfaceConfig *config, CoreSurfaceTypeFlags type, unsigned long resource_id, CorePalette *palette, CoreSurface **ret_surface ) { DFBResult ret = DFB_BUG; int i; int buffers; CoreSurface *surface; char buf[64]; D_ASSERT( core != NULL ); D_FLAGS_ASSERT( type, CSTF_ALL ); D_MAGIC_ASSERT_IF( palette, CorePalette ); D_ASSERT( ret_surface != NULL ); D_DEBUG_AT( Core_Surface, "dfb_surface_create( %p, %p, %p )\n", core, config, ret_surface ); surface = dfb_core_create_surface( core ); if (!surface) return DFB_FUSION; if (config) { D_FLAGS_ASSERT( config->flags, CSCONF_ALL ); surface->config.flags = config->flags; if (config->flags & CSCONF_SIZE) { D_DEBUG_AT( Core_Surface, " -> %dx%d\n", config->size.w, config->size.h ); surface->config.size = config->size; } if (config->flags & CSCONF_FORMAT) { D_DEBUG_AT( Core_Surface, " -> %s\n", dfb_pixelformat_name( config->format ) ); surface->config.format = config->format; } if (config->flags & CSCONF_CAPS) { D_DEBUG_AT( Core_Surface, " -> caps 0x%08x\n", config->caps ); surface->config.caps = config->caps; } if (config->flags & CSCONF_PREALLOCATED) { D_DEBUG_AT( Core_Surface, " -> prealloc %p [%d]\n", config->preallocated[0].addr, config->preallocated[0].pitch ); direct_memcpy( surface->config.preallocated, config->preallocated, sizeof(config->preallocated) ); type |= CSTF_PREALLOCATED; } } if (surface->config.caps & DSCAPS_SYSTEMONLY) surface->type = (type & ~CSTF_EXTERNAL) | CSTF_INTERNAL; else if (surface->config.caps & DSCAPS_VIDEOONLY) surface->type = (type & ~CSTF_INTERNAL) | CSTF_EXTERNAL; else surface->type = type & ~(CSTF_INTERNAL | CSTF_EXTERNAL); if (surface->config.caps & DSCAPS_SHARED) surface->type |= CSTF_SHARED; surface->resource_id = resource_id; if (surface->config.caps & DSCAPS_TRIPLE) buffers = 3; else if (surface->config.caps & DSCAPS_DOUBLE) buffers = 2; else buffers = 1; surface->notifications = CSNF_ALL & ~CSNF_FLIP; surface->alpha_ramp[0] = 0x00; surface->alpha_ramp[1] = 0x55; surface->alpha_ramp[2] = 0xaa; surface->alpha_ramp[3] = 0xff; if (surface->config.caps & DSCAPS_STATIC_ALLOC) surface->config.min_size = surface->config.size; surface->shmpool = dfb_core_shmpool( core ); direct_serial_init( &surface->serial ); snprintf( buf, sizeof(buf), "Surface %dx%d %s", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format) ); fusion_ref_set_name( &surface->object.ref, buf ); fusion_skirmish_init( &surface->lock, buf, dfb_core_world(core) ); fusion_object_set_lock( &surface->object, &surface->lock ); D_MAGIC_SET( surface, CoreSurface ); if (dfb_config->warn.flags & DCWF_CREATE_SURFACE && dfb_config->warn.create_surface.min_size.w <= surface->config.size.w && dfb_config->warn.create_surface.min_size.h <= surface->config.size.h) D_WARN( "create-surface %4dx%4d %6s, buffers %d, caps 0x%08x, type 0x%08x", surface->config.size.w, surface->config.size.h, dfb_pixelformat_name(surface->config.format), buffers, surface->config.caps, surface->type ); if (palette) { dfb_surface_set_palette( surface, palette ); } else if (DFB_PIXELFORMAT_IS_INDEXED( surface->config.format )) { ret = dfb_surface_init_palette( core, surface ); if (ret) goto error; } /* Create the Surface Buffers. */ for (i=0; i<buffers; i++) { CoreSurfaceBuffer *buffer; ret = dfb_surface_buffer_new( surface, CSBF_NONE, &buffer ); if (ret) { D_DERROR( ret, "Core/Surface: Error creating surface buffer!\n" ); goto error; } surface->buffers[surface->num_buffers++] = buffer; switch (i) { case 0: surface->buffer_indices[CSBR_FRONT] = i; case 1: surface->buffer_indices[CSBR_BACK] = i; case 2: surface->buffer_indices[CSBR_IDLE] = i; } } fusion_object_activate( &surface->object ); *ret_surface = surface; return DFB_OK; error: D_MAGIC_CLEAR( surface ); for (i=0; i<MAX_SURFACE_BUFFERS; i++) { if (surface->buffers[i]) dfb_surface_buffer_destroy( surface->buffers[i] ); } fusion_skirmish_destroy( &surface->lock ); direct_serial_deinit( &surface->serial ); fusion_object_destroy( &surface->object ); return ret; }
static DFBResult Test_CreateSubWindow( IDirectFBDisplayLayer *layer, void *arg ) { IDirectFBWindow *window; DFBWindowID window_id; DFBDimension size = { m_desc_sub.width, m_desc_sub.height }; D_ASSERT( m_toplevel_id != 0 ); /* Write window ID of top level into description */ m_desc_sub.toplevel_id = m_toplevel_id; /* * Create a new sub window with 75% width/height and positioned at 20,20 within top level window */ SHOW_TEST( "CreateWindow( %d,%d - %dx%d %s + toplevel ID %u, options 0x%08x )...", m_desc_sub.posx, m_desc_sub.posy, m_desc_sub.width, m_desc_sub.height, dfb_pixelformat_name( m_desc_sub.pixelformat ), m_desc_sub.toplevel_id, m_desc_top.options ); _T( layer->CreateWindow( layer, &m_desc_sub, &window ) ); if (m_subcolor.valid) { DFBColor c = m_subcolor.color; SHOW_INFO( " - SetColor( 0x%02x, 0x%02x, 0x%02x, 0x%02x )...", c.r, c.g, c.b, c.a ); _T( window->SetColor( window, c.r, c.g, c.b, c.a ) ); } /* * Query its surface and clear it with light gray (if not input or color only) */ if (!(m_desc_sub.caps & (DWCAPS_INPUTONLY | DWCAPS_COLOR) )) { IDirectFBSurface *surface; SHOW_INFO( " - GetSurface()..." ); _T( window->GetSurface( window, &surface ) ); SHOW_INFO( " - Clear( 0xC0, 0xC0, 0xC0, 0xFF )..." ); _T( surface->Clear( surface, 0xC0, 0xC0, 0xC0, 0xFF ) ); _T( surface->DrawRectangle( surface, 0, 0, size.w, size.h ) ); _T( surface->FillRectangle( surface, size.w / 2, 1, 1, size.h - 2 ) ); _T( surface->FillRectangle( surface, 1, size.h / 2, size.w - 2, 1 ) ); surface->Release( surface ); } /* * Show the window */ SHOW_INFO( " - SetOpacity( 255 )..." ); _T( window->SetOpacity( window, 0xff ) ); /* * Query and print ID of new window */ SHOW_INFO( " - GetID()..." ); _T( window->GetID( window, &window_id ) ); /* * Set association of new window */ if (m_desc_sub.parent_id) { SHOW_INFO( " - SetAssociation( %u )...", m_desc_sub.parent_id ); _T( window->SetAssociation( window, m_desc_sub.parent_id ) ); } /* * Set top level window ID (user hasn't specified one) */ m_subwindow_id = window_id; m_subwindow = window; SHOW_RESULT( "...CreateWindow( %d,%d - %dx%d %s + toplevel ID %u ) done. => Sub Window ID %u", m_desc_sub.posx, m_desc_sub.posy, m_desc_sub.width, m_desc_sub.height, dfb_pixelformat_name( m_desc_sub.pixelformat ), m_desc_sub.toplevel_id, window_id ); return DFB_OK; }
static void print_usage (const char *prg_name) { int i = 0; fprintf (stderr, "\n"); fprintf (stderr, "== DirectFB Window Test (version %s) ==\n", DIRECTFB_VERSION); fprintf (stderr, "\n"); fprintf (stderr, "Known pixel formats:\n"); while (format_names[i].format != DSPF_UNKNOWN) { DFBSurfacePixelFormat format = format_names[i].format; fprintf (stderr, " %-10s %2d bits, %d bytes", format_names[i].name, DFB_BITS_PER_PIXEL(format), DFB_BYTES_PER_PIXEL(format)); if (DFB_PIXELFORMAT_HAS_ALPHA(format)) fprintf (stderr, " ALPHA"); if (DFB_PIXELFORMAT_IS_INDEXED(format)) fprintf (stderr, " INDEXED"); if (DFB_PLANAR_PIXELFORMAT(format)) { int planes = DFB_PLANE_MULTIPLY(format, 1000); fprintf (stderr, " PLANAR (x%d.%03d)", planes / 1000, planes % 1000); } fprintf (stderr, "\n"); ++i; } fprintf (stderr, "\n"); fprintf (stderr, "Known window capabilities:\n"); for (i=0; caps_names[i].capability != DWCAPS_NONE; i++) fprintf (stderr, " %s\n", caps_names[i].name); fprintf (stderr, "\n"); fprintf (stderr, "Known window options:\n"); for (i=0; options_names[i].option != DWOP_NONE; i++) fprintf (stderr, " %s\n", options_names[i].name); fprintf (stderr, "\n"); fprintf (stderr, "\n"); fprintf (stderr, "Usage: %s [options]\n", prg_name); fprintf (stderr, "\n"); fprintf (stderr, "Options:\n"); fprintf (stderr, " -h, --help Show this help message\n"); fprintf (stderr, " -v, --version Print version information\n"); fprintf (stderr, " -T, --top-level <toplevel_id> WindowID (skips top creation)\n"); fprintf (stderr, " -W, --wait-at-end Wait at the end (don't exit)\n"); fprintf (stderr, "\n"); fprintf (stderr, "Top window:\n"); fprintf (stderr, " -r, --run <test> Run test (see list below)\n"); fprintf (stderr, " -p, --pos <posx>,<posy> Position (%d,%d)\n", m_desc_top.posx, m_desc_top.posy); fprintf (stderr, " -s, --size <width>x<height> Size (%dx%d)\n", m_desc_top.width, m_desc_top.height); fprintf (stderr, " -f, --format <pixelformat> Pixel Format (%s)\n", dfb_pixelformat_name(m_desc_top.pixelformat)); fprintf (stderr, " -c, --caps <window_caps> Capabilities (NONE)\n"); fprintf (stderr, " -l, --color <aarrggbb> Fixed Color (NONE)\n"); fprintf (stderr, " -o, --option <window_option> Options (NONE)\n"); fprintf (stderr, " -a, --associate <parent_id> Association (N/A)\n"); fprintf (stderr, "\n"); fprintf (stderr, "Sub window:\n"); fprintf (stderr, " -R, --sub-run <test> Run test (see list below)\n"); fprintf (stderr, " -P, --sub-pos <posx>,<posy> Position (%d,%d)\n", m_desc_sub.posx, m_desc_sub.posy); fprintf (stderr, " -S, --sub-size <width>x<height> Size (%dx%d)\n", m_desc_sub.width, m_desc_sub.height); fprintf (stderr, " -F, --sub-format <pixelformat> Format (%s)\n", dfb_pixelformat_name(m_desc_sub.pixelformat)); fprintf (stderr, " -C, --sub-caps <window_caps> Capabilities (NONE)\n"); fprintf (stderr, " -L, --sub-color <aarrggbb> Fixed Color (NONE)\n"); fprintf (stderr, " -O, --sub-option <window_option> Options (NONE)\n"); fprintf (stderr, " -A, --sub-associate <parent_id> Association (N/A)\n"); fprintf (stderr, "\n"); fprintf (stderr, "Available tests:\n"); for (i=0; i<D_ARRAY_SIZE(m_tests); i++) fprintf (stderr, " %s\n", m_tests[i].name); fprintf (stderr, "\n"); }
static DFBResult fbdevAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret; CoreSurface *surface; FBDevPoolData *data = pool_data; FBDevPoolLocalData *local = pool_local; FBDevAllocationData *alloc = alloc_data; D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( data, FBDevPoolData ); D_MAGIC_ASSERT( local, FBDevPoolLocalData ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if ((surface->type & CSTF_LAYER) && surface->resource_id == DLID_PRIMARY) { int i, index = dfb_surface_buffer_index( buffer ); /* HACK FIXME_SC_2 ALLOCATE/SETMODE TWIST */ for (i=0; i<surface->num_buffers; i++) { if (surface->buffers[i]->allocs.elements) break; } if (i == surface->num_buffers && dfb_fbdev->shared->test_mode) { ret = dfb_fbdev_set_mode( surface, dfb_fbdev->shared->test_mode, &dfb_fbdev->shared->test_config ); if (ret) return ret; dfb_fbdev->shared->test_mode = NULL; } /* /HACK FIXME_SC_2 ALLOCATE/SETMODE TWIST */ alloc->pitch = dfb_fbdev->shared->fix.line_length; alloc->size = surface->config.size.h * alloc->pitch; alloc->offset = index * alloc->size; D_INFO( "FBDev/Surface: Allocated %dx%d %dbit %s buffer at offset %d and pitch %d.\n", surface->config.size.w, surface->config.size.h, dfb_fbdev->shared->current_var.bits_per_pixel, dfb_pixelformat_name(buffer->format), alloc->offset, alloc->pitch ); } else { Chunk *chunk; ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, &chunk ); if (ret) return ret; D_MAGIC_ASSERT( chunk, Chunk ); alloc->offset = chunk->offset; alloc->pitch = chunk->pitch; alloc->size = chunk->length;// DFB_PLANE_MULTIPLY( buffer->format, surface->config.size.h ) * alloc->pitch; alloc->chunk = chunk; } D_DEBUG_AT( FBDev_Surfaces, " -> offset %d, pitch %d, size %d\n", alloc->offset, alloc->pitch, alloc->size ); allocation->size = alloc->size; allocation->offset = alloc->offset; D_MAGIC_SET( alloc, FBDevAllocationData ); return DFB_OK; }
DFBResult dfb_surface_pool_bridges_transfer( CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *from, CoreSurfaceAllocation *to, const DFBRectangle *rects, unsigned int num_rects ) { DFBResult ret; int i; DFBRectangle rect; CoreSurfacePoolBridge *bridge = NULL; const SurfacePoolBridgeFuncs *funcs; CoreSurfacePoolTransfer *transfer; D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); CORE_SURFACE_ALLOCATION_ASSERT( from ); CORE_SURFACE_ALLOCATION_ASSERT( to ); D_ASSERT( rects != NULL || num_rects == 0 ); D_ASSERT( num_rects > 0 || rects == NULL ); D_DEBUG_AT( Core_SurfPoolBridge, "%s( %p [%dx%d %s], %p -> %p, %d rects )\n", __FUNCTION__, buffer, buffer->config.size.w, buffer->config.size.h, dfb_pixelformat_name( buffer->format ), from, to, num_rects ); if (!rects) { rect.x = rect.y = 0; rect.w = buffer->config.size.w; rect.h = buffer->config.size.h; rects = ▭ num_rects = 1; } for (i=0; i<bridge_count; i++) { D_ASSERT( bridge_order[i] >= 0 ); D_ASSERT( bridge_order[i] < bridge_count ); bridge = bridge_array[bridge_order[i]]; D_MAGIC_ASSERT( bridge, CoreSurfacePoolBridge ); funcs = get_funcs( bridge ); D_ASSERT( funcs->CheckTransfer != NULL ); ret = funcs->CheckTransfer( bridge, bridge->data, get_local(bridge), buffer, from, to ); if (ret) bridge = NULL; else break; } if (!bridge) return DFB_UNSUPPORTED; D_DEBUG_AT( Core_SurfPoolBridge, " -> using '%s'\n", bridge->desc.name ); ret = allocate_transfer( bridge, buffer, from, to, rects, num_rects, &transfer ); if (ret) return ret; D_ASSERT( funcs->StartTransfer != NULL ); D_DEBUG_AT( Core_SurfPoolBridge, " -> start...\n" ); ret = funcs->StartTransfer( bridge, bridge->data, get_local(bridge), transfer, transfer->data ); if (ret) D_DERROR( ret, "Core/SurfacePoolBridge: Starting transfer via '%s' failed!\n", bridge->desc.name ); else if (funcs->FinishTransfer) { D_DEBUG_AT( Core_SurfPoolBridge, " -> finish...\n" ); ret = funcs->FinishTransfer( bridge, bridge->data, get_local(bridge), transfer, transfer->data ); if (ret) D_DERROR( ret, "Core/SurfacePoolBridge: Finishing transfer via '%s' failed!\n", bridge->desc.name ); } D_DEBUG_AT( Core_SurfPoolBridge, " => %s\n", DirectResultString(ret) ); deallocate_transfer( transfer ); return ret; }
int main( int argc, char *argv[] ) { DFBResult ret; int i; DFBSurfaceDescription desc; IDirectFB *dfb; IDirectFBSurface *dest = NULL; DFBSurfacePixelFormat dest_format = DSPF_UNKNOWN; char pixel_buffer[100*100*4]; IDirectFBSurface *source = NULL; IDirectFBEventBuffer *keybuffer; DFBInputEvent evt; bool quit = false; /* Initialize DirectFB. */ ret = DirectFBInit( &argc, &argv ); if (ret) { D_DERROR( ret, "DFBTest/PreAlloc: DirectFBInit() failed!\n" ); return ret; } /* Parse arguments. */ for (i=1; i<argc; i++) { const char *arg = argv[i]; if (strcmp( arg, "-h" ) == 0 || strcmp (arg, "--help") == 0) return print_usage( argv[0] ); else if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) { fprintf (stderr, "dfbtest_blit version %s\n", DIRECTFB_VERSION); return false; } else if (strcmp (arg, "-d") == 0 || strcmp (arg, "--dest") == 0) { if (++i == argc) { print_usage (argv[0]); return false; } if (!parse_format( argv[i], &dest_format )) return false; } else if (strcmp (arg, "-s") == 0 || strcmp (arg, "--static") == 0) { static_caps = DSCAPS_STATIC_ALLOC; } else return print_usage( argv[0] ); } /* Create super interface. */ ret = DirectFBCreate( &dfb ); if (ret) { D_DERROR( ret, "DFBTest/PreAlloc: DirectFBCreate() failed!\n" ); return ret; } /* Fill description for a primary surface. */ desc.flags = DSDESC_CAPS; desc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING; if (dest_format != DSPF_UNKNOWN) { desc.flags |= DSDESC_PIXELFORMAT; desc.pixelformat = dest_format; } dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN ); /* Create an input buffer for key events */ dfb->CreateInputEventBuffer( dfb, DICAPS_KEYS, DFB_TRUE, &keybuffer); /* Create a primary surface. */ ret = dfb->CreateSurface( dfb, &desc, &dest ); if (ret) { D_DERROR( ret, "DFBTest/PreAlloc: IDirectFB::CreateSurface() for the destination failed!\n" ); goto out; } dest->GetSize( dest, &desc.width, &desc.height ); dest->GetPixelFormat( dest, &desc.pixelformat ); D_INFO( "DFBTest/PreAlloc: Destination is %dx%d using %s\n", desc.width, desc.height, dfb_pixelformat_name(desc.pixelformat) ); /* Create a preallocated surface. */ desc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS | DSDESC_PREALLOCATED; desc.width = 100; desc.height = 100; desc.pixelformat = DSPF_ARGB; desc.caps = static_caps; desc.preallocated[0].data = pixel_buffer; desc.preallocated[0].pitch = 100 * 4; ret = dfb->CreateSurface( dfb, &desc, &source ); if (ret) { D_DERROR( ret, "DFBTest/PreAlloc: IDirectFB::CreateSurface() for the preallocated source failed!\n" ); goto out; } /* Before any other operation the pixel data can be written to without locking */ gen_pixels( pixel_buffer, 100 * 4, 100 ); while (!quit) { void *ptr; int pitch; /* Lock source surface for writing before making updates to the pixel buffer */ source->Lock( source, DSLF_WRITE, &ptr, &pitch ); if (ptr == pixel_buffer) D_INFO( "DFBTest/PreAlloc: Locking preallocated source gave original preallocated pixel buffer :-)\n" ); else { if (static_caps) D_INFO( "DFBTest/PreAlloc: Locking preallocated source gave different pixel buffer, ERROR with static alloc!\n" ); else D_INFO( "DFBTest/PreAlloc: Locking preallocated source gave different pixel buffer, but OK (no static alloc)\n" ); } update_pixels( ptr, pitch, 100 ); /* Unlock source surface after writing, before making further Blits, to have the buffer be transfered to master again */ source->Unlock( source ); dest->Clear( dest, 0, 0, 0, 0xff ); /* First Blit from preallocated source, data will be transfered to master */ dest->Blit( dest, source, NULL, 50, 50 ); /* Second Blit from preallocated source, data is already master */ dest->Blit( dest, source, NULL, 150, 150 ); dest->Flip( dest, NULL, DSFLIP_NONE ); /* This will upload again the preallocated buffer to the master, where it is modified and outdates the preallocated buffer. Now it depends on the static alloc flag whether the next Lock will directly go into the shared memory allocation or the preallocated buffer again (with a transfer back from master to us). */ source->FillRectangle( source, 0, 0, 10, 10 ); /* Process keybuffer */ while (keybuffer->GetEvent( keybuffer, DFB_EVENT(&evt)) == DFB_OK) { if (evt.type == DIET_KEYPRESS) { switch (DFB_LOWER_CASE(evt.key_symbol)) { case DIKS_ESCAPE: case DIKS_SMALL_Q: case DIKS_BACK: case DIKS_STOP: case DIKS_EXIT: /* Quit main loop & test thread */ quit = true; break; default: break; } } } if (!quit) sleep( 5 ); } out: if (source) source->Release( source ); if (dest) dest->Release( dest ); keybuffer->Release( keybuffer ); /* Shutdown DirectFB. */ dfb->Release( dfb ); return ret; }
static DFBResult sdlAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret; CoreSurface *surface; SDLAllocationData *alloc = alloc_data; D_DEBUG_AT( SDL_Pool, "%s()\n", __FUNCTION__ ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if (surface->type & CSTF_LAYER) { dfb_sdl->screen = NULL; /* clear? */ ret = dfb_sdl_set_video_mode( dfb_sdl_core, &surface->config ); if (ret) { D_DERROR( ret, "SDL/Surface: dfb_sdl_set_video_mode() failed!\n" ); return ret; } D_ASSERT( dfb_sdl->screen != NULL ); if (!dfb_sdl->screen) { D_ERROR( "SDL/Surface: No screen surface!?\n" ); return DFB_BUG; } alloc->sdl_surf = dfb_sdl->screen; D_DEBUG_AT( SDL_Pool, " -> screen surface %dx%d, %d, 0x%08x, pitch %d\n", dfb_sdl->screen->w, dfb_sdl->screen->h, dfb_sdl->screen->format->BitsPerPixel, dfb_sdl->screen->flags, dfb_sdl->screen->pitch ); allocation->flags |= CSALF_ONEFORALL; } else { DFBSurfacePixelFormat format = surface->config.format; Uint32 flags = SDL_HWSURFACE;// | SDL_ASYNCBLIT | SDL_FULLSCREEN; Uint32 rmask; Uint32 gmask; Uint32 bmask; Uint32 amask; if (surface->config.caps & DSCAPS_FLIPPING) flags |= SDL_DOUBLEBUF; switch (format) { case DSPF_A8: rmask = 0x00; gmask = 0x00; bmask = 0x00; amask = 0xff; break; case DSPF_RGB16: rmask = 0xf800; gmask = 0x07e0; bmask = 0x001f; amask = 0x0000; break; case DSPF_RGB32: rmask = 0x00ff0000; gmask = 0x0000ff00; bmask = 0x000000ff; amask = 0x00000000; break; case DSPF_ARGB: rmask = 0x00ff0000; gmask = 0x0000ff00; bmask = 0x000000ff; amask = 0xff000000; break; default: D_ERROR( "SDL/Surface: %s() has no support for %s!\n", __FUNCTION__, dfb_pixelformat_name(format) ); return DFB_UNSUPPORTED; } D_DEBUG_AT( SDL_Pool, " -> SDL_CreateRGBSurface( 0x%08x, " "%dx%d, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x )\n", flags, surface->config.size.w, surface->config.size.h, DFB_BITS_PER_PIXEL(format), rmask, gmask, bmask, amask ); alloc->sdl_surf = SDL_CreateRGBSurface( flags, surface->config.size.w, surface->config.size.h, DFB_BITS_PER_PIXEL(format), rmask, gmask, bmask, amask ); if (!alloc->sdl_surf) { D_ERROR( "SDL/Surface: SDL_CreateRGBSurface( 0x%08x, " "%dx%d, %d, 0x%08x, 0x%08x, 0x%08x, 0x%08x ) failed!\n", flags, surface->config.size.w, surface->config.size.h, DFB_BITS_PER_PIXEL(format), rmask, gmask, bmask, amask ); return DFB_FAILURE; } } D_MAGIC_SET( alloc, SDLAllocationData ); return DFB_OK; }
DFBResult dfb_surface_write_buffer( CoreSurface *surface, CoreSurfaceBufferRole role, const void *source, int pitch, const DFBRectangle *prect ) { DFBResult ret; int bytes; DFBRectangle rect; DFBSurfacePixelFormat format; CoreSurfaceAllocation *allocation; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( pitch > 0 || source == NULL ); DFB_RECTANGLE_ASSERT_IF( prect ); D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, source, pitch ); /* Determine area. */ rect.x = 0; rect.y = 0; rect.w = surface->config.size.w; rect.h = surface->config.size.h; if (prect) { if (!dfb_rectangle_intersect( &rect, prect )) { D_DEBUG_AT( Core_Surface, " -> no intersection!\n" ); return DFB_INVAREA; } if (!DFB_RECTANGLE_EQUAL( rect, *prect )) { D_DEBUG_AT( Core_Surface, " -> got clipped to %d,%d-%dx%d!\n", DFB_RECTANGLE_VALS(&rect) ); return DFB_INVAREA; } } /* Calculate bytes per read line. */ format = surface->config.format; bytes = DFB_BYTES_PER_LINE( format, rect.w ); D_DEBUG_AT( Core_Surface, " -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect), dfb_pixelformat_name( format ) ); ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_WRITE, false, &allocation ); if (ret) return ret; D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_DEBUG_AT( Core_Surface, " -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name ); /* Try writing to allocation directly... */ ret = source ? dfb_surface_pool_write( allocation->pool, allocation, source, pitch, &rect ) : DFB_UNSUPPORTED; if (ret) { /* ...otherwise use fallback method via locking if possible. */ if (allocation->access[CSAID_CPU] & CSAF_WRITE) { int y; int bytes; DFBSurfacePixelFormat format; CoreSurfaceBufferLock lock; /* Calculate bytes per written line. */ format = surface->config.format; bytes = DFB_BYTES_PER_LINE( format, rect.w ); /* Lock the allocation. */ dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE ); ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock ); if (ret) { D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); dfb_surface_allocation_unref( allocation ); return ret; } /* Move to start of write. */ lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch; /* Copy the data. */ for (y=0; y<rect.h; y++) { if (source) { direct_memcpy( lock.addr, source, bytes ); source += pitch; } else memset( lock.addr, 0, bytes ); lock.addr += lock.pitch; } /* Unlock the allocation. */ ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock ); if (ret) D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); } } dfb_surface_allocation_unref( allocation ); return DFB_OK; }
Bool dfb_x11_open_window( DFBX11 *x11, XWindow** ppXW, int iXPos, int iYPos, int iWidth, int iHeight, DFBSurfacePixelFormat format ) { XWindow *xw; XSetWindowAttributes attr = { .background_pixmap = 0 }; void *old_error_handler = 0; unsigned int cw_mask = CWEventMask; D_DEBUG_AT( X11_Window, "Creating %4dx%4d %s window...\n", iWidth, iHeight, dfb_pixelformat_name(format) ); xw = D_CALLOC( 1, sizeof(XWindow) ); if (!xw) return D_OOM(); /* We set the structure as needed for our window */ xw->width = iWidth; xw->height = iHeight; xw->display = x11->display; xw->screenptr = DefaultScreenOfDisplay(xw->display); xw->screennum = DefaultScreen(xw->display); xw->depth = DefaultDepthOfScreen(xw->screenptr); xw->visual = DefaultVisualOfScreen(xw->screenptr); attr.event_mask = ButtonPressMask | ButtonReleaseMask | PointerMotionMask | KeyPressMask | KeyReleaseMask | ExposureMask | StructureNotifyMask; if (dfb_config->x11_borderless) { attr.override_redirect = True; cw_mask |= CWOverrideRedirect; } XLockDisplay( x11->display ); old_error_handler = XSetErrorHandler( error_handler ); error_code = 0; xw->window = XCreateWindow( xw->display, RootWindowOfScreen(xw->screenptr), iXPos, iYPos, iWidth, iHeight, 0, xw->depth, InputOutput, xw->visual, cw_mask, &attr ); XSync( xw->display, False ); if (!xw->window || error_code) { D_FREE( xw ); XUnlockDisplay( x11->display ); return False; } XSizeHints Hints; /* * Here we inform the function of what we are going to change for the * window (there's also PPosition but it's obsolete) */ Hints.flags = PSize | PMinSize | PMaxSize; /* * Now we set the structure to the values we need for width & height. * For esthetic reasons we set Width=MinWidth=MaxWidth. * The same goes for Height. You can try whith differents values, or * let's use Hints.flags=Psize; and resize your window.. */ Hints.min_width = Hints.max_width = Hints.base_width = xw->width; Hints.min_height = Hints.max_height = Hints.base_height = xw->height; /* Now we can set the size hints for the specified window */ XSetWMNormalHints(xw->display,xw->window,&Hints); /* We change the title of the window (default:Untitled) */ XStoreName(xw->display,xw->window,"DFB X11 system window"); xw->gc = XCreateGC(xw->display, xw->window, 0, NULL); #if 0 // Create a null cursor Pixmap pixmp1; Pixmap pixmp2; XColor fore; XColor back; char zero = 0; pixmp1 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 ); pixmp2 = XCreateBitmapFromData( xw->display, xw->window, &zero, 1, 1 ); xw->NullCursor = XCreatePixmapCursor( xw->display, pixmp1, pixmp2, &fore, &back, 0, 0 ); XFreePixmap ( xw->display, pixmp1 ); XFreePixmap ( xw->display, pixmp2 ); XDefineCursor( xw->display, xw->window, xw->NullCursor ); #endif /* maps the window and raises it to the top of the stack */ XMapRaised( xw->display, xw->window ); if (x11->use_shm) { // Shared memory xw->shmseginfo=(XShmSegmentInfo *)D_CALLOC(1, sizeof(XShmSegmentInfo)); if (!xw->shmseginfo) { x11->use_shm = false; goto no_shm; } xw->ximage=XShmCreateImage(xw->display, xw->visual, xw->depth, ZPixmap, NULL,xw->shmseginfo, xw->width, xw->height * 2); XSync( xw->display, False ); if (!xw->ximage || error_code) { D_ERROR("X11: Error creating shared image (XShmCreateImage) \n"); x11->use_shm = false; D_FREE(xw->shmseginfo); error_code = 0; goto no_shm; } xw->bpp = (xw->ximage->bits_per_pixel + 7) / 8; /* we firstly create our shared memory segment with the size we need, and correct permissions for the owner, the group and the world --> 0777 */ xw->shmseginfo->shmid=shmget(IPC_PRIVATE, xw->ximage->bytes_per_line * xw->ximage->height * 2, IPC_CREAT|0777); if (xw->shmseginfo->shmid<0) { x11->use_shm = false; XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); goto no_shm; } /* Then, we have to attach the segment to our process, and we let the function search the correct memory place --> NULL. It's safest ! */ xw->shmseginfo->shmaddr = shmat( xw->shmseginfo->shmid, NULL, 0 ); if (!xw->shmseginfo->shmaddr) { x11->use_shm = false; shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL); XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); goto no_shm; } /* We set the buffer in Read and Write mode */ xw->shmseginfo->readOnly=False; xw->virtualscreen= xw->ximage->data = xw->shmseginfo->shmaddr; XSetErrorHandler( error_handler_shm ); XShmAttach(x11->display,xw->shmseginfo); XShmPutImage(x11->display, xw->window, xw->gc, xw->ximage, 0, 0, 0, 0, 1, 1, False); XSync(x11->display, False); XSetErrorHandler( error_handler ); if (!x11->use_shm) { shmdt(xw->shmseginfo->shmaddr); shmctl(xw->shmseginfo->shmid,IPC_RMID,NULL); XDestroyImage(xw->ximage); D_FREE(xw->shmseginfo); } } no_shm: if (!x11->use_shm) { int pitch; xw->bpp = (xw->depth > 16) ? 4 : (xw->depth > 8) ? 2 : 1; pitch = (xw->bpp * xw->width + 3) & ~3; /* Use malloc(), not D_MALLOC() here, because XCreateImage() * will call free() on this data. */ xw->virtualscreen = malloc ( 2 * xw->height * pitch ); xw->ximage = XCreateImage( xw->display, xw->visual, xw->depth, ZPixmap, 0, xw->virtualscreen, xw->width, xw->height * 2, 32, pitch ); XSync( xw->display, False ); if (!xw->ximage || error_code) { D_ERROR( "X11/Window: XCreateImage( Visual %02lu, depth %d, size %dx%d, buffer %p [%d] ) failed!\n", xw->visual->visualid, xw->depth, xw->width, xw->height * 2, xw->virtualscreen, pitch ); XFreeGC(xw->display,xw->gc); XDestroyWindow(xw->display,xw->window); XSetErrorHandler( old_error_handler ); XUnlockDisplay( x11->display ); D_FREE( xw ); return False; } } XSetErrorHandler( old_error_handler ); XUnlockDisplay( x11->display ); D_INFO( "X11/Display: %ssing XShm.\n", x11->use_shm ? "U" : "Not u" ); (*ppXW) = xw; return True; } void dfb_x11_close_window( DFBX11 *x11, XWindow* xw ) { if (x11->use_shm) { XShmDetach( xw->display, xw->shmseginfo ); shmdt( xw->shmseginfo->shmaddr ); shmctl( xw->shmseginfo->shmid, IPC_RMID, NULL ); D_FREE( xw->shmseginfo ); } XDestroyImage( xw->ximage ); XFreeGC( xw->display, xw->gc ); XDestroyWindow( xw->display, xw->window ); #if 0 XFreeCursor( xw->display, xw->NullCursor ); #endif D_FREE( xw ); }
int main( int argc, char *argv[] ) { int i; DFBResult ret; DFBSurfaceDescription desc; IDirectFB *dfb; IDirectFBSurface *dest = NULL; const char *url = NULL; DFBFontAttributes attributes = DFFA_NONE; DFBSurfaceTextFlags text_flags = DSTF_TOPLEFT; int outline_width = 0x10000; int outline_opacity = 255; const DFBColorID color_ids[2] = { DCID_PRIMARY, DCID_OUTLINE }; const DFBColor colors[2] = { { 0xff, 0xff, 0xff, 0xff }, { 0xff, 0x00, 0x80, 0xff } }; /* Initialize DirectFB. */ ret = DirectFBInit( &argc, &argv ); if (ret) { D_DERROR( ret, "DFBTest/Font: DirectFBInit() failed!\n" ); return ret; } /* Parse arguments. */ for (i=1; i<argc; i++) { const char *arg = argv[i]; if (strcmp( arg, "-h" ) == 0 || strcmp (arg, "--help") == 0) return print_usage( argv[0] ); else if (strcmp (arg, "-v") == 0 || strcmp (arg, "--version") == 0) { fprintf (stderr, "dfbtest_blit version %s\n", DIRECTFB_VERSION); return false; } else if (strcmp (arg, "-o") == 0 || strcmp (arg, "--outline") == 0) { attributes |= DFFA_OUTLINED; text_flags |= DSTF_OUTLINE; } else if (strcmp (arg, "-ow") == 0 || strcmp (arg, "--outline-width") == 0) { if (++i == argc) return print_usage( argv[0] ); if (sscanf( argv[i], "%d", &outline_width ) != 1) return print_usage( argv[0] ); outline_width <<= 16; } else if (strcmp (arg, "-oo") == 0 || strcmp (arg, "--outline-opacity") == 0) { if (++i == argc) return print_usage( argv[0] ); if (sscanf( argv[i], "%d", &outline_opacity ) != 1) return print_usage( argv[0] ); } else if (!url) url = arg; else return print_usage( argv[0] ); } /* Check if we got an URL. */ if (!url) return print_usage( argv[0] ); /* Create super interface. */ ret = DirectFBCreate( &dfb ); if (ret) { D_DERROR( ret, "DFBTest/Font: DirectFBCreate() failed!\n" ); return ret; } /* Fill description for a primary surface. */ desc.flags = DSDESC_CAPS; desc.caps = DSCAPS_PRIMARY | DSCAPS_FLIPPING; dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN ); /* Create a primary surface. */ ret = dfb->CreateSurface( dfb, &desc, &dest ); if (ret) { D_DERROR( ret, "DFBTest/Font: IDirectFB::CreateSurface() failed!\n" ); goto out; } dest->GetSize( dest, &desc.width, &desc.height ); dest->GetPixelFormat( dest, &desc.pixelformat ); D_INFO( "DFBTest/Font: Destination is %dx%d using %s\n", desc.width, desc.height, dfb_pixelformat_name(desc.pixelformat) ); for (i=10; i<50; i++) { IDirectFBFont *font; font = CreateFont( dfb, url, i, attributes, outline_width, outline_opacity ); RenderChecker( dest, 64, 64 ); dest->SetColors( dest, color_ids, colors, 2 ); dest->SetFont( dest, font ); dest->DrawString( dest, "Test String AVAWA", -1, 100, 100, text_flags ); dest->Flip( dest, NULL, DSFLIP_NONE ); font->Release( font ); usleep( 500000 ); } out: if (dest) dest->Release( dest ); /* Shutdown DirectFB. */ dfb->Release( dfb ); return ret; }
DFBResult dfb_surface_read_buffer( CoreSurface *surface, CoreSurfaceBufferRole role, void *destination, int pitch, const DFBRectangle *prect ) { DFBResult ret; int y; int bytes; DFBRectangle rect; DFBSurfacePixelFormat format; CoreSurfaceAllocation *allocation; D_MAGIC_ASSERT( surface, CoreSurface ); D_ASSERT( destination != NULL ); D_ASSERT( pitch > 0 ); DFB_RECTANGLE_ASSERT_IF( prect ); D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, destination, pitch ); /* Determine area. */ rect.x = 0; rect.y = 0; rect.w = surface->config.size.w; rect.h = surface->config.size.h; if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect ))) return DFB_INVAREA; /* Calculate bytes per read line. */ format = surface->config.format; bytes = DFB_BYTES_PER_LINE( format, rect.w ); D_DEBUG_AT( Core_Surface, " -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect), dfb_pixelformat_name( format ) ); ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_READ, false, &allocation ); if (ret == DFB_NOALLOCATION) { for (y=0; y<rect.h; y++) { memset( destination, 0, bytes ); destination += pitch; } return DFB_OK; } if (ret) return ret; D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation ); D_DEBUG_AT( Core_Surface, " -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name ); /* Try reading from allocation directly... */ ret = dfb_surface_pool_read( allocation->pool, allocation, destination, pitch, &rect ); if (ret) { /* ...otherwise use fallback method via locking if possible. */ if (allocation->access[CSAID_CPU] & CSAF_READ) { CoreSurfaceBufferLock lock; /* Lock the allocation. */ dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_READ ); ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock ); if (ret) { D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); dfb_surface_allocation_unref( allocation ); return ret; } /* Move to start of read. */ lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch; /* Copy the data. */ for (y=0; y<rect.h; y++) { direct_memcpy( destination, lock.addr, bytes ); destination += pitch; lock.addr += lock.pitch; } /* Unlock the allocation. */ ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock ); if (ret) D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name ); dfb_surface_buffer_lock_deinit( &lock ); } } dfb_surface_allocation_unref( allocation ); return DFB_OK; }
/* * Check for acceleration of 'accel' using the given 'state'. */ void pvr2dCheckState(void *drv, void *dev, CardState *state, DFBAccelerationMask accel) { D_DEBUG_AT(PVR2D__2D, "%s(state %p, accel 0x%08x) <- dest %p [%lu]\n", __FUNCTION__, state, accel, state->destination, state->dst.offset); // Return if the desired function is not supported at all. if (accel & ~(PVR2D_SUPPORTED_DRAWINGFUNCTIONS | PVR2D_SUPPORTED_BLITTINGFUNCTIONS)) { D_DEBUG_AT(PVR2D__2D, " -> unsupported function\n"); return; } // Return if the destination format is not supported. switch (state->destination->config.format) { case DSPF_ARGB: case DSPF_RGB32: case DSPF_RGB16: break; default: D_DEBUG_AT (PVR2D__2D, " -> unsupported destination format %s\n", dfb_pixelformat_name(state->destination->config.format)); return; } // Check if drawing or blitting is requested. if (DFB_DRAWING_FUNCTION(accel)) { // Return if unsupported drawing flags are set. if (state->drawingflags & ~PVR2D_SUPPORTED_DRAWINGFLAGS) { D_DEBUG_AT(PVR2D__2D, " -> unsupported drawing flags 0x%08x\n", state->drawingflags); return; } } else { // Return if the source format is not supported. switch (state->source->config.format) { case DSPF_A8: case DSPF_ARGB: case DSPF_RGB32: case DSPF_RGB16: break; default: D_DEBUG_AT (PVR2D__2D, " -> unsupported source format %s\n", dfb_pixelformat_name(state->source->config.format)); return; } // Return if unsupported blitting flags are set. if (state->blittingflags & ~PVR2D_SUPPORTED_BLITTINGFLAGS) { D_DEBUG_AT(PVR2D__2D, " -> unsupported blit flags 0x%08x\n", state->blittingflags); return; } if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) { if (state->dst_blend != DSBF_INVSRCALPHA || (state->src_blend != DSBF_SRCALPHA && state->src_blend != DSBF_ONE)) { D_DEBUG_AT(PVR2D__2D, " -> unsupported blend functions 0x%02x 0x%02x\n", state->src_blend, state->dst_blend); return; } } } // Enable acceleration of the function. state->accel |= accel; D_DEBUG_AT(PVR2D__2D, " => OK\n"); }
static DFBResult driver_init_device( CoreGraphicsDevice *device, GraphicsDeviceInfo *device_info, void *driver_data, void *device_data ) { SH7722DriverData *sdrv = driver_data; SH7722DeviceData *sdev = device_data; D_DEBUG_AT( SH7722_Driver, "%s()\n", __FUNCTION__ ); /* FIXME: Add a runtime option / config file. */ sdev->lcd_format = DSPF_RGB16; /* Check format of LCD buffer. */ switch (sdev->lcd_format) { case DSPF_RGB16: case DSPF_NV16: break; default: return DFB_UNSUPPORTED; } /* * Setup LCD buffer. */ sdev->lcd_width = SH7722_LCD_WIDTH; sdev->lcd_height = SH7722_LCD_HEIGHT; sdev->lcd_pitch = (DFB_BYTES_PER_LINE( sdev->lcd_format, sdev->lcd_width ) + 0xf) & ~0xf; sdev->lcd_size = DFB_PLANE_MULTIPLY( sdev->lcd_format, sdev->lcd_height ) * sdev->lcd_pitch; sdev->lcd_offset = dfb_gfxcard_reserve_memory( device, sdev->lcd_size ); if (sdev->lcd_offset < 0) { D_ERROR( "SH7722/Driver: Allocating %d bytes for the LCD buffer failed!\n", sdev->lcd_size ); return DFB_FAILURE; } sdev->lcd_phys = dfb_gfxcard_memory_physical( device, sdev->lcd_offset ); /* Get virtual addresses for JPEG reload buffers in master here, slaves do it in driver_init_driver(). */ sdrv->lcd_virt = dfb_gfxcard_memory_virtual( device, sdev->lcd_offset ); D_INFO( "SH7722/LCD: Allocated %dx%d %s Buffer (%d bytes) at 0x%08lx (%p)\n", sdev->lcd_width, sdev->lcd_height, dfb_pixelformat_name(sdev->lcd_format), sdev->lcd_size, sdev->lcd_phys, sdrv->lcd_virt ); D_ASSERT( ! (sdev->lcd_pitch & 0xf) ); D_ASSERT( ! (sdev->lcd_phys & 0xf) ); /* * Setup JPEG reload buffers. */ sdev->jpeg_size = SH7722GFX_JPEG_RELOAD_SIZE * 2 + SH7722GFX_JPEG_LINEBUFFER_SIZE * 2; sdev->jpeg_offset = dfb_gfxcard_reserve_memory( device, sdev->jpeg_size ); if (sdev->jpeg_offset < 0) { D_ERROR( "SH7722/Driver: Allocating %d bytes for the JPEG reload and line buffers failed!\n", sdev->jpeg_size ); return DFB_FAILURE; } sdev->jpeg_phys = dfb_gfxcard_memory_physical( device, sdev->jpeg_offset ); sdev->jpeg_lb1 = sdev->jpeg_phys + SH7722GFX_JPEG_RELOAD_SIZE * 2; sdev->jpeg_lb2 = sdev->jpeg_lb1 + SH7722GFX_JPEG_LINEBUFFER_SIZE; /* Get virtual addresses for JPEG reload buffers in master here, slaves do it in driver_init_driver(). */ sdrv->jpeg_virt = dfb_gfxcard_memory_virtual( device, sdev->jpeg_offset ); D_INFO( "SH7722/JPEG: Allocated reload and line buffers (%d bytes) at 0x%08lx (%p)\n", sdev->jpeg_size, sdev->jpeg_phys, sdrv->jpeg_virt ); D_ASSERT( ! (sdev->jpeg_size & 0xff) ); D_ASSERT( ! (sdev->jpeg_phys & 0xf) ); /* Fill in the device info. */ snprintf( device_info->name, DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH, "SH7722" ); snprintf( device_info->vendor, DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "Renesas" ); /* Set device limitations. */ device_info->limits.surface_byteoffset_alignment = 16; device_info->limits.surface_bytepitch_alignment = 8; /* Set device capabilities. */ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS; device_info->caps.accel = SH7722_SUPPORTED_DRAWINGFUNCTIONS | SH7722_SUPPORTED_BLITTINGFUNCTIONS; device_info->caps.drawing = SH7722_SUPPORTED_DRAWINGFLAGS; device_info->caps.blitting = SH7722_SUPPORTED_BLITTINGFLAGS; /* Change font format for acceleration. */ if (!dfb_config->software_only) { dfb_config->font_format = DSPF_ARGB; dfb_config->font_premult = false; } /* * Initialize hardware. */ /* Reset the drawing engine. */ sh7722EngineReset( sdrv, sdev ); /* Wait for idle BEU. */ while (SH7722_GETREG32( sdrv, BSTAR ) & 1); /* Disable all inputs. */ SH7722_SETREG32( sdrv, BESTR, 0 ); /* Disable all multi windows. */ SH7722_SETREG32( sdrv, BMWCR0, SH7722_GETREG32( sdrv, BMWCR0 ) & ~0xf ); /* Clear LCD buffer. */ switch (sdev->lcd_format) { case DSPF_RGB16: memset( (void*) sdrv->lcd_virt, 0x00, sdev->lcd_height * sdev->lcd_pitch ); break; case DSPF_NV16: memset( (void*) sdrv->lcd_virt, 0x10, sdev->lcd_height * sdev->lcd_pitch ); memset( (void*) sdrv->lcd_virt + sdev->lcd_height * sdev->lcd_pitch, 0x80, sdev->lcd_height * sdev->lcd_pitch ); break; default: D_BUG( "unsupported format" ); return DFB_BUG; } /* * TODO: Make LCD Buffer format and primary BEU format runtime configurable. */ /* Set output pixel format of the BEU. */ switch (sdev->lcd_format) { case DSPF_RGB16: SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | WPCK_RGB16 ); break; case DSPF_NV16: SH7722_SETREG32( sdrv, BPKFR, BPKFR_RY_RGB | BPKFR_TE_ENABLED | CHDS_YCBCR422 ); SH7722_SETREG32( sdrv, BDACR, sdev->lcd_phys + sdev->lcd_height * sdev->lcd_pitch ); break; default: D_BUG( "unsupported format" ); return DFB_BUG; } SH7722_SETREG32( sdrv, BPROCR, 0x00000000 ); /* Have BEU render into LCD buffer. */ SH7722_SETREG32( sdrv, BBLCR1, MT_MEMORY ); SH7722_SETREG32( sdrv, BDAYR, sdev->lcd_phys & 0xfffffffc ); SH7722_SETREG32( sdrv, BDMWR, sdev->lcd_pitch & 0x0003fffc ); /* Setup LCD controller to show the buffer. */ sh7722_lcd_setup( sdrv, sdev->lcd_width, sdev->lcd_height, sdev->lcd_phys, sdev->lcd_pitch, sdev->lcd_format, false ); /* Initialize BEU lock. */ fusion_skirmish_init( &sdev->beu_lock, "BEU", dfb_core_world(sdrv->core) ); /* Initialize JPEG lock. */ fusion_skirmish_init( &sdev->jpeg_lock, "JPEG", dfb_core_world(sdrv->core) ); return DFB_OK; }
/* * Make sure that the hardware is programmed for execution of 'accel' according to the 'state'. */ void davinciSetState( void *drv, void *dev, GraphicsDeviceFuncs *funcs, CardState *state, DFBAccelerationMask accel ) { DavinciDeviceData *ddev = dev; StateModificationFlags modified = state->mod_hw; D_DEBUG_AT( Davinci_2D, "%s( state %p, accel 0x%08x ) <- dest %p, modified 0x%08x\n", __FUNCTION__, state, accel, state->destination, modified ); /* * 1) Invalidate hardware states * * Each modification to the hw independent state invalidates one or more hardware states. */ /* Simply invalidate all? */ if (modified == SMF_ALL) { D_DEBUG_AT( Davinci_2D, " <- ALL\n" ); DAVINCI_INVALIDATE( ALL ); } else if (modified) { /* Invalidate destination settings. */ if (modified & SMF_DESTINATION) { D_DEBUG_AT( Davinci_2D, " <- DESTINATION | FILLCOLOR\n" ); DAVINCI_INVALIDATE( DESTINATION | FILLCOLOR ); } else if (modified & SMF_COLOR) { D_DEBUG_AT( Davinci_2D, " <- FILLCOLOR\n" ); DAVINCI_INVALIDATE( FILLCOLOR ); } /* Invalidate source settings. */ if (modified & SMF_SOURCE) { D_DEBUG_AT( Davinci_2D, " <- SOURCE\n" ); DAVINCI_INVALIDATE( SOURCE ); } /* Invalidate source color(ize) settings. */ if (modified & (SMF_BLITTING_FLAGS | SMF_COLOR)) { D_DEBUG_AT( Davinci_2D, " <- SOURCE_MULT\n" ); DAVINCI_INVALIDATE( SOURCE_MULT ); } /* Invalidate blend function for blitting. */ if (modified & (SMF_BLITTING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND)) { D_DEBUG_AT( Davinci_2D, " <- BLIT_BLEND_SUB\n" ); DAVINCI_INVALIDATE( BLIT_BLEND_SUB ); } /* Invalidate blend function for drawing. */ if (modified & (SMF_DRAWING_FLAGS | SMF_SRC_BLEND | SMF_DST_BLEND)) { D_DEBUG_AT( Davinci_2D, " <- DRAW_BLEND_SUB\n" ); DAVINCI_INVALIDATE( DRAW_BLEND_SUB ); } } /* * Just keep these values, no computations needed here. * Values used by state validation or rendering functions. */ ddev->blitting_flags = state->blittingflags; ddev->clip = state->clip; ddev->color = state->color; ddev->colorkey = state->src_colorkey; ddev->color_argb = PIXEL_ARGB( state->color.a, state->color.r, state->color.g, state->color.b ); /* * 2) Validate hardware states * * Each function has its own set of states that need to be validated. */ /* Always requiring valid destination... */ DAVINCI_CHECK_VALIDATE( DESTINATION ); /* Depending on the function... */ switch (accel) { case DFXL_FILLRECTANGLE: D_DEBUG_AT( Davinci_2D, " -> FILLRECTANGLE\n" ); /* Validate blend sub function index for drawing... */ if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY)) DAVINCI_CHECK_VALIDATE( DRAW_BLEND_SUB ); else /* ...or just validate fill color. */ DAVINCI_CHECK_VALIDATE( FILLCOLOR ); /* Choose function. */ switch (DFB_BYTES_PER_PIXEL( state->destination->config.format )) { case 2: funcs->FillRectangle = davinciFillRectangle16; break; case 4: if (state->drawingflags & (DSDRAW_BLEND | DSDRAW_SRC_PREMULTIPLY)) funcs->FillRectangle = davinciFillRectangleBlend32; else funcs->FillRectangle = davinciFillRectangle32; break; default: D_BUG( "unexpected destination bpp %d", DFB_BYTES_PER_PIXEL( state->destination->config.format ) ); break; } /* * 3) Tell which functions can be called without further validation, i.e. SetState() * * When the hw independent state is changed, this collection is reset. */ state->set |= DAVINCI_SUPPORTED_DRAWINGFUNCTIONS; break; case DFXL_BLIT: D_DEBUG_AT( Davinci_2D, " -> BLIT\n" ); /* ...require valid source. */ DAVINCI_CHECK_VALIDATE( SOURCE ); /* Validate blend sub function index for blitting. */ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) { DAVINCI_CHECK_VALIDATE( BLIT_BLEND_SUB ); /* Validate ARGB source modulator. */ DAVINCI_CHECK_VALIDATE( SOURCE_MULT ); } /* Choose function. */ switch (DFB_BYTES_PER_PIXEL( state->destination->config.format )) { case 2: if (state->blittingflags & DSBLIT_SRC_COLORKEY) funcs->Blit = davinciBlitKeyed16; else if (state->source->config.format == DSPF_ARGB || state->source->config.format == DSPF_RGB32) funcs->Blit = davinciBlit32to16; else funcs->Blit = davinciBlit16; break; case 4: if (state->blittingflags & DSBLIT_SRC_COLORKEY) funcs->Blit = davinciBlitKeyed32; else if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) funcs->Blit = davinciBlitBlend32; else funcs->Blit = davinciBlit32; break; default: D_BUG( "unexpected destination bpp %d", DFB_BYTES_PER_PIXEL( state->destination->config.format ) ); break; } /* * 3) Tell which functions can be called without further validation, i.e. SetState() * * When the hw independent state is changed, this collection is reset. */ state->set |= DFXL_BLIT; break; case DFXL_STRETCHBLIT: D_DEBUG_AT( Davinci_2D, " -> STRETCHBLIT\n" ); /* ...require valid source. */ DAVINCI_CHECK_VALIDATE( SOURCE ); /* Choose function. */ #if 0 // only 32bit, statically set in driver_init_driver() switch (state->destination->config.format) { case DSPF_ARGB: case DSPF_RGB32: funcs->StretchBlit = davinciStretchBlit32; break; default: D_BUG( "unexpected destination format %s", dfb_pixelformat_name( state->destination->config.format ) ); break; } #endif /* * 3) Tell which functions can be called without further validation, i.e. SetState() * * When the hw independent state is changed, this collection is reset. */ state->set |= DFXL_STRETCHBLIT; break; default: D_BUG( "unexpected drawing/blitting function" ); break; } /* * 4) Clear modification flags * * All flags have been evaluated in 1) and remembered for further validation. * If the hw independent state is not modified, this function won't get called * for subsequent rendering functions, unless they aren't defined by 3). */ state->mod_hw = 0; }
static DFBResult fbdevAllocateBuffer( CoreSurfacePool *pool, void *pool_data, void *pool_local, CoreSurfaceBuffer *buffer, CoreSurfaceAllocation *allocation, void *alloc_data ) { DFBResult ret; CoreSurface *surface; FBDevPoolData *data = pool_data; FBDevPoolLocalData *local = pool_local; FBDevAllocationData *alloc = alloc_data; D_DEBUG_AT( FBDev_Surfaces, "%s( %p )\n", __FUNCTION__, buffer ); D_MAGIC_ASSERT( pool, CoreSurfacePool ); D_MAGIC_ASSERT( data, FBDevPoolData ); D_MAGIC_ASSERT( local, FBDevPoolLocalData ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); surface = buffer->surface; D_MAGIC_ASSERT( surface, CoreSurface ); if ((surface->type & CSTF_LAYER) && surface->resource_id == DLID_PRIMARY) { FBDevShared *shared = dfb_fbdev->shared; int index = dfb_surface_buffer_index( buffer ); D_DEBUG_AT( FBDev_Surfaces, " -> primary layer buffer (index %d)\n", index ); if (( (surface->config.caps & DSCAPS_FLIPPING) && index == 1) || (!(surface->config.caps & DSCAPS_FLIPPING) && index == 0) ) { const VideoMode *highest; /* FIXME: this should use source.w/source.h from layer region config! */ unsigned int width = surface->config.size.w; unsigned int height = surface->config.size.h; D_INFO( "FBDev/Mode: Setting %dx%d %s\n", width, height, dfb_pixelformat_name(surface->config.format) ); highest = dfb_fbdev_find_mode( width, height ); if (!highest) return DFB_UNSUPPORTED; ret = dfb_fbdev_set_mode( highest, surface, 0, 0 ); if (ret) return ret; } alloc->pitch = shared->fix.line_length; alloc->size = surface->config.size.h * alloc->pitch; alloc->offset = index * alloc->size; D_INFO( "FBDev/Surface: Allocated %dx%d %d bit %s buffer (index %d) at offset %d and pitch %d.\n", surface->config.size.w, surface->config.size.h, shared->current_var.bits_per_pixel, dfb_pixelformat_name(buffer->format), index, alloc->offset, alloc->pitch ); } else { Chunk *chunk; ret = dfb_surfacemanager_allocate( local->core, data->manager, buffer, allocation, &chunk ); if (ret) return ret; D_MAGIC_ASSERT( chunk, Chunk ); alloc->offset = chunk->offset; alloc->pitch = chunk->pitch; alloc->size = chunk->length; alloc->chunk = chunk; } D_DEBUG_AT( FBDev_Surfaces, " -> offset %d, pitch %d, size %d\n", alloc->offset, alloc->pitch, alloc->size ); allocation->size = alloc->size; allocation->offset = alloc->offset; D_MAGIC_SET( alloc, FBDevAllocationData ); return DFB_OK; }
int main( int argc, char *argv[] ) { int i; DFBResult ret; DFBSurfaceDescription desc; IDirectFB *dfb; IDirectFBImageProvider *provider = NULL; IDirectFBSurface *source = NULL; IDirectFBSurface *dest = NULL; const char *url = NULL; /* Parse arguments. */ for (i=1; i<argc; i++) { if (!strcmp( argv[i], "-h" )) return show_usage( argv[0] ); else if (!url) url = argv[i]; else return show_usage( argv[0] ); } /* Check if we got an URL. */ if (!url) return show_usage( argv[0] ); /* Initialize DirectFB. */ ret = DirectFBInit( &argc, &argv ); if (ret) { D_DERROR( ret, "DFBTest/Scale: DirectFBInit() failed!\n" ); return ret; } /* Create super interface. */ ret = DirectFBCreate( &dfb ); if (ret) { D_DERROR( ret, "DFBTest/Scale: DirectFBCreate() failed!\n" ); return ret; } /* Create an image provider for the image to be loaded. */ ret = dfb->CreateImageProvider( dfb, url, &provider ); if (ret) { D_DERROR( ret, "DFBTest/Scale: IDirectFB::CreateImageProvider( '%s' ) failed!\n", url ); goto out; } /* Get the surface description. */ ret = provider->GetSurfaceDescription( provider, &desc ); if (ret) { D_DERROR( ret, "DFBTest/Scale: IDirectFBImageProvider::GetSurfaceDescription() failed!\n" ); goto out; } desc.pixelformat = DSPF_LUT8; D_INFO( "DFBTest/Scale: Source is %dx%d using %s\n", desc.width, desc.height, dfb_pixelformat_name(desc.pixelformat) ); /* Create a surface for the image. */ ret = dfb->CreateSurface( dfb, &desc, &source ); if (ret) { D_DERROR( ret, "DFBTest/Scale: IDirectFB::CreateSurface() failed!\n" ); goto out; } ret = provider->RenderTo( provider, source, NULL ); if (ret) { D_DERROR( ret, "DFBTest/Scale: IDirectFBImageProvider::RenderTo() failed!\n" ); goto out; } desc.width = desc.width * 3 / 4; desc.height = desc.height * 3 / 4; if (DFB_PIXELFORMAT_IS_INDEXED( desc.pixelformat )) desc.pixelformat = DSPF_ARGB; D_INFO( "DFBTest/Scale: Destination is %dx%d using %s\n", desc.width, desc.height, dfb_pixelformat_name(desc.pixelformat) ); /* Create a surface for the image. */ ret = dfb->CreateSurface( dfb, &desc, &dest ); if (ret) { D_DERROR( ret, "DFBTest/Scale: IDirectFB::CreateSurface() failed!\n" ); goto out; } dest->SetBlittingFlags( dest, DSBLIT_SRC_PREMULTIPLY ); dest->StretchBlit( dest, source, NULL, NULL ); dest->Dump( dest, "dfbtest_scale", NULL ); out: if (dest) dest->Release( dest ); if (source) source->Release( source ); if (provider) provider->Release( provider ); /* Shutdown DirectFB. */ dfb->Release( dfb ); return ret; }