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