Here is some code extracted straight from my actual program that I'm working on, containing the elements needed to reproduce the situation I described.
The basic idea is this: I have a custom `Bitmap` type which I am using to process my version of pixmap's in main memory, for use with my own blitting routines and such. The program should load a regular PNG image which must be 256x200 pixels in RGBA format, into the Bitmap object. To do this the PNG is loaded into a Pixmap and then the Bitmap object `cludges` onto the pixmap memory with a static bank, and stores the pixmap handle in one of the type's Fields for safekeeping. Then, more or less the same file, only in a RAW RGBA data version, also 256x200, is loaded into the same Bitmap object, the pixmap reference is made Null, and a Flushmem is performed. What SHOULD happen, you'd think, is that the other handle on that pixmap - the Local variable TestPX:TPixmap, should still point to the pixmap and it should still be drawable with DrawPixmap(). However, it isn't. When TestPX is a Local, the pixmap is not drawn at all. When TestPX is changed to a Global, the pixmap is drawn.
So what is going on here, if it's not a memory management bug/issue/feature? I'd like to know if this is a bug, or if its working how it's meant to but I'm just not understanding it right.
Strict
Type Bitmap
'Object to define the dimensions and properties of a `bitmap` containing 4-byte-per-pixel (RGBA) data
Field DataBankPtr:Byte Ptr 'Byte-Pointer to the actual memory reserved in the bank
Field DataBankIntPtr:Int Ptr 'Int-Pointer to the memory in the bank
Field DataBankLongPtr:Long Ptr 'Long-Pointer to the memory in the bank
Field DataBank:TBank 'Pointer to a TBank object to store data
Field Width:Int 'Total width of the bitmap in terms of pixels or units of representation
Field Height:Int 'Total height of the bitmap in terms of pixels or units of representation
Field RowBytes:Int 'How many total bytes of data are allocated in each row of pixels or units (Width*4)
Field TotalBytes:Int 'How many bytes in total does the bitmap data take up
Field FromPixmap:TPixmap 'Pointer to a Pixmap object which may have been used for loading data from an image, used as a static bank
Field MaskValue:Int 'RGBA color or 4-byte value, where all pixels in the Bitmap of that color/value are transparent/non-copied when copying in Mode 2 (ValueMask mode)
Method New()
'Executed when a new instance of `Bitmap` is created
DataBankPtr=Null
DataBankIntPtr=Null
DataBankLongPtr=Null
DataBank=Null
Width=0
Height=0
RowBytes=0
TotalBytes=0
FromPixmap=Null
MaskValue=0
End Method
Method Initialize(MWidth:Int,MHeight:Int)
'To create and populate this `Bitmap` instance with memory space and valid variables
Width=MWidth
Height=MHeight
RowBytes=MWidth Shl 2 '4 Bytes per pixel
TotalBytes=MWidth*MHeight Shl 2 '4 Bytes per pixel
DataBank=CreateBank(TotalBytes)
DataBankPtr=BankBuf(DataBank)
DataBankIntPtr=Int Ptr(DataBankPtr)
DataBankLongPtr=Long Ptr(DataBankPtr)
FromPixmap=Null
MaskValue=0 'Default black or $0000
FlushMem
End Method
Method LoadRAWData(MFilePath:String)
'To load RAW data from a file into the memory bank
'You should call Initialize() first
If DataBank=Null
Print "Bitmap was not initilized prior to trying to load RAW file "+MFilePath+" into Bitmap!"
End '!!!!
EndIf
Local MStream:TStream
MStream=ReadStream(MFilePath) 'For reading only, pre-exists
If MStream
MStream=BigEndianStream(MStream) 'To read data in order, left to right
MStream.Read(DataBankPtr,TotalBytes)
CloseStream(MStream)
Else
Print "Couldn't load RAW file "+MFilePath+" into Bitmap!"
End '!!!!
EndIf
FromPixmap=Null
FlushMem
End Method
Method LoadImageData(MFilePath:String)
'To load an image-format file (png/jpg etc) and convert it into the `Bitmap`s memory bank to represent 4-byte-per-pixel values
Local TempPixmap:TPixmap=New TPixmap
TempPixmap=LoadPixmap(MFilePath)
If TempPixmap=Null
Print "There was a problem loading the file "+MFilePath+" as an image into a Bitmap object. File not found or error with file or wrong file type!"
End '!!!!
EndIf
If PixmapFormat(TempPixmap)<>PF_RGBA8888 Then TempPixmap=ConvertPixmap(TempPixmap,PF_RGBA8888)
DataBankPtr=PixmapPixelPtr(TempPixmap,0,0)
DataBankIntPtr=Int Ptr(DataBankPtr)
DataBankLongPtr=Long Ptr(DataBankPtr)
Width=PixmapWidth(TempPixmap)
Height=PixmapHeight(TempPixmap)
RowBytes=PixmapPitch(TempPixmap)
If RowBytes Mod 4>0 'Mod 4 due to PF_RGBA8888 which is 4 bytes per pixel
Print "Image being loaded as Color "+MFilePath+" has width that is not multiple of 4 bytes (ie has skip pixels per row) even after ConvertPixmap!"
End '!!!!!
EndIf
TotalBytes=(Width*Height) Shl 2 '4 Bytes per pixel
DataBank=CreateStaticBank(DataBankPtr,TotalBytes) 'Bank's memory pointer = pixmap's memory pointer
FromPixmap=TempPixmap 'Store
FlushMem
End Method
End Type
Graphics 640,480,0
Cls
Flip
Cls
Flip
Local Test:Bitmap=New Bitmap
Cls
Test.Initialize(256,200)
Test.LoadImageData("TestImages/Green256x200.png")
Local TestPX:TPixmap=Test.FromPixmap 'Must be Global otherwise when the only other Global FromPixmap is freed, the pixmap is lost
DrawPixmap TestPX,320,16
Test.LoadRAWData("TestImages/SavedRAWData-Green256x200.raw")
DrawPixmap TestPX,320,16
Flip;WaitKey
End