Original Post
I have a problem that has taken a good 2-3 hours of my time; I was hoping someone would be able to help me out. I wrote a simple, yet nice-looking, slideshow program using OpenGL, similar in appearance to the one that comes with Windows Media Center. It is presented with a list of images to display, and it displays them in order. The images are slowly moved and zoomed in/out while being displayed, and fade slowly into the next image (also moving). Now, since there could be a lot of (relatively big) images, I didn't want to load them all at the beginning. Loading them in the same thread as the game loop resulted in some really bad jerkiness in the smooth movement. So I load the next image in a separate background thread with slightly lower priority. Now, since OpenGL isn't thread-safe (or so I've heard), the image gets loaded into a separate buffer. When the thread is complete, the main thread copies the data into the OpenGL texture using glTexSubImage2D. (I even spread this copying over 50 frames to make sure I didn't miss any frames!) Now here's the problem: For some images, the image loading thread would crash. After several hours of debugging, I narrowed the problem down to an issue with memory. It seemed like I couldn't access some parts of the data array I'd allocated. The image library is something that I've been using in my game engines for months, so I don't think that it should have a problem. I guessed that the problem was in reallocation, so I made it so that the memory for the image wasn't deallocated and reallocated when the image size changed. I just allocated a large amount of memory, equal to the maximum allowed size, and set a flag (data_norealloc), to override delete and new operations. Here's the final reallocation code:
void Image::setsize(int width, int height) {
if (w==width && h==height && data) return;
if (width<0) width=0; if (height<0) height=0;
if (data && !data_norealloc) delete [] data;
if (width==0 || height==0) {
w=h=0;
data=0;
return;
}
w=width; h=height;
if (!data_norealloc)
data = new Pixel[w*h];
}
void Image::set_constant_allocation(int width, int height) {
setsize(width, height);
data_norealloc=true;
}
Anyway, that seemed to fix the problem. But my question is, WHY does that fix the problem? I haven't done much work with multithreaded applications, could it be that memory allocated by one thread cannot be deleted from another thread? I just want to know if I really fixed the problem, or if it will come back to haunt me..