views:

794

answers:

2

I've been fighting with my rendering (http://stackoverflow.com/questions/297697/outofmemoryexception-when-creating-a-large-bitmap-in-cf-net) for a while, and I'm still looking for a good way to fix my issues.

My engine creates a single large bitmap (2x or 3x bigger than the size of the screen), and draws everything to that surface. I then draw that image onto the screen at an offset, allowing the user to scroll VERY smoothly.

This works great most of the time, but some users encounter OutOfMemoryExecptions when creating that large bitmap. I've done my homework and it appears that this is because I am creating a Device Dependant Bitmap (DDB), and on Windows Mobile all DDBs are assigned to the gwes.exe process, along with every other apps bitmaps. If that gwes.exe process takes up more than 32M, you get this exception.

I do see that Device Independent Bitmaps(DIB) are actually created in your own process space, rather than be assigned to gwes.exe. Since I have way more room before reaching 32M in my process, I thought I'd explore this possibility.

But the only way I can find to create a DIB is through creating a bitmap from a stream, like an existing file. I can't figure out any way to create one from scratch and specify that I want it to be 1280x240 with 256 colors.

Does anyone know how this can be done?

A: 

This article might help you alot from Crhis Tacke, especially this part:

  1. Creating a bitmap using the stream constructor will construct a DIB (Device Independent Bitmap).
  2. Creating a bitmap using the width/height constructor will construct a DDB (Device Dependent Bitmap).
  3. DIB's are allocated out of the virtual address space of the application.
  4. DDB's are allocated by the driver. This typically means that they are allocated in the virtual address space of gwes.exe. Alternatively, the driver could allocate these in dedicated video ram.
  5. Creating a bitmap with the stream constructor will generate a fair amount of garbage as it copies data from one buffer to the other.

Edit: The nerdkill application might even help more :)

Stormenet
That article is what basically brought about this whole question. I understand why it's creating DDBs. And creating a bitmap from a stream only seems to work if that stream contains an existing file.
Jake Stevenson
+1  A: 

I had to do something similar to this a while back when I was creating custom reports printed from a Pocket PC to a bluetootch printer. I had to generate bitmaps the size of a piece of paper, then stream that to the printer, and all attempts to do that with a managed object kept hitting memory issues like you're seeing.

What I did (sorry I can't give you the direct source on this one):

You now have an HDC, and from that you can call Graphics.FromHdc.

This way you have all of it in your own process (and in fact if you make it big enough, it will come from shared memory and avoid the 32MB process space altogether).

ctacke
This is exactly what I have been looking for, thank you! Can you tell me more about how it would avoid using the 32MB process space?
Jake Stevenson