DFBResult dfb_state_set_destination( CardState *state, CoreSurface *destination ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); D_ASSUME( !(state->flags & CSF_DRAWING) ); if (state->destination != destination) { if (destination) { if (dfb_surface_ref( destination )) { D_WARN( "could not ref() destination" ); dfb_state_unlock( state ); return DFB_DEAD; } validate_clip( state, destination->config.size.w - 1, destination->config.size.h - 1, false ); } if (state->destination) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_DESTINATION ) ); dfb_surface_unref( state->destination ); } state->destination = destination; state->modified |= SMF_DESTINATION; if (destination) { direct_serial_copy( &state->dst_serial, &destination->serial ); D_FLAGS_SET( state->flags, CSF_DESTINATION ); } else D_FLAGS_CLEAR( state->flags, CSF_DESTINATION ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult dfb_layer_region_get_configuration( CoreLayerRegion *region, CoreLayerRegionConfig *config ) { D_ASSERT( region != NULL ); D_ASSERT( config != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) ); /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; /* Return the current configuration. */ *config = region->config; /* Unlock the region. */ dfb_layer_region_unlock( region ); return DFB_OK; }
static DFBResult IDirectFBDisplayLayer_SetScreenPosition( IDirectFBDisplayLayer *thiz, int x, int y ) { DFBPoint position; D_DEBUG_AT( Layer, "%s( %p )\n", __FUNCTION__, thiz ); DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_POSITION )) return DFB_UNSUPPORTED; if (data->level == DLSCL_SHARED) return DFB_ACCESSDENIED; position.x = x; position.y = y; return CoreLayerContext_SetScreenPosition( data->context, &position ); }
DFBResult dfb_state_set_source_mask( CardState *state, CoreSurface *source_mask ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source_mask != source_mask) { bool ref = true;//!fusion_config->secure_fusion || dfb_core_is_master( core_dfb ); if (source_mask && ref && dfb_surface_ref( source_mask )) { D_WARN( "could not ref() source mask" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source_mask) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE_MASK ) ); if (ref) dfb_surface_unref( state->source_mask ); } state->source_mask = source_mask; state->modified |= SMF_SOURCE_MASK; if (source_mask) { direct_serial_copy( &state->src_mask_serial, &source_mask->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE_MASK ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE_MASK ); } dfb_state_unlock( state ); return DFB_OK; }
static DFBResult IDirectFBDisplayLayer_SetScreenRectangle( IDirectFBDisplayLayer *thiz, int x, int y, int width, int height ) { DFBRectangle rect = { x, y, width, height }; D_DEBUG_AT( Layer, "%s( %p )\n", __FUNCTION__, thiz ); DIRECT_INTERFACE_GET_DATA(IDirectFBDisplayLayer) if (! D_FLAGS_IS_SET( data->desc.caps, DLCAPS_SCREEN_LOCATION )) return DFB_UNSUPPORTED; if (width <= 0 || height <= 0) return DFB_INVARG; if (data->level == DLSCL_SHARED) return DFB_ACCESSDENIED; return CoreLayerContext_SetScreenRectangle( data->context, &rect ); }
static DFBResult realize_region( CoreLayerRegion *region ) { DFBResult ret; CoreLayer *layer; CoreLayerShared *shared; DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) ); D_ASSERT( ! D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( ! fusion_vector_contains( &shared->added_regions, region ) ); /* Allocate the driver's region data. */ if (funcs->RegionDataSize) { int size = funcs->RegionDataSize(); if (size > 0) { region->region_data = SHCALLOC( 1, size ); if (!region->region_data) return D_OOSHM(); } } D_DEBUG_AT( Core_Layers, "Adding region (%d, %d - %dx%d) to '%s'.\n", DFB_RECTANGLE_VALS( ®ion->config.dest ), shared->description.name ); /* Add the region to the driver. */ if (funcs->AddRegion) { ret = funcs->AddRegion( layer, layer->driver_data, layer->layer_data, region->region_data, ®ion->config ); if (ret) { D_DERROR( ret, "Core/Layers: Could not add region!\n" ); if (region->region_data) { SHFREE( region->region_data ); region->region_data = NULL; } return ret; } } /* Add the region to the 'added' list. */ fusion_vector_add( &shared->added_regions, region ); /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_REALIZED ); /* Initially setup hardware. */ ret = set_region( region, ®ion->config, CLRCF_ALL, region->surface ); if (ret) { unrealize_region( region ); return ret; } return DFB_OK; }
/* * listen to the layer's surface */ ReactionResult _dfb_layer_region_surface_listener( const void *msg_data, void *ctx ) { CoreSurfaceNotificationFlags flags; CoreSurface *surface; CoreLayer *layer; CoreLayerShared *shared; DisplayLayerFuncs *funcs; const CoreSurfaceNotification *notification = msg_data; CoreLayerRegion *region = ctx; D_ASSERT( notification != NULL ); D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_DEBUG_AT( Core_Layers, "_dfb_layer_region_surface_listener( %p, %p ) <- 0x%08x\n", notification, region, notification->flags ); D_ASSERT( notification->surface != NULL ); D_ASSUME( notification->surface == region->surface ); if (notification->surface != region->surface) return RS_OK; layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->funcs != NULL ); D_ASSERT( layer->funcs->SetRegion != NULL ); D_ASSERT( layer->shared != NULL ); funcs = layer->funcs; shared = layer->shared; flags = notification->flags; surface = notification->surface; if (flags & CSNF_DESTROY) { D_WARN( "layer region surface destroyed" ); region->surface = NULL; return RS_REMOVE; } if (dfb_layer_region_lock( region )) return RS_OK; if (D_FLAGS_ARE_SET( region->state, CLRSF_REALIZED | CLRSF_CONFIGURED )) { if (D_FLAGS_IS_SET( flags, CSNF_PALETTE_CHANGE | CSNF_PALETTE_UPDATE )) { if (surface->palette) funcs->SetRegion( layer, layer->driver_data, layer->layer_data, region->region_data, ®ion->config, CLRCF_PALETTE, surface, surface->palette ); } if ((flags & CSNF_FIELD) && funcs->SetInputField) funcs->SetInputField( layer, layer->driver_data, layer->layer_data, region->region_data, surface->field ); if ((flags & CSNF_ALPHA_RAMP) && (shared->description.caps & DLCAPS_ALPHA_RAMP)) { region->config.alpha_ramp[0] = surface->alpha_ramp[0]; region->config.alpha_ramp[1] = surface->alpha_ramp[1]; region->config.alpha_ramp[2] = surface->alpha_ramp[2]; region->config.alpha_ramp[3] = surface->alpha_ramp[3]; funcs->SetRegion( layer, layer->driver_data, layer->layer_data, region->region_data, ®ion->config, CLRCF_ALPHA_RAMP, surface, surface->palette ); } } dfb_layer_region_unlock( region ); return RS_OK; }
DFBResult dfb_layer_region_set_configuration( CoreLayerRegion *region, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags flags ) { DFBResult ret; CoreLayer *layer; DisplayLayerFuncs *funcs; CoreLayerRegionConfig new_config; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( config != NULL ); D_ASSERT( config->buffermode != DLBM_WINDOWS ); D_ASSERT( (flags == CLRCF_ALL) || (region->state & CLRSF_CONFIGURED) ); D_ASSUME( flags != CLRCF_NONE ); D_ASSUME( ! (flags & ~CLRCF_ALL) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->funcs != NULL ); D_ASSERT( layer->funcs->TestRegion != NULL ); funcs = layer->funcs; /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; /* Full configuration supplied? */ if (flags == CLRCF_ALL) { new_config = *config; } else { /* Use the current configuration. */ new_config = region->config; /* Update each modified entry. */ if (flags & CLRCF_WIDTH) new_config.width = config->width; if (flags & CLRCF_HEIGHT) new_config.height = config->height; if (flags & CLRCF_FORMAT) new_config.format = config->format; if (flags & CLRCF_SURFACE_CAPS) new_config.surface_caps = config->surface_caps; if (flags & CLRCF_BUFFERMODE) new_config.buffermode = config->buffermode; if (flags & CLRCF_OPTIONS) new_config.options = config->options; if (flags & CLRCF_SOURCE_ID) new_config.source_id = config->source_id; if (flags & CLRCF_SOURCE) new_config.source = config->source; if (flags & CLRCF_DEST) new_config.dest = config->dest; if (flags & CLRCF_OPACITY) new_config.opacity = config->opacity; if (flags & CLRCF_ALPHA_RAMP) { new_config.alpha_ramp[0] = config->alpha_ramp[0]; new_config.alpha_ramp[1] = config->alpha_ramp[1]; new_config.alpha_ramp[2] = config->alpha_ramp[2]; new_config.alpha_ramp[3] = config->alpha_ramp[3]; } if (flags & CLRCF_SRCKEY) new_config.src_key = config->src_key; if (flags & CLRCF_DSTKEY) new_config.dst_key = config->dst_key; if (flags & CLRCF_PARITY) new_config.parity = config->parity; } /* Check if the new configuration is supported. */ ret = funcs->TestRegion( layer, layer->driver_data, layer->layer_data, &new_config, NULL ); if (ret) { dfb_layer_region_unlock( region ); return ret; } /* Propagate new configuration to the driver if the region is realized. */ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { ret = set_region( region, &new_config, flags, region->surface ); if (ret) { dfb_layer_region_unlock( region ); return ret; } } /* Update the region's current configuration. */ region->config = new_config; /* Update the region's state. */ D_FLAGS_SET( region->state, CLRSF_CONFIGURED ); /* Unlock the region. */ dfb_layer_region_unlock( region ); return DFB_OK; }
DFBResult dfb_layer_region_flip_update( CoreLayerRegion *region, const DFBRegion *update, DFBSurfaceFlipFlags flags ) { DFBResult ret = DFB_OK; CoreLayer *layer; CoreLayerContext *context; CoreSurface *surface; SurfaceBuffer *buffer; DisplayLayerFuncs *funcs; if (update) D_DEBUG_AT( Core_Layers, "dfb_layer_region_flip_update( %p, %p, 0x%08x ) <- [%d, %d - %dx%d]\n", region, update, flags, DFB_RECTANGLE_VALS_FROM_REGION( update ) ); else D_DEBUG_AT( Core_Layers, "dfb_layer_region_flip_update( %p, %p, 0x%08x )\n", region, update, flags ); D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; D_ASSUME( region->surface != NULL ); /* Check for NULL surface. */ if (!region->surface) { D_DEBUG_AT( Core_Layers, " -> No surface => no update!\n" ); dfb_layer_region_unlock( region ); return DFB_UNSUPPORTED; } context = region->context; surface = region->surface; buffer = surface->back_buffer; layer = dfb_layer_at( context->layer_id ); D_ASSERT( layer->funcs != NULL ); funcs = layer->funcs; /* Depending on the buffer mode... */ switch (region->config.buffermode) { case DLBM_TRIPLE: case DLBM_BACKVIDEO: /* Check if simply swapping the buffers is possible... */ if (!(flags & DSFLIP_BLIT) && (!update || (update->x1 == 0 && update->y1 == 0 && update->x2 == surface->width - 1 && update->y2 == surface->height - 1))) { D_DEBUG_AT( Core_Layers, " -> Going to swap buffers...\n" ); /* Use the driver's routine if the region is realized. */ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { D_ASSUME( funcs->FlipRegion != NULL ); D_DEBUG_AT( Core_Layers, " -> Waiting for pending writes...\n" ); if (buffer->video.access & VAF_HARDWARE_WRITE) { dfb_gfxcard_wait_serial( &buffer->video.serial ); buffer->video.access &= ~VAF_HARDWARE_WRITE; } D_DEBUG_AT( Core_Layers, " -> Flipping region using driver...\n" ); if (funcs->FlipRegion) ret = funcs->FlipRegion( layer, layer->driver_data, layer->layer_data, region->region_data, surface, flags ); } else { D_DEBUG_AT( Core_Layers, " -> Flipping region not using driver...\n" ); /* Just do the hardware independent work. */ dfb_surface_flip_buffers( surface, false ); } break; } /* fall through */ case DLBM_BACKSYSTEM: D_DEBUG_AT( Core_Layers, " -> Going to copy portion...\n" ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAITFORSYNC) { D_DEBUG_AT( Core_Layers, " -> Waiting for VSync...\n" ); dfb_layer_wait_vsync( layer ); } D_DEBUG_AT( Core_Layers, " -> Copying content from back to front buffer...\n" ); /* ...or copy updated contents from back to front buffer. */ dfb_back_to_front_copy( surface, update ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAIT) { D_DEBUG_AT( Core_Layers, " -> Waiting for VSync...\n" ); dfb_layer_wait_vsync( layer ); } /* fall through */ case DLBM_FRONTONLY: /* Tell the driver about the update if the region is realized. */ if (funcs->UpdateRegion && D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { D_DEBUG_AT( Core_Layers, " -> Notifying driver about updated content...\n" ); ret = funcs->UpdateRegion( layer, layer->driver_data, layer->layer_data, region->region_data, surface, update ); } break; default: D_BUG("unknown buffer mode"); ret = DFB_BUG; } D_DEBUG_AT( Core_Layers, " -> done.\n" ); /* Unlock the region. */ dfb_layer_region_unlock( region ); return ret; }
static DFBResult sh_du_set_region( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags updated, CoreSurface *surface, CorePalette *palette, CoreSurfaceBufferLock *left_lock, CoreSurfaceBufferLock *right_lock ) { DFBResult ret; SHGfxDriverData *drv; SHDuLayerData *lyr; u32 *pal, dirty; D_DEBUG_AT( SH_DU_LAYER, "%s( %u, 0x%x, 0x%lx )\n", __FUNCTION__, dfb_layer_id( layer ), updated, D_FLAGS_IS_SET( updated, CLRCF_SURFACE ) ? left_lock->phys : 0 ); D_UNUSED_P( region_data ); D_UNUSED_P( surface ); D_UNUSED_P( right_lock ); drv = (SHGfxDriverData *)driver_data; lyr = (SHDuLayerData *)layer_data; pal = NULL; dirty = 0u; /* color palette */ if (D_FLAGS_IS_SET( updated, CLRCF_PALETTE ) && palette) { unsigned int i; if (palette->num_entries > 256) return DFB_UNSUPPORTED; pal = malloc(256 * sizeof(u32)); if (!pal) return DFB_NOSYSTEMMEMORY; for (i = 0; i < palette->num_entries; i++) pal[i] = SH_DU_COLOR_TO_PALETTE(palette->entries[i]); while (i < 256) pal[i++] = 0u; } /* buffer address and stride */ if (D_FLAGS_IS_SET( updated, CLRCF_SURFACE )) { u32 stride; stride = (u32)(left_lock->pitch * 8); stride /= DFB_BITS_PER_PIXEL( left_lock->buffer->format ); if (lyr->plane.stride != stride) { lyr->plane.stride = stride; SH_DU_PLANE_SET_DIRTY( dirty, STRIDE ); } if (lyr->plane.pa0 != left_lock->phys) { lyr->plane.pa0 = left_lock->phys; SH_DU_PLANE_SET_DIRTY( dirty, PA0 ); } } /* area */ if (D_FLAGS_IS_SET( updated, CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_SOURCE | CLRCF_DEST )) { u32 sx, sy, dx, dy, w, h; if (D_FLAGS_IS_SET( updated, CLRCF_WIDTH )) { D_ASSERT( config->width > 0 ); lyr->width = config->width; } if (D_FLAGS_IS_SET( updated, CLRCF_HEIGHT )) { D_ASSERT( config->height > 0 ); lyr->height = config->height; } if (D_FLAGS_IS_SET( updated, CLRCF_SOURCE )) { D_ASSERT( config->source.x >= 0 ); D_ASSERT( config->source.y >= 0 ); lyr->sx = config->source.x; lyr->sy = config->source.y; } if (D_FLAGS_IS_SET( updated, CLRCF_DEST )) { lyr->dx = config->dest.x; lyr->dy = config->dest.y; } if (lyr->dx >= 0) { w = (u32)lyr->width; sx = (u32)lyr->sx; dx = (u32)lyr->dx; } else { w = (lyr->width + lyr->dx) <= 0 ? 0u : (u32)(lyr->width + lyr->dx); sx = (u32)(lyr->sx - lyr->dx); dx = 0u; } if (lyr->dy >= 0) { h = (u32)lyr->height; sy = (u32)lyr->sy; dy = (u32)lyr->dy; } else { h = (lyr->height + lyr->dy) <= 0 ? 0u : (u32)(lyr->height + lyr->dy); sy = (u32)(lyr->sy - lyr->dy); dy = 0u; } if (lyr->plane.width != w) { lyr->plane.width = w; SH_DU_PLANE_SET_DIRTY( dirty, WIDTH ); } if (lyr->plane.height != h) { lyr->plane.height = h; SH_DU_PLANE_SET_DIRTY( dirty, HEIGHT ); } if (lyr->plane.sx != sx) { lyr->plane.sx = sx; SH_DU_PLANE_SET_DIRTY( dirty, SX ); } if (lyr->plane.sy != sy) { lyr->plane.sy = sy; SH_DU_PLANE_SET_DIRTY( dirty, SY ); } if (lyr->plane.dx != dx) { lyr->plane.dx = dx; SH_DU_PLANE_SET_DIRTY( dirty, DX ); } if (lyr->plane.dy != dy) { lyr->plane.dy = dy; SH_DU_PLANE_SET_DIRTY( dirty, DY ); } } /* mode and opacity */ if (D_FLAGS_IS_SET( updated, CLRCF_FORMAT | CLRCF_OPTIONS | CLRCF_OPACITY )) { u32 mode, opacity; mode = lyr->plane.mode; opacity = lyr->plane.opacity; if (D_FLAGS_IS_SET( updated, CLRCF_OPACITY )) lyr->opacity = config->opacity; if (D_FLAGS_IS_SET( updated, CLRCF_OPTIONS )) { if (D_FLAGS_IS_SET( config->options, DLOP_ALPHACHANNEL )) { D_FLAGS_SET( mode, SH_DU_PMR_BLEND ); D_FLAGS_CLEAR( opacity, SH_DU_PALPHAR_ABIT_IGNORE ); D_FLAGS_SET( opacity, SH_DU_PALPHAR_PALETTE ); } else if (D_FLAGS_IS_SET( config->options, DLOP_OPACITY )) { D_FLAGS_SET( mode, SH_DU_PMR_BLEND ); D_FLAGS_SET( opacity, SH_DU_PALPHAR_ABIT_IGNORE ); D_FLAGS_CLEAR( opacity, SH_DU_PALPHAR_PALETTE ); } else { D_FLAGS_CLEAR( mode, SH_DU_PMR_BLEND ); } if (D_FLAGS_IS_SET( config->options, DLOP_SRC_COLORKEY )) D_FLAGS_CLEAR( mode, SH_DU_PMR_NOSRCKEY ); else D_FLAGS_SET( mode, SH_DU_PMR_NOSRCKEY ); } if (D_FLAGS_IS_SET( updated, CLRCF_FORMAT )) { mode &= ~SH_DU_PMR_DDF_MASK; switch (config->format) { case DSPF_RGB16: mode |= SH_DU_PMR_DDF565; break; case DSPF_ARGB1555: mode |= SH_DU_PMR_DDF1555; break; default: D_ASSERT( config->format == DSPF_LUT8 ); mode |= SH_DU_PMR_DDF8; break; } } if (D_FLAGS_IS_SET( mode, SH_DU_PMR_BLEND )) { if (D_FLAGS_IS_SET( opacity, SH_DU_PALPHAR_PALETTE )) /* pixel alpha blending */ opacity |= SH_DU_PALPHAR_ALPHA_MASK; else /* const alpha blending */ opacity = (opacity & ~SH_DU_PALPHAR_ALPHA_MASK) | (u32)lyr->opacity; } if (lyr->plane.opacity != opacity) { lyr->plane.opacity = opacity; SH_DU_PLANE_SET_DIRTY( dirty, OPACITY ); } if (lyr->plane.mode != mode) { lyr->plane.mode = mode; SH_DU_PLANE_SET_DIRTY( dirty, MODE ); } } /* src color key */ if (D_FLAGS_IS_SET( updated, CLRCF_SRCKEY )) lyr->ckey = config->src_key; if (D_FLAGS_IS_SET( updated, CLRCF_SRCKEY | CLRCF_FORMAT )) { u32 ddf, ckey; ddf = lyr->plane.mode & SH_DU_PMR_DDF_MASK; if (ddf == SH_DU_PMR_DDF8) { ckey = (u32)lyr->ckey.index; if (lyr->plane.ckey8 != ckey) { lyr->plane.ckey8 = ckey; SH_DU_PLANE_SET_DIRTY( dirty, CKEY8 ); } } else { ckey = (ddf == SH_DU_PMR_DDF565) ? SH_DU_COLORKEY_TO_RGB565( lyr->ckey ) : SH_DU_COLORKEY_TO_ARGB1555( lyr->ckey ); if (lyr->plane.ckey16 != ckey) { lyr->plane.ckey16 = ckey; SH_DU_PLANE_SET_DIRTY( dirty, CKEY16 ); } } } ret = (dirty || pal) ? update_layer( drv, lyr, dirty, pal ) : DFB_OK; if (pal) free( pal ); return ret; }
static void init_layer( const SHGfxDriverData *drv, SHDuLayerData *layer, DFBDisplayLayerID id, const CoreLayerRegionConfig *config ) { struct sh_du_reg reg; layer->id = id; /* NOTE: layer->level is assigned after added */ layer->level = -1; layer->sx = 0; layer->sy = 0; layer->dx = 0; layer->dy = 0; layer->width = config->width; layer->height = config->height; layer->opacity = 0xFF; layer->ckey.index = 0; layer->ckey.r = 0; layer->ckey.g = 0; layer->ckey.b = 0; layer->plane.id = (u8)(2 * id); layer->plane.mode = SH_DU_PMR_CPSL(id); layer->plane.pa0 = 0; layer->plane.pa1 = 0; layer->plane.pa2 = 0; layer->plane.stride = config->width; layer->plane.sx = 0; layer->plane.sy = 0; layer->plane.dx = 0; layer->plane.dy = 0; layer->plane.width = config->width; layer->plane.height = config->height; layer->plane.opacity = 0xFF; layer->plane.ckey8 = 0; layer->plane.ckey16 = 0; if (D_FLAGS_IS_SET( config->options, DLOP_ALPHACHANNEL | DLOP_OPACITY )) { layer->plane.mode |= SH_DU_PMR_BLEND; } if (!D_FLAGS_IS_SET( config->options, DLOP_SRC_COLORKEY )) { layer->plane.mode |= SH_DU_PMR_NOSRCKEY; } switch (config->format) { case DSPF_RGB16: layer->plane.mode |= SH_DU_PMR_DDF565; break; case DSPF_ARGB1555: layer->plane.mode |= SH_DU_PMR_DDF1555; if (D_FLAGS_IS_SET( config->options, DLOP_OPACITY )) layer->plane.opacity |= SH_DU_PALPHAR_ABIT_IGNORE; break; default: D_ASSERT( config->format == DSPF_LUT8 ); layer->plane.mode |= SH_DU_PMR_DDF8; break; } /* initialize undefined registers */ reg.offset = SH_DU_PWASPR( layer->plane.id ); reg.value = 0; (void)SH_DU_WRITE( drv->dpy_fd, reg ); }
static void window_update( StretRegion *region, void *region_data, void *update_data, unsigned long arg, int x, int y, const DFBRegion *updates, int num ) { int i; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; UniqueWindow *window = region_data; CardState *state = update_data; bool alpha = arg; bool visible; D_ASSERT( updates != NULL ); D_MAGIC_ASSERT( region, StretRegion ); D_MAGIC_ASSERT( window, UniqueWindow ); D_MAGIC_ASSERT( state, CardState ); D_ASSERT( window->surface != NULL ); visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE ); D_DEBUG_AT( UniQuE_Window, "window_update( region %p, window %p, visible %s, num %d )\n", region, window, visible ? "yes" : "no", num ); #if D_DEBUG_ENABLED for (i=0; i<num; i++) { D_DEBUG_AT( UniQuE_Window, " (%d) %4d,%4d - %4dx%4d\n", i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) ); } #endif if (!visible) return; /* Use per pixel alpha blending. */ if (alpha && (window->options & DWOP_ALPHACHANNEL)) flags |= DSBLIT_BLEND_ALPHACHANNEL; /* Use global alpha blending. */ if (window->opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; /* Set opacity as blending factor. */ if (state->color.a != window->opacity) { state->color.a = window->opacity; state->modified |= SMF_COLOR; } } /* Use source color keying. */ if (window->options & DWOP_COLORKEYING) { flags |= DSBLIT_SRC_COLORKEY; /* Set window color key. */ dfb_state_set_src_colorkey( state, window->color_key ); } /* Use automatic deinterlacing. */ if (window->surface->config.caps & DSCAPS_INTERLACED) flags |= DSBLIT_DEINTERLACE; /* Set blitting flags. */ dfb_state_set_blitting_flags( state, flags ); /* Set blitting source. */ state->source = window->surface; state->modified |= SMF_SOURCE; for (i=0; i<num; i++) { DFBRectangle src = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] ); /* Blit from the window to the region being updated. */ dfb_gfxcard_blit( &src, x + src.x, y + src.y, state ); } /* Reset blitting source. */ state->source = NULL; state->modified |= SMF_SOURCE; }
static DFBResult set_region( CoreLayerRegion *region, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags flags, CoreSurface *surface ) { DFBResult ret; CoreLayer *layer; CoreLayerShared *shared; const DisplayLayerFuncs *funcs; D_DEBUG_AT( Core_Layers, "%s( %p, %p, 0x%08x, %p )\n", __FUNCTION__, region, config, flags, surface ); DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( Core_Layers, config ); D_DEBUG_AT( Core_Layers, " -> state 0x%08x\n", region->state ); D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( config != NULL ); D_ASSERT( config->buffermode != DLBM_WINDOWS ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); D_ASSERT( layer->funcs->SetRegion != NULL ); if (region->state & CLRSF_FROZEN) { D_DEBUG_AT( Core_Layers, " -> FROZEN!\n" ); return DFB_OK; } shared = layer->shared; funcs = layer->funcs; if (surface) { if (flags & (CLRCF_SURFACE | CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT)) { ret = region_buffer_lock( region, surface, CSBR_FRONT ); if (ret) return ret; dfb_surface_unlock( surface ); } D_ASSERT( region->surface_lock.buffer != NULL ); } else if (region->surface_lock.buffer) { D_MAGIC_ASSERT( region->surface_lock.buffer, CoreSurfaceBuffer ); dfb_surface_unlock_buffer( region->surface_lock.buffer->surface, ®ion->surface_lock ); } D_DEBUG_AT( Core_Layers, " => setting region of '%s'\n", shared->description.name ); /* Setup hardware. */ return funcs->SetRegion( layer, layer->driver_data, layer->layer_data, region->region_data, config, flags, surface, surface ? surface->palette : NULL, ®ion->surface_lock ); }
DFBResult dfb_layer_region_flip_update( CoreLayerRegion *region, const DFBRegion *update, DFBSurfaceFlipFlags flags ) { DFBResult ret = DFB_OK; DFBRegion rotated; CoreLayer *layer; CoreLayerContext *context; CoreSurface *surface; const DisplayLayerFuncs *funcs; if (update) D_DEBUG_AT( Core_Layers, "dfb_layer_region_flip_update( %p, %p, 0x%08x ) <- [%d, %d - %dx%d]\n", region, update, flags, DFB_RECTANGLE_VALS_FROM_REGION( update ) ); else D_DEBUG_AT( Core_Layers, "dfb_layer_region_flip_update( %p, %p, 0x%08x )\n", region, update, flags ); D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); /* Lock the region. */ if (dfb_layer_region_lock( region )) return DFB_FUSION; D_ASSUME( region->surface != NULL ); /* Check for NULL surface. */ if (!region->surface) { D_DEBUG_AT( Core_Layers, " -> No surface => no update!\n" ); dfb_layer_region_unlock( region ); return DFB_UNSUPPORTED; } context = region->context; surface = region->surface; layer = dfb_layer_at( context->layer_id ); D_ASSERT( layer->funcs != NULL ); funcs = layer->funcs; /* Unfreeze region? */ if (D_FLAGS_IS_SET( region->state, CLRSF_FROZEN )) { D_FLAGS_CLEAR( region->state, CLRSF_FROZEN ); if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { ret = set_region( region, ®ion->config, CLRCF_ALL, surface ); if (ret) D_DERROR( ret, "Core/LayerRegion: set_region() in dfb_layer_region_flip_update() failed!\n" ); } else if (D_FLAGS_ARE_SET( region->state, CLRSF_ENABLED | CLRSF_ACTIVE )) { ret = realize_region( region ); if (ret) D_DERROR( ret, "Core/LayerRegion: realize_region() in dfb_layer_region_flip_update() failed!\n" ); } if (ret) { dfb_layer_region_unlock( region ); return ret; } } /* Depending on the buffer mode... */ switch (region->config.buffermode) { case DLBM_TRIPLE: case DLBM_BACKVIDEO: /* Check if simply swapping the buffers is possible... */ if (!(flags & DSFLIP_BLIT) && !surface->rotation && (!update || (update->x1 == 0 && update->y1 == 0 && update->x2 == surface->config.size.w - 1 && update->y2 == surface->config.size.h - 1))) { D_DEBUG_AT( Core_Layers, " -> Going to swap buffers...\n" ); /* Use the driver's routine if the region is realized. */ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { D_ASSUME( funcs->FlipRegion != NULL ); ret = region_buffer_lock( region, surface, CSBR_BACK ); if (ret) { dfb_layer_region_unlock( region ); return ret; } D_DEBUG_AT( Core_Layers, " -> Flipping region using driver...\n" ); if (funcs->FlipRegion) ret = funcs->FlipRegion( layer, layer->driver_data, layer->layer_data, region->region_data, surface, flags, ®ion->surface_lock ); dfb_surface_unlock( surface ); } else { D_DEBUG_AT( Core_Layers, " -> Flipping region not using driver...\n" ); /* Just do the hardware independent work. */ dfb_surface_lock( surface ); dfb_surface_flip( surface, false ); dfb_surface_unlock( surface ); } break; } /* fall through */ case DLBM_BACKSYSTEM: D_DEBUG_AT( Core_Layers, " -> Going to copy portion...\n" ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAITFORSYNC) { D_DEBUG_AT( Core_Layers, " -> Waiting for VSync...\n" ); dfb_layer_wait_vsync( layer ); } D_DEBUG_AT( Core_Layers, " -> Copying content from back to front buffer...\n" ); /* ...or copy updated contents from back to front buffer. */ dfb_back_to_front_copy_rotation( surface, update, surface->rotation ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAIT) { D_DEBUG_AT( Core_Layers, " -> Waiting for VSync...\n" ); dfb_layer_wait_vsync( layer ); } /* fall through */ case DLBM_FRONTONLY: /* Tell the driver about the update if the region is realized. */ if (funcs->UpdateRegion && D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { if (surface) { CoreSurfaceAllocation *allocation; allocation = region->surface_lock.allocation; D_ASSERT( allocation != NULL ); /* If hardware has written or is writing... */ if (allocation->accessed[CSAID_GPU] & CSAF_WRITE) { D_DEBUG_AT( Core_Layers, " -> Waiting for pending writes...\n" ); /* ...wait for the operation to finish. */ if (!(flags & DSFLIP_PIPELINE)) dfb_gfxcard_sync(); /* TODO: wait for serial instead */ allocation->accessed[CSAID_GPU] &= ~CSAF_WRITE; } dfb_surface_lock( surface ); dfb_surface_allocation_update( allocation, CSAF_READ ); dfb_surface_unlock( surface ); } D_DEBUG_AT( Core_Layers, " -> Notifying driver about updated content...\n" ); dfb_region_from_rotated( &rotated, update, &surface->config.size, surface->rotation ); ret = funcs->UpdateRegion( layer, layer->driver_data, layer->layer_data, region->region_data, surface, &rotated, ®ion->surface_lock ); } break; default: D_BUG("unknown buffer mode"); ret = DFB_BUG; } D_DEBUG_AT( Core_Layers, " -> done.\n" ); /* Unlock the region. */ dfb_layer_region_unlock( region ); return ret; }
static DFBResult unrealize_region( CoreLayerRegion *region ) { DFBResult ret; int index; CoreLayer *layer; CoreLayerShared *shared; const DisplayLayerFuncs *funcs; D_DEBUG_AT( Core_Layers, "%s( %p )\n", __FUNCTION__, region ); D_ASSERT( region != NULL ); DFB_CORE_LAYER_REGION_CONFIG_DEBUG_AT( Core_Layers, ®ion->config ); D_DEBUG_AT( Core_Layers, " -> state 0x%08x\n", region->state ); D_ASSERT( region->context != NULL ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->shared != NULL ); D_ASSERT( layer->funcs != NULL ); shared = layer->shared; funcs = layer->funcs; D_ASSERT( fusion_vector_contains( &shared->added_regions, region ) ); index = fusion_vector_index_of( &shared->added_regions, region ); D_DEBUG_AT( Core_Layers, " => removing region from '%s'\n", shared->description.name ); /* Remove the region from hardware and driver. */ if (funcs->RemoveRegion) { ret = funcs->RemoveRegion( layer, layer->driver_data, layer->layer_data, region->region_data ); if (ret) { D_DERROR( ret, "Core/Layers: Could not remove region!\n" ); return ret; } } /* Remove the region from the 'added' list. */ fusion_vector_remove( &shared->added_regions, index ); /* Deallocate the driver's region data. */ if (region->region_data) { SHFREE( shared->shmpool, region->region_data ); region->region_data = NULL; } /* Update the region's state. */ D_FLAGS_CLEAR( region->state, CLRSF_REALIZED ); D_FLAGS_SET( region->state, CLRSF_FROZEN ); if (region->surface && region->surface_lock.buffer) { dfb_surface_unlock_buffer( region->surface, ®ion->surface_lock ); dfb_surface_destroy_buffers( region->surface ); } return DFB_OK; }
static DFBResult set_region( CoreLayerRegion *region, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags flags, CoreSurface *surface ) { DFBResult ret = DFB_OK; CoreLayer *layer; const DisplayLayerFuncs *funcs; D_ASSERT( region != NULL ); D_ASSERT( region->context != NULL ); D_ASSERT( config != NULL ); D_ASSERT( config->buffermode != DLBM_WINDOWS ); D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_REALIZED ) ); layer = dfb_layer_at( region->context->layer_id ); D_ASSERT( layer != NULL ); D_ASSERT( layer->funcs != NULL ); D_ASSERT( layer->funcs->SetRegion != NULL ); if (region->state & CLRSF_FROZEN) return DFB_OK; funcs = layer->funcs; if (surface) { if (flags & (CLRCF_SURFACE | CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT)) { if (region->surface_lock.buffer) { CoreSurfaceBuffer *buffer = region->surface_lock.buffer; D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); if (surface == buffer->surface) { if (dfb_surface_lock( surface )) return DFB_FUSION; dfb_surface_buffer_unlock( ®ion->surface_lock ); buffer = dfb_surface_get_buffer( surface, CSBR_FRONT ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); ret = dfb_surface_buffer_lock( buffer, CSAF_CPU_READ | CSAF_GPU_READ, ®ion->surface_lock ); dfb_surface_unlock( surface ); } else { dfb_surface_unlock_buffer( buffer->surface, ®ion->surface_lock ); ret = dfb_surface_lock_buffer( surface, CSBR_FRONT, CSAF_CPU_READ | CSAF_GPU_READ, ®ion->surface_lock ); } } else ret = dfb_surface_lock_buffer( surface, CSBR_FRONT, CSAF_CPU_READ | CSAF_GPU_READ, ®ion->surface_lock ); } if (ret) { D_DERROR( ret, "Core/LayerRegion: Could not lock region surface for SetRegion()!\n" ); return ret; } D_ASSERT( region->surface_lock.buffer != NULL ); } else if (region->surface_lock.buffer) { D_MAGIC_ASSERT( region->surface_lock.buffer, CoreSurfaceBuffer ); dfb_surface_unlock_buffer( region->surface_lock.buffer->surface, ®ion->surface_lock ); } /* Setup hardware. */ return funcs->SetRegion( layer, layer->driver_data, layer->layer_data, region->region_data, config, flags, surface, surface ? surface->palette : NULL, ®ion->surface_lock ); }
static void foo_update( StretRegion *region, void *region_data, void *update_data, unsigned long arg, int x, int y, const DFBRegion *updates, int num ) { int i; DFBRegion clip; DFBDimension size; bool visible; WMShared *shared; UniqueContext *context; UniqueWindow *window = region_data; CardState *state = update_data; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; D_ASSERT( region != NULL ); D_ASSERT( region_data != NULL ); D_ASSERT( update_data != NULL ); D_ASSERT( updates != NULL ); D_MAGIC_ASSERT( window, UniqueWindow ); D_MAGIC_ASSERT( state, CardState ); shared = window->shared; D_MAGIC_ASSERT( shared, WMShared ); D_ASSERT( shared->foo_surface != NULL ); context = window->context; D_MAGIC_ASSERT( context, UniqueContext ); visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE ); D_DEBUG_AT( UniQuE_Foo, "foo_update( region %p, window %p, visible %s, num %d )\n", region, window, visible ? "yes" : "no", num ); #if D_DEBUG_ENABLED for (i=0; i<num; i++) { D_DEBUG_AT( UniQuE_Foo, " (%d) %4d,%4d - %4dx%4d\n", i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) ); } #endif if (!visible) return; stret_region_get_size( region, &size ); /* Use per pixel alpha blending. */ flags |= DSBLIT_BLEND_ALPHACHANNEL; /* Use global alpha blending. */ if (window->opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; /* Set opacity as blending factor. */ if (state->color.a != window->opacity) { state->color.a = window->opacity; state->modified |= SMF_COLOR; } } /* Use colorizing if the color is not white. */ if (context->color.r != 0xff || context->color.g != 0xff || context->color.b != 0xff) { flags |= DSBLIT_COLORIZE; state->color.r = context->color.r; state->color.g = context->color.g; state->color.b = context->color.b; state->modified |= SMF_COLOR; } /* Set blitting flags. */ dfb_state_set_blitting_flags( state, flags ); /* Set blitting source. */ state->source = shared->foo_surface; state->modified |= SMF_SOURCE; switch (arg) { case UFI_N: case UFI_E: case UFI_S: case UFI_W: clip = state->clip; /* for (i=0; i<num; i++) { DFBRegion update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y ); DFBRectangle source = shared->foo_rects[arg]; DFBRectangle dest = { x, y, size.w, size.h }; dfb_state_set_clip( state, &update ); dfb_gfxcard_stretchblit( &source, &dest, state ); }*/ for (i=0; i<num; i++) { DFBRegion update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y ); DFBRectangle source = shared->foo_rects[arg]; dfb_state_set_clip( state, &update ); dfb_gfxcard_tileblit( &source, x, y, x + size.w - 1, y + size.h - 1, state ); } dfb_state_set_clip( state, &clip ); break; case UFI_NE: case UFI_SE: case UFI_SW: case UFI_NW: for (i=0; i<num; i++) { DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] ); dfb_rectangle_translate( &rect, shared->foo_rects[arg].x, shared->foo_rects[arg].y ); dfb_gfxcard_blit( &rect, x + updates[i].x1, y + updates[i].y1, state ); } break; default: D_BUG( "invalid arg" ); } /* Reset blitting source. */ state->source = NULL; state->modified |= SMF_SOURCE; }
static bool window_callback( UniqueWindow *window ) { int refs; DirectResult ret; DFBRectangle *bounds = &window->bounds; if (window->object.state != FOS_ACTIVE) return true; ret = fusion_ref_stat( &window->object.ref, &refs ); if (ret) { printf( "Fusion error %d!\n", ret ); return false; } #if FUSION_BUILD_MULTI printf( "0x%08x : ", window->object.ref.multi.id ); #else printf( "N/A : " ); #endif printf( "%3d ", refs ); printf( "%4d, %4d ", bounds->x, bounds->y ); printf( "%4d x %4d ", bounds->w, bounds->h ); printf( "0x%02x ", window->opacity ); printf( "%5d ", dfb_window_id( window->window ) ); switch (window->stacking) { case DWSC_UPPER: printf( "^ " ); break; case DWSC_MIDDLE: printf( "- " ); break; case DWSC_LOWER: printf( "v " ); break; default: printf( "? " ); break; } if (D_FLAGS_IS_SET( window->flags, UWF_VISIBLE )) printf( "VISIBLE " ); if (D_FLAGS_IS_SET( window->flags, UWF_DECORATED )) printf( "DECORATED " ); if (D_FLAGS_IS_SET( window->flags, UWF_DESTROYED )) printf( "DESTROYED " ); printf( "\n" ); return true; }