ARSD PNG memory usage

Joerg Joergonson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Jun 16 18:51:41 PDT 2016


Hi, so, do you have any idea why when I load an image with png.d 
it takes a ton of memory?

I have a 3360x2100 that should take around 26mb of memory 
uncompressed and a bunch of other smaller png files.

Are you keeping multiple buffers of the image around? A 
trueimage, a memoryimage, an opengl texture thing that might be 
in main memory, etc? Total file space of all the images is only 
about 3MB compressed and 40MB uncompressed. So it's using around 
10x more memory than it should! I tried a GC collect and all that.

I don't think my program will have a chance in hell using that 
much memory. That's just a few images for gui work. I'll be 
loading full page png's later on that might have many pages(100+) 
that I would want to pre-cache. This would probably cause the 
program to use TB's of space.

I don't know where to begin diagnosing the problem. I am using 
openGL but I imagine that shouldn't really allocate anything new?

I have embedded the images using `import` but that shouldn't 
really add much size(since it is compressed) or change things.

You could try it out yourself on a test case to see? (might be a 
windows thing too) Create a high res image(3000x3000, say) and 
load it like

auto eImage = cast(ubyte[])import("mylargepng.png");

TrueColorImage image = 
imageFromPng(readPng(eImage)).getAsTrueColorImage;	
OpenGlTexture oGLimage = new OpenGlTexture(image); // Will crash 
without create2dwindow
//oGLimage.draw(0,0,3000,3000);


When I do a bare loop minimum project(create2dwindow + event 
handler) I get 13% cpu(on 8-core skylake 4ghz) and 14MB memory.

When I add the code above I get 291MB of memory(for one image.

Here's the full D code source:


module winmain;

import arsd.simpledisplay;
import arsd.png;
import arsd.gamehelpers;

void main()
{
			
		auto window = create2dWindow(1680, 1050, "Test");

		auto eImage = cast(ubyte[])import("Mock.png");

		TrueColorImage image = 
imageFromPng(readPng(eImage)).getAsTrueColorImage;   // 178MB	
		OpenGlTexture oGLimage = new OpenGlTexture(image);	 // 291MB
		//oGLimage.draw(0,0,3000,3000);

		window.eventLoop(50,
			delegate ()
			{
				window.redrawOpenGlSceneNow();
			},

		);
}

Note that I have modified create2dWindow to take the viewport and 
set it to 2x as large in my own code(I removed here). It 
shouldn't matter though as it's the png and OpenGlTexture that 
seem to have the issue.

Surely once the image is loaded by opengl we could potentially 
disregard the other images and virtually no extra memory would be 
required? I do use getpixel though, not sure it that could be 
used on OpenGLTexture's? I don't mind keeping a main memory copy 
though but I just need it to have a realistic size ;)

So two problems: 1 is the cpu usage, which I'll try to get more 
info on my side when I can profile and 2 is the 10x memory usage. 
If it doesn't happen on your machine can you try alternate(if 
'nix, go for win, or vice versa). This way we can get an idea 
where the problem might be.

Thanks!  Also, when I try to run the app in 64-bit windows, 
RegisterClassW throws for some reason ;/ I haven't been able to 
figure that one out yet ;/














More information about the Digitalmars-d-learn mailing list