Пример #1
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;
}
static bool
stretch_hvx( CardState *state, DFBRectangle *srect, DFBRectangle *drect )
{
     GenefxState                *gfxs;
     const StretchFunctionTable *table;
     StretchHVx                  stretch;
     bool                        down = false;
     void                       *dst;
     void                       *src;
     StretchCtx                  ctx;
     int                         idx = STRETCH_NONE;
     u32                         colors[256];

     D_ASSERT( state != NULL );
     DFB_RECTANGLE_ASSERT( srect );
     DFB_RECTANGLE_ASSERT( drect );

     gfxs = state->gfxs;

     if (srect->w > drect->w && srect->h > drect->h)
          down = true;

     if (down) {
          if (!(state->render_options & DSRO_SMOOTH_DOWNSCALE))
               return false;
     }
     else {
          if (!(state->render_options & DSRO_SMOOTH_UPSCALE))
               return false;
     }

     switch (gfxs->dst_format) {
          case DSPF_NV12:
          case DSPF_NV21:
               return stretch_hvx_planar( state, srect, drect, down );

          default:
               break;
     }

     if (state->blittingflags & ~(DSBLIT_COLORKEY_PROTECT | DSBLIT_SRC_COLORKEY | DSBLIT_SRC_PREMULTIPLY))
          return false;

     if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY && !DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format ))
          return false;

     if (DFB_PIXELFORMAT_INDEX(gfxs->dst_format) >= D_ARRAY_SIZE(stretch_tables))
          return false;

     if (DFB_PIXELFORMAT_INDEX(gfxs->src_format) >= D_ARRAY_SIZE((stretch_tables[0])->f))
          return false;

     table = stretch_tables[DFB_PIXELFORMAT_INDEX(gfxs->dst_format)];
     if (!table)
          return false;

     if (state->blittingflags & DSBLIT_SRC_COLORKEY)
          idx |= STRETCH_SRCKEY;

     if (state->blittingflags & DSBLIT_COLORKEY_PROTECT)
          idx |= STRETCH_PROTECT;

     if (down)
          stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].down[idx];
     else
          stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].up[idx];

     if (!stretch)
          return false;

     ctx.clip = state->clip;

     if (!dfb_region_rectangle_intersect( &ctx.clip, drect ))
          return false;

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

     if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) {
          int             i;
          const DFBColor *entries;
          u16            *colors16 = (void*) colors;

          D_ASSERT( gfxs->Blut != NULL );

          entries = gfxs->Blut->entries;

          switch (gfxs->dst_format) {
               case DSPF_ARGB:
                    if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
                         for (i=0; i<gfxs->Blut->num_entries; i++) {
                              int alpha = entries[i].a + 1;

                              switch (alpha) {
                                   case 0:
                                        colors[i] = 0;
                                        break;

                                   case 255:
                                        colors[i] = PIXEL_ARGB( entries[i].a,
                                                                entries[i].r,
                                                                entries[i].g,
                                                                entries[i].b );
                                        break;

                                   default:
                                        colors[i] = PIXEL_ARGB( entries[i].a,
                                                                (alpha * entries[i].r) >> 8,
                                                                (alpha * entries[i].g) >> 8,
                                                                (alpha * entries[i].b) >> 8 );
                              }
                         }
                    }
                    else {
                         for (i=0; i<gfxs->Blut->num_entries; i++)
                              colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b );
                    }
                    break;

               case DSPF_RGB32:
                    for (i=0; i<gfxs->Blut->num_entries; i++)
                         colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b );
                    break;

               case DSPF_RGB16:
                    for (i=0; i<gfxs->Blut->num_entries; i++)
                         colors16[i] = PIXEL_RGB16( entries[i].r, entries[i].g, entries[i].b );
                    break;

               case DSPF_ARGB4444:
                    if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
                         for (i=0; i<gfxs->Blut->num_entries; i++) {
                              int alpha = entries[i].a + 1;

                              switch (alpha) {
                                   case 0:
                                        colors16[i] = 0;
                                        break;

                                   case 255:
                                        colors16[i] = PIXEL_ARGB4444( entries[i].a,
                                                                      entries[i].r,
                                                                      entries[i].g,
                                                                      entries[i].b );
                                        break;

                                   default:
                                        colors16[i] = PIXEL_ARGB4444( entries[i].a,
                                                                      (alpha * entries[i].r) >> 8,
                                                                      (alpha * entries[i].g) >> 8,
                                                                      (alpha * entries[i].b) >> 8 );
                              }
                         }
                    }
                    else {
                         for (i=0; i<gfxs->Blut->num_entries; i++)
static bool
stretch_hvx_planar( CardState *state, DFBRectangle *srect, DFBRectangle *drect, bool down )
{
     GenefxState *gfxs;
     void        *dst;
     void        *src;
     DFBRegion    clip;

     D_ASSERT( state != NULL );
     DFB_RECTANGLE_ASSERT( srect );
     DFB_RECTANGLE_ASSERT( drect );

     gfxs = state->gfxs;

     if (state->blittingflags)
          return false;

     if (gfxs->dst_format != gfxs->src_format)
          return false;

     clip = state->clip;

     if (!dfb_region_rectangle_intersect( &clip, drect ))
          return false;

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

     dst = gfxs->dst_org[0] + drect->y * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
     src = gfxs->src_org[0] + srect->y * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );

     switch (gfxs->dst_format) {
          case DSPF_NV12:
          case DSPF_NV21:
               if (down)
                    stretch_hvx_8_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                        srect->w, srect->h, drect->w, drect->h, &clip );
               else
                    stretch_hvx_8_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                      srect->w, srect->h, drect->w, drect->h, &clip );

               clip.x1 /= 2;
               clip.x2 /= 2;
               clip.y1 /= 2;
               clip.y2 /= 2;

               dst = gfxs->dst_org[1] + drect->y/2 * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
               src = gfxs->src_org[1] + srect->y/2 * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );

               if (down)
                    stretch_hvx_88_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                         srect->w/2, srect->h, drect->w/2, drect->h, &clip );
               else
                    stretch_hvx_88_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                       srect->w/2, srect->h, drect->w/2, drect->h, &clip );
               break;

          default:
               break;
     }

     return true;
}
Пример #4
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;
}
Пример #5
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;
}