Ejemplo n.º 1
0
/*
 * 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, &region->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, &region->config,
                                 CLRCF_ALPHA_RAMP, surface, surface->palette );
          }
     }

     dfb_layer_region_unlock( region );

     return RS_OK;
}
Ejemplo n.º 2
0
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, &region ) == 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 );
     }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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, &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) && !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, &region->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, &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.º 5
0
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;
}
Ejemplo n.º 6
0
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);
}