Improved the performance of dds data loading (love.image.newCompressedData / love.graphics.newImage("myfile.dds"))

This commit is contained in:
Alex Szpakowski
2013-06-14 08:43:07 -03:00
parent be33d17f89
commit 03f5bd9a5a
5 changed files with 30 additions and 4 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ void *CompressedData::getData() const
// Data for different mipmap levels is not stored contiguously in memory, so // Data for different mipmap levels is not stored contiguously in memory, so
// getData() won't work properly for CompressedData. // getData() won't work properly for CompressedData.
if (dataImages.size() > 0 && dataImages[0].size > 0) if (dataImages.size() > 0 && dataImages[0].size > 0)
return (void *) &(dataImages[0].data[0]); return (void *) dataImages[0].data;
else else
return 0; return 0;
} }
+1 -1
View File
@@ -63,7 +63,7 @@ public:
{ {
int width, height; int width, height;
size_t size; size_t size;
std::vector<unsigned char> data; char *data;
}; };
CompressedData(); CompressedData();
@@ -36,6 +36,9 @@ CompressedData::CompressedData(love::filesystem::FileData *data)
CompressedData::~CompressedData() CompressedData::~CompressedData()
{ {
// We have ownership of the heap memory in dataImages, so we have to free it.
for (size_t i = 0; i < dataImages.size(); i++)
delete[] dataImages[i].data;
} }
void CompressedData::load(love::filesystem::FileData *data) void CompressedData::load(love::filesystem::FileData *data)
@@ -53,6 +56,13 @@ void CompressedData::load(love::filesystem::FileData *data)
if (parsedimages.size() == 0) if (parsedimages.size() == 0)
throw love::Exception("Could not parse compressed data: No valid data?"); throw love::Exception("Could not parse compressed data: No valid data?");
// Make sure to clean up any previously loaded data.
for (size_t i = 0; i < dataImages.size(); i++)
{
delete[] dataImages[i].data;
dataImages[i].data = 0;
}
dataImages = parsedimages; dataImages = parsedimages;
type = textype; type = textype;
} }
+7 -1
View File
@@ -54,6 +54,11 @@ void DevilHandler::init()
void DevilHandler::quit() void DevilHandler::quit()
{ {
ilShutDown(); ilShutDown();
if (devilMutex)
{
delete devilMutex;
devilMutex = 0;
}
} }
bool DevilHandler::canDecode(love::filesystem::FileData * /*data*/) bool DevilHandler::canDecode(love::filesystem::FileData * /*data*/)
@@ -210,9 +215,10 @@ DevilHandler::EncodedImage DevilHandler::encode(const DecodedImage &img, ImageDa
} }
catch (std::exception &e) catch (std::exception &e)
{ {
// catches love and std exceptions // Catches love and std exceptions.
ilDeleteImage(tempimage); ilDeleteImage(tempimage);
delete[] encodedimage.data; delete[] encodedimage.data;
encodedimage.data = 0;
throw love::Exception("%s", e.what()); throw love::Exception("%s", e.what());
} }
+11 -1
View File
@@ -44,6 +44,7 @@ CompressedData::TextureType ddsHandler::parse(filesystem::FileData *data, std::v
try try
{ {
// Attempt to parse the dds file.
dds::Parser parser(data->getData(), data->getSize()); dds::Parser parser(data->getData(), data->getSize());
textype = convertFormat(parser.getFormat()); textype = convertFormat(parser.getFormat());
@@ -54,8 +55,10 @@ CompressedData::TextureType ddsHandler::parse(filesystem::FileData *data, std::v
if (parser.getMipmapCount() == 0) if (parser.getMipmapCount() == 0)
throw love::Exception("Could not parse compressed data: No readable texture data."); throw love::Exception("Could not parse compressed data: No readable texture data.");
// Copy the parsed mipmap levels from the FileData to our CompressedData.
for (size_t i = 0; i < parser.getMipmapCount(); i++) for (size_t i = 0; i < parser.getMipmapCount(); i++)
{ {
// Fetch the data for this mipmap level.
const dds::Image *img = parser.getImageData(i); const dds::Image *img = parser.getImageData(i);
CompressedData::SubImage mip; CompressedData::SubImage mip;
@@ -63,13 +66,20 @@ CompressedData::TextureType ddsHandler::parse(filesystem::FileData *data, std::v
mip.width = img->width; mip.width = img->width;
mip.height = img->height; mip.height = img->height;
mip.size = img->dataSize; mip.size = img->dataSize;
mip.data.insert(mip.data.begin(), &img->data[0], &img->data[mip.size]);
// Copy the mipmap image from the FileData.
mip.data = new char[mip.size];
memcpy(mip.data, img->data, mip.size);
images.push_back(mip); images.push_back(mip);
} }
} }
catch (std::exception &e) catch (std::exception &e)
{ {
// Clean up any newly allocated heap memory before throwing.
for (size_t i = 0; i < images.size(); i++)
delete[] images[i].data;
throw love::Exception(e.what()); throw love::Exception(e.what());
} }