Пример #1
0
bool
davinciStretchBlit32( void *drv, void *dev, DFBRectangle *srect, DFBRectangle *drect )
{
     DavinciDriverData *ddrv = drv;
     DavinciDeviceData *ddev = dev;

     DFBRegion clip = DFB_REGION_INIT_FROM_RECTANGLE( drect );

     D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d )\n",
                 __FUNCTION__, DFB_RECTANGLE_VALS(drect), DFB_RECTANGLE_VALS(srect) );

     if (!dfb_region_region_intersect( &clip, &ddev->clip ))
          return true;

     dfb_region_translate( &clip, -drect->x, -drect->y );

     davinci_c64x_stretch_32__L( &ddrv->tasks,
                                 ddev->dst_phys + ddev->dst_pitch * drect->y + ddev->dst_bpp * drect->x,
                                 ddev->dst_pitch,
                                 ddev->src_phys + ddev->src_pitch * srect->y + ddev->src_bpp * srect->x,
                                 ddev->src_pitch,
                                 drect->w, drect->h,
                                 srect->w, srect->h,
                                 &clip );

     return true;
}
Пример #2
0
static DFBResult
Test_DstGeometry( IDirectFBDisplayLayer *layer, void *arg )
{
    int                i;
    IDirectFBWindow   *window;
    DFBWindowGeometry  geometry;
    DFBDimension       size;

    D_ASSERT( m_toplevel_id != 0 );

    /*
     * Get the top level window
     */
    _T( layer->GetWindow( layer, arg ? (unsigned long) arg : m_toplevel_id, &window ) );

    window->GetSize( window, &size.w, &size.h );

    /*
     * Change destination geometry
     */
    {
        DFBRectangle rects[] = { {          0,          0, size.w / 2, size.h / 2 },
            { size.w / 2,          0, size.w / 2, size.h / 2 },
            { size.w / 2, size.h / 2, size.w / 2, size.h / 2 },
            {          0, size.h / 2, size.w / 2, size.h / 2 }
        };

        for (i=0; i<D_ARRAY_SIZE(rects); i++) {
            SHOW_TEST( "SetDstGeometry( %4d,%4d-%4dx%4d - [%02d] )...", DFB_RECTANGLE_VALS(&rects[i]), i );

            geometry.mode      = DWGM_RECTANGLE;
            geometry.rectangle = rects[i];

            _T( window->SetDstGeometry( window, &geometry ) );

            SHOW_RESULT( "...SetDstGeometry( %4d,%4d-%4dx%4d - [%02d] ) done.", DFB_RECTANGLE_VALS(&rects[i]), i );
        }
    }


    SHOW_TEST( "SetDstGeometry( DEFAULT )..." );

    geometry.mode = DWGM_DEFAULT;

    _T( window->SetDstGeometry( window, &geometry ) );

    SHOW_RESULT( "...SetDstGeometry( DEFAULT ) done." );


    window->Release( window );

    return DFB_OK;
}
Пример #3
0
/*
 * Blit a scaled rectangle using the current hardware state.
 */
bool
gles2StretchBlit(void *drv, void *dev,
                 DFBRectangle *srect, DFBRectangle *drect)
{
     GLES2DriverData *gdrv = drv;

     float x1 = drect->x;
     float y1 = drect->y;
     float x2 = drect->w + x1;
     float y2 = drect->h + y1;

     float tx1 = srect->x;
     float ty1 = srect->y;
     float tx2 = srect->w + tx1;
     float ty2 = srect->h + ty1;

     GLfloat pos[] = {
          x1, y1,   x2, y1,   x2, y2,   x1, y2
     };

     GLfloat tex[8];

     D_DEBUG_AT(GLES2__2D, "%s(%4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d)\n",
                __FUNCTION__, DFB_RECTANGLE_VALS(drect),
                DFB_RECTANGLE_VALS(srect));

     if (gdrv->blittingflags & DSBLIT_ROTATE180) {
          tex[0] = tx2; tex[1] = ty2;
          tex[2] = tx1; tex[3] = ty2;
          tex[4] = tx1; tex[5] = ty1;
          tex[6] = tx2; tex[7] = ty1;
     }
     else {
          tex[0] = tx1; tex[1] = ty1;
          tex[2] = tx2; tex[3] = ty1;
          tex[4] = tx2; tex[5] = ty2;
          tex[6] = tx1; tex[7] = ty2;
     }

     glVertexAttribPointer(GLES2VA_POSITIONS, 2, GL_FLOAT, GL_FALSE, 0, pos);
     glVertexAttribPointer(GLES2VA_TEXCOORDS, 2, GL_FLOAT, GL_FALSE, 0, tex);

     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

     // XXX hood - how are these magic numbers determined?
     gdrv->calls += 1 + drect->w * drect->h / (23 * 42);

     return true;
}
Пример #4
0
static void *
ScreenUpdateLoop( DirectThread *thread, void *arg )
{
     pthread_mutex_lock( &dfb_sdl->update.lock );

     D_DEBUG_AT( SDL_Updates, "Entering %s()...\n", __FUNCTION__ );

     while (!dfb_sdl->update.quit) {
          if (dfb_sdl->update.pending) {
               DFBRectangle update = DFB_RECTANGLE_INIT_FROM_REGION( &dfb_sdl->update.region );

               dfb_sdl->update.pending = false;

               D_DEBUG_AT( SDL_Updates, "Got update %d,%d - %dx%d...\n", DFB_RECTANGLE_VALS( &update ) );

               pthread_mutex_unlock( &dfb_sdl->update.lock );


               update_screen( update.x, update.y, update.w, update.h );


               pthread_mutex_lock( &dfb_sdl->update.lock );
          }
          else
               pthread_cond_wait( &dfb_sdl->update.cond, &dfb_sdl->update.lock );
     }

     D_DEBUG_AT( SDL_Updates, "Returning from %s()...\n", __FUNCTION__ );

     pthread_mutex_unlock( &dfb_sdl->update.lock );

     return NULL;
}
Пример #5
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
gles2FillRectangle(void *drv, void *dev, DFBRectangle *rect)
{
     GLES2DriverData *gdrv = drv;

     float x1 = rect->x;
     float y1 = rect->y;
     float x2 = rect->w + x1;
     float y2 = rect->h + y1;

     GLfloat pos[] = {
          x1, y1,   x2, y1,   x2, y2,   x1, y2
     };

     D_DEBUG_AT(GLES2__2D, "%s(%4d,%4d-%4dx%4d)\n",
                __FUNCTION__, DFB_RECTANGLE_VALS(rect));

     glVertexAttribPointer(GLES2VA_POSITIONS, 2, GL_FLOAT, GL_FALSE, 0, pos);
     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

     // XXX hood - how are these magic numbers determined?
     gdrv->calls += 1 + rect->w * rect->h / (23 * 42);

     return true;
}
Пример #6
0
/*
 * Blend a rectangle using the alpha value from the color using the current hardware state.
 */
static bool
pxa3xxBlitBlendColorAlpha( void *drv, void *dev, DFBRectangle *rect, int x, int y )
{
     PXA3XXDriverData *pdrv = drv;
     PXA3XXDeviceData *pdev = dev;
     u32              *prep = start_buffer( pdrv, 9 );

     D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d  -> %d, %d )\n",
                 __FUNCTION__, DFB_RECTANGLE_VALS( rect ), x, y );
     DUMP_INFO();

     prep[0] = 0x47000138;
     prep[1] = x;
     prep[2] = y;
     prep[3] = rect->x;
     prep[4] = rect->y;
     prep[5] = x;
     prep[6] = y;
     prep[7] = PXA3XX_WH( rect->w, rect->h );
     prep[8] = (pdev->color.a << 24) | (pdev->color.a << 16);

     submit_buffer( pdrv, 9 );

     return true;
}
Пример #7
0
static bool
davinciFillRectangle32( void *drv, void *dev, DFBRectangle *rect )
{
     DavinciDriverData *ddrv = drv;
     DavinciDeviceData *ddev = dev;

     D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect) );

     if (ddev->dst_format == DSPF_ARGB && ddev->color.a == 0xff)
          davinci_c64x_blit_blend_32__L( &ddrv->tasks,
                                         C64X_BLEND_ONE_INVSRC,
                                         ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x,
                                         ddev->dst_pitch,
                                         0,
                                         0,
                                         rect->w, rect->h,
                                         ddev->color_argb,
                                         0xff );
     else
          davinci_c64x_fill_32__L( &ddrv->tasks,
                                   ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x,
                                   ddev->dst_pitch,
                                   rect->w, rect->h,
                                   ddev->fillcolor );

     return true;
}
Пример #8
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
pvr2dFillRectangle(void *drv, void *dev, DFBRectangle *rect)
{
     PVR2DDriverData *gdrv = drv;

     D_DEBUG_AT(PVR2D__2D, "%s(%4d,%4d-%4dx%4d)\n",
                __FUNCTION__, DFB_RECTANGLE_VALS(rect));


     PVR2DERROR ePVR2DStatus;

     gdrv->bltinfo.DstX   = rect->x;
     gdrv->bltinfo.DstY   = rect->y;
     gdrv->bltinfo.DSizeX = rect->w;
     gdrv->bltinfo.DSizeY = rect->h;

     gdrv->bltinfo.SrcX   = rect->x;
     gdrv->bltinfo.SrcY   = rect->y;
     gdrv->bltinfo.SizeX  = rect->w;
     gdrv->bltinfo.SizeY  = rect->h;

     gdrv->bltinfo.CopyCode = 0xF0;

     ePVR2DStatus = PVR2DBlt( gdrv->hPVR2DContext, &gdrv->bltinfo );
     if (ePVR2DStatus) {
          D_ERROR( "DirectFB/PVR2D: PVR2DBlt() failed! (status %d)\n", ePVR2DStatus );
          return false;
     }

     return true;
}
Пример #9
0
static DFBResult
unrealize_region( CoreLayerRegion *region )
{
     DFBResult                ret;
     int                      index;
     CoreLayer               *layer;
     CoreLayerShared         *shared;
     const DisplayLayerFuncs *funcs;

     D_ASSERT( region != NULL );
     D_ASSERT( region->context != NULL );
     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->shared != NULL );
     D_ASSERT( layer->funcs != NULL );

     shared = layer->shared;
     funcs  = layer->funcs;

     D_ASSERT( fusion_vector_contains( &shared->added_regions, region ) );

     index = fusion_vector_index_of( &shared->added_regions, region );

     D_DEBUG_AT( Core_Layers, "Removing region (%d, %d - %dx%d) from '%s'.\n",
                 DFB_RECTANGLE_VALS( &region->config.dest ), shared->description.name );

     /* Remove the region from hardware and driver. */
     if (funcs->RemoveRegion) {
          ret = funcs->RemoveRegion( layer, layer->driver_data,
                                     layer->layer_data, region->region_data );
          if (ret) {
               D_DERROR( ret, "Core/Layers: Could not remove region!\n" );
               return ret;
          }
     }

     /* Remove the region from the 'added' list. */
     fusion_vector_remove( &shared->added_regions, index );

     /* Deallocate the driver's region data. */
     if (region->region_data) {
          SHFREE( shared->shmpool, region->region_data );
          region->region_data = NULL;
     }

     /* Update the region's state. */
     D_FLAGS_CLEAR( region->state, CLRSF_REALIZED );
     D_FLAGS_SET( region->state, CLRSF_FROZEN );

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

     return DFB_OK;
}
Пример #10
0
DFBResult
IWindow_Real::SetBounds( const DFBRectangle *bounds )
{
     D_DEBUG_AT( Core_Window, "IWindow_Real::%s( %p )\n", __FUNCTION__, obj );

     D_MAGIC_ASSERT( obj, CoreWindow );

     return dfb_window_set_bounds( obj, DFB_RECTANGLE_VALS( bounds ) );
}
Пример #11
0
/*
 * Render a rectangle outline using the current hardware state.
 */
bool
pvr2dDrawRectangle(void *drv, void *dev, DFBRectangle *rect)
{
//     PVR2DDriverData *gdrv = drv;

     D_DEBUG_AT(PVR2D__2D, "%s(%4d,%4d-%4dx%4d)\n",
                __FUNCTION__, DFB_RECTANGLE_VALS(rect));

     return true;
}
Пример #12
0
void
sawman_dispatch_blit( SaWMan             *sawman,
                      SaWManWindow       *sawwin,
                      bool                right_eye,
                      const DFBRectangle *src,
                      const DFBRectangle *dst,
                      const DFBRegion    *clip )
{
     SaWManListenerCallData data;

     if (clip) {
          D_DEBUG_AT( SaWMan_Draw, "%s( %p,  %d,%d-%dx%d %d,%d-%dx%d    %d,%d-%dx%d )\n", __FUNCTION__,
                      sawwin, DFB_RECTANGLE_VALS( src ),
                      DFB_RECTANGLE_VALS( dst ), DFB_RECTANGLE_VALS_FROM_REGION( clip ) );
     }
     else {
          D_DEBUG_AT( SaWMan_Draw, "%s( %p,  %d,%d-%dx%d %d,%d-%dx%d    NO CLIP )\n", __FUNCTION__,
                      sawwin, DFB_RECTANGLE_VALS( src ), DFB_RECTANGLE_VALS( dst ) );
     }

     data.call        = SWMLC_WINDOW_BLIT;
     data.stereo_eye  = right_eye ? DSSE_RIGHT : DSSE_LEFT;
     data.window_id   = sawwin->window->id;
     data.resource_id = sawwin->window->resource_id;
     data.src         = *src;
     data.dst         = *dst;

     if (clip) {
          if (dfb_clip_blit_precheck( clip, dst->w, dst->h, dst->x, dst->y )) {
               dfb_clip_stretchblit( clip, &data.src, &data.dst );

               fusion_reactor_dispatch( sawman->reactor, &data, true, NULL );
          }
          else
               D_DEBUG_AT( SaWMan_Draw, "  -> CLIPPED!\n" );
     }
     else
          fusion_reactor_dispatch( sawman->reactor, &data, true, NULL );
}
Пример #13
0
/*
 * Render a blended rectangle using the current hardware state.
 *
 * As the hardware does not directly support this, we blit a single
 * pixel with blending.
 */
static bool
pxa3xxFillRectangleBlend( void *drv, void *dev, DFBRectangle *rect )
{
     PXA3XXDriverData *pdrv   = drv;
     PXA3XXDeviceData *pdev   = dev;
     u32              *prep   = start_buffer( pdrv, 22 );
     const u32         format = pixel_formats[DFB_PIXELFORMAT_INDEX( DSPF_ARGB )];

     D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
                 DFB_RECTANGLE_VALS( rect ) );
     DUMP_INFO();

     /* Set fake destination. */
     prep[0]  = 0x020000A2;
     prep[1]  = pdev->fake_phys;
     prep[2]  = (format << 19) | 4;

     /* Fill rectangle. */
     prep[3]  = 0x40000014 | (format << 8);
     prep[4]  = 0;
     prep[5]  = 0;
     prep[6]  = PXA3XX_WH( rect->w, 1 );
     prep[7]  = PIXEL_ARGB( pdev->color.a, pdev->color.r, pdev->color.g, pdev->color.b );

     /* Restore destination. */
     prep[8]  = 0x020000A2;
     prep[9]  = pdev->dst_phys;
     prep[10] = (pixel_formats[pdev->dst_index] << 19) | (pdev->dst_pitch << 5) | pdev->dst_bpp;

     /* Set fake buffer as source. */
     prep[11] = 0x02000002;
     prep[12] = pdev->fake_phys;
     prep[13] = (format << 19) | 4;

     /* Blit with blending. */
     prep[14] = 0x47000107;
     prep[15] = rect->x;
     prep[16] = rect->y;
     prep[17] = 0;
     prep[18] = 0;
     prep[19] = rect->x;
     prep[20] = rect->y;
     prep[21] = PXA3XX_WH( rect->w, rect->h );

     submit_buffer( pdrv, 22 );

     /* Clear the flag. */
     PXA3XX_INVALIDATE( SOURCE );

     return true;
}
Пример #14
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
vmwareFillRectangle( void *drv, void *dev, DFBRectangle *rect )
{
     VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
     void             *addr = vdev->dst_addr + rect->y * vdev->dst_pitch +
                              DFB_BYTES_PER_LINE(vdev->dst_format, rect->x);

     D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( rect ) );

     switch (vdev->dst_bpp) {
          case 4:
               while (rect->h--) {
                    int  w   = rect->w;
                    u32 *dst = addr;

                    while (w--)
                         *dst++ = vdev->color_pixel;

                    addr += vdev->dst_pitch;
               }
               break;

          case 2:
               while (rect->h--) {
                    int  w   = rect->w;
                    u16 *dst = addr;

                    while (w--)
                         *dst++ = vdev->color_pixel;

                    addr += vdev->dst_pitch;
               }
               break;

          case 1:
               while (rect->h--) {
                    int  w   = rect->w;
                    u8  *dst = addr;

                    while (w--)
                         *dst++ = vdev->color_pixel;

                    addr += vdev->dst_pitch;
               }
               break;
     }

     return true;
}
Пример #15
0
/*
 * Render a filled rectangle using the current hardware state.
 */
static bool
pxa3xxFillRectangle( void *drv, void *dev, DFBRectangle *rect )
{
     PXA3XXDriverData *pdrv = drv;
     u32              *prep = start_buffer( pdrv, 4 );

     D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
                 DFB_RECTANGLE_VALS( rect ) );
     DUMP_INFO();

     prep[0] = 0x40000003;
     prep[1] = rect->x;
     prep[2] = rect->y;
     prep[3] = PXA3XX_WH( rect->w, rect->h );

     submit_buffer( pdrv, 4 );

     return true;
}
Пример #16
0
static bool
davinciFillRectangleBlend32( void *drv, void *dev, DFBRectangle *rect )
{
     DavinciDriverData *ddrv = drv;
     DavinciDeviceData *ddev = dev;

     D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect) );

     davinci_c64x_blit_blend_32__L( &ddrv->tasks,
                                    ddev->draw_blend_sub_function,
                                    ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x,
                                    ddev->dst_pitch,
                                    0,
                                    0,
                                    rect->w, rect->h,
                                    ddev->color_argb,
                                    0xff );

     return true;
}
Пример #17
0
/*
 * Render a filled rectangle using the current hardware state.
 */
bool
vmwareBlit( void *drv, void *dev, DFBRectangle *srect, int dx, int dy )
{
     VMWareDeviceData *vdev = (VMWareDeviceData*) dev;
     void             *dst  = vdev->dst_addr + dy * vdev->dst_pitch +
                              DFB_BYTES_PER_LINE(vdev->dst_format, dx);
     void             *src  = vdev->src_addr + srect->y * vdev->src_pitch +
                              DFB_BYTES_PER_LINE(vdev->src_format, srect->x);

     D_DEBUG_AT( VMWare_2D, "%s( %d,%d-%dx%d -> %d, %d )\n", __FUNCTION__,
                 DFB_RECTANGLE_VALS( srect ), dx, dy );

     while (srect->h--) {
          direct_memcpy( dst, src, srect->w * vdev->dst_bpp );

          dst += vdev->dst_pitch;
          src += vdev->src_pitch;
     }

     return true;
}
Пример #18
0
/*
 * Render a filled rectangle using the current hardware state.
 */
static bool
davinciFillRectangle16( void *drv, void *dev, DFBRectangle *rect )
{
     DavinciDriverData *ddrv = drv;
     DavinciDeviceData *ddev = dev;

     D_DEBUG_AT( Davinci_2D, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS(rect) );

     /* FIXME: Optimize in DSP. */
     if ((rect->x | rect->w) & 1)
          davinci_c64x_fill_16__L( &ddrv->tasks,
                                   ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x,
                                   ddev->dst_pitch,
                                   rect->w, rect->h,
                                   ddev->fillcolor );
     else
          davinci_c64x_fill_32__L( &ddrv->tasks,
                                   ddev->dst_phys + ddev->dst_pitch * rect->y + ddev->dst_bpp * rect->x,
                                   ddev->dst_pitch,
                                   rect->w/2, rect->h,
                                   ddev->fillcolor );

     return true;
}
Пример #19
0
/*
 * Render a rectangle outline using the current hardware state.
 */
bool
gles2DrawRectangle(void *drv, void *dev, DFBRectangle *rect)
{
     GLES2DriverData *gdrv = drv;

     float x1 = rect->x + 1;
     float y1 = rect->y + 1;
     float x2 = rect->x + rect->w;
     float y2 = rect->y + rect->h;

     GLfloat pos[] = {
          x1, y1,   x2, y1,   x2, y2,   x1, y2
     };

     D_DEBUG_AT(GLES2__2D, "%s(%4d,%4d-%4dx%4d)\n",
                __FUNCTION__, DFB_RECTANGLE_VALS(rect));

     glVertexAttribPointer(GLES2VA_POSITIONS, 2, GL_FLOAT, GL_FALSE, 0, pos);
     glDrawArrays(GL_LINE_LOOP, 0, 4);

     gdrv->calls++;

     return true;
}
Пример #20
0
static void
draw_window( SaWManTier   *tier,
             SaWManWindow *sawwin,
             SaWManWindow *sawwin2,
             CardState    *state,
             DFBRegion    *region,
             bool          alpha_channel,
             bool          right_eye )
{
     SaWMan                  *sawman;
     CoreWindow              *window;
     DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
     DFBRectangle             dst;
     DFBRectangle             src;
     DFBRegion                clip;
     DFBRegion                old_clip;
     int                      offset;

     D_MAGIC_ASSERT( sawwin,  SaWManWindow );
     D_MAGIC_ASSERT( state, CardState );
     DFB_REGION_ASSERT( region );

     sawman = sawwin->sawman;
     window = sawwin->window;
     dst    = sawwin->dst;
     src    = sawwin->src;

     D_MAGIC_ASSERT( sawman, SaWMan );
     D_ASSERT( window != NULL );
     D_ASSERT( window->surface != NULL );

     D_DEBUG_AT( SaWMan_Draw, "%s( %p, %d,%d-%dx%d )\n", __FUNCTION__,
                 sawwin, DFB_RECTANGLE_VALS_FROM_REGION( region ) );

     if (window->config.options & DWOP_STEREO_SIDE_BY_SIDE_HALF) {
          src.x /= 2;
          src.w /= 2;

          if (right_eye)
               src.x += window->surface->config.size.w / 2;
     }

     /* Modify dst for stereo offset. */
     offset = window->config.z;
     offset *= right_eye ? -1 : 1;
     dfb_rectangle_translate( &dst, offset, 0 );

     /* Setup clipping region. */
     clip = *region;

     if (!dfb_region_rectangle_intersect( &clip, &dst ))
          return;


     sawman_dispatch_blit( sawman, sawwin, right_eye, &sawwin->src, &dst, &clip );

     if (sawwin2)
          sawman_dispatch_blit( sawman, sawwin2, right_eye, &sawwin2->src, &dst, &clip );


     /* Backup clipping region. */
     old_clip = state->clip;

     /* Use per pixel alpha blending. */
     if (alpha_channel && (window->config.options & DWOP_ALPHACHANNEL))
          flags |= DSBLIT_BLEND_ALPHACHANNEL;

     /* Use global alpha blending. */
     if (window->config.opacity != 0xFF) {
          flags |= DSBLIT_BLEND_COLORALPHA;

          if (window->surface->config.caps & DSCAPS_PREMULTIPLIED) {
               /* Need to premultiply source with Ac? */
               flags |= DSBLIT_SRC_PREMULTCOLOR;

               dfb_state_set_src_blend( state, DSBF_ONE );
          }
          else
               dfb_state_set_src_blend( state, DSBF_SRCALPHA );

          /* Set opacity as blending factor. */
          if (state->color.a != window->config.opacity) {
               state->color.a   = window->config.opacity;
               state->modified |= SMF_COLOR;
          }
     }

     /* if we specified some kind of color, we will colorise. no DWCAPS_COLOR here. */
     if (window->config.color.a != 0) {
          DFBColor c;

          flags |= DSBLIT_COLORIZE;

          c   = window->config.color;
          c.a = state->color.a;

          if (! DFB_COLOR_EQUAL( c, state->color )) {
               state->color     = c;
               state->modified |= SMF_COLOR;
          }
     }

     /* Use source color keying. */
     if (window->config.options & DWOP_COLORKEYING) {
          flags |= DSBLIT_SRC_COLORKEY;

          D_DEBUG_AT( SaWMan_Draw, "  -> key 0x%08x\n", window->config.color_key );

          /* Set window color key. */
          dfb_state_set_src_colorkey( state, window->config.color_key );
     }

     /* Use automatic deinterlacing. */
     if (window->surface->config.caps & DSCAPS_INTERLACED)
          flags |= DSBLIT_DEINTERLACE;

     /* Different compositing methods depending on destination format. */
     if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
          if (DFB_PIXELFORMAT_HAS_ALPHA( state->destination->config.format )) {
               /*
                * Always use compliant Porter/Duff SRC_OVER,
                * if the destination has an alpha channel.
                *
                * Cd = destination color  (non-premultiplied)
                * Ad = destination alpha
                *
                * Cs = source color       (non-premultiplied)
                * As = source alpha
                *
                * Ac = color alpha
                *
                * cd = Cd * Ad            (premultiply destination)
                * cs = Cs * As            (premultiply source)
                *
                * The full equation to calculate resulting color and alpha (premultiplied):
                *
                * cx = cd * (1-As*Ac) + cs * Ac
                * ax = Ad * (1-As*Ac) + As * Ac
                */
               dfb_state_set_src_blend( state, DSBF_ONE );

               /* Need to premultiply source with As*Ac or only with Ac? */
               if (! (window->surface->config.caps & DSCAPS_PREMULTIPLIED))
                    flags |= DSBLIT_SRC_PREMULTIPLY;
               else if (flags & DSBLIT_BLEND_COLORALPHA)
                    flags |= DSBLIT_SRC_PREMULTCOLOR;

               /* Need to premultiply/demultiply destination? */
//               if (! (state->destination->caps & DSCAPS_PREMULTIPLIED))
//                    flags |= DSBLIT_DST_PREMULTIPLY | DSBLIT_DEMULTIPLY;
          }
          else {
               /*
                * We can avoid DSBLIT_SRC_PREMULTIPLY for destinations without an alpha channel
                * by using another blending function, which is more likely that it's accelerated
                * than premultiplication at this point in time.
                *
                * This way the resulting alpha (ax) doesn't comply with SRC_OVER,
                * but as the destination doesn't have an alpha channel it's no problem.
                *
                * As the destination's alpha value is always 1.0 there's no need for
                * premultiplication. The resulting alpha value will also be 1.0 without
                * exceptions, therefore no need for demultiplication.
                *
                * cx = Cd * (1-As*Ac) + Cs*As * Ac  (still same effect as above)
                * ax = Ad * (1-As*Ac) + As*As * Ac  (wrong, but discarded anyways)
                */
               if (window->surface->config.caps & DSCAPS_PREMULTIPLIED) {
                    /* Need to premultiply source with Ac? */
                    if (flags & DSBLIT_BLEND_COLORALPHA)
                         flags |= DSBLIT_SRC_PREMULTCOLOR;

                    dfb_state_set_src_blend( state, DSBF_ONE );
               }
               else
                    dfb_state_set_src_blend( state, DSBF_SRCALPHA );
          }
     }

     /* Use color (key) protection if layer is keyed. */
     if (tier->context->config.options & DLOP_SRC_COLORKEY) {
          flags |= DSBLIT_COLORKEY_PROTECT;

          dfb_state_set_colorkey( state, &tier->key );
     }

     /* Set blitting flags. */
     dfb_state_set_blitting_flags( state, flags );

     /* Set render options. */
     if (sawman->scaling_mode == SWMSM_SMOOTH)
          dfb_state_set_render_options( state, DSRO_SMOOTH_DOWNSCALE | DSRO_SMOOTH_UPSCALE );
     else
          dfb_state_set_render_options( state, DSRO_NONE );

     /* Set blitting source. */
     state->source    = window->surface;
     state->from_eye  = (right_eye && (sawwin->caps & DWCAPS_STEREO)) ? DSSE_RIGHT : DSSE_LEFT;
     state->modified |= SMF_SOURCE | SMF_FROM;

     D_DEBUG_AT( SaWMan_Draw, "  [][] %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &clip ) );

     /* Change clipping region. */
     dfb_state_set_clip( state, &clip );

     D_DEBUG_AT( SaWMan_Draw, "    => %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d\n",
                 DFB_RECTANGLE_VALS( &dst ), DFB_RECTANGLE_VALS( &src ) );

#ifndef OLD_COREWINDOWS_STRUCTURE
     if (sawwin2) {
          CoreWindow   *window2;
          DFBRectangle *src2;
          DFBPoint      p1,p2,p;

          D_MAGIC_ASSERT( sawwin2, SaWManWindow );
          window2 = sawwin2->window;
          D_ASSERT( window2 != NULL );
          D_ASSERT( window2->surface != NULL );
          src2 = &sawwin2->src;

          state->source2  = window2->surface;
          state->modified = SMF_SOURCE2;

          p1.x = src2->x + (sawwin->dst.x - sawwin2->dst.x);
          p1.y = src2->y + (sawwin->dst.y - sawwin2->dst.y);
          p2.x = sawwin->dst.x;
          p2.y = sawwin->dst.y;

          p.x = p1.x;
          p.y = p1.y;

          p1.x = src.x;
          p1.y = src.y;

          src.x = p.x;
          src.y = p.y;

          CoreGraphicsStateClient_Blit2( state->client, &src, &p2, &p1, 1 );
     }
     else
#endif
     {
          /* Scale window to the screen clipped by the region being updated. */
          CoreGraphicsStateClient_StretchBlit( state->client, &src, &dst, 1 );
     }

     /* Restore clipping region. */
     dfb_state_set_clip( state, &old_clip );
}
Пример #21
0
void
dfb_clip_blit_flipped_rotated( const DFBRegion *clip,
                               DFBRectangle *srect, DFBRectangle *drect, DFBSurfaceBlittingFlags flags )
{

    DFBRegion dest    = DFB_REGION_INIT_FROM_RECTANGLE( drect );
    DFBRegion clipped = dest;

    D_ASSERT( !(flags & (DSBLIT_ROTATE270 | DSBLIT_ROTATE180)) );

    if (flags & DSBLIT_ROTATE90) {
        D_ASSERT( srect->w == drect->h );
        D_ASSERT( srect->h == drect->w );
    }
    else {
        D_ASSERT( srect->w == drect->w );
        D_ASSERT( srect->h == drect->h );
    }

    dfb_region_region_intersect( &clipped, clip );
    dfb_rectangle_from_region( drect, &clipped );

    switch (flags & (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL | DSBLIT_ROTATE90)) {
    case DSBLIT_NOFX:
        srect->x += clipped.x1 - dest.x1;
        srect->y += clipped.y1 - dest.y1;
        break;
    case DSBLIT_FLIP_HORIZONTAL:
        srect->x += dest.x2 - clipped.x2;
        srect->y += clipped.y1 - dest.y1;
        break;
    case DSBLIT_FLIP_VERTICAL:
        srect->x += clipped.x1 - dest.x1;
        srect->y += dest.y2 - clipped.y2;
        break;
    case DSBLIT_ROTATE90:
        srect->x += dest.y2 - clipped.y2;
        srect->y += clipped.x1 - dest.x1;
        break;
    case (DSBLIT_FLIP_HORIZONTAL | DSBLIT_FLIP_VERTICAL): // ROTATE180
        srect->x += dest.x2 - clipped.x2;
        srect->y += dest.y2 - clipped.y2;
        break;
    case (DSBLIT_ROTATE90 | DSBLIT_FLIP_VERTICAL | DSBLIT_FLIP_HORIZONTAL): // ROTATE270
        srect->x += clipped.y1 - dest.y1;
        srect->y += dest.x2 - clipped.x2;
        break;
    case (DSBLIT_ROTATE90 | DSBLIT_FLIP_HORIZONTAL):
        srect->x += clipped.y1 - dest.y1;
        srect->y += clipped.x1 - dest.x1;
        break;
    case (DSBLIT_ROTATE90 | DSBLIT_FLIP_VERTICAL):
        srect->x += dest.y2 - clipped.y2;
        srect->y += dest.x2 - clipped.x2;
        break;
    }

    if (flags & DSBLIT_ROTATE90) {
        srect->w  = drect->h;
        srect->h  = drect->w;
    }
    else {
        srect->w = drect->w;
        srect->h = drect->h;
    }

    D_DEBUG_AT( Core_Clipping, "  => %4d,%4d-%4dx%4d -> %4d,%4d-%4dx%4d\n",
                DFB_RECTANGLE_VALS(srect), DFB_RECTANGLE_VALS(drect) );
}
Пример #22
0
DFBResult
dfb_surface_write_buffer( CoreSurface            *surface,
                          CoreSurfaceBufferRole   role,
                          const void             *source,
                          int                     pitch,
                          const DFBRectangle     *prect )
{
     DFBResult              ret;
     int                    bytes;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     CoreSurfaceAllocation *allocation;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( pitch > 0 || source == NULL );
     DFB_RECTANGLE_ASSERT_IF( prect );

     D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, source, pitch );

     /* Determine area. */
     rect.x = 0;
     rect.y = 0;
     rect.w = surface->config.size.w;
     rect.h = surface->config.size.h;

     if (prect) {
          if (!dfb_rectangle_intersect( &rect, prect )) {
               D_DEBUG_AT( Core_Surface, "  -> no intersection!\n" );
               return DFB_INVAREA;
          }

          if (!DFB_RECTANGLE_EQUAL( rect, *prect )) {
               D_DEBUG_AT( Core_Surface, "  -> got clipped to %d,%d-%dx%d!\n", DFB_RECTANGLE_VALS(&rect) );
               return DFB_INVAREA;
          }
     }

     /* Calculate bytes per read line. */
     format = surface->config.format;
     bytes  = DFB_BYTES_PER_LINE( format, rect.w );

     D_DEBUG_AT( Core_Surface, "  -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
                 dfb_pixelformat_name( format ) );

     ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_WRITE, false, &allocation );
     if (ret)
          return ret;

     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );

     D_DEBUG_AT( Core_Surface, "  -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name );

     /* Try writing to allocation directly... */
     ret = source ? dfb_surface_pool_write( allocation->pool, allocation, source, pitch, &rect ) : DFB_UNSUPPORTED;
     if (ret) {
          /* ...otherwise use fallback method via locking if possible. */
          if (allocation->access[CSAID_CPU] & CSAF_WRITE) {
               int                   y;
               int                   bytes;
               DFBSurfacePixelFormat format;
               CoreSurfaceBufferLock lock;

               /* Calculate bytes per written line. */
               format = surface->config.format;
               bytes  = DFB_BYTES_PER_LINE( format, rect.w );

               /* Lock the allocation. */
               dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_WRITE );

               ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
               if (ret) {
                    D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
                              allocation->pool->desc.name );
                    dfb_surface_buffer_lock_deinit( &lock );
                    dfb_surface_allocation_unref( allocation );
                    return ret;
               }

               /* Move to start of write. */
               lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;

               /* Copy the data. */
               for (y=0; y<rect.h; y++) {
                    if (source) {
                         direct_memcpy( lock.addr, source, bytes );

                         source += pitch;
                    }
                    else
                         memset( lock.addr, 0, bytes );

                    lock.addr += lock.pitch;
               }

               /* Unlock the allocation. */
               ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
               if (ret)
                    D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );

               dfb_surface_buffer_lock_deinit( &lock );
          }
     }

     dfb_surface_allocation_unref( allocation );

     return DFB_OK;
}
Пример #23
0
static DFBResult
drmkmsPlaneSetRegion( CoreLayer                  *layer,
                      void                       *driver_data,
                      void                       *layer_data,
                      void                       *region_data,
                      CoreLayerRegionConfig      *config,
                      CoreLayerRegionConfigFlags  updated,
                      CoreSurface                *surface,
                      CorePalette                *palette,
                      CoreSurfaceBufferLock      *left_lock,
                      CoreSurfaceBufferLock      *right_lock )
{
     int              ret;
     bool             unmute = false;
     DRMKMSData      *drmkms = driver_data;
     DRMKMSLayerData *data   = layer_data;

     D_DEBUG_AT( DRMKMS_Layer, "%s()\n", __FUNCTION__ );
     if ((updated & CLRCF_OPACITY) && data->muted && config->opacity)
          unmute = true;

     if ((updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_BUFFERMODE | CLRCF_DEST | CLRCF_SOURCE)) || unmute) {
          ret = drmModeSetPlane(drmkms->fd, data->plane->plane_id, drmkms->encoder[0]->crtc_id, (u32)(long)left_lock->handle,
                                /* plane_flags */ 0, config->dest.x, config->dest.y, config->dest.w, config->dest.h,
                                config->source.x << 16, config->source.y <<16, config->source.w << 16, config->source.h << 16);

          if (ret) {
               D_INFO( "DirectFB/DRMKMS: drmModeSetPlane(plane_id=%d, fb_id=%d ,  dest=%d,%d-%dx%d, src=%d,%d-%dx%d) failed! (%d)\n", data->plane->plane_id, (u32)(long)left_lock->handle,
                       DFB_RECTANGLE_VALS(&config->dest), DFB_RECTANGLE_VALS(&config->source), ret );

               return DFB_FAILURE;
          }

          data->config = config;
          data->muted = false;
     }

     if ((updated & (CLRCF_SRCKEY | CLRCF_OPTIONS)) && data->colorkey_propid) {
          uint32_t drm_colorkey = config->src_key.r << 16 | config->src_key.g << 8 | config->src_key.b;

          if (config->options & DLOP_SRC_COLORKEY)
               drm_colorkey |= 0x01000000;

          ret = drmModeObjectSetProperty( drmkms->fd, data->plane->plane_id, DRM_MODE_OBJECT_PLANE, data->colorkey_propid, drm_colorkey );

          if (ret) {
               D_ERROR( "DirectFB/DRMKMS: drmModeObjectSetProperty() failed setting colorkey\n");
               return DFB_FAILURE;
          }
     }

     if (updated & CLRCF_OPACITY) {
          if (config->opacity == 0) {
               ret = drmModeSetPlane(drmkms->fd, data->plane->plane_id, drmkms->encoder[0]->crtc_id, 0,
                                     /* plane_flags */ 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0);

	       if (ret) {
                    D_ERROR( "DirectFB/DRMKMS: drmModeSetPlane() failed disabling plane\n");
                    return DFB_FAILURE;
               }

	       data->muted = true;
	  } else if (data->alpha_propid) {
               ret = drmModeObjectSetProperty( drmkms->fd, data->plane->plane_id, DRM_MODE_OBJECT_PLANE, data->alpha_propid, config->opacity );

               if (ret) {
                    D_ERROR( "DirectFB/DRMKMS: drmModeObjectSetProperty() failed setting alpha\n");
                    return DFB_FAILURE;
               }
	  }
     }

     return DFB_OK;
}
Пример #24
0
/*
 * Blit a glyph with alpha blending and colorizing using the current hardware state.
 */
static bool
pxa3xxBlitGlyph( void *drv, void *dev, DFBRectangle *rect, int x, int y )
{
     PXA3XXDriverData *pdrv   = drv;
     PXA3XXDeviceData *pdev   = dev;
     u32              *prep   = start_buffer( pdrv, 40 );
     const u32         format = pixel_formats[DFB_PIXELFORMAT_INDEX( DSPF_ARGB )];

     D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d )\n", __FUNCTION__,
                 DFB_RECTANGLE_VALS( rect ) );
     DUMP_INFO();

     if (rect->w * (rect->h + 1) * 4 > pdev->fake_size)
          return false;

     /* Set fake destination. */
     prep[0]  = 0x020000A2;
     prep[1]  = pdev->fake_phys;
     prep[2]  = (format << 19) | ((rect->w << 2) << 5) | 4;

     /* Fill first row of fake buffer. */
     prep[3]  = 0x40000014 | (format << 8);
     prep[4]  = 0;
     prep[5]  = 0;
     prep[6]  = PXA3XX_WH( rect->w, 1 );
     prep[7]  = PIXEL_ARGB( pdev->color.a, pdev->color.r, pdev->color.g, pdev->color.b );

     /* Set first row of fake buffer as source1. */
     prep[8]  = 0x02000012;
     prep[9]  = pdev->fake_phys;
     prep[10] = (format << 19) | 4;

     /* Blit with blending. */
     prep[11] = 0x47000118;
     prep[12] = 0;
     prep[13] = 1;
     prep[14] = rect->x;
     prep[15] = rect->y;
     prep[16] = 0;
     prep[17] = 0;
     prep[18] = PXA3XX_WH( rect->w, rect->h );
     prep[19] = 0;

     /* Restore destination. */
     prep[20] = 0x020000A2;
     prep[21] = pdev->dst_phys;
     prep[22] = (pixel_formats[pdev->dst_index] << 19) | (pdev->dst_pitch << 5) | pdev->dst_bpp;

     /* Restore source1 to destination. */
     prep[23] = 0x02000012;
     prep[24] = prep[21];
     prep[25] = prep[22];

     /* Set fake buffer as source0. */
     prep[26] = 0x02000002;
     prep[27] = pdev->fake_phys;
     prep[28] = (format << 19) | ((rect->w << 2) << 5) | 4;

     /* Blit with blending. */
     prep[29] = 0x47000107;
     prep[30] = x;
     prep[31] = y;
     prep[32] = 0;
     prep[33] = 1;
     prep[34] = x;
     prep[35] = y;
     prep[36] = PXA3XX_WH( rect->w, rect->h );

     /* Restore source0. */
     prep[37] = 0x02000002;
     prep[38] = pdev->src_phys;
     prep[39] = (pixel_formats[pdev->src_index] << 19) | (pdev->src_pitch << 5) | pdev->src_bpp;

     submit_buffer( pdrv, 40 );

     return true;
}
Пример #25
0
DFBResult
dfb_surface_read_buffer( CoreSurface            *surface,
                         CoreSurfaceBufferRole   role,
                         void                   *destination,
                         int                     pitch,
                         const DFBRectangle     *prect )
{
     DFBResult              ret;
     int                    y;
     int                    bytes;
     DFBRectangle           rect;
     DFBSurfacePixelFormat  format;
     CoreSurfaceAllocation *allocation;

     D_MAGIC_ASSERT( surface, CoreSurface );
     D_ASSERT( destination != NULL );
     D_ASSERT( pitch > 0 );
     DFB_RECTANGLE_ASSERT_IF( prect );

     D_DEBUG_AT( Core_Surface, "%s( %p, %p [%d] )\n", __FUNCTION__, surface, destination, pitch );

     /* Determine area. */
     rect.x = 0;
     rect.y = 0;
     rect.w = surface->config.size.w;
     rect.h = surface->config.size.h;

     if (prect && (!dfb_rectangle_intersect( &rect, prect ) || !DFB_RECTANGLE_EQUAL( rect, *prect )))
          return DFB_INVAREA;

     /* Calculate bytes per read line. */
     format = surface->config.format;
     bytes  = DFB_BYTES_PER_LINE( format, rect.w );

     D_DEBUG_AT( Core_Surface, "  -> %d,%d - %dx%d (%s)\n", DFB_RECTANGLE_VALS(&rect),
                 dfb_pixelformat_name( format ) );

     ret = CoreSurface_PreLockBuffer2( surface, role, CSAID_CPU, CSAF_READ, false, &allocation );
     if (ret == DFB_NOALLOCATION) {
          for (y=0; y<rect.h; y++) {
               memset( destination, 0, bytes );

               destination += pitch;
          }

          return DFB_OK;
     }
     if (ret)
          return ret;

     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );

     D_DEBUG_AT( Core_Surface, "  -> PreLockBuffer returned allocation %p (%s)\n", allocation, allocation->pool->desc.name );

     /* Try reading from allocation directly... */
     ret = dfb_surface_pool_read( allocation->pool, allocation, destination, pitch, &rect );
     if (ret) {
          /* ...otherwise use fallback method via locking if possible. */
          if (allocation->access[CSAID_CPU] & CSAF_READ) {
               CoreSurfaceBufferLock lock;

               /* Lock the allocation. */
               dfb_surface_buffer_lock_init( &lock, CSAID_CPU, CSAF_READ );

               ret = dfb_surface_pool_lock( allocation->pool, allocation, &lock );
               if (ret) {
                    D_DERROR( ret, "Core/SurfBuffer: Locking allocation failed! [%s]\n",
                              allocation->pool->desc.name );
                    dfb_surface_buffer_lock_deinit( &lock );
                    dfb_surface_allocation_unref( allocation );
                    return ret;
               }

               /* Move to start of read. */
               lock.addr += DFB_BYTES_PER_LINE( format, rect.x ) + rect.y * lock.pitch;

               /* Copy the data. */
               for (y=0; y<rect.h; y++) {
                    direct_memcpy( destination, lock.addr, bytes );

                    destination += pitch;
                    lock.addr   += lock.pitch;
               }

               /* Unlock the allocation. */
               ret = dfb_surface_pool_unlock( allocation->pool, allocation, &lock );
               if (ret)
                    D_DERROR( ret, "Core/SurfBuffer: Unlocking allocation failed! [%s]\n", allocation->pool->desc.name );

               dfb_surface_buffer_lock_deinit( &lock );
          }
     }

     dfb_surface_allocation_unref( allocation );

     return DFB_OK;
}
Пример #26
0
static DFBResult
update_screen( DFBX11 *x11, const DFBRectangle *clip, CoreSurfaceBufferLock *lock, XWindow *xw )
{
     void                  *dst;
     void                  *src;
     unsigned int           offset = 0;
     XImage                *ximage;
     CoreSurface           *surface;
     CoreSurfaceAllocation *allocation;
     DFBX11Shared          *shared;
     DFBRectangle           rect;
     bool                   direct = false;

     D_ASSERT( x11 != NULL );
     DFB_RECTANGLE_ASSERT( clip );

     D_DEBUG_AT( X11_Update, "%s( %4d,%4d-%4dx%4d )\n", __FUNCTION__, DFB_RECTANGLE_VALS( clip ) );

     CORE_SURFACE_BUFFER_LOCK_ASSERT( lock );

     shared = x11->shared;
     D_ASSERT( shared != NULL );

     XLockDisplay( x11->display );

     if (!xw) {
          XUnlockDisplay( x11->display );
          return DFB_OK;
     }

     allocation = lock->allocation;
     CORE_SURFACE_ALLOCATION_ASSERT( allocation );

     surface = allocation->surface;
     D_ASSERT( surface != NULL );


     rect.x = rect.y = 0;
     rect.w = xw->width;
     rect.h = xw->height;

     if (!dfb_rectangle_intersect( &rect, clip )) {
          XUnlockDisplay( x11->display );
          return DFB_OK;
     }

     D_DEBUG_AT( X11_Update, "  -> %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS( &rect ) );

#ifdef USE_GLX
     /* Check for GLX allocation... */
     if (allocation->pool == shared->glx_pool && lock->handle) {
          LocalPixmap *pixmap = lock->handle;

          D_MAGIC_ASSERT( pixmap, LocalPixmap );

          /* ...and just call SwapBuffers... */
          //D_DEBUG_AT( X11_Update, "  -> Calling glXSwapBuffers( 0x%lx )...\n", alloc->drawable );
          //glXSwapBuffers( x11->display, alloc->drawable );


          D_DEBUG_AT( X11_Update, "  -> Copying from GLXPixmap...\n" );

          glXWaitGL();

          XCopyArea( x11->display, pixmap->pixmap, xw->window, xw->gc,
                     rect.x, rect.y, rect.w, rect.h, rect.x, rect.y );

          glXWaitX();

          XUnlockDisplay( x11->display );

          return DFB_OK;
     }
#endif

     /* Check for our special native allocation... */
     if (allocation->pool == shared->x11image_pool && lock->handle) {
          x11Image *image = lock->handle;

          D_MAGIC_ASSERT( image, x11Image );

          /* ...and directly XShmPutImage from that. */
          ximage = image->ximage;

          direct = true;
     }
     else {
          /* ...or copy or convert into XShmImage or XImage allocated with the XWindow. */
          ximage = xw->ximage;
          offset = xw->ximage_offset;

          xw->ximage_offset = (offset ? 0 : ximage->height / 2);

          /* make sure the 16-bit input formats are properly 2-pixel-clipped */
          switch (surface->config.format) {
               case DSPF_I420:
               case DSPF_YV12:
               case DSPF_NV12:
               case DSPF_NV21:
                    if (rect.y & 1) {
                         rect.y--;
                         rect.h++;
                    }
                    /* fall through */
               case DSPF_YUY2:
               case DSPF_UYVY:
               case DSPF_NV16:
                    if (rect.x & 1) {
                         rect.x--;
                         rect.w++;
                    }
               default: /* no action */
                    break;
          }

          dst = xw->virtualscreen + rect.x * xw->bpp + (rect.y + offset) * ximage->bytes_per_line;
          src = lock->addr + DFB_BYTES_PER_LINE( surface->config.format, rect.x ) + rect.y * lock->pitch;

          switch (xw->depth) {
               case 32:
                    dfb_convert_to_argb( surface->config.format, src, lock->pitch,
                                         surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               case 24:
                    dfb_convert_to_rgb32( surface->config.format, src, lock->pitch,
                                          surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               case 16:
                    if (surface->config.format == DSPF_LUT8) {
                         int width = rect.w; int height = rect.h;
                         const u8    *src8    = src;
                         u16         *dst16   = dst;
                         CorePalette *palette = surface->palette;
                         int          x;
                         while (height--) {

                              for (x=0; x<width; x++) {
                                   DFBColor color = palette->entries[src8[x]];
                                   dst16[x] = PIXEL_RGB16( color.r, color.g, color.b );
                              }

                              src8  += lock->pitch;
                              dst16 += ximage->bytes_per_line / 2;
                         }
                    }
                    else {
                    dfb_convert_to_rgb16( surface->config.format, src, lock->pitch,
                                          surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    }
                    break;

               case 15:
                    dfb_convert_to_rgb555( surface->config.format, src, lock->pitch,
                                           surface->config.size.h, dst, ximage->bytes_per_line, rect.w, rect.h );
                    break;

               default:
                    D_ONCE( "unsupported depth %d", xw->depth );
          }
     }

     D_ASSERT( ximage != NULL );


     /* Wait for previous data to be processed... */
     XSync( x11->display, False );

     /* ...and immediately queue or send the next! */
     if (x11->use_shm) {
          /* Just queue the command, it's XShm :) */
          XShmPutImage( xw->display, xw->window, xw->gc, ximage,
                        rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h, False );

          /* Make sure the queue has really happened! */
          XFlush( x11->display );
     }
     else
          /* Initiate transfer of buffer... */
          XPutImage( xw->display, xw->window, xw->gc, ximage,
                     rect.x, rect.y + offset, rect.x, rect.y, rect.w, rect.h );

     /* Wait for display if single buffered and not converted... */
     if (direct && !(surface->config.caps & DSCAPS_FLIPPING))
          XSync( x11->display, False );

     XUnlockDisplay( x11->display );

     return DFB_OK;
}
Пример #27
0
/*
 * Blit a rectangle using the current hardware state.
 */
static bool
pxa3xxBlit( void *drv, void *dev, DFBRectangle *rect, int x, int y )
{
     PXA3XXDriverData *pdrv     = drv;
     PXA3XXDeviceData *pdev     = dev;
     u32               rotation = 0;
     u32              *prep     = start_buffer( pdrv, 6 );

     D_DEBUG_AT( PXA3XX_BLT, "%s( %d, %d - %dx%d  -> %d, %d )\n",
                 __FUNCTION__, DFB_RECTANGLE_VALS( rect ), x, y );
     DUMP_INFO();

     if (pdev->bflags & DSBLIT_ROTATE90)
           rotation = 3;
     else if (pdev->bflags & DSBLIT_ROTATE180)
           rotation = 2;
     else if (pdev->bflags & DSBLIT_ROTATE270)
           rotation = 1;

     prep[0] = 0x4A000005 | (rotation << 4); // FIXME: use 32byte alignment hint
     prep[1] = x;
     prep[2] = y;
     prep[3] = rect->x;
     prep[4] = rect->y;
     prep[5] = PXA3XX_WH( rect->w, rect->h );

     submit_buffer( pdrv, 6 );

/* RASTER

     prep[0] = 0x4BCC0007;
     prep[1] = x;
     prep[2] = y;
     prep[3] = rect->x;
     prep[4] = rect->y;
     prep[5] = rect->x;
     prep[6] = rect->y;
     prep[7] = PXA3XX_WH( rect->w, rect->h );

     submit_buffer( pdrv, 8 );
 */

/* PATTERN

     prep[0] = 0x4C000006;
     prep[1] = x;
     prep[2] = y;
     prep[3] = rect->x;
     prep[4] = rect->y;
     prep[5] = PXA3XX_WH( rect->w, rect->h );
     prep[6] = PXA3XX_WH( rect->w, rect->h );

     submit_buffer( pdrv, 7 );
 */

/* BIAS

     prep[0] = 0x49000016;
     prep[1] = x;
     prep[2] = y;
     prep[3] = rect->x;
     prep[4] = rect->y;
     prep[5] = PXA3XX_WH( rect->w, rect->h );
     prep[6] = 0;

     submit_buffer( pdrv, 7 );
 */

     return true;
}
Пример #28
0
static DFBResult
x11Read( CoreSurfacePool       *pool,
         void                  *pool_data,
         void                  *pool_local,
         CoreSurfaceAllocation *allocation,
         void                  *alloc_data,
         void                  *destination,
         int                    pitch,
         const DFBRectangle    *rect )
{
     XImage            *image;
     XImage            *sub;
     x11PoolLocalData  *local = pool_local;
     x11AllocationData *alloc = alloc_data;
     DFBX11            *x11   = local->x11;

     D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
     D_DEBUG_AT( X11_Surfaces, "  -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
     D_ASSERT( destination != NULL );
     D_ASSERT( pitch >= 0 );
     DFB_RECTANGLE_ASSERT( rect );

     D_DEBUG_AT( X11_Surfaces, "  => %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );


     XLockDisplay( x11->display );

#if 1
     image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, destination, rect->w, rect->h, 32, pitch );
     if (!image) {
          D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth );
          XUnlockDisplay( x11->display );
          return DFB_FAILURE;
     }

     sub = XGetSubImage( x11->display, alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap, image, 0, 0 );
#else
     image = XGetImage( x11->display, alloc->window ? alloc->window : alloc->xid,
                        rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap );
#endif

     if (image) {
//          dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Read", false, image->data, image->bytes_per_line );

          /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */
          image->data = NULL;
          XDestroyImage( image );
     }

     XUnlockDisplay( x11->display );

#if 1
     if (!sub) {
          D_ERROR( "X11/Surfaces: XGetSubImage( %d,%d-%dx%d ) failed!\n", DFB_RECTANGLE_VALS(rect) );
          return DFB_FAILURE;
     }
#endif
     return DFB_OK;
}
Пример #29
0
static DFBResult
x11Write( CoreSurfacePool       *pool,
          void                  *pool_data,
          void                  *pool_local,
          CoreSurfaceAllocation *allocation,
          void                  *alloc_data,
          const void            *source,
          int                    pitch,
          const DFBRectangle    *rect )
{
     XImage            *image;
     x11PoolLocalData  *local = pool_local;
     x11AllocationData *alloc = alloc_data;
     DFBX11            *x11   = local->x11;

     D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
     D_DEBUG_AT( X11_Surfaces, "  -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
     D_ASSERT( source != NULL );
     D_ASSERT( pitch >= 0 );
     DFB_RECTANGLE_ASSERT( rect );

     D_DEBUG_AT( X11_Surfaces, "  <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );

     XLockDisplay( x11->display );

     x11->Sync( x11 );

     D_DEBUG_AT( X11_Surfaces, "  <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );

     image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, (void*) source, rect->w, rect->h, 32, pitch );
     if (!image) {
          D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth );
          XUnlockDisplay( x11->display );
          return DFB_FAILURE;
     }
     x11->Sync( x11 );
     D_DEBUG_AT( X11_Surfaces, "  <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );

//     dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Write", false, image->data, image->bytes_per_line );

     XPutImage( x11->display, alloc->xid, alloc->gc, image, 0, 0, rect->x, rect->y, rect->w, rect->h );

     x11->Sync( x11 );
     D_DEBUG_AT( X11_Surfaces, "  <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );

     /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */
     image->data = NULL;
     XDestroyImage( image );

     x11->Sync( x11 );
     D_DEBUG_AT( X11_Surfaces, "  <= %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );

     XUnlockDisplay( x11->display );

     return DFB_OK;
}
Пример #30
0
static DFBResult
realize_region( CoreLayerRegion *region )
{
     DFBResult          ret;
     CoreLayer         *layer;
     CoreLayerShared   *shared;
     DisplayLayerFuncs *funcs;

     D_ASSERT( region != NULL );
     D_ASSERT( region->context != NULL );
     D_ASSERT( D_FLAGS_IS_SET( region->state, CLRSF_CONFIGURED ) );
     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->shared != NULL );
     D_ASSERT( layer->funcs != NULL );

     shared = layer->shared;
     funcs  = layer->funcs;

     D_ASSERT( ! fusion_vector_contains( &shared->added_regions, region ) );

     /* Allocate the driver's region data. */
     if (funcs->RegionDataSize) {
          int size = funcs->RegionDataSize();

          if (size > 0) {
               region->region_data = SHCALLOC( 1, size );
               if (!region->region_data)
                    return D_OOSHM();
          }
     }

     D_DEBUG_AT( Core_Layers, "Adding region (%d, %d - %dx%d) to '%s'.\n",
                 DFB_RECTANGLE_VALS( &region->config.dest ), shared->description.name );

     /* Add the region to the driver. */
     if (funcs->AddRegion) {
          ret = funcs->AddRegion( layer,
                                  layer->driver_data, layer->layer_data,
                                  region->region_data, &region->config );
          if (ret) {
               D_DERROR( ret, "Core/Layers: Could not add region!\n" );

               if (region->region_data) {
                    SHFREE( region->region_data );
                    region->region_data = NULL;
               }

               return ret;
          }
     }

     /* Add the region to the 'added' list. */
     fusion_vector_add( &shared->added_regions, region );

     /* Update the region's state. */
     D_FLAGS_SET( region->state, CLRSF_REALIZED );

     /* Initially setup hardware. */
     ret = set_region( region, &region->config, CLRCF_ALL, region->surface );
     if (ret) {
          unrealize_region( region );
          return ret;
     }

     return DFB_OK;
}