Hi,

I would like to extend directfb to support Portrait Mode (rotated TFT screen).

I found some earlier posts, but seems it stalled.

Anyway, attached is a tiny extension (not very complete and untested, just to 
give you an idea what I'm up to) to the nvidia driver to support rotating an 
image (for now by 270 degrees).

I also had a look at src/core/layer_region.c:dfb_layer_region_flip_update, but 
I don't have enough knowledge yet to "connect it all together" from here.

If DirectFB always uses a back buffer, the obvious and least-impact way would 
be to have the back buffer(s) be for example 768x1024 and rotate-update the 
front buffer to 1024x768.

However, most Flippers seem to just set some offset register on the graphics 
adapter, so that isn't really possible.

My earlier tries included swapping every x and y in nvidia_2d.c, which worked 
kind of, but I guess DirectFB mostly works over the frame buffer and so not all 
things were actually rotated.

What do you think?

cheers,
   Danny

-- 
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! 
Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
? Q
? nvidia-add-rotated-blit.patch
Index: nvidia_2d.c
===================================================================
RCS file: /cvs/directfb/DirectFB/gfxdrivers/nvidia/nvidia_2d.c,v
retrieving revision 1.19
diff -u -p -u -p -r1.19 nvidia_2d.c
--- nvidia_2d.c 28 Jan 2006 11:36:56 -0000      1.19
+++ nvidia_2d.c 14 Oct 2006 10:30:11 -0000
@@ -326,6 +326,119 @@ bool nvBlitFromCPU( void *drv, void *dev
      return true;
 }
 
+static void vertical_memcpy( void* destination, void* source, int count, int 
pixel_size, int src_pitch)
+{
+     D_ASSUME( pixel_size == 2 || pixel_size == 4);
+
+     if (pixel_size == 2) {
+          src_pitch = src_pitch >> 1;
+          __u16* destination_16 = (__u16*) destination;
+          __u16* source_16 = (__u16*) source;
+
+          for (; count--; ) {
+               *(destination_16++) = *source_16;
+               source_16 += src_pitch;
+          }
+     } else {
+          src_pitch = src_pitch >> 2;
+          __u32* destination_32 = (__u32*) destination;
+          __u32* source_32 = (__u32*) source;
+
+          for (; count--; ) {
+               *(destination_32++) = *source_32;
+               source_32 += src_pitch;
+          }
+     }
+}
+
+bool nvRotatedBlitFromCPU( void *drv, void *dev, DFBRectangle *rect, int dx, 
int dy, int rotation_degrees )
+{
+     if (rotation_degrees == 0) {
+          return nvBlitFromCPU( drv, dev, rect, dx, dy);
+     }
+     
+     NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+     NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+     __u8             *src   = nvdev->src_address;
+     __u32             src_w;
+     __u32             src_h;
+     int               w, h, n;
+     char              real_buffer[256 * 4];
+     char*             buffer;
+     
+     
+     if (!nv_clip_source( rect, nvdev->src_width, nvdev->src_height ))
+          return true;
+
+     int bytes_per_pixel;
+     bytes_per_pixel = DFB_BYTES_PER_PIXEL(nvdev->src_format);
+
+     buffer = real_buffer;
+
+     src_w = (DFB_BYTES_PER_PIXEL(nvdev->src_format) == 2)
+             ? ((rect->w + 1) & ~1) : rect->w;
+     src_h = rect->h;
+
+     nv_begin( SUBC_IMAGEBLT, IBLIT_COLOR_FORMAT, 1 );
+     nv_outr( nvdev->system_format );
+     
+     nv_begin( SUBC_IMAGEBLT, IBLIT_POINT, 3 );
+     nv_outr( (dy      << 16) | (dx      & 0xFFFF) );
+     nv_outr( (rect->h << 16) | (rect->w & 0xFFFF) );
+     nv_outr( (src_h   << 16) | (src_w   & 0xFFFF) );
+
+     n = nvdev->use_dma ? 256 : 128;
+     
+     src += rect->y * nvdev->src_pitch + (rect->x + rect->w) * bytes_per_pixel;
+
+     switch (nvdev->src_format) {
+          case DSPF_ARGB1555:
+          case DSPF_RGB16:
+               for (w = rect->w; w--;) {
+                    src -= bytes_per_pixel;
+
+                    __u8 *s2 = src;
+
+                    for (h = rect->h; h >= n * 2; h -= n * 2) {
+                         vertical_memcpy( (void*) buffer, s2, n, 4, 
nvdev->src_pitch);
+
+                         nv_begin( SUBC_IMAGEBLT, IBLIT_PIXEL0, n );
+                         direct_memcpy( (void*)nvdev->cmd_ptr, buffer, n * 4 );
+                         s2 += n * 4;
+                    }
+                    if (h > 0) {
+                         vertical_memcpy( (void*) buffer, s2, h, 4, 
nvdev->src_pitch);
+                         nv_begin( SUBC_IMAGEBLT, IBLIT_PIXEL0, (h + 1)>>1 );
+                         nv_copy16( nvdev->cmd_ptr, buffer, h );
+                    }
+               }
+               break;
+               
+          default:
+               for (w = rect->w; w--;) {
+                    src -= bytes_per_pixel;
+
+                    __u8 *s2 = src;
+
+                    vertical_memcpy( (void*) buffer, s2, n, bytes_per_pixel, 
nvdev->src_pitch);
+                    
+                    for (h = rect->h; h >= n; h -= n) {
+                         vertical_memcpy( (void*) buffer, s2, n, 4, 
nvdev->src_pitch);
+                         nv_begin( SUBC_IMAGEBLT, IBLIT_PIXEL0, n );
+                         direct_memcpy( (void*)nvdev->cmd_ptr, buffer, h * 4 );
+                         s2 += h * 4;
+                    }
+                    if (h > 0) {
+                         vertical_memcpy( (void*) buffer, s2, h, 4, 
nvdev->src_pitch);
+                         nv_begin( SUBC_IMAGEBLT, IBLIT_PIXEL0, h );
+                         nv_copy32( nvdev->cmd_ptr, buffer, h );
+                    }
+                    
+               }
+               break;
+     }
+}
+
 bool nvStretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr )
 {
      NVidiaDriverData *nvdrv      = (NVidiaDriverData*) drv;
Index: nvidia_2d.h
===================================================================
RCS file: /cvs/directfb/DirectFB/gfxdrivers/nvidia/nvidia_2d.h,v
retrieving revision 1.5
diff -u -p -u -p -r1.5 nvidia_2d.h
--- nvidia_2d.h 28 Jan 2006 11:36:56 -0000      1.5
+++ nvidia_2d.h 14 Oct 2006 10:30:11 -0000
@@ -41,6 +41,8 @@ bool nvBlit( void *drv, void *dev, DFBRe
 
 bool nvBlitFromCPU( void *drv, void *dev, DFBRectangle *rect, int dx, int dy );
 
+bool nvRotatedBlitFromCPU( void *drv, void *dev, DFBRectangle *rect, int dx, 
int dy, int rotation_degrees );
+
 bool nvStretchBlit( void *drv, void *dev, DFBRectangle *sr, DFBRectangle *dr );
 
 bool nvStretchBlitFromCPU( void *drv, void *dev, DFBRectangle *sr, 
DFBRectangle *dr );
Index: nvidia_primary.c
===================================================================
RCS file: /cvs/directfb/DirectFB/gfxdrivers/nvidia/nvidia_primary.c,v
retrieving revision 1.14
diff -u -p -u -p -r1.14 nvidia_primary.c
--- nvidia_primary.c    28 Jan 2006 11:36:56 -0000      1.14
+++ nvidia_primary.c    14 Oct 2006 10:30:11 -0000
@@ -156,6 +156,8 @@ void        *OldPrimaryScreenDriverData;
 
 /*************************** Primary Layer hooks 
******************************/
 
+/* TODO dannym rotate if needed */
+
 static DFBResult
 fb0FlipRegion( CoreLayer           *layer,
                void                *driver_data,
_______________________________________________
directfb-dev mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to