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.n
et/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
directfb-dev directfb.org
http://mail.directfb.org/cgi-bin/mailman/listinfo/
directfb-dev
|