DFBResult dfb_layer_region_get_surface( CoreLayerRegion *region, CoreSurface **ret_surface ) { D_ASSERT( region != NULL ); D_ASSERT( ret_surface != 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) { dfb_layer_region_unlock( region ); return DFB_UNSUPPORTED; } /* Increase the surface's reference counter. */ if (dfb_surface_ref( region->surface )) { dfb_layer_region_unlock( region ); return DFB_FUSION; } /* Return the surface. */ *ret_surface = region->surface; /* Unlock the region. */ dfb_layer_region_unlock( region ); return DFB_OK; }
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) { if (source_mask && 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 ) ); 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; }
DFBResult dfb_state_set_source2( CardState *state, CoreSurface *source2 ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source2 != source2) { if (source2 && dfb_surface_ref( source2 )) { D_WARN( "could not ref() source2" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source2) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE2 ) ); dfb_surface_unref( state->source2 ); } state->source2 = source2; state->modified |= SMF_SOURCE2; if (source2) { direct_serial_copy( &state->src2_serial, &source2->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE2 ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE2 ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult dfb_state_set_source_2( CardState *state, CoreSurface *source, u32 flip_count ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source != source || state->source_flip_count != flip_count || !state->source_flip_count_used) { bool ref = true;//!fusion_config->secure_fusion || dfb_core_is_master( core_dfb ); if (source && ref && dfb_surface_ref( source )) { D_WARN( "could not ref() source" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE ) ); if (ref) dfb_surface_unref( state->source ); } state->source = source; state->modified |= SMF_SOURCE; state->source_flip_count = flip_count; state->source_flip_count_used = true; if (source) { direct_serial_copy( &state->src_serial, &source->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE ); } dfb_state_unlock( state ); return DFB_OK; }
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 IWindow_Real::GetSurface( CoreSurface **ret_surface ) { DFBResult ret; D_DEBUG_AT( Core_Window, "IWindow_Real::%s( %p )\n", __FUNCTION__, obj ); D_ASSERT( ret_surface != NULL ); if (!obj->surface) return DFB_UNSUPPORTED; ret = (DFBResult) dfb_surface_ref( obj->surface ); if (ret) return ret; *ret_surface = obj->surface; return DFB_OK; }
DFBResult dfb_state_set_source2( CardState *state, CoreSurface *source2 ) { D_MAGIC_ASSERT( state, CardState ); dfb_state_lock( state ); if (state->source2 != source2) { bool ref = true;//!fusion_config->secure_fusion || dfb_core_is_master( core_dfb ); if (source2 && ref && dfb_surface_ref( source2 )) { D_WARN( "could not ref() source2" ); dfb_state_unlock( state ); return DFB_DEAD; } if (state->source2) { D_ASSERT( D_FLAGS_IS_SET( state->flags, CSF_SOURCE2 ) ); if (ref) dfb_surface_unref( state->source2 ); } state->source2 = source2; state->modified |= SMF_SOURCE2; if (source2) { direct_serial_copy( &state->src2_serial, &source2->serial ); D_FLAGS_SET( state->flags, CSF_SOURCE2 ); } else D_FLAGS_CLEAR( state->flags, CSF_SOURCE2 ); } dfb_state_unlock( state ); return DFB_OK; }
DFBResult SurfacePeer::Init() { DFBResult ret = DFB_OK; D_DEBUG_AT( DirectFB_Graphics, "Graphics::SurfacePeer::%s( %p ) <- surface %p\n", __FUNCTION__, this, surface ); if (surface) { ret = (DFBResult) dfb_surface_ref( surface ); if (ret) { D_DERROR( ret, "Graphics/SurfacePeer: dfb_surface_ref() failed!\n" ); surface = NULL; return ret; } surface_type = surface->type; ret = updateBuffers(); } return ret; }
static DFBResult drmkmsPlaneUpdateFlipRegion( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreSurface *surface, DFBSurfaceFlipFlags flags, const DFBRegion *left_update, CoreSurfaceBufferLock *left_lock, const DFBRegion *right_update, CoreSurfaceBufferLock *right_lock, bool flip ) { int ret; DRMKMSData *drmkms = driver_data; DRMKMSLayerData *data = layer_data; D_DEBUG_AT( DRMKMS_Layer, "%s()\n", __FUNCTION__ ); direct_mutex_lock( &data->lock ); while (data->flip_pending) { D_DEBUG_AT( DRMKMS_Layer, " -> waiting for pending flip (previous)\n" ); if (direct_waitqueue_wait_timeout( &data->wq_event, &data->lock, 30000 ) == DR_TIMEOUT) break; } dfb_surface_ref( surface ); data->surface = surface; data->surfacebuffer_index = left_lock->buffer->index; /* Task */ data->pending_task = left_lock->task; if (!data->muted) { ret = drmModeSetPlane(drmkms->fd, data->plane->plane_id, drmkms->encoder[0]->crtc_id, (u32)(long)left_lock->handle, /* plane_flags */ 0, data->config->dest.x, data->config->dest.y, data->config->dest.w, data->config->dest.h, data->config->source.x << 16, data->config->source.y <<16, data->config->source.w << 16, data->config->source.h << 16); if (ret) { D_PERROR( "DRMKMS/Layer/FlipRegion: Failed setting plane configuration!\n" ); direct_mutex_unlock( &data->lock ); return ret; } } if (flip) dfb_surface_flip( surface, false ); data->flip_pending = true; drmVBlank vbl; vbl.request.type = DRM_VBLANK_EVENT | DRM_VBLANK_RELATIVE; vbl.request.signal = (unsigned long)data; vbl.request.sequence = 1; drmWaitVBlank( drmkms->fd, &vbl ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAITFORSYNC) { while (data->flip_pending) { D_DEBUG_AT( DRMKMS_Layer, " -> waiting for pending flip (WAITFORSYNC)\n" ); if (direct_waitqueue_wait_timeout( &data->wq_event, &data->lock, 30000 ) == DR_TIMEOUT) break; } } direct_mutex_unlock( &data->lock ); return DFB_OK; }
static DFBResult drmkmsUpdateFlipRegion( CoreLayer *layer, void *driver_data, void *layer_data, void *region_data, CoreSurface *surface, DFBSurfaceFlipFlags flags, const DFBRegion *left_update, CoreSurfaceBufferLock *left_lock, const DFBRegion *right_update, CoreSurfaceBufferLock *right_lock, bool flip ) { int ret, i; DRMKMSData *drmkms = driver_data; DRMKMSDataShared *shared = drmkms->shared; DRMKMSLayerData *data = layer_data; D_DEBUG_AT( DRMKMS_Layer, "%s()\n", __FUNCTION__ ); if (!drmkms->resources) { if (flip) dfb_surface_flip( surface, false ); if (left_lock->buffer) dfb_surface_notify_display( surface, left_lock->buffer ); if (right_lock && right_lock->buffer) dfb_surface_notify_display( surface, right_lock->buffer ); if (left_lock->task) Task_Done( left_lock->task ); if (right_lock && right_lock->task) Task_Done( right_lock->task ); return DFB_OK; } direct_mutex_lock( &data->lock ); while (data->flip_pending) { D_DEBUG_AT( DRMKMS_Layer, " -> waiting for pending flip (previous)\n" ); if (direct_waitqueue_wait_timeout( &data->wq_event, &data->lock, 30000 ) == DR_TIMEOUT) break; } dfb_surface_ref( surface ); data->surface = surface; data->surfacebuffer_index = left_lock->buffer->index; /* Task */ data->pending_task = left_lock->task; D_DEBUG_AT( DRMKMS_Layer, " -> calling drmModePageFlip()\n" ); data->flip_pending = true; ret = drmModePageFlip( drmkms->fd, drmkms->encoder[data->layer_index]->crtc_id, (u32)(long)left_lock->handle, DRM_MODE_PAGE_FLIP_EVENT, layer_data ); if (ret) { D_PERROR( "DirectFB/DRMKMS: drmModePageFlip() failed on layer %d!\n", data->index ); direct_mutex_unlock( &data->lock ); return DFB_FAILURE; } if (shared->mirror_outputs) { for (i=1; i<shared->enabled_crtcs; i++) { ret = drmModePageFlip( drmkms->fd, drmkms->encoder[i]->crtc_id, (u32)(long)left_lock->handle, 0, 0); if (ret) D_WARN( "DirectFB/DRMKMS: drmModePageFlip() failed for mirror on crtc id %d!\n", drmkms->encoder[i]->crtc_id ); } } shared->primary_fb = (u32)(long)left_lock->handle; if (flip) dfb_surface_flip( surface, false ); if ((flags & DSFLIP_WAITFORSYNC) == DSFLIP_WAITFORSYNC) { while (data->flip_pending) { D_DEBUG_AT( DRMKMS_Layer, " -> waiting for pending flip (WAITFORSYNC)\n" ); if (direct_waitqueue_wait_timeout( &data->wq_event, &data->lock, 30000 ) == DR_TIMEOUT) break; } } direct_mutex_unlock( &data->lock ); return DFB_OK; }