Ejemplo n.º 1
0
DFBResult
dfb_surface_write_buffer( CoreSurface            *surface,
                          CoreSurfaceBufferRole   role,
                          const void             *source,
                          int                     pitch,
                          const DFBRectangle     *rect )
{
     DFBResult          ret;
     CoreSurfaceBuffer *buffer;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( source != NULL );
     D_ASSERT( pitch > 0 );
     DFB_RECTANGLE_ASSERT_IF( rect );

     if (fusion_skirmish_prevail( &surface->lock ))
          return DFB_FUSION;

     buffer = dfb_surface_get_buffer( surface, role );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     ret = dfb_surface_buffer_write( buffer, source, pitch, rect );

     fusion_skirmish_dismiss( &surface->lock );

     return ret;
}
Ejemplo n.º 2
0
DFBResult
dfb_surface_dump_buffer( CoreSurface           *surface,
                         CoreSurfaceBufferRole  role,
                         const char            *path,
                         const char            *prefix )
{
     DFBResult          ret;
     CoreSurfaceBuffer *buffer;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( path != NULL );
     D_ASSERT( prefix != NULL );

     if (fusion_skirmish_prevail( &surface->lock ))
          return DFB_FUSION;

     if (surface->num_buffers == 0) {
          fusion_skirmish_dismiss( &surface->lock );
          return DFB_SUSPENDED;
     }

     buffer = dfb_surface_get_buffer( surface, role );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     ret = dfb_surface_buffer_dump( buffer, path, prefix );

     fusion_skirmish_dismiss( &surface->lock );

     return ret;
}
Ejemplo n.º 3
0
static DFBResult
region_buffer_lock( CoreLayerRegion       *region,
                    CoreSurface           *surface,
                    CoreSurfaceBufferRole  role )
{
     DFBResult              ret;
     CoreSurfaceBuffer     *buffer;
     CoreSurfaceAllocation *allocation;
     CoreLayerContext      *context;

     D_ASSERT( region != NULL );
     D_MAGIC_ASSERT( surface, CoreSurface );

     context = region->context;
     D_MAGIC_ASSERT( context, CoreLayerContext );

     /* First unlock any previously locked buffer. */
     if (region->surface_lock.buffer) {
          D_MAGIC_ASSERT( region->surface_lock.buffer, CoreSurfaceBuffer );

          dfb_surface_unlock_buffer( region->surface_lock.buffer->surface, &region->surface_lock );
     }

     if (dfb_surface_lock( surface ))
          return DFB_FUSION;

     buffer = dfb_surface_get_buffer( surface, role );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     /* Lock the surface buffer. */
     ret = dfb_surface_buffer_lock( buffer, CSAID_LAYER0 + context->layer_id, CSAF_READ, &region->surface_lock );
     if (ret) {
          D_DERROR( ret, "Core/LayerRegion: Could not lock region surface for SetRegion()!\n" );
          dfb_surface_unlock( surface );
          return ret;
     }

     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. */
          dfb_gfxcard_sync(); /* TODO: wait for serial instead */

          allocation->accessed[CSAID_GPU] &= ~CSAF_WRITE;
     }

     /* surface is unlocked by caller */

     return DFB_OK;
}
Ejemplo n.º 4
0
static DFBResult
region_buffer_lock( CoreLayerRegion       *region,
                    CoreSurface           *surface,
                    CoreSurfaceBufferRole  role )
{
     DFBResult               ret;
     CoreSurfaceAccessFlags  flags;
     CoreSurfaceBuffer      *buffer;
     CoreSurfaceAllocation  *allocation;

     /* First unlock any previously locked buffer. */
     if (region->surface_lock.buffer) {
          D_MAGIC_ASSERT( region->surface_lock.buffer, CoreSurfaceBuffer );

          dfb_surface_unlock_buffer( region->surface_lock.buffer->surface, &region->surface_lock );
     }

     /* Determine flags to use. */
     if (surface->config.caps & DSCAPS_SYSTEMONLY)
          flags = CSAF_CPU_READ;
     else
          flags = CSAF_GPU_READ;
         
     if (dfb_surface_lock( surface ))
          return DFB_FUSION;

     buffer = dfb_surface_get_buffer( surface, role );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     /* Lock the surface buffer. */
     ret = dfb_surface_buffer_lock( buffer, flags, &region->surface_lock );
     if (ret) {
          D_DERROR( ret, "Core/LayerRegion: Could not lock region surface for SetRegion()!\n" );
          dfb_surface_unlock( surface );
          return ret;
     }

     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;
     }

     return DFB_OK;
}
Ejemplo n.º 5
0
DFBResult
dfb_surface_lock_buffer( CoreSurface            *surface,
                         CoreSurfaceBufferRole   role,
                         CoreSurfaceAccessFlags  access,
                         CoreSurfaceBufferLock  *ret_lock )
{
     DFBResult          ret;
     CoreSurfaceBuffer *buffer;

     D_MAGIC_ASSERT( surface, CoreSurface );

     if (fusion_skirmish_prevail( &surface->lock ))
          return DFB_FUSION;

     buffer = dfb_surface_get_buffer( surface, role );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     ret = dfb_surface_buffer_lock( buffer, access, ret_lock );

     fusion_skirmish_dismiss( &surface->lock );

     return ret;
}
Ejemplo n.º 6
0
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( &region->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,
                                                        &region->surface_lock );

                         dfb_surface_unlock( surface );
                    }
                    else {
                         dfb_surface_unlock_buffer( buffer->surface, &region->surface_lock );

                         ret = dfb_surface_lock_buffer( surface, CSBR_FRONT, CSAF_CPU_READ | CSAF_GPU_READ,
                                                        &region->surface_lock );
                    }

               }
               else
                    ret = dfb_surface_lock_buffer( surface, CSBR_FRONT, CSAF_CPU_READ | CSAF_GPU_READ,
                                                   &region->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, &region->surface_lock );
     }
		
     /* Setup hardware. */
     return funcs->SetRegion( layer, layer->driver_data, layer->layer_data,
                              region->region_data, config, flags,
                              surface, surface ? surface->palette : NULL, &region->surface_lock );
}
Ejemplo n.º 7
0
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, &region->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( &region->surface_lock );

                         D_DEBUG_AT( Core_Layers, "  -> Waiting for pending writes...\n" );

                         dfb_surface_buffer_lock( buffer, CSAF_CPU_READ | CSAF_GPU_READ,
                                                  &region->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, &region->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, &region->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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
DFBResult
ISurface_Real__PreLockBuffer2(
                         CoreSurface                               *obj,
                         CoreSurfaceBufferRole                      role,
                         CoreSurfaceAccessorID                      accessor,
                         CoreSurfaceAccessFlags                     access,
                         bool                                       lock,
                         CoreSurfaceAllocation                    **ret_allocation
                         )
{
     DFBResult              ret;
     CoreSurfaceBuffer     *buffer;
     CoreSurfaceAllocation *allocation;
     CoreSurface           *surface    = obj;
     bool                   allocated  = false;

     D_DEBUG_AT( DirectFB_CoreSurface, "%s( surface %p, role %d, accessor 0x%02x, access 0x%02x, %slock )\n",
                 __FUNCTION__, surface, role, accessor, access, lock ? "" : "no " );

     ret = (DFBResult) dfb_surface_lock( surface );
     if (ret)
          return ret;

     if (surface->num_buffers < 1) {
          dfb_surface_unlock( surface );
          return DFB_BUFFEREMPTY;
     }

     buffer = dfb_surface_get_buffer( surface, role );
     D_MAGIC_ASSERT( buffer, CoreSurfaceBuffer );

     D_DEBUG_AT( DirectFB_CoreSurface, "  -> buffer %p\n", buffer );

     if (!lock && access & CSAF_READ) {
          if (fusion_vector_is_empty( &buffer->allocs )) {
               dfb_surface_unlock( surface );
               return DFB_NOALLOCATION;
          }
     }

     /* Look for allocation with proper access. */
     allocation = dfb_surface_buffer_find_allocation( buffer, accessor, access, lock );
     if (!allocation) {
          /* If no allocation exists, create one. */
          ret = dfb_surface_pools_allocate( buffer, accessor, access, &allocation );
          if (ret) {
               if (ret != DFB_NOVIDEOMEMORY && ret != DFB_UNSUPPORTED)
                    D_DERROR( ret, "Core/SurfBuffer: Buffer allocation failed!\n" );

               goto out;
          }

          allocated = true;
     }

     CORE_SURFACE_ALLOCATION_ASSERT( allocation );

     /* Synchronize with other allocations. */
     ret = dfb_surface_allocation_update( allocation, access );
     if (ret) {
          /* Destroy if newly created. */
          if (allocated)
               dfb_surface_allocation_decouple( allocation );
          goto out;
     }

     if (!lock) {
          if (access & CSAF_WRITE) {
               if (!(allocation->pool->desc.caps & CSPCAPS_WRITE))
                    lock = true;
          }
          else if (access & CSAF_READ) {
               if (!(allocation->pool->desc.caps & CSPCAPS_READ))
                    lock = true;
          }
     }

     if (lock) {
          ret = dfb_surface_pool_prelock( allocation->pool, allocation, accessor, access );
          if (ret) {
               /* Destroy if newly created. */
               if (allocated)
                    dfb_surface_allocation_decouple( allocation );
               goto out;
          }

          manage_interlocks( allocation, accessor, access );
     }

     dfb_surface_allocation_ref( allocation );

     *ret_allocation = allocation;

out:
     dfb_surface_unlock( surface );

     return ret;
}