Greetings All!
I'm currently in the process of design an implementation of a multi-threaded texture streaming system. It's for my quasi-open-world 2D side scroller game & I have a few concerns regarding how I hope it's going to work..
Currently I'm looking at a setup like this..
The main game runs on the main thread & on initialisation, I setup a second thread to run in the background as my texture streaming thread.. My spacial sub-division system (which segments the world into finite cells, each tentatively the dimensions of 3xscreenWidth by 3xScreenHeight & with 3 cells present in memory at any one time.. ) will run at the start of my update loop (on the main thread), check the camera position, direction of movement & velocity & then adjust the current loaded cells by doing the following:
(e.g. Player is moving to the right..)
- If the camera reaches the bounding edge of middle cell/left most edge of rightmost cell do the following;
- Compile a list of all the textures to load in for the next cell (from the LevelDefinition obj)
- Grab the cell ID & setup a LoadRequestDataStructure
- Push the LoadRequestDataStructure on the end of the stream load queue
- Create & setup the new cell, & set all the entities within it to render as & when their textures are available/loaded
- Compile a list of all the textures in the left most cell (the one we've moved far away from)
- Grab the cell ID & setup a DisposeRequestDataStructure
- Push the DisposeRequestDataStructure on the end of the stream dispose queue
- Destroy the old cell
- Rinse, Repeat
- From here the texture streaming thread will do as follows;
- Check the stream load queue for a LoadRequestDataStructure (if none then skip nest three points)
- If there is one then pop it off the queue
- Create a ContentManager & run a load ThreadTask with it to load in all the textures specific to the cell ID (check the LevelDefinition)
- Once loaded, send a LoadRequestCompleted callback to tell the main thread it's done
- Check the stream dispose queue for a DisposeRequestDataStructure (if none then sleep till next run..)
- If there is one then pop it off the queue
- find the ContentManager for the cell ID & dispose of it
- once done, send a DisposeRequestCompleted callback in case the main thread cares
So this is what I have so far however i'm concerned that there are going to be some issues relating to the implementation so I need some clarification on them:
- Is it ok to create & destroy multiple content managers in this way & will it affect performance?
- Is it ok to pass information this way between threads & will it affect performance?
- Is there anything I need to be aware of when dealing with accessing Texture2Ds created by a seperate thread's content manager?
- I believe ContentManagers support load redundancy (i.e. trying to load a texture thats already in memory will just assign it & not load it into memory again..) however if each cell has a seperate content manager then will this still be the case (across seperate contentmanager loads?)
- Are there any other 'gotchas' with the design that I need to be aware of before continuing to implement everything..?
Thanks guys!
My Game Blog: http://houseofsmash.blogspot.com
My Blog: http://watchhogstories.wordpress.com