DFBResult dfb_surface_unlock_buffer( CoreSurface *surface, CoreSurfaceBufferLock *lock ) { DFBResult ret; D_MAGIC_ASSERT( surface, CoreSurface ); ret = dfb_surface_buffer_unlock( lock ); return ret; }
DFBResult dfb_surface_unlock_buffer( CoreSurface *surface, CoreSurfaceBufferLock *lock ) { DFBResult ret; D_MAGIC_ASSERT( surface, CoreSurface ); if (fusion_skirmish_prevail( &surface->lock )) return DFB_FUSION; ret = dfb_surface_buffer_unlock( lock ); fusion_skirmish_dismiss( &surface->lock ); return ret; }
DFBResult dfb_layer_region_flip_update( CoreLayerRegion *region, const DFBRegion *update, DFBSurfaceFlipFlags flags ) { DFBResult ret = DFB_OK; 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) && !context->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" ); ret = dfb_surface_lock( surface ); if (ret) break; /* Use the driver's routine if the region is realized. */ if (D_FLAGS_IS_SET( region->state, CLRSF_REALIZED )) { CoreSurfaceBuffer *buffer; D_ASSUME( funcs->FlipRegion != NULL ); buffer = dfb_surface_get_buffer( surface, CSBR_BACK ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); if (region->surface_lock.buffer) dfb_surface_buffer_unlock( ®ion->surface_lock ); D_DEBUG_AT( Core_Layers, " -> Waiting for pending writes...\n" ); dfb_surface_buffer_lock( buffer, CSAF_CPU_READ | CSAF_GPU_READ, ®ion->surface_lock ); 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 ); } else { D_DEBUG_AT( Core_Layers, " -> Flipping region not using driver...\n" ); /* Just do the hardware independent work. */ 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. */ if (context->rotation == 180) dfb_back_to_front_copy_180( surface, update ); else 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 )) { if (region->surface) { CoreSurfaceAllocation *allocation; allocation = region->surface_lock.allocation; D_ASSERT( allocation != NULL ); /* If hardware has written or is writing... */ if (allocation->accessed & CSAF_GPU_WRITE) { D_DEBUG_AT( Core_Layers, " -> Waiting for pending writes...\n" ); /* ...wait for the operation to finish. */ dfb_gfxcard_sync(); /* TODO: wait for serial instead */ allocation->accessed &= ~CSAF_GPU_WRITE; } } 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, ®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 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 DFBResult update_screen( int x, int y, int w, int h ) { #if 0 int i, n; void *dst; void *src; DFBResult ret; CoreSurface *surface; CoreSurfaceBuffer *buffer; CoreSurfaceBufferLock lock; u16 *src16, *dst16; u8 *src8; #endif D_DEBUG_AT( SDL_Updates, "%s( %d, %d, %d, %d )\n", __FUNCTION__, x, y, w, h ); D_DEBUG_AT( SDL_Updates, " -> locking sdl lock...\n" ); fusion_skirmish_prevail( &dfb_sdl->lock ); #if 0 surface = dfb_sdl->primary; D_MAGIC_ASSERT_IF( surface, CoreSurface ); D_DEBUG_AT( SDL_Updates, " -> primary is %p\n", surface ); if (!surface) { D_DEBUG_AT( SDL_Updates, " -> unlocking sdl lock...\n" ); fusion_skirmish_dismiss( &dfb_sdl->lock ); D_DEBUG_AT( SDL_Updates, " -> done.\n" ); return DFB_OK; } buffer = dfb_surface_get_buffer( surface, CSBR_FRONT ); D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer ); D_DEBUG_AT( SDL_Updates, " -> locking sdl surface...\n" ); if (SDL_LockSurface( screen ) < 0) { D_ERROR( "DirectFB/SDL: " "Couldn't lock the display surface: %s\n", SDL_GetError() ); fusion_skirmish_dismiss( &dfb_sdl->lock ); return DFB_FAILURE; } D_DEBUG_AT( SDL_Updates, " -> locking dfb surface...\n" ); ret = dfb_surface_buffer_lock( buffer, CSAF_CPU_READ, &lock ); if (ret) { D_ERROR( "DirectFB/SDL: Couldn't lock layer surface: %s\n", DirectFBErrorString( ret ) ); SDL_UnlockSurface(screen); fusion_skirmish_dismiss( &dfb_sdl->lock ); return ret; } src = lock.addr; dst = screen->pixels; src += DFB_BYTES_PER_LINE( surface->config.format, x ) + y * lock.pitch; dst += DFB_BYTES_PER_LINE( surface->config.format, x ) + y * screen->pitch; D_DEBUG_AT( SDL_Updates, " -> copying pixels...\n" ); switch (screen->format->BitsPerPixel) { case 16: dfb_convert_to_rgb16( surface->config.format, src, lock.pitch, surface->config.size.h, dst, screen->pitch, w, h ); break; default: direct_memcpy( dst, src, DFB_BYTES_PER_LINE( surface->config.format, w ) ); } D_DEBUG_AT( SDL_Updates, " -> unlocking dfb surface...\n" ); dfb_surface_buffer_unlock( &lock ); D_DEBUG_AT( SDL_Updates, " -> unlocking sdl surface...\n" ); SDL_UnlockSurface( screen ); #endif D_DEBUG_AT( SDL_Updates, " -> calling SDL_UpdateRect()...\n" ); SDL_UpdateRect( dfb_sdl->screen, x, y, w, h ); D_DEBUG_AT( SDL_Updates, " -> unlocking sdl lock...\n" ); fusion_skirmish_dismiss( &dfb_sdl->lock ); D_DEBUG_AT( SDL_Updates, " -> done.\n" ); return DFB_OK; }