Page 1 of 2

Frame Buffer, DMA Question

PostPosted: Oct 29, 2003 @ 11:29am
by j.edwards
Hi everyone,

I am planning on building a game for pocket pc, and have seen GAPI, PocketFrog, and a few other libraries. However, I am trying to understand how these libraries work. I have built a test app that can access the frame buffer (I think) at address 0x8451a000 on my iPaq. I got that address from the Microsoft GAPI dll.

What I want to understand though is where did that address come from - it seems that it can be anything depending on the device.

I have done heaps of searching around newsgroups and web pages and I have found a spot in the registry on my iPaq where I can get bpp and screen size but I'm not sure how portable that is. It also referenced ddi.dll which almost looked like the solution except I looked through all of the help on the MS site and none of the functions seem to return the address.

Using that address I do a VirtualAlloc, VirtualCopy to get a pointer to it and can write directly to what I think is the frame buffer. I have noticed discussions on this website about writing through DMA and there seems to be "direct access", and "backbuffer access" and I don't know how these fit together.

My little test app can draw a tile based map (tiles 32x32 pixels) and scroll around it at between 160fps and 200fps. This is by using memcpy, and having an offscreen bitmap the same size and bpp as the screen and drawing each tile to it, and then copying that whole bitmap to the frame buffer. I tried doing it pixel by pixel and it was heaps slower - about 50fps at best. I had a quick read of the ARM assembler commands and looked at the code produced by EC++4 and it seemed very inefficient from my limited knowledge, but I really don't want to go down to that level.

If anyone could shed some light on these topics it would be much appreciated.

Example source code to return some fo the values

PostPosted: Oct 29, 2003 @ 11:16pm
by j.edwards

565 555 bit format

PostPosted: Oct 30, 2003 @ 12:46am
by j.edwards
I just found this:



It seems to be able to get the number of bits per pixel for each color (ulDACRed etc). However, it's not supported on CE according to the MS documentation.

Here is the same structure for "normal" windows:



Any ideas anyone?

I think I'm getting somewhere!

PostPosted: Oct 30, 2003 @ 2:57am
by j.edwards

PostPosted: Oct 30, 2003 @ 8:27am
by j.edwards

PostPosted: Oct 30, 2003 @ 9:33am
by Sam Nova
Just wanted to comment about the port's.. That is for PC's when you are doing normal VGA graphics. So no use on PocketPC.

-Sam

PostPosted: Oct 30, 2003 @ 10:43am
by Johan
j.edwards: GapiDraw uses the frame buffer address as returned by GAPI (gx.dll). As proven by Thierry (PocketFrog author) performance can be improved by bypassing GAPI and accessing the display buffer directly, using ARM-specific optimizations.

I do not know how this is done, and neither do most people here on the forum. Thierry has previously stated that he cannot pass on any details on his implementation, so asking him will probably not help as well.

If you find out any details however, please do feel free to post them here...

Thanks...

PostPosted: Oct 30, 2003 @ 11:07am
by j.edwards

PostPosted: Oct 30, 2003 @ 11:22am
by j.edwards

PostPosted: Oct 30, 2003 @ 11:47am
by j.edwards

PostPosted: Oct 30, 2003 @ 2:35pm
by mlepage

PostPosted: Oct 30, 2003 @ 6:42pm
by Johan

PostPosted: Oct 30, 2003 @ 6:48pm
by Johan

PostPosted: Oct 31, 2003 @ 12:08am
by j.edwards
Johan, to clarify:

If I have an offscreen bitmap the same dimensions as the display (and same bpp) then it takes 3ms to copy to the screen buffer using VirtualCopy, VirtualAlloc. However, I also tested with a tile based map. The map was 24x24 tiles, with each tile being 32x32 pixels. This map was then scrolled around randomly - ie. scroll to an edge then reverse direction etc. So to draw approx 75 tiles (with clipping as scrolling was by single pixel) into the offscreen bitmap, and then copy the bitmap to the screen it was taking between 4 and 5 ms. This seems to indicate that copy data to the frame buffer is considerable slower than working in "normal" ram. So the lesson I got from this is that everything should be built in a memory bitmap the same dimensions as the screen and then one simple memcpy to blit the whole lot. Also, my code for copying the tiles used memcpy per line as you mentioned.

I don't think there would be any difference from using the address gapi returns compared to VirtualAlloc/Copy. Wouldn't be surprised if gapi does the same thing.

From my understanding I think any address at 0x80000000 is always cached (or buffered, but not sure of the difference), whereas the range 0xa0000000 is not supposed to be, but not sure if that applies to pocket pcs, as I haven't got it working on that range. The more I am finding out the more I realise how little I know about these things. Are there any electonic engineers out there who can help? :cry:

Datasheet on the MQ1178:


- 2 window buffers
- 256kb sram
- usb (not sure why it would have it)
- absolute minimum time to transfer 240x320x2 bytes of data through it's bus is 0.3ms - there's a goal to work towards :D
- the interesting thing is it supports hardware accelarated rectangular source-copy block transfers, raster operations, line draw, pattern and area fill, clipping, and transparency

I haven't looked up any others yet, but I bet that is how Thierry is getting better than "normal" speeds - probably taking advantage of the hardware acceleration.

Can anyone explain the whole frame buffer, display memory, virtual mapping, etc etc architecture? as I'm really starting to get confused now. If I could understand what all of the terms referred to exactly it would probably really accelerate my learning of all of this stuff.

PostPosted: Oct 31, 2003 @ 5:00am
by efortier
Hi!

I'm really not an expert, but here is a few things that I understand and that may help someone.

A frame buffer is an area of memory, preferably held in video memory, that holds the content of the screen. This is usually what is displayed on the device screen when you look at it.

Video memory is independant memory used to hold one (or more) frame buffer. If more than one frame buffer can exists in video memory (or system memory) they are called back buffers. Using a back buffer in addition to the main (primary) frame buffer allows for double buffering.

Virtual mapping is a way to assign a range of memory address to a specific resource. For example, in Win32 you can open a file using CreateFile() and then have the content of the file mapped to a memory range that you can access by pointers instead of reading from the file directly. I assume the same principle apply to other things.

BTW, if the "absolute minimun time to transfer 240x320x2" is 0.3 ms, since the screen is 16 bits you would have to multiply that time by 8, so the absolute minimal time to copy a screen would be 2.4 ms. Isn't this correct?

BTW #2, Thierry Tremblay is more of a french Canadian name than italian ;) . Since we've been known as "frogs" to some other countries, this may well be the origin of Thierry's name for PocketFrog (just a wild guess).

--Eric