GP2X Drawing To The Frame Buffer


scrapheap

Still Fresh
Joined
Oct 31, 2006
Messages
28
I am working on moving to using the hardware more directly rather than through SDL, but I have encountered an oddity with using the frame buffer. It seems to be that after getting my pointer to the framebuffer by mmaping /dev/fb0 and writing to it with fb[y*320+x]=(colour in 16bbp format) I should be using y's from1 to 240, but I can't see why it shouldn't be y's from 0 to 239 as I would expect.

I will post my code later if needs be but hopefully someone else has already come across this and has an answer.
 
scrapheap said:
I am working on moving to using the hardware more directly rather than through SDL, but I have encountered an oddity with using the frame buffer. It seems to be that after getting my pointer to the framebuffer by mmaping /dev/fb0 and writing to it with fb[y*320+x]=(colour in 16bbp format) I should be using y's from1 to 240, but I can't see why it shouldn't be y's from 0 to 239 as I would expect.

I will post my code later if needs be but hopefully someone else has already come across this and has an answer.
its 0 to 239, both included
 
Last edited by a moderator:
Parkydr said:
I assume fb if short* (or other 16 bit type) not char*

I am using the following as pointers to the frame buffers
CODE

u_int16_t *fb;
u_int16_t *fbs[2];



The fbs array stores the pointers to the two frame buffers and fb points to the buffer that I should currently be working on (I am using double buffering)

and I set them using this code
CODE

devfb0 = open("/dev/fb0", O_RDWR);
devfb1 = open("/dev/fb1", O_RDWR);
fb=fbs[0] = (u_int16_t *) mmap(0, 320*240*sizeof(u_int16_t), PROT_WRITE, MAP_SHARED, devfb0, 0);
fbs[1] = (u_int16_t *) mmap(0, 320*240*sizeof(u_int16_t), PROT_WRITE, MAP_SHARED, devfb1, 0);
 
Last edited by a moderator:
I have been looking at this frame buffer problem I have and it is very odd. It looks like the pointer to the frame buffers is pointing 640 bytes (one row with 2 bytes per pixel) before the start of the frame buffer.

Has anyone encountered this before. Is there something that I am missing?

Found the problem the code on the wiki for flipping the buffers seems to be wrong. In the bellow code their is a line in the fb_flip routine that adds 640 to the frame buffers address. I remove this and sure enough the frame buffer is working as I would expect.

Unless someone can show me why it's needed I will update the wiki to remove the line. (Unless someone beats me too it.)

CODE

static volatile uint16_t *memregs16;
static volatile uint32_t *memregs32;
int32_t devmem;
int32_t devfb0;
int32_t devfb1;

void fb_flip(uint32_t fb_addr)
{
memregs16[0x290E>>1] = (uint16_t)(fb_addr & 0xffff);
memregs16[0x2910>>1] = (uint16_t)(fb_addr >> 16);
fb_addr += 640;
memregs16[0x2912>>1] = (uint16_t)(fb_addr & 0xffff);
memregs16[0x2914>>1] = (uint16_t)(fb_addr >> 16);
}

int main()
{
devmem = open("/dev/mem", O_RDWR);
devfb0 = open("/dev/fb0", O_RDWR);
devfb1 = open("/dev/fb1", O_RDWR);

fb0 = (uint16_t *) mmap(0, 320*240*sizeof(uint16_t), PROT_WRITE, MAP_SHARED, devfb0, 0);
fb1 = (uint16_t *) mmap(0, 320*240*sizeof(uint16_t), PROT_WRITE, MAP_SHARED, devfb1, 0);

fb_flip((uint32_t) 0x03101000); // flips to fb0
fb_flip((uint32_t) 0x03381000); // flips to fb1
}
 
For non-interlaced displays like the screen then the odd field address and even field address should be the same. That code would only work for an interlaced display (i.e. tv-out) and even then only for high resolutions as by default when using 320x240 on the tv-out the display is configured to show the same image for both odd and even fields.
The hardware only uses the even field address for the lcd which is why you were seeing the screen shifted up a line, but you should still set the odd field address to the same value just case the user had set tv-out before starting your application.
 
Back
Top