Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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;
}