/* * 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; }
static void handle_expose_Async( void *ctx, void *ctx2 ) { DFBX11 *x11 = ctx; DFBX11Shared *shared = x11->shared; const XExposeEvent *expose = ctx2; CoreLayer *layer; CoreLayerContext *context; int i; X11LayerData *lds; D_DEBUG_AT( X11_Input, "%s( %d,%d-%dx%d )\n", __FUNCTION__, expose->x, expose->y, expose->width, expose->height ); //D_INFO_LINE_MSG("handle_expose %d,%d-%dx%d", expose->x, expose->y, expose->width, expose->height); /* find the correct layer */ for (i=0; i<shared->outputs; i++) { if (shared->output[i].xw && (shared->output[i].xw->window == expose->window)) break; } /* layer not found? */ if (i == shared->outputs) return; lds = shared->output[i].layers[0]; layer = dfb_layer_at( lds->layer_id ); D_ASSERT( layer != NULL ); /* Get the currently active context. */ if (dfb_layer_get_active_context( layer, &context ) == DFB_OK) { CoreLayerRegion *region; /* Get the first region. */ if (dfb_layer_context_get_primary_region( context, false, ®ion ) == DFB_OK) { /* Lock the region. */ dfb_layer_region_lock( region ); /* Get the surface of the region. */ if (region->surface && D_FLAGS_ARE_SET( region->state, CLRSF_REALIZED )) { if (dfb_config->task_manager) { DFBRegion update = { expose->x, expose->y, expose->x + expose->width - 1, expose->y + expose->height - 1 }; /* Tell the driver about the update if the region is realized. */ D_DEBUG_AT( X11_Input, " -> Issuing display task...\n" ); dfb_surface_lock( region->surface ); DisplayTask_Generate( region, &update, &update, DSFLIP_NONE, -1, NULL ); dfb_surface_unlock( region->surface ); } else { //if (lds->lock_left.buffer) { DFBRegion update = { expose->x, expose->y, expose->x + expose->width - 1, expose->y + expose->height - 1 }; // dfb_x11_update_screen( x11, lds, &update, &update, &lds->lock_left, &lds->lock_right ); //} dfb_x11_update_screen( x11, lds, &update, &update, NULL, NULL ); } } /* Unlock the region. */ dfb_layer_region_unlock( region ); /* Release the region. */ dfb_layer_region_unref( region ); } /* Release the context. */ dfb_layer_context_unref( context ); } }
static DFBResult sh_du_test_region( CoreLayer *layer, void *driver_data, void *layer_data, CoreLayerRegionConfig *config, CoreLayerRegionConfigFlags *failed ) { CoreLayerRegionConfigFlags fail; DFBResult result; int w, h; D_DEBUG_AT( SH_DU_LAYER, "%s( %u )\n", __FUNCTION__, dfb_layer_id( layer ) ); D_UNUSED_P( driver_data ); D_UNUSED_P( layer_data ); result = dfb_screen_get_screen_size( dfb_layer_screen( layer ), &w, &h ); if (result) return result; fail = CLRCF_NONE; if ((config->width < 0) || (config->width > w)) fail |= CLRCF_WIDTH; if ((config->height < 0) || (config->height > h)) fail |= CLRCF_HEIGHT; switch (config->format) { case DSPF_RGB16: case DSPF_ARGB1555: case DSPF_LUT8: break; default: fail |= CLRCF_FORMAT; break; } switch (config->buffermode) { case DLBM_FRONTONLY: case DLBM_BACKVIDEO: break; default: fail |= CLRCF_BUFFERMODE; break; } if (D_FLAGS_INVALID( config->options, DLOP_ALPHACHANNEL | DLOP_SRC_COLORKEY | DLOP_OPACITY )) fail |= CLRCF_OPTIONS; if (D_FLAGS_ARE_SET( config->options, DLOP_ALPHACHANNEL | DLOP_OPACITY )) fail |= CLRCF_OPTIONS; if ((config->source.x < 0) || (config->source.y < 0) || (config->source.w < 0) || (config->source.h < 0) || ((config->source.x + config->source.w) > config->width) || ((config->source.y + config->source.h) > config->height)) fail |= CLRCF_SOURCE; if ((config->dest.w != config->source.w) || (config->dest.h != config->source.h)) fail |= CLRCF_DEST; if (config->colorspace != DSCS_RGB) fail |= CLRCF_COLORSPACE; if (config->num_clips > 0) fail |= CLRCF_CLIPS; if (failed) *failed = fail; return (fail == CLRCF_NONE) ? DFB_OK : DFB_UNSUPPORTED; }
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; }
DFBResult GP2DEngine::CheckState( CardState *state, DFBAccelerationMask accel ) { D_DEBUG_AT( GP2D_Engine, "GP2DEngine::%s()\n", __FUNCTION__ ); /* Return if the desired function is not supported at all. */ if (accel & ~(GP2D_SUPPORTED_DRAWINGFUNCTIONS | GP2D_SUPPORTED_BLITTINGFUNCTIONS)) return DFB_UNSUPPORTED; /* Return if the destination format is not supported. */ switch (state->destination->config.format) { case DSPF_RGB16: // case DSPF_ARGB1555: break; default: return DFB_UNSUPPORTED; } /* Check if drawing or blitting is requested. */ if (DFB_DRAWING_FUNCTION( accel )) { /* Return if unsupported drawing flags are set. */ if (state->drawingflags & ~GP2D_SUPPORTED_DRAWINGFLAGS) return DFB_UNSUPPORTED; /* Return if blending with unsupported blend functions is requested. */ if (state->drawingflags & DSDRAW_BLEND) { switch (accel) { case DFXL_FILLRECTANGLE: case DFXL_FILLTRIANGLE: break; default: return DFB_UNSUPPORTED; } /* Return if blending with unsupported blend functions is requested. */ if (state->src_blend != DSBF_SRCALPHA || state->dst_blend != DSBF_INVSRCALPHA) return DFB_UNSUPPORTED; /* XOR only without blending. */ if (state->drawingflags & DSDRAW_XOR) return DFB_UNSUPPORTED; } } else { DFBSurfaceBlittingFlags flags = state->blittingflags; /* Return if unsupported blitting flags are set. */ if (flags & ~GP2D_SUPPORTED_BLITTINGFLAGS) return DFB_UNSUPPORTED; /* Return if the source format is not supported. */ if (state->source->config.format != state->destination->config.format) return DFB_UNSUPPORTED; /* Return if blending with unsupported blend functions is requested. */ if (flags & (DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) { if (state->src_blend != DSBF_SRCALPHA || state->dst_blend != DSBF_INVSRCALPHA) return DFB_UNSUPPORTED; } /* XOR only without blending etc. */ if (flags & DSBLIT_XOR && flags & ~(DSBLIT_SRC_COLORKEY | DSBLIT_ROTATE180 | DSBLIT_XOR)) return DFB_UNSUPPORTED; /* Return if colorizing for non-font surfaces is requested. */ if ((flags & DSBLIT_COLORIZE) && !(state->source->type & CSTF_FONT)) return DFB_UNSUPPORTED; /* Return if blending with both alpha channel and value is requested. */ if (D_FLAGS_ARE_SET( flags, DSBLIT_BLEND_ALPHACHANNEL | DSBLIT_BLEND_COLORALPHA)) return DFB_UNSUPPORTED; } return DFB_OK; }
static void manage_interlocks( CoreSurfaceAllocation *allocation, CoreSurfaceAccessorID accessor, CoreSurfaceAccessFlags access ) { int locks; locks = dfb_surface_allocation_locks( allocation ); #if 1 /* * Manage access interlocks. * * SOON FIXME: Clearing flags only when not locked yet. Otherwise nested GPU/CPU locks are a problem. */ /* Software read/write access... */ if (accessor == CSAID_CPU) { /* If hardware has written or is writing... */ if (allocation->accessed[CSAID_GPU] & CSAF_WRITE) { /* ...wait for the operation to finish. */ dfb_gfxcard_sync(); /* TODO: wait for serial instead */ /* Software read access after hardware write requires flush of the (bus) read cache. */ dfb_gfxcard_flush_read_cache(); if (!locks) { /* ...clear hardware write access. */ allocation->accessed[CSAID_GPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_GPU] & ~CSAF_WRITE); /* ...clear hardware read access (to avoid syncing twice). */ allocation->accessed[CSAID_GPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_GPU] & ~CSAF_READ); } } /* Software write access... */ if (access & CSAF_WRITE) { /* ...if hardware has (to) read... */ if (allocation->accessed[CSAID_GPU] & CSAF_READ) { /* ...wait for the operation to finish. */ dfb_gfxcard_sync(); /* TODO: wait for serial instead */ /* ...clear hardware read access. */ if (!locks) allocation->accessed[CSAID_GPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_GPU] & ~CSAF_READ); } } } /* Hardware read access... */ if (accessor == CSAID_GPU && access & CSAF_READ) { /* ...if software has written before... */ if (allocation->accessed[CSAID_CPU] & CSAF_WRITE) { /* ...flush texture cache. */ dfb_gfxcard_flush_texture_cache(); /* ...clear software write access. */ if (!locks) allocation->accessed[CSAID_CPU] = (CoreSurfaceAccessFlags)(allocation->accessed[CSAID_CPU] & ~CSAF_WRITE); } } if (! D_FLAGS_ARE_SET( allocation->accessed[accessor], access )) { /* FIXME: surface_enter */ } #endif /* Collect... */ allocation->accessed[accessor] = (CoreSurfaceAccessFlags)(allocation->accessed[accessor] | access); }