Browse Source

Apply patch "More efficient SoundData allocator" that allocates memory less often, and shrinks to minimum size afterwards

Bart van Strien 13 years ago
parent
commit
eb7a758691
1 changed files with 19 additions and 2 deletions
  1. 19 2
      src/modules/sound/SoundData.cpp

+ 19 - 2
src/modules/sound/SoundData.cpp

@@ -36,16 +36,22 @@ namespace sound
 	SoundData::SoundData(Decoder * decoder)
 	SoundData::SoundData(Decoder * decoder)
 		: data(0), size(0), sampleRate(Decoder::DEFAULT_SAMPLE_RATE), bits(0), channels(0)
 		: data(0), size(0), sampleRate(Decoder::DEFAULT_SAMPLE_RATE), bits(0), channels(0)
 	{
 	{
+		size_t bufferSize = 524288;
 		int decoded = decoder->decode();
 		int decoded = decoder->decode();
 
 
 		while (decoded > 0)
 		while (decoded > 0)
 		{
 		{
 			// Expand or allocate buffer. Note that realloc may move
 			// Expand or allocate buffer. Note that realloc may move
 			// memory to other locations.
 			// memory to other locations.
-			data = (char*)realloc(data, size + decoder->getSize());
+			if (!data || bufferSize < (size_t) size + decoded)
+			{
+				while (bufferSize < (size_t) size + decoded)
+					bufferSize <<= 1;
+				data = (char*)realloc(data, bufferSize);
+			}
 
 
 			if (!data)
 			if (!data)
-				throw love::Exception("Not enough memory."); // I know, I know, little memory, creating objects..
+				throw love::Exception("Not enough memory.");
 
 
 			// Copy memory into new part of memory.
 			// Copy memory into new part of memory.
 			memcpy(data + size, decoder->getBuffer(), decoded);
 			memcpy(data + size, decoder->getBuffer(), decoded);
@@ -53,9 +59,20 @@ namespace sound
 			// Keep this up to date.
 			// Keep this up to date.
 			size += decoded;
 			size += decoded;
 
 
+			// Overflow check.
+			if (size < 0)
+			{
+				free(data);
+				throw love::Exception("Not enough memory.");
+			}
+
 			decoded = decoder->decode();
 			decoded = decoder->decode();
 		}
 		}
 
 
+		// Shrink buffer if necessary.
+		if (data && bufferSize > (size_t) size)
+			data = (char*) realloc(data, size);
+
 		channels = decoder->getChannels();
 		channels = decoder->getChannels();
 		bits = decoder->getBits();
 		bits = decoder->getBits();
 		sampleRate = decoder->getSampleRate();
 		sampleRate = decoder->getSampleRate();