|
Features

Streaming For Next Generation Games
Stream Queue Items
When a game system needs to load a resource through the stream
system, it creates a stream item and passes it to the streamer.
The stream item has the id of the file (the name or hash, depending
on if we run in debug or release), the offset we need to read in
the file, and the size of the read. It also contains a pointer
to an object implementing a callback interface that will be called
when the data is available or if something goes wrong.
struct StreamQueueItem
{
std::string filename;
unsigned int file_offset;
unsigned int size;
IStreamQueueItemCallback *callback;
};
The stream items are kept in one of several queues in the stream
system. The streamer pops as many disc-stored items in the current
queue as possible and fits them into
the
buffer. Data is then read by doing one read request from the
reader thread. The buffer will eventually be filled by data when
the threaded read operation completes, and during this time the
buffer is marked as locked. When the read operation completes,
the buffer
is unlocked and the reader thread switches to repeat the process
on the other buffer.
After the switch, a callback to the game
system is generated for each stream queue item with a pointer
to the newly loaded data, a pointer into one of the static
buffers, and the size of the read data. While the callbacks are
being
issued, the buffer is marked as locked to prevent the read
thread to overwrite the data before the game has had a chance to
process
it. When code called from one of the callback functions needs
to access the data after the callback it has to lock the buffer.
It is then up to the game system to unlock the buffer - until
this happens, streaming will stall.
When running from a DVD, data processing is typically much faster
than data read. As always, do profiling and tuning on the actual
system you are designing for.
Priorities
Stream items are added to the streamer at one of several priority
queues. The queues are processed in priority order, but we only
change the current queue when reading the next item would cause
a seek. In practice, you probably do not need more than three priority
queues.
When the streaming system is under stress, changes in the game's
state might cause the data to be obsolete before its read. Imagine
an NPC that wants to play back dialogue, but before the dialogue
has finished loading, the NPC gets killed. If the dialogue is still
scheduled
as a stream item we can simply remove the item from its queue.
If we have started reading, the best is to let it load but ignore
the callback.
Music Streaming
Streaming music is really nothing different from other types of
data. When music streaming is implemented by middleware, we must
take care to synchronize the different streaming systems and make
sure the stream buffers for music are set up as large enough. If
music is allowed to interrupt, our streaming system performance
will suffer.
One solution is to allow music streaming to take place when we
are finished with our data, by adding a function to pause our streamer
when we load music. Create a budget and decide how many data blocks
we should be able to read after each music block. This kind of
budget is easy to verify and serves as a guideline when you create
the dimensions of the streaming buffers needed for music.
Compressed Data
Our streaming system is easily extended to support on the fly
decompression of data by adding a third static buffer - a decompression
buffer. As data is read into the static buffer, instead of passing
it directly to the game system in a callback, it is decompressed
into the decompression buffer one stream queue item a time. When
the data is decompressed, we issue the callback and pass the game
a pointer to the decompression buffer instead. We need to ensure
an extra lock to handle decompression, and none of the stream queue
items can be a larger size decompressed than the decompression
buffer itself.

Just Cause
Conclusion
Using all of these methods in Just Cause, our hero Rico
can do everything from walking around to flying jets through
32x32 km
game environments.
Everything is streamed directly from DVD on both current generation
(PS2/XBOX) and next generation platforms (X360).
|