Community
3ds Max Programming
Welcome to Autodesk’s 3ds Max Forums. Share your knowledge, ask questions, and explore popular 3ds Max SDK, Maxscript and Python topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Loading bitmaps in a thread-safe manner

2 REPLIES 2
Reply
Message 1 of 3
chrisdawlud
404 Views, 2 Replies

Loading bitmaps in a thread-safe manner

chrisdawlud
Enthusiast
Enthusiast

I have a function which I use for generating thumbnails for the UI, but when I call it from multiple threads I get memory access errors in TheManager->Load() . I tried locking it with both Win32 critical sections and Qmutex, but with no success. I guess TheManager->Load() itself is not thread-safe. Is there another way? 

Bitmap* Loader::loadHDR(const QString & path) {
	Bitmap* bmap;
	BitmapInfo bi;

	QFile file(path);
	if (file.exists() && file.fileName().endsWith(".exr") || file.fileName().endsWith(".hdr"))
	{
		bi.SetName(TSTR(path));
		bmap = TheManager->Load(&bi);
		if (!bmap)
		{
			return nullptr;
		}
		return bmap;
	}
	return nullptr;
}

QIcon Loader::getIcon(const QString & path, QSize size)
{
	Bitmap* bmap = loadHDR(path);
	if (bmap) {
		BitmapInfo bi_icon;
		bi_icon.SetWidth(size.width());
		bi_icon.SetHeight(size.height());
		bi_icon.SetType(BMM_TRUE_32);
 
		Bitmap* icon = TheManager->Create(&bi_icon);
 
		icon->CopyImage(bmap, COPY_IMAGE_RESIZE_LO_QUALITY,
			BMM_Color_64(0000));
 
		int type;
		uchar* buffer = static_cast<uchar*>(icon->GetStoragePtr(&type));
		QImage image(buffer, icon->Width(),
			icon->Height(), QImage::Format::Format_RGB888);
 
		if (bmap) bmap->DeleteThis();
		return QIcon(QPixmap::fromImage(image));
	}
	return QIcon();
}

 

 

0 Likes

Loading bitmaps in a thread-safe manner

I have a function which I use for generating thumbnails for the UI, but when I call it from multiple threads I get memory access errors in TheManager->Load() . I tried locking it with both Win32 critical sections and Qmutex, but with no success. I guess TheManager->Load() itself is not thread-safe. Is there another way? 

Bitmap* Loader::loadHDR(const QString & path) {
	Bitmap* bmap;
	BitmapInfo bi;

	QFile file(path);
	if (file.exists() && file.fileName().endsWith(".exr") || file.fileName().endsWith(".hdr"))
	{
		bi.SetName(TSTR(path));
		bmap = TheManager->Load(&bi);
		if (!bmap)
		{
			return nullptr;
		}
		return bmap;
	}
	return nullptr;
}

QIcon Loader::getIcon(const QString & path, QSize size)
{
	Bitmap* bmap = loadHDR(path);
	if (bmap) {
		BitmapInfo bi_icon;
		bi_icon.SetWidth(size.width());
		bi_icon.SetHeight(size.height());
		bi_icon.SetType(BMM_TRUE_32);
 
		Bitmap* icon = TheManager->Create(&bi_icon);
 
		icon->CopyImage(bmap, COPY_IMAGE_RESIZE_LO_QUALITY,
			BMM_Color_64(0000));
 
		int type;
		uchar* buffer = static_cast<uchar*>(icon->GetStoragePtr(&type));
		QImage image(buffer, icon->Width(),
			icon->Height(), QImage::Format::Format_RGB888);
 
		if (bmap) bmap->DeleteThis();
		return QIcon(QPixmap::fromImage(image));
	}
	return QIcon();
}

 

 

2 REPLIES 2
Message 2 of 3
drew.avis
in reply to: chrisdawlud

drew.avis
Autodesk
Autodesk

I'm guessing, but...

The docs say:

Note: When several plug-ins call this method to load the same image, they all receive the same pointer to one instance of the BitmapStorage. So if one plug-in manipulates the image, the changes will get reflected everywhere. A developer may use BitmapManager::Create() followed by Bitmap::CopyImage() to create a unique instance of BitmapStorage.

Does that help?

 

Drew



Drew Avis
Content Experience Designer
0 Likes

I'm guessing, but...

The docs say:

Note: When several plug-ins call this method to load the same image, they all receive the same pointer to one instance of the BitmapStorage. So if one plug-in manipulates the image, the changes will get reflected everywhere. A developer may use BitmapManager::Create() followed by Bitmap::CopyImage() to create a unique instance of BitmapStorage.

Does that help?

 

Drew



Drew Avis
Content Experience Designer
Message 3 of 3
chrisdawlud
in reply to: chrisdawlud

chrisdawlud
Enthusiast
Enthusiast

The reason I was getting errors in TheManager->Load() was that the code didn't handle task cancellation. It's all working fine now.

0 Likes

The reason I was getting errors in TheManager->Load() was that the code didn't handle task cancellation. It's all working fine now.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report