Esempio n. 1
0
void
dfb_gfx_copy_to( CoreSurface *source, CoreSurface *destination, const DFBRectangle *rect, int x, int y, bool from_back )
{
     DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h };

     pthread_mutex_lock( &copy_lock );

     if (!copy_state_inited) {
          dfb_state_init( &copy_state, NULL );
          copy_state_inited = true;
     }

     copy_state.modified   |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION;

     copy_state.clip.x2     = destination->config.size.w - 1;
     copy_state.clip.y2     = destination->config.size.h - 1;
     copy_state.source      = source;
     copy_state.destination = destination;
     copy_state.from        = from_back ? CSBR_BACK : CSBR_FRONT;
     copy_state.to          = CSBR_BACK;

     if (rect) {
          if (dfb_rectangle_intersect( &sourcerect, rect ))
               dfb_gfxcard_blit( &sourcerect,
                                 x + sourcerect.x - rect->x,
                                 y + sourcerect.y - rect->y, &copy_state );
     }
     else
          dfb_gfxcard_blit( &sourcerect, x, y, &copy_state );

     /* Signal end of sequence. */
     dfb_state_stop_drawing( &copy_state );

     pthread_mutex_unlock( &copy_lock );
}
static DFBResult
IDirectFBSurface_Layer_GetSubSurface( IDirectFBSurface    *thiz,
                                      const DFBRectangle  *rect,
                                      IDirectFBSurface   **surface )
{
     DFBResult ret;

     DIRECT_INTERFACE_GET_DATA(IDirectFBSurface_Layer)

     D_DEBUG_AT( Surface, "%s( %p )\n", __FUNCTION__, thiz );

     /* Check arguments */
     if (!data->base.surface)
          return DFB_DESTROYED;

     if (!surface)
          return DFB_INVARG;
          
     /* Allocate interface */
     DIRECT_ALLOCATE_INTERFACE( *surface, IDirectFBSurface );

     if (rect || data->base.limit_set) {
          DFBRectangle wanted, granted;
          
          /* Compute wanted rectangle */
          if (rect) {
               wanted = *rect;

               wanted.x += data->base.area.wanted.x;
               wanted.y += data->base.area.wanted.y;

               if (wanted.w <= 0 || wanted.h <= 0) {
                    wanted.w = 0;
                    wanted.h = 0;
               }
          }
          else {
               wanted = data->base.area.wanted;
          }
          
          /* Compute granted rectangle */
          granted = wanted;

          dfb_rectangle_intersect( &granted, &data->base.area.granted );
          
          /* Construct */
          ret = IDirectFBSurface_Layer_Construct( *surface, thiz, &wanted, &granted,
                                                  data->region, data->base.caps |
                                                  DSCAPS_SUBSURFACE, data->base.core );
     }
     else {
          /* Construct */
          ret = IDirectFBSurface_Layer_Construct( *surface, thiz, NULL, NULL,
                                                  data->region, data->base.caps |
                                                  DSCAPS_SUBSURFACE, data->base.core );
     }
     
     return ret;
}
Esempio n. 3
0
void dfb_gfx_stretch_stereo( CoreSurface         *source,
                             DFBSurfaceStereoEye  source_eye,
                             CoreSurface         *destination,
                             DFBSurfaceStereoEye  destination_eye,
                             const DFBRectangle  *srect,
                             const DFBRectangle  *drect,
                             bool                 from_back )
{
     DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle destrect =   { 0, 0, destination->config.size.w, destination->config.size.h };

     D_ASSERT( !dfb_config->task_manager );

     if (srect) {
          if (!dfb_rectangle_intersect( &sourcerect, srect ))
               return;
     }

     if (drect) {
          if (!dfb_rectangle_intersect( &destrect, drect ))
               return;
     }

     StateClient *client = state_client_tls.Get();

     D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

     client->state.clip.x2     = destination->config.size.w - 1;
     client->state.clip.y2     = destination->config.size.h - 1;
     client->state.source      = source;
     client->state.destination = destination;
     client->state.from        = from_back ? CSBR_BACK : CSBR_FRONT;
     client->state.from_eye    = source_eye;
     client->state.to          = CSBR_BACK;
     client->state.to_eye      = destination_eye;

     CoreGraphicsStateClient_StretchBlit( &client->client, &sourcerect, &destrect, 1 );

     CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE );

     /* Signal end of sequence. */
     dfb_state_stop_drawing( &client->state );

     client->state.destination = NULL;
     client->state.source      = NULL;
}
Esempio n. 4
0
void
dfb_gfx_copy_regions_stereo( CoreSurface           *source,
                             CoreSurfaceBufferRole  from,
                             DFBSurfaceStereoEye    source_eye,
                             CoreSurface           *destination,
                             CoreSurfaceBufferRole  to,
                             DFBSurfaceStereoEye    destination_eye,
                             const DFBRegion       *regions,
                             unsigned int           num,
                             int                    x,
                             int                    y )
{
     unsigned int i, n = 0;
     DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle rects[num];
     DFBPoint     points[num];

     D_ASSERT( !dfb_config->task_manager );

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x - rect.x;
               points[n].y = y + rects[n].y - rect.y;

               n++;
          }
     }

     if (n > 0) {
          StateClient *client = state_client_tls.Get();

          D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

          client->state.clip.x2     = destination->config.size.w - 1;
          client->state.clip.y2     = destination->config.size.h - 1;
          client->state.source      = source;
          client->state.destination = destination;
          client->state.from        = from;
          client->state.from_eye    = source_eye;
          client->state.to          = to;
          client->state.to_eye      = destination_eye;

          CoreGraphicsStateClient_Blit( &client->client, rects, points, n );

          CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE );

          /* Signal end of sequence. */
          dfb_state_stop_drawing( &client->state );

          client->state.destination = NULL;
          client->state.source      = NULL;
     }
}
Esempio n. 5
0
void
dfb_gfx_copy_regions( CoreSurface           *source,
                      CoreSurfaceBufferRole  from,
                      CoreSurface           *destination,
                      CoreSurfaceBufferRole  to,
                      const DFBRegion       *regions,
                      unsigned int           num,
                      int                    x,
                      int                    y )
{
     unsigned int i, n = 0;
     DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle rects[num];
     DFBPoint     points[num];

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x - rect.x;
               points[n].y = y + rects[n].y - rect.y;

               n++;
          }
     }

     if (n > 0) {
          pthread_mutex_lock( &copy_lock );

          if (!copy_state_inited) {
               dfb_state_init( &copy_state, NULL );
               copy_state_inited = true;
          }

          copy_state.modified   |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION;

          copy_state.clip.x2     = destination->config.size.w - 1;
          copy_state.clip.y2     = destination->config.size.h - 1;
          copy_state.source      = source;
          copy_state.destination = destination;
          copy_state.from        = from;
          copy_state.to          = to;

          dfb_gfxcard_batchblit( rects, points, n, &copy_state );
     
          /* Signal end of sequence. */
          dfb_state_stop_drawing( &copy_state );

          pthread_mutex_unlock( &copy_lock );
     }
}
Esempio n. 6
0
void
dfb_gfx_stretch_to( CoreSurface *source, CoreSurface *destination,
                    const DFBRectangle *srect, const DFBRectangle *drect, bool from_back )
{
     DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle destrect =   { 0, 0, destination->config.size.w, destination->config.size.h };

     if (srect) {
          if (!dfb_rectangle_intersect( &sourcerect, srect ))
               return;
     }

     if (drect) {
          if (!dfb_rectangle_intersect( &destrect, drect ))
               return;
     }

     pthread_mutex_lock( &copy_lock );

     if (!copy_state_inited) {
          dfb_state_init( &copy_state, NULL );
          copy_state_inited = true;
     }

     copy_state.modified   |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION;

     copy_state.clip.x2     = destination->config.size.w - 1;
     copy_state.clip.y2     = destination->config.size.h - 1;
     copy_state.source      = source;
     copy_state.destination = destination;
     copy_state.from        = from_back ? CSBR_BACK : CSBR_FRONT;

     dfb_gfxcard_stretchblit( &sourcerect, &destrect, &copy_state );

     /* Signal end of sequence. */
     dfb_state_stop_drawing( &copy_state );

     pthread_mutex_unlock( &copy_lock );
}
Esempio n. 7
0
void
dfb_gfx_copy_stereo( CoreSurface         *source,
                     DFBSurfaceStereoEye  source_eye,
                     CoreSurface         *destination,
                     DFBSurfaceStereoEye  destination_eye,
                     const DFBRectangle  *rect,
                     int                  x,
                     int                  y,
                     bool                 from_back )
{
     DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h };

     StateClient *client = state_client_tls.Get();

     D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

     client->state.clip.x2     = destination->config.size.w - 1;
     client->state.clip.y2     = destination->config.size.h - 1;
     client->state.source      = source;
     client->state.destination = destination;
     client->state.from        = from_back ? CSBR_BACK : CSBR_FRONT;
     client->state.from_eye    = source_eye;
     client->state.to          = CSBR_BACK;
     client->state.to_eye      = destination_eye;

     if (rect) {
          if (dfb_rectangle_intersect( &sourcerect, rect )) {
               DFBPoint point = { x + sourcerect.x - rect->x, y + sourcerect.y - rect->y };

               CoreGraphicsStateClient_Blit( &client->client, &sourcerect, &point, 1 );
          }
     }
     else {
          DFBPoint point = { x, y };

          CoreGraphicsStateClient_Blit( &client->client, &sourcerect, &point, 1 );
     }

     CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE );

     /* Signal end of sequence. */
     dfb_state_stop_drawing( &client->state );

     client->state.destination = NULL;
     client->state.source      = NULL;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
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;
}
Esempio n. 11
0
void
dfb_gfx_copy_regions_client( CoreSurface             *source,
                             CoreSurfaceBufferRole    from,
                             DFBSurfaceStereoEye      source_eye,
                             CoreSurface             *destination,
                             CoreSurfaceBufferRole    to,
                             DFBSurfaceStereoEye      destination_eye,
                             const DFBRegion         *regions,
                             unsigned int             num,
                             int                      x,
                             int                      y,
                             CoreGraphicsStateClient *_client )
{
     unsigned int             i, n = 0;
     DFBRectangle             rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle             rects[num];
     DFBPoint                 points[num];
     CoreGraphicsStateClient *client = _client ? _client : &state_client_tls.Get()->client;
     CardState               *state  = client->state;
     CardState                backup;

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x;
               points[n].y = y + rects[n].y;

               n++;
          }
     }

     if (n > 0) {
          backup.clip          = state->clip;
          backup.source        = state->source;
          backup.destination   = state->destination;
          backup.from          = state->from;
          backup.from_eye      = state->from_eye;
          backup.to            = state->to;
          backup.to_eye        = state->to_eye;
          backup.blittingflags = state->blittingflags;


          D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS );

          state->clip.x1     = 0;
          state->clip.y1     = 0;
          state->clip.x2     = destination->config.size.w - 1;
          state->clip.y2     = destination->config.size.h - 1;
          state->source      = source;
          state->destination = destination;
          state->from        = from;
          state->from_eye    = source_eye;
          state->to          = to;
          state->to_eye      = destination_eye;
          state->blittingflags = DSBLIT_NOFX;

          CoreGraphicsStateClient_Blit( client, rects, points, n );

          if (!_client)
               CoreGraphicsStateClient_Flush( client, 0, CGSCFF_NONE );

          D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS );

          state->clip          = backup.clip;
          state->source        = backup.source;
          state->destination   = backup.destination;
          state->from          = backup.from;
          state->from_eye      = backup.from_eye;
          state->to            = backup.to;
          state->to_eye        = backup.to_eye;
          state->blittingflags = backup.blittingflags;
     }
}
Esempio n. 12
0
void sawman_draw_cursor    ( CoreWindowStack *stack,
                             CardState       *state,
                             CoreSurface     *surface,
                             DFBRegion       *region,
                             int              x,
                             int              y )
{
     DFBRectangle            src;
     DFBRectangle            clip;
     DFBSurfaceBlittingFlags flags = DSBLIT_BLEND_ALPHACHANNEL;

     D_ASSERT( stack != NULL );
     D_MAGIC_ASSERT( state, CardState );
     DFB_REGION_ASSERT( region );

     D_ASSUME( stack->cursor.opacity > 0 );

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

     /* Initialize source rectangle. */
     src.x = region->x1 - x + stack->cursor.hot.x;
     src.y = region->y1 - y + stack->cursor.hot.y;
     src.w = region->x2 - region->x1 + 1;
     src.h = region->y2 - region->y1 + 1;

     D_DEBUG_AT( SaWMan_Draw, "  -> cursor surface %p\n", stack->cursor.surface );

     /* Initialize source clipping rectangle */
     clip.x = clip.y = 0;
     clip.w = stack->cursor.surface->config.size.w;
     clip.h = stack->cursor.surface->config.size.h;

     /* Intersect rectangles */
     if (!dfb_rectangle_intersect( &src, &clip ))
          return;

     /* Set destination. */
     if (surface) {
          state->destination  = surface;
          state->modified    |= SMF_DESTINATION;
     }

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

          if (stack->cursor.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 != stack->cursor.opacity) {
               state->color.a   = stack->cursor.opacity;
               state->modified |= SMF_COLOR;
          }
     }

     /* 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 (! (stack->cursor.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 (stack->cursor.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 );
          }
     }

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

     /* Set blitting source. */
     state->source    = stack->cursor.surface;
     state->from_eye  = DSSE_LEFT;
     state->modified |= SMF_SOURCE | SMF_FROM;

     /* Set clipping region. */
     dfb_state_set_clip( state, region );

     /* Blit from the window to the region being updated. */
     DFBPoint point = {
          region->x1, region->y1
     };
     D_DEBUG_AT( SaWMan_Draw, "  -> client %p\n", state->client );
     CoreGraphicsStateClient_Blit( state->client, &src, &point, 1 );

     /* Reset blitting source. */
     state->source    = NULL;
     state->modified |= SMF_SOURCE;

     /* Reset destination. */
     if (surface) {
          state->destination  = NULL;
          state->modified    |= SMF_DESTINATION;
     }
}