C api: getBitmapMask do we need to free the returned bitmap ?+ clarifications needed

Hi,

The documention does not metion that we need to free the bitmap returned by getBitmapMask. Initially i was not doing this i had gotten a 32 byte leak with each call to getBitmapMask, and it seems to go away if i free the bitmap returned by getBitmapMask. But whats even more weird is that we can directly do things with the returned bitmap and it will immediatly update the mask so we don't have to call setbitmapmask again to readd it. But if that is the case why do we have to free the returned bitmap to prevent the leak ?

for example i have this code now that works and does not produce the leak anymore since i added the freebitmap call, but it looks very weird as you free the bitmap you just modified yet the mask was still updated ?

void bitmap_set_alpha_rect(LCDBitmap *Bitmap, int rx, int ry, int rw, int rh, float alpha)
{
	if (!Bitmap)
		return;

	LCDPattern pattern;
	pattern_set_black(&pattern);
	pattern_set_alpha(&pattern, 1.0f - alpha);
	
	LCDBitmap* mask = pd->graphics->getBitmapMask(Bitmap);
	pd->graphics->pushContext(mask);
	pd->graphics->fillRect(rx,ry,rw,rh, (LCDColor)pattern);
	pd->graphics->popContext();
	//docs does not metion it but seems we need to free the mask returned ?
	//otherwise get 32 bytes of leaks per call to getbitmapmask
	pd->graphics->freeBitmap(mask);
}

So at the very least i like to know if we have to call freebitmap on the returned bitmap by getBitmapMask and that the documention is just lacking this info.

I also like to know if my code above is correct as it looks very weird to free the bitmap that you just edited and that the mask gets updated without having to call setbitmapmask again ? But it seems to fix the memory leak i was getting

basically looking for some clarifications

2 Likes

Sorry for the lag! Finally have some time to try and catch up with the dev forum..

What's happening is the LCDBitmap returned from getBitmapMask() has a flag set that tells us the data for the image is located somewhere else; in this case it points to the mask part of the referred bitmap, which is why drawing into the bitmap affects the target immediately--they both point to the same data.

Here's what I added to the docs:

LCDBitmap* playdate->graphics->getBitmapMask(LCDBitmap* bitmap);

Gets a mask image for the given bitmap, or returns NULL if the bitmap doesn't have a mask layer. The returned image points to bitmap's data, so drawing into the mask image affects the source bitmap directly. The caller takes ownership of the returned LCDBitmap and is responsible for freeing it when it's no longer in use.

Good enough, or do you have any suggestions for improvement?

1 Like

That is good enough i think, thanks.