mirror of
https://github.com/love2d/love.git
synced 2026-08-19 20:19:42 +02:00
Improved the performance of dds data loading (love.image.newCompressedData / love.graphics.newImage("myfile.dds"))
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user