public void Draw(Graphics2D g)
{
for(int i=0;i<10000;i++)
{
g.setPaint(new TexturePaint(theImage, new Rectangle(0,0,theImage.getWidth(),theImage.getHeight())));
g.fillRect(0,0,theImage.getWidth(),theImage.getHeight());
}
}
i’ve measured the time it takes this function to end, and than i’ve changed it to this:
public void Draw(Graphics2D g)
{
for(int i=0;i<10000;i++)
{
g.drawImage(theImage,0,0,null);
}
}
again, i’ve measure the time it takes the function to end, and it takes alot more time with the second method… how come? it looks so much simpler…
the image is a BufferedImage of TYPE_INT_ARGB, btw.
Something is royally screwed in the pipeline if your benchmark results are correct.
what is the Graphics context you are drawing onto associated with?
What version JVM?
How are you constructing the BufferedImage TYPE_INT_ARGB?
There are atleast 2 potencial hypothesis’
The Graphics context onto which you are drawing, originated from the Image you are drawing. aka you are drawing the image onto itself.
If this was the case, I would expect the 2 methods to be equally slow.
You are running a Java version 1.4.x, (so the TYPE_INT_ARGB BufferedImage is not being cached in VRAM [i.e. managed])
The TexturePaint constructor is copying the passed in BufferedImage into a managed image,
and is also caching the managed image. (because it knows the source BufferedImage has not been changed)
If this were the case, I would expect the 1st loop to be MUCH faster than the 2nd loop.
From a quick scan of the code, it appears the 2nd hypothesis may well be correct - there does appear to be a caching system present in TexturePaintContext =/
So should i use fillrect for all my sprites?
or am i going the wrong way from the start (seems logical, because if this is the correct method for drawing sprites you would have been familiar with the problem)?
No please not that would be more or less a bit … well … strange.
You could do the following:
1.) Use only Java-1.5 and above, it caches BufferedImages of they are blitted many times withought any change of the image data (preffered way of doing it)
2.) Blit your sprites into ManagedImages (images created with Component.createImage(int, int). These images are accerlated also in java-1.4 and above
I don’t get it. in this thread: http://192.18.37.44/forums/index.php?topic=10520.0
the third message starts with:
“Unless Chet has added some hadrware support for BufferedImage sicne last I looked at it, id stay away from it as it by definition means you are holding and modifying your image data in Java heap space whcih is abotua s far from the graphics card as you can get.”
so, this guy sais i shold stay away from buffered Images. why?
1.) Please don’t do cross-posting - its not the way to behave here.
Many people double-answer questions and also the information is spread arround several places.
I’ll get your answers, just everythings needs the time it needs. (btw. I also saw your double-post before and qas quite angry that I wasted my time replying to this).
2.)
To be honest I don’t know why this “guy” says you should stay away from bufferd images, starting with java-1.5 I would rather stay away from “Managed Images” since they do not really fir into java’s imaging semantics and are under the hood emulated using BufferedImages on the 3d accalerated pipelines.
Maybe he’s not up to date?
Java caches BufferedImages since Tiger (aka 5.0) in VRam (Windows Images, OpenGL Textures) so its even faster than a VI -> VI or VI -> Surface blit as long as you don’t modify the BufferedImages.
Wow Wow Wow…
If by “cross posting” you mean that i have mentioned another thread on this thread, than i didn’t know it was against the rules, and i appologize, though i would like to know why it is forbidden.
but, if you meant i was double posting, i.e asking the same question on two different threads, than you’re wrong.
i didn’t post the other thread. only this one. i assure you i’m not using two usernames.
Maybe you got confused because my user’s “No_Germs” and his is “games”?
anyway…
you’re saying i should stay away from “managed images”?
i thought that was the way to get a buffered image.
Well if you want to use it for tiles and you have the ability to use BufferedImages (java-1.5 or higher) I would not use ManagedImages since you know not how they are implemented under the hood. Since 1.5 the rule BufferedImage for reading, VI for writing) But well, at least the modern java2d pipelines (at leats opengl/Mustang for sure) return a BufferedImage since developers decided that managedimage rendering performance is not too critical any more, but for example on X11 you get a X11???-Image since X11 cares that no surface-lost may happen so theres no need to cache data in heap too.
ManagedImages were introduced somewhere in 1.0 or 1.1 mainly to allow offscreen-rendering, whereas Toolkit-Images (not user-accasible image type) were mainly used for reading. ManagedImages were implemented as PBuffers in OpenGL/Tiger and therefor have much higher overhead when blitting them.
However I do not think your program would suffer if you would use ManagedImages, furthermore they are accerlated also before java-1.5.
to create a managedimage call: Component.createImage
to cretae a bufferdImage: new BufferedImage…
As I say, I don’t know if things have chanegd sicne about 1.4 BUT up til then certainly all of the follwing is true. This is a condensation of a paper I wrote explainign all of this that Ill give you a pointer to at the end.
Buffered Images:
Buffered images by definition at least as far as 1.4 were held in Java Heap space. Thats why you can easily read and write to them.
The problem is that Java Heap space is as far as you can get from video memory, thus there are two issues:
(1) You cannot use any of the garphics card’s acceleration to draw to them as graphics cards only draw to video memory.
(2) ALthough they are very fast for Java code to write into, they are hiddeously SLOW to move the results to to screen. That is because you need to move all tht data from Java Heap space through C heap space to Video Memory.
Volatile Images:
Volatile images are images in video memory.
(1) They are very fast to move to the screen (pretty much free.)
(2) You can use the hardware acceleration to draw to them
BUT
(3) They are very slow to do non-hardware accleerated drawing to or to BLT to from non Volatile memory. They are also very slow to read pixel data otu of for anything but display or BLT to other Volatile Images. Thsi is because Java must again reach across the link between regular and video memory, which is by definition slow.
Managed Images:
Managed Images are an attempt by the system to free you from worry about all of the above. (We used to call them “automatic Images” which is the term you will se in the article.) Managed Images are Java Heap images backed by a Volatile Image cache. The first write of any ManagedImage to screen is slow ebcause it has to be tyrasnferred to that cache. After that display and BLT to Volatile Images is fast UNLESS you change the image. If you chnage it it invalidates the cache and the new data needs to be transferred again.
It may be a little out of date. the “Chet” Imentioned is the tech lead at Sun on all of this image stuff. Maybe Ill try to talk to him and see about doing an updated version of this article sometime…
I have no idea what you mean by “make managed images redundant”. Linuxhippy’s answer is fairly accurate: since 5.0, all BufferedImages are “managed”, meaning their contents can potentially be cached in VRAM. And VRAM->VRAM copies can be much faster in most cases than sending the bits from system memory on each copy.
There’s a whole lot of misinformation in many of these responses. Please, before anyone else answers, go read any of Chet’s articles on using images in Java 2D…
RIght, Which was the meaning of “managed image” when it was coined. So apaprently its now a redundant term as it sounds like all non-volatile images have become managed.
Yes, chet actually checked over the article I wrote and pointed at when we orignally published it. It slightly predates his. Many of his explainations cover things I covered in that orginal article and in more detailso I think his are well worth reading and a creaful rading of them might obviate the need to read mine.
I saw nothing in any of those articles that says that BuffredImages are backed these days by a volatile image cache, but ive already written Chet for clarity on that matter.
In gerneal I wish yould be more specific about what you are calling “misinformation” so it can be addressed. The fact of the matter is saying “there is a lot of misinformation here” and no more just makes the entire thread of questionable use to the uninformed reader.
As I say I skimmed those articles you pointed at and can find nothign that contridcts any of my explainations. perhaspe you can point at specific issues you see?
As of 1.5 (and no earlier) all non-VRAM images (everythiung except voilatile ) are now VRAM cached, and thus are all “managed images” with one important caveat to be wary of.
The following from Chet on it:
The reason why VolatileImages arent VRAM cahced, just for completeness, is that this would be silly as they are already IN VRAM.
It is covered in at least two of his articles. For example, on the topic of JDK 5.0:
“Managed images everywhere! You will now get managed images by calling most of our image creation and loading mechanisms. In jdk1.4.*, only some of the image creation methods (such as Component.createImage() and GraphicsConfiguration.createCompatibleImage()) returned managed images. But in 1.5, you can even call new BufferedImage(…) with a type that is not in the screen bit depth and end up with an accelerated managed image.”
Conceptually you could say that a “managed image” has a system memory copy and zero or more “VolatileImages” underneath it. But that’s not entirely accurate because a managed image could be backed by one kind of accelerated surface, and a VolatileImage by another. For example, in the OGL pipeline, managed images cache their contents in an OGL texture, whereas VolatileImages are backed by a pbuffer, or FBO. But these are just implementation details; you were on the right track.
That statement wasn’t directed at your post, which did have useful information. I was talking more about things like this:
I don’t follow this. As of 5.0, BufferedImages and “managed images” are pretty much synonymous. Sometimes (as in this case) I think people say “managed image” for those returned by Component.createImage() or GraphicsConfig.createCompatibleImage(). Those methods are useful for returning a BufferedImage in the screen format, so they will still be optimized for blitting to the screen or a VolatileImage when the heap-based surface is used. So I’m not sure why “managed images” are not being recommended in this case.
Managed images (as we know them today) were introduced in 1.4, but were only returned from certain methods. In 5.0, we generalized this approach so that any BufferedImage is “managable”. Managed images were implemented using pbuffers for the OGL pipeline in Tiger in some rare cases. In Mustang this is no longer the case, managed images are always backed by textures when the OGL pipeline is enabled.
I just saw quite low performance when using the pbuffer-based managed images since blitting the pbuffer-content seems to be much slower than blitting texture-cached images.
The reason why I claimed that was that some JVM vendors may optimize mutable managed images ( ) for rendering instead of blitting since pre-1.4 code mainly uses this image type for offscreen images.
But however BufferedImages also are not forced to be accerlated by definition and furthermore SUN did a fairly well job in making java as un-open as possible so I don’t even know a SINGLE cleanroom-jvm that is j2se-1.4 certified.
Well of course
Just because of interrest do you know how Offscreen images were implemented in 1.1 days?
As far as I remember they were accerlated but also guaranteed to hold their contents (however there were quite a few bugs g).
Hmm. I dunno how i missed this. Skimming too fast I guess
Anyway in the meantime i got my response from my note to Chet which said the same thing!
Which is great 'casue it means we can more or elss forget abotu the “managed image” distinction which was always confusing to the end programmer!
[quote]. For example, in the OGL pipeline, managed images cache their contents in an OGL texture, whereas VolatileImages are backed by a pbuffer, or FBO. But these are just implementation details; you were on the right track.
[/quote]
Interesting, I assume this is because of the current transition to OGL underpinnings, yes? I had wondered how this was going to effect things.
Do we intend to keep both models indefintiely or are we going to transition Volatile and BufferStrategy to use the OGL pipeline?
That statement wasn’t directed at your post, which did have useful information. I was talking more about things like this:
Okay. Its just a lot more useful to the reader if we have real correction so they know what to discount and what not to.
“The most correct info is here” is great, but it doesn’t “unring the bell” as lawyers say. Someone already having read all this has it all in their heads and is helped most by specific corrections. Thanks for the details!
Interesting, I assume this is because of the current transition to OGL underpinnings, yes? I had wondered how this was going to effect things.
Do we intend to keep both models indefintiely or are we going to transition Volatile and BufferStrategy to use the OGL pipeline?
[/quote]
Perhaps I didn’t quite follow your question. The way managed images are cached or VolatileImages are stored in VRAM depends on the pipeline. Depending on which flags are enabled on Windows for example, a VolatileImage could be backed by a DirectDraw surface, or a managed image could be cached in a D3D texture. It all depends, but just because we have the OGL pipeline now doesn’t mean we’ve changed the way images are managed for other pipelines.
Both “managed” images and VolatileImages have been accelerated by the OGL-based Java 2D pipeline since it was introduced in JDK 5. Managed images are cached in an OpenGL texture if possible.
VolatileImages are backed by an OpenGL “pbuffer”, which allows accelerated rendering into it and accelerated copies from it. Just recently in Mustang, I added a codepath (disabled by default for the near future) that allows VolatileImages to be backed by a “framebuffer object”, or FBO (see GL_EXT_framebuffer_object extension). You can think of FBOs as a faster, more cross-platform cousin of pbuffers and render-to-texture.
As for BufferStrategy, if a “flip” BS is requested and the GraphicsConfig has a hardware backbuffer, then the OGL pipeline can render directly into the OpenGL backbuffer, and BufferStrategy.show() is equivalent to doing a SwapBuffers().