It'd be beneficial if the Image Docs were updated with the addendum:
Ensure you call fwt::Desktop#disposeImage() to dispose of allocated System resources.
Simply leaving Images to go out of scope will result in memory leaks.
I guess the same should be written about Font and Color also.
Double buffering in my app was eating up about 1 Gb per minute! Eeek!
This also leads me to ask about the tight coupling between gfx::Image and fwt::Desktop... is not possible to have Image and Desktop in the same pod? Or maybe a means to dispose of the Image in the gfx pod?
AkcelistoMon 27 Feb 2012
?!?! Yes, it's trap. I think that gfx::Image is like BufferedImage and stores in heap. And disposes by gc.
as I say, I use it for double buffering so the screen updates don't flicker.
Steve.
brianMon 27 Feb 2012
The way this stuff is designed is that gfx is designed to be independently used from fwt. Which makes sense if you consider we often wish to model concepts such as color, fonts, and images independent from a specific toolkit (for example if we wanted to create a css API).
Then the FWT maps those instances like Color, Font, and Image into SWT/OS resources as needed when you use them in a context such as FWT rendering. Only after they get used like this do they require disposing. And in general when you create colors, font, images you tend to reuse them over and over so dispose isn't needed. But if creating lots of any of these things, then you definitely want to explicitly dispose them to free up memory. Images especially since they can take up lots of memory.
This is sort of how dispose end up in Desktop. But I agree its not a very discoverable design. So I moved the dispose method directly into Image, Font, and Color and deprecated the Desktop versions. I have a bit of plumbing already to make that work, so seems like a much cleaner design.
as I say, I use it for double buffering so the screen updates don't flicker.
One trick which can really increase performance is to allocate your double buffer once and then reuse across all paints until you need a resize it. That avoids repetitive really big memory allocations.
AkcelistoMon 27 Feb 2012
SWT have own double buffering. FWT no have it?
SlimerDudeMon 27 Feb 2012
Cheers Brain, I'll try the single allocation. (But for what it does, it's not so bad right now.)
SlimerDudeMon 27 Feb 2012
Ah yes, I remember now...
Other than Image#makePainted I couldn't find any other way to (re)draw an Image from a Graphics context. For unlike a Canvas, the Image doesn't seem to allow you to redraw its contents.
Have I missed any part of the gfx / fwt API or is constructing a new Image currently the only way to draw offscreen?
SlimerDudeMon 27 Feb 2012
Then again, the flicker (if I draw straight to the Canvas) does give it a bit a cool retro CRT feel!
go4Tue 28 Feb 2012
Another design is to keep Image as mixin. so the implemention can hold a handle of native image. Avoid the images cache, and could dispose image by java garbage collector.
SlimerDude Mon 27 Feb 2012
It'd be beneficial if the Image Docs were updated with the addendum:
I guess the same should be written about Font and Color also.
Double buffering in my app was eating up about 1 Gb per minute! Eeek!
This also leads me to ask about the tight coupling between
gfx::Image
andfwt::Desktop
... is not possible to have Image and Desktop in the same pod? Or maybe a means to dispose of the Image in the gfx pod?Akcelisto Mon 27 Feb 2012
?!?! Yes, it's trap. I think that gfx::Image is like BufferedImage and stores in heap. And disposes by gc.
But now I confused. Why fwt::Desktop#disposeImage? When it need called? Give me example, plz.
SlimerDude Mon 27 Feb 2012
Sure, my one and only use case looks like this:
as I say, I use it for double buffering so the screen updates don't flicker.
Steve.
brian Mon 27 Feb 2012
The way this stuff is designed is that
gfx
is designed to be independently used fromfwt
. Which makes sense if you consider we often wish to model concepts such as color, fonts, and images independent from a specific toolkit (for example if we wanted to create a css API).Then the FWT maps those instances like Color, Font, and Image into SWT/OS resources as needed when you use them in a context such as FWT rendering. Only after they get used like this do they require disposing. And in general when you create colors, font, images you tend to reuse them over and over so dispose isn't needed. But if creating lots of any of these things, then you definitely want to explicitly dispose them to free up memory. Images especially since they can take up lots of memory.
This is sort of how dispose end up in Desktop. But I agree its not a very discoverable design. So I moved the dispose method directly into Image, Font, and Color and deprecated the Desktop versions. I have a bit of plumbing already to make that work, so seems like a much cleaner design.
One trick which can really increase performance is to allocate your double buffer once and then reuse across all paints until you need a resize it. That avoids repetitive really big memory allocations.
Akcelisto Mon 27 Feb 2012
SWT have own double buffering. FWT no have it?
SlimerDude Mon 27 Feb 2012
Cheers Brain, I'll try the single allocation. (But for what it does, it's not so bad right now.)
SlimerDude Mon 27 Feb 2012
Ah yes, I remember now...
Other than Image#makePainted I couldn't find any other way to (re)draw an Image from a
Graphics
context. For unlike aCanvas
, theImage
doesn't seem to allow you to redraw its contents.Have I missed any part of the gfx / fwt API or is constructing a new
Image
currently the only way to draw offscreen?SlimerDude Mon 27 Feb 2012
Then again, the flicker (if I draw straight to the Canvas) does give it a bit a cool retro CRT feel!
go4 Tue 28 Feb 2012
Another design is to keep
Image
as mixin. so the implemention can hold a handle of native image. Avoid the images cache, and could dispose image by java garbage collector.@SlimerDude: If you want more powerful graphics API. see: https://bitbucket.org/chunquedong/fan3d It support mutable image, affine transform, draw path...