Esempio n. 1
0
static DFBResult
uc_ovl_set_level(CoreLayer    *layer,
                 void         *driver_data,
                 void         *layer_data,
                 int          level)
{
    UcOverlayData* ucovl = (UcOverlayData*) layer_data;
    UcDriverData*  ucdrv = (UcDriverData*) driver_data;

    if (level == 0) return DFB_INVARG;
    
    if (level < 0) {
        // Enable underlay mode.
        VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL,
            uc_ovl_map_alpha(ucovl->opacity_primary));
    }
    else {
        // Enable overlay mode (default)
        VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL,
            uc_ovl_map_alpha(ucovl->v1.opacity));
    }
    VIDEO_OUT(ucdrv->hwregs, V_COMPOSE_MODE, V1_COMMAND_FIRE |
        (ucovl->v1.dstkey_enabled ? ENABLE_COLOR_KEYING : 0));

    ucovl->v1.level = level;
    return DFB_OK;
}
Esempio n. 2
0
static DFBResult
uc_ovl_set_level(CoreLayer    *layer,
                 void         *driver_data,
                 void         *layer_data,
                 int          level)
{
    UcOverlayData* ucovl = (UcOverlayData*) layer_data;
    UcDriverData*  ucdrv = (UcDriverData*) driver_data;

    if (level == 0) return DFB_INVARG;
    if (level > 0) {
        // Enable underlay mode.
        VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(-1));
    }
    else {
        // Enable overlay mode (default)
        VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL,
            uc_ovl_map_alpha(ucovl->v1.opacity));
    }

    ucovl->v1.level = level;
    return DFB_OK;
}
Esempio n. 3
0
static DFBResult
osdSetRegion( CoreLayer                  *layer,
              void                       *driver_data,
              void                       *layer_data,
              void                       *region_data,
              CoreLayerRegionConfig      *config,
              CoreLayerRegionConfigFlags  updated,
              CoreSurface                *surface,
              CorePalette                *palette,
              CoreSurfaceBufferLock      *lock )
{
     DFBResult     ret;
     UcDriverData *ucdrv = (UcDriverData*) driver_data;

     /* call the original function */
     ret = ucOldPrimaryFuncs.SetRegion( layer, ucOldPrimaryDriverData,
                                        layer_data, region_data,
                                        config, updated, surface,
                                        palette, lock );
     if (ret)
          return ret;

     uc_ovl_vcmd_wait(ucdrv->hwregs);

     /* select pixel based or global alpha */

     if (config->options & DLOP_ALPHACHANNEL)
          VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(-1));
     else if (config->options & DLOP_OPACITY)
          VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(config->opacity));
     else
          VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL, uc_ovl_map_alpha(0xff));

     VIDEO_OUT(ucdrv->hwregs, V_COMPOSE_MODE, V1_COMMAND_FIRE);

     return DFB_OK;
}
Esempio n. 4
0
static DFBResult
osdSetRegion( CoreLayer                  *layer,
              void                       *driver_data,
              void                       *layer_data,
              void                       *region_data,
              CoreLayerRegionConfig      *config,
              CoreLayerRegionConfigFlags  updated,
              CoreSurface                *surface,
              CorePalette                *palette,
              CoreSurfaceBufferLock      *lock )
{
     DFBResult     ret;
     UcDriverData *ucdrv = (UcDriverData*) driver_data;

     /* call the original function */
     ret = ucOldPrimaryFuncs.SetRegion( layer, ucOldPrimaryDriverData,
                                        layer_data, region_data,
                                        config, updated, surface,
                                        palette, lock );
     if (ret)
          return ret;

     uc_ovl_vcmd_wait(ucdrv->hwregs);

     /* select pixel based or global alpha */

     if (!ucdrv->ovl)   // overlay not present
          return DFB_OK;
     
     if (config->options & DLOP_ALPHACHANNEL)
          ucdrv->ovl->opacity_primary = -1; // use primary alpha for overlay
     else if (config->options & DLOP_OPACITY)
          ucdrv->ovl->opacity_primary = config->opacity ^ 0xff; // use inverse for overlay
     else
          ucdrv->ovl->opacity_primary = 0x00; // primary opaque == overlay transparent

     if (ucdrv->ovl->v1.level < 0)  // primary on top?
     {
          VIDEO_OUT(ucdrv->hwregs, V_ALPHA_CONTROL,
               uc_ovl_map_alpha(ucdrv->ovl->opacity_primary));
          VIDEO_OUT(ucdrv->hwregs, V_COMPOSE_MODE,
               VIDEO_IN(ucdrv->hwregs, V_COMPOSE_MODE) | V1_COMMAND_FIRE);
     }
     
     return DFB_OK;
}
Esempio n. 5
0
DFBResult uc_ovl_update(UcDriverData* ucdrv,
                        UcOverlayData* ucovl,
                        int action,
                        CoreSurface* surface)
{
     int sw, sh, sp, sfmt;   // Source width, height, pitch and format
     int dx, dy;             // Destination position
     int dw, dh;             // Destination width and height
     int pfetch;             // Source pixels required for one line
     VideoMode *videomode;
     DFBRectangle scr;       // Screen size
     u32 dst_key = 0;        // Destination color key (hw format)

     bool write_buffers = false;
     bool write_settings = false;

     volatile u8* vio = ucdrv->hwregs;

     u32 win_start, win_end;   // Overlay register settings
     u32 zoom, mini;
     u32 dcount, falign, qwfetch;
     u32 y_start, u_start, v_start;
     u32 v_ctrl, fifo_ctrl;
     u32 alpha = 0;

     int offset = surface->front_buffer->video.offset;

     if (!ucovl->v1.isenabled) return DFB_OK;

     qwfetch = 0;

     // Get screen size
     videomode = dfb_system_current_mode();
     scr.w = videomode ? videomode->xres : 720;
     scr.h = videomode ? videomode->yres : 576;
     scr.x = 0;
     scr.y = 0;

     if (ucovl->scrwidth != scr.w) {
          // FIXME: fix uc_ovl_setup_fifo()
          //    uc_ovl_setup_fifo(ucovl, scr.w);
          action |= UC_OVL_CHANGE;
     }

     D_ASSERT(surface);

     sw = surface->config.size.w;
     sh = surface->config.size.h;
     sp = surface->front_buffer->video.pitch;
     sfmt = surface->config.format;

     if (ucovl->deinterlace) {
          /*if (ucovl->field)
               offset += sp;*/

          sh /= 2;
          //sp *= 2;
     }

     if (action & UC_OVL_CHANGE) {

          if ((sw > 4096) || (sh > 4096) ||
              (sw < 32) || (sh < 1) || (sp > 0x1fff)) {
               D_DEBUG("Layer surface size is out of bounds.");
               return DFB_INVAREA;
          }

          dx = ucovl->v1.win.x;
          dy = ucovl->v1.win.y;
          dw = ucovl->v1.win.w;
          dh = ucovl->v1.win.h;

          // Get image format, FIFO size, etc.

          uc_ovl_map_v1_control(sfmt, sw, ucovl->hwrev, ucovl->extfifo_on,
                                &v_ctrl, &fifo_ctrl);

          if (ucovl->deinterlace) {
               v_ctrl |= /*V1_BOB_ENABLE |*/ V1_FRAME_BASE;
          }

          // Get layer window.
          // The parts that fall outside the screen are clipped.

          uc_ovl_map_window(scr.w, scr.h, &(ucovl->v1.win), sw, sh,
                            &win_start, &win_end,
                            &ucovl->v1.ox, &ucovl->v1.oy, &pfetch);

          // Get scaling and data-fetch parameters

          // Note: the *_map_?zoom() functions return false if the scaling
          // is out of bounds. We don't act on it for now, because it only
          // makes the display look strange.

          zoom = 0;
          mini = 0;

          uc_ovl_map_vzoom(sh, dh, &zoom, &mini);
          uc_ovl_map_hzoom(sw, dw, &zoom, &mini, &falign, &dcount);
          qwfetch = uc_ovl_map_qwfetch(falign, sfmt, pfetch);

          // Prepare destination color key
          dst_key = uc_ovl_map_colorkey(&(ucovl->v1.dst_key));

          // prepare opacity
          if (ucovl->v1.level > 0)  // overlay
               alpha = uc_ovl_map_alpha(ucovl->v1.opacity);
          else
               alpha = uc_ovl_map_alpha(ucovl->opacity_primary);
          
          write_settings = true;
     }

     if (action & (UC_OVL_FIELD | UC_OVL_FLIP | UC_OVL_CHANGE)) {
          int field = 0;
          // Update the buffer pointers

          if (ucovl->deinterlace) {
               field = ucovl->field;
          }

          uc_ovl_map_buffer(sfmt, offset,
                            ucovl->v1.ox, ucovl->v1.oy, sw, surface->config.size.h, sp, 0/*field*/, &y_start,
                            &u_start, &v_start);

          if (field) {
               y_start |= 0x08000000;
          }

          write_buffers = true;
     }

     // Write to the hardware

/*    if (write_settings || write_buffers)
        uc_ovl_vcmd_wait(vio);*/

     if (write_settings) {

          VIDEO_OUT(vio, V1_CONTROL, v_ctrl);
          VIDEO_OUT(vio, V_FIFO_CONTROL, fifo_ctrl);

          VIDEO_OUT(vio, V1_WIN_START_Y, win_start);
          VIDEO_OUT(vio, V1_WIN_END_Y, win_end);

          VIDEO_OUT(vio, V1_SOURCE_HEIGHT, (sh << 16) | dcount);
          VIDEO_OUT(vio, V12_QWORD_PER_LINE, qwfetch);
          VIDEO_OUT(vio, V1_STRIDE, sp | ((sp >> 1) << 16));

          VIDEO_OUT(vio, V1_MINI_CONTROL, mini);
          VIDEO_OUT(vio, V1_ZOOM_CONTROL, zoom);

          VIDEO_OUT(vio, V_COLOR_KEY, dst_key);
          
          VIDEO_OUT(vio, V_ALPHA_CONTROL, alpha);
     }

     if (write_buffers) {

          VIDEO_OUT(vio, V1_STARTADDR_0, y_start);
          VIDEO_OUT(vio, V1_STARTADDR_CB0, u_start);
          VIDEO_OUT(vio, V1_STARTADDR_CR0, v_start);
     }

     if (write_settings || write_buffers) {
          VIDEO_OUT(vio, V_COMPOSE_MODE, V1_COMMAND_FIRE |
              (ucovl->v1.dstkey_enabled ? ENABLE_COLOR_KEYING : 0));
     }

     return DFB_OK;
}