[JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
Greetings Everyone,

I am just wondering about something I stumbled over during programming. I 
implemented a slice plane rendering for a voxel cube, meaning I needed to 
create 2d images on the fly. My first approach was to use a BufferedImage 
(only one) which I filled pixel by pixel with setRGB when the slice plane 
position changed.

To my surprise, it was not so slow as many ppl reported - but had a huge memory 
leak effect. Whenever I changed the slice plane position quickly (causing many, 
many, many setRGB() calls but NO new images), the garbage collector got lots of 
work to do.

The memory-leaking behavior is not relevant for me anymore since I changed the 
implementation to MemoryImageSource already, but I am still curious if anyone 
has an idea why setting pixels consumes that much memory.

MfG;
ChaosE
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269243

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
Can you post sample code? Small runnable test will be best.

It is interesting to understand whether you call setRGB() for individual pixels 
or arrays.
What type of buffered image are you using, etc.
[Message sent by forum member 'neigor' (neigor)]

http://forums.java.net/jive/thread.jspa?messageID=269249

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] collision detection in Java 2D???

2008-04-15 Thread java2d
consider this library Kollider2D (also available on google code).
New update very soon (today or tomorrow).
[Message sent by forum member 'orelero' (orelero)]

http://forums.java.net/jive/thread.jspa?messageID=269253

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
Sure. It is part of a bigger program, but I will try to extract what is needed 
and turn it into a runnable example. I used setRGB for each pixel (not arrrays) 
and for a TYPE_INT_ARGB image. Example will follow later.
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269259

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


[JAVA2D] Small runnable test

2008-04-15 Thread java2d
As requested, here a small runnable test. When you run it please start the JVM 
with something like -XX:NewSize=256m -XX:MaxNewSize=256m, elsehow the memory 
message wont be of much use.

Here comes the code:

---

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * Small example to compare MemoryImageSource and BufferedImage.
 * 
 * @author kif
 *
 */
public class SetPixelTest {
private static MyDrawingArea _mda;
private static boolean _use_mis = false;
private static JCheckBox _jcb_use_mis;

public static class MyDrawingArea extends JPanel {
private static int IMG_WIDTH = 256;
private static int IMG_HEIGHT = 256;

// either use a BufferedImage ...
private BufferedImage _bimg;

// ... or a MemoryImageSource
private Image _img;
protected int[] _pixels;
protected MemoryImageSource _mis;

public MyDrawingArea() {
setPreferredSize(new Dimension(400,400));
setBackground(Color.black);

_bimg = new BufferedImage(IMG_WIDTH,IMG_HEIGHT, 
BufferedImage.TYPE_INT_ARGB);
_pixels = new int[IMG_WIDTH*IMG_HEIGHT];
_mis = new MemoryImageSource(IMG_WIDTH, IMG_HEIGHT, 
_pixels, 0, IMG_WIDTH);
_mis.setAnimated(true);
_img = createImage(_mis);
}

public void random_fill() {
Random rand = new Random();
int r, g, b, rgb;

if (_use_mis) { // MemoryImage Source
int pixel_counter = 0;
for (int y=0; yIMG_HEIGHT; y++) {
for (int x=0; xIMG_WIDTH; x++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;
rgb = 0xff24 | r16 | g8 | 
b;
_pixels[pixel_counter++] = rgb;
}
}
_mis.newPixels();
} else { // BufferedImage
for (int y=0; yIMG_HEIGHT; y++) {
for (int x=0; xIMG_WIDTH; x++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;
rgb = 0xff24 | r16 | g8 | 
b;

_bimg.setRGB(x, y, rgb);
}
}
}
repaint();
}

public void paint(Graphics g) {
if (_use_mis) { // MemoryImage Source
g.drawImage(_img, 0, 0, getWidth(), 
getHeight(), this);
} else { // BufferedImage
g.drawImage(_bimg, 0, 0, getWidth(), 
getHeight(), this);
}
}
}

/**
 * @param args
 */
public static void main(String[] args) {
JFrame window = new JFrame(Pixel Performance Test);
_mda = new MyDrawingArea();

// if someone closes the main window, the program shall end.
window.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});

JButton jb_fill = new JButton(Random Fill);
jb_fill.addActionListener(new ActionListener() {

Re: [JAVA2D] Small runnable test

2008-04-15 Thread Igor Nekrestyanov

I am not sure what is going on. Perhaps this Runtime reporting wrong values.

I see that number printed to the console is growing but at the same time 
i do not observe heap growth in the jconsole.


-igor


[EMAIL PROTECTED] wrote:

As requested, here a small runnable test. When you run it please start the JVM with 
something like -XX:NewSize=256m -XX:MaxNewSize=256m, elsehow the memory 
message wont be of much use.

Here comes the code:

---

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * Small example to compare MemoryImageSource and BufferedImage.
 * 
 * @author kif

 *
 */
public class SetPixelTest {
private static MyDrawingArea _mda;
private static boolean _use_mis = false;
private static JCheckBox _jcb_use_mis;

public static class MyDrawingArea extends JPanel {
private static int IMG_WIDTH = 256;
private static int IMG_HEIGHT = 256;

// either use a BufferedImage ...
private BufferedImage _bimg;

// ... or a MemoryImageSource
private Image _img;
protected int[] _pixels;
protected MemoryImageSource _mis;

public MyDrawingArea() {
setPreferredSize(new Dimension(400,400));
setBackground(Color.black);

_bimg = new BufferedImage(IMG_WIDTH,IMG_HEIGHT, 
BufferedImage.TYPE_INT_ARGB);
_pixels = new int[IMG_WIDTH*IMG_HEIGHT];
_mis = new MemoryImageSource(IMG_WIDTH, IMG_HEIGHT, 
_pixels, 0, IMG_WIDTH);
_mis.setAnimated(true);
_img = createImage(_mis);
}

public void random_fill() {
Random rand = new Random();
int r, g, b, rgb;

if (_use_mis) { // MemoryImage Source
int pixel_counter = 0;
for (int y=0; yIMG_HEIGHT; y++) {
for (int x=0; xIMG_WIDTH; x++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;
rgb = 0xff24 | r16 | g8 | 
b;
_pixels[pixel_counter++] = rgb;
}
}
_mis.newPixels();
} else { // BufferedImage
for (int y=0; yIMG_HEIGHT; y++) {
for (int x=0; xIMG_WIDTH; x++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;
rgb = 0xff24 | r16 | g8 | 
b;

_bimg.setRGB(x, y, rgb);
}
}
}
repaint();
}

public void paint(Graphics g) {
if (_use_mis) { // MemoryImage Source
g.drawImage(_img, 0, 0, getWidth(), 
getHeight(), this);
} else { // BufferedImage
g.drawImage(_bimg, 0, 0, getWidth(), 
getHeight(), this);
}
}
}

/**
 * @param args
 */
public static void main(String[] args) {
JFrame window = new JFrame(Pixel Performance Test);
_mda = new MyDrawingArea();

// if someone closes the main window, the program shall end.
window.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
  

Re: [JAVA2D] Small runnable test

2008-04-15 Thread java2d
Hello Igor,

thank you for your reply. Its not only the runtime the reporting: in the 
original application where I extracted this code from, it produced a noticable 
slowdown in the rendering threads because of the garbage collector runs.

As I said, since I am using MemoryImageSources now, it has no practical 
relevance for me anymore. Still, it would be interested to understand what is 
happening ..

MfG;
ChaosE
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269289

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
 The memory-leaking behavior is not relevant for me
 anymore since I changed the implementation to
 MemoryImageSource already, but I am still curious if
 anyone has an idea why setting pixels consumes that
 much memory.

I would really recommend not using MemoryImageSource. Its an API from the 
java-1.1 days and its not recommended to use it any further. Its just there for 
compatibility reasons.

Setting large amount of pixels using setRGB is not a good practise, best way is 
to directly grab the raster from a BufferedImage:
[code]
byte[] data=((DataBufferByte)tex.getRaster().getDataBuffer()).getData() 
[/code]
this is for a byte-backed BufferedImage, but looks almost the same for an int[] 
one (which I recommend for best performance).

lg Clemems
[Message sent by forum member 'linuxhippy' (linuxhippy)]

http://forums.java.net/jive/thread.jspa?messageID=269294

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Small runnable test

2008-04-15 Thread java2d
Hmm, the forum is cropping my code. Is it to long? Do I need to use some tag 
like [pre]? I will try to edit the post 
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269280

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread Ken Warner

I hope MemoryImageSource is not going to be depricated!!!

I use it big time in all my applets.

What would be the replacement for MemoryImageSource?  I hope
you aren't thinking that BufferedImage is better.  BufferedImage
is a giant, poorly thought out hairball...

[EMAIL PROTECTED] wrote:

The memory-leaking behavior is not relevant for me
anymore since I changed the implementation to
MemoryImageSource already, but I am still curious if
anyone has an idea why setting pixels consumes that
much memory.



I would really recommend not using MemoryImageSource. Its an API from the 
java-1.1 days and its not recommended to use it any further. Its just there for 
compatibility reasons.

Setting large amount of pixels using setRGB is not a good practise, best way is 
to directly grab the raster from a BufferedImage:
[code]
byte[] data=((DataBufferByte)tex.getRaster().getDataBuffer()).getData() 
[/code]

this is for a byte-backed BufferedImage, but looks almost the same for an int[] 
one (which I recommend for best performance).

lg Clemems
[Message sent by forum member 'linuxhippy' (linuxhippy)]

http://forums.java.net/jive/thread.jspa?messageID=269294

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.




===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread Dmitri Trembovetski

Ken Warner wrote:

I hope MemoryImageSource is not going to be depricated!!!

I use it big time in all my applets.

What would be the replacement for MemoryImageSource?  I hope
you aren't thinking that BufferedImage is better.  BufferedImage
is a giant, poorly thought out hairball...


  Here we go again (for those uninitiated Ken sends
  something like this every couple of months it seems).

  Just because you don't seem to be able to grasp
  and use effectively the concept of Color/Sample models,
  data buffer and raster doesn't mean others can't.

  Please continue to use MIS, it won't go away.

  The rest of us can use the flexibility and
  performance benefits BufferedImages offer.

  Thanks,
Dmitri



[EMAIL PROTECTED] wrote:

The memory-leaking behavior is not relevant for me
anymore since I changed the implementation to
MemoryImageSource already, but I am still curious if
anyone has an idea why setting pixels consumes that
much memory.



I would really recommend not using MemoryImageSource. Its an API from 
the java-1.1 days and its not recommended to use it any further. Its 
just there for compatibility reasons.


Setting large amount of pixels using setRGB is not a good practise, 
best way is to directly grab the raster from a BufferedImage:

[code]
byte[] 
data=((DataBufferByte)tex.getRaster().getDataBuffer()).getData() [/code]
this is for a byte-backed BufferedImage, but looks almost the same for 
an int[] one (which I recommend for best performance).


lg Clemems
[Message sent by forum member 'linuxhippy' (linuxhippy)]

http://forums.java.net/jive/thread.jspa?messageID=269294

=== 

To unsubscribe, send email to [EMAIL PROTECTED] and include in the 
body
of the message signoff JAVA2D-INTEREST.  For general help, send 
email to

[EMAIL PROTECTED] and include in the body of the message help.




===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
True - but thats an array. Depending on the internal representation of 
DataBuffer (which I have not looked into yet), this could mean that the casting 
has to be done for each element of the array.

The fact that using setRGB() for individual pixels costs so much memory, could 
suggest that the internal raster is not int[]. If it would be that way, this 
would mean that setRGB() needs to do do a lot of casting and create temporaray 
objects, which would be a good explanation for the noticed memory consumption. 
Since I am no expert here, I can only guess.

MfG;
ChaosE
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269321

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
 Is it
 really faster then the MemoryImageSource approach?
Yes.

 Can you try to modify my example code using your
 suggestion, so that we can see if it produces
 similiar memory leaking behavior or if it solves it?
Sorry, no ... I don't have the time.

I post a snippit which should be easy to use:
[code]
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int[] buffer = ((DataBufferInt) img.getRaster().getDataBuffer())
.getData();
[/code]

buffer is now width*height in lenght. so width-1 is the first element of the 
second line.


 In the original application, switching from
 BufferedImage to MIS reduced frame rendering time
 from 45ms to 5ms (not taking into account the extra
 memory consumption). But then of course, I was not
 using the raster but setRGB().
If you don't render this image many times without chnging its data, I am sure 
it will be faster.
If you change it every frame, I guarantee its at least equally fast ;)

lg Clemens
[Message sent by forum member 'linuxhippy' (linuxhippy)]

http://forums.java.net/jive/thread.jspa?messageID=269318

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Small runnable test

2008-04-15 Thread Dmitri Trembovetski

  I only see a bunch of small collections (I tried on
  6u10) - probably because for each pixel you set an
  int[1] array is created.

  I don't see the heap growing. Run it with -verbose:gc ,
  see what it says.

  If you want to try the approach Clemens suggested, you'll
  only need to change your random_fill method:
   import java.awt.image.DataBufferInt;
   ...
int data[] = ((DataBufferInt)(_bimg.getRaster().getDataBuffer())).getData();
for (int i = 0; i  data.length; i++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;
data[i] = 0xff24 | r16 | g8 | b;
}

  (in real life examples you'll need to calculate
   the index for each element based on raster's
   data)

  Note that you can only cast to DataBufferInt here
  because you create an INT_RGB image.

  Also, getting the DataBuffer of a BufferedImage
  will forfeit any possibility of caching this image
  in video memory. For this particular case
  it doesn't matter that much since you're updating
  it on every frame, but it is something that needs
  to be considered.

  You can use DataBuffer to set pixels without
  having to reference the array directly - by using
  DataBufferInt.setElem(i, val). This will keep the
  possibility of the image being cached in vram, but
  may be slightly slower than direct array access
  approach.

  Thanks,
Dmitri


[EMAIL PROTECTED] wrote:

As requested, here a small runnable test. When you run it please start the JVM with 
something like -XX:NewSize=256m -XX:MaxNewSize=256m, elsehow the memory 
message wont be of much use.

Here comes the code:

---

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * Small example to compare MemoryImageSource and BufferedImage.
 * 
 * @author kif

 *
 */
public class SetPixelTest {
private static MyDrawingArea _mda;
private static boolean _use_mis = false;
private static JCheckBox _jcb_use_mis;

public static class MyDrawingArea extends JPanel {
private static int IMG_WIDTH = 256;
private static int IMG_HEIGHT = 256;

// either use a BufferedImage ...
private BufferedImage _bimg;

// ... or a MemoryImageSource
private Image _img;
protected int[] _pixels;
protected MemoryImageSource _mis;

public MyDrawingArea() {
setPreferredSize(new Dimension(400,400));
setBackground(Color.black);

_bimg = new BufferedImage(IMG_WIDTH,IMG_HEIGHT, 
BufferedImage.TYPE_INT_ARGB);
_pixels = new int[IMG_WIDTH*IMG_HEIGHT];
_mis = new MemoryImageSource(IMG_WIDTH, IMG_HEIGHT, 
_pixels, 0, IMG_WIDTH);
_mis.setAnimated(true);
_img = createImage(_mis);
}

public void random_fill() {
Random rand = new Random();
int r, g, b, rgb;

if (_use_mis) { // MemoryImage Source
int pixel_counter = 0;
for (int y=0; yIMG_HEIGHT; y++) {
for (int x=0; xIMG_WIDTH; x++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;
rgb = 0xff24 | r16 | g8 | 
b;
_pixels[pixel_counter++] = rgb;
}
}
_mis.newPixels();
} else { // BufferedImage
for (int y=0; yIMG_HEIGHT; y++) {
for (int x=0; xIMG_WIDTH; x++) {
r = rand.nextInt() % 256;
g = rand.nextInt() % 256;
b = rand.nextInt() % 256;

Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
Hi Clemens,

okay - I tested it. Memory consumption is gone. Will do some performance 
measuring later.

MfG;
ChaosE
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269324

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread Ken Warner

One Raster?  When I went through the same problem,
I had to do that three times to get the R,G,B channels.

[EMAIL PROTECTED] wrote:

[code]byte[]
data=((DataBufferByte)tex.getRaster().getDataBuffer())
.getData() [/code]
looks like there is a lot of casting involved. 



I can see only one.
[Message sent by forum member 'kirillcool' (kirillcool)]

http://forums.java.net/jive/thread.jspa?messageID=269313

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.




===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread Jim Graham

[EMAIL PROTECTED] wrote:

True - but thats an array. Depending on the internal representation of 
DataBuffer (which I have not looked into yet), this could mean that the casting 
has to be done for each element of the array.


Once you grab the Java array, you are done grabbing it and done casting. 
 If the image has only one bank (like TYPE_INT_*) then you only need to 
grab one array.


setRGB() on the other hand, which is just a convenience API for setting 
a few pixels (or even setting all of the pixels if the performance hit 
isn't in a critical area) has to start from scratch on each operation 
and must work on all BufferedImage types so it necessarily has to use a 
lot of more general APIs and perform a lot of duplicate work on every 
call.  If the image format is known, then more direct procedures (like 
grabbing the Java array) are available, but you have to pack your own 
pixels if you do so.



The fact that using setRGB() for individual pixels costs so much memory, could 
suggest that the internal raster is not int[]. If it would be that way, this 
would mean that setRGB() needs to do do a lot of casting and create temporaray 
objects, which would be a good explanation for the noticed memory consumption. 
Since I am no expert here, I can only guess.


setRGB() consumes memory because it makes no assumptions about any 
internal storage because it has to work even on a custom constructed 
BufferedImage with a 3rd party SampleModel and a 3rd party ColorModel 
and a 3rd party DataBuffer (and a 3rd party ColorSpace as well).  For 
all it knows the colors are represented by calculating the Nth number in 
the Fibonacci sequence, composing a pixel by distributing its bits using 
a reversible scrambling algorithm, and finally storing them into an SQL 
database on another continent.


(Perhaps if it took the time to examine the data structures actually 
being used it might be able to discern a more direct route than using 
the general APIs on ColorModel, SampleModel and DataBuffer, but it is 
only available for convenience, not performance.)


The primary consumption of memory for setRGB() has nothing to do with 
whether or not the internal raster is int[], but the fact that many of 
the general APIs on ColorModel, SampleModel and DataBuffer take small 
arrays of size 3 or 4 containing one color component per entry in the 
array - so each call to setRGB() involves the creation of at least one, 
possibly 2 of these tiny arrays.  With the modern garbage collectors in 
Hotspot, they are geared to be forgiving of a lot of small objects that 
are used quickly and discarded.



MfG;
ChaosE
[Message sent by forum member 'chaose71' (chaose71)]


I think one of the problems is that we never really documented the 
internal representation of the standard BufferedImage types very well.


On one hand, this is for a good reason which I'll get into further 
below, and on the other hand, this lack of documentation causes them to 
be scary for the casual user even though they are quite simple.


Basically, if you create a TYPE_INT_RGB, or TYPE_INT_ARGB, then it will 
have 1 Raster with 1 DataBuffer with 1 array of int[] that is large 
enough for every pixel in the image.  You can verify this by examining 
the SampleModel that it uses and the number of banks in the DataBuffer, 
etc., but that is the way it will (appear?) to store the internal data.


Thus, if you create a BufferedImage of one of those types then you can 
grab its int[] array once using a code snippet similar to what has 
already been posted here and keep using it for the life of the image for 
any pixel in the image - one grab of the array and one cast and then you 
are done for the life of the image.


Now, the good reason why we wanted to be a bit vague on this (even 
though it is information that is implied by all of the data structures 
that are composed into the BufferedImage) is that, for example, we 
wanted the flexibility to not use a Java array for a BufferedImage and 
put the data into the C heap memory, or into VRAM.  Apple has done such 
an optimization for performance on some of their older runtimes (before 
we created the managed image facilities which give most of the benefit 
of that technique without ditching the Java arrays), but that 
optimization was not a problem for the Java developer because their 
runtime would automagically promote the image to use a real Java array 
if you ever called the getData() method on the DataBuffer.  In other 
words, the shift in the underlying storage was transparent to the 
developer.  Thus, optimized storage until you needed then Java array and 
then first class Java array convenience when you needed it.  Also, any 
benefit of using cached copies or an alternate storage methodology is 
lost if you are modifying every pixel on every frame (which is what 
these animation situations tend to do) anyway since one way or another 
the pixels have to cross the RAM/VRAM boundary and the performance of 
moving 

Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread Jim Graham

Just a small correction...

[EMAIL PROTECTED] wrote:

Can you try to modify my example code using your
suggestion, so that we can see if it produces
similiar memory leaking behavior or if it solves it?

Sorry, no ... I don't have the time.

I post a snippit which should be easy to use:
[code]
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
int[] buffer = ((DataBufferInt) img.getRaster().getDataBuffer())
.getData();
[/code]

buffer is now width*height in lenght. so width-1 is the first element of the 
second line.


The first element of the first line would be at index 0.
The last element of the first line would be at index width-1.
The first element of the second line would actually be at index width 
(not width-1 ;-).


But, these rules of thumb make an assumption about the scan stride being 
used and the offset to the first pixel.  Those assumptions will be true 
for a brand new BufferedImage and on the reference runtime, but there 
are 2 cases where those assumptions may fail if you care about these 
situations:


- If Java is ever ported to an architecture where alignment stricter 
than 4-bytes for image data is desired, then the scanline stride may 
need to be padded to the next 8 (or 16 or ?) byte boundary.


- If you want to work on an sub-image, such as those created by the 
BufferedImage.getSubimage() call then the scanline stride may be totally 
unrelated to the width of this image, and the offset to the first pixel 
may not be 0 any more either (since the sub-image is talking to a subset 
of the image data for the parent image).


- If you want to work on a BufferedImage that someone created using 
their own Raster, it might still be tagged as TYPE_INT_[A]RGB, even 
though they didn't honor those restrictions that the BufferedImage 
constructor would impose and so the offset to the first pixel and the 
scanline stride may be different.  The only restrictions on an image 
created from a Raster to be classified as TYPE_INT_* are that it use a 
DirectColorModel, a SinglePixelPackedSampleModel and have a pixel stride 
of 1.


If you want to be just a little bit more technically correct then the 
following should cover you in the situations that require a different 
scanline stride:


// one-time setup
Raster r = img.getRaster();
SinglePixelPackedSampleModel sppsm;
int buf[] = ((DataBufferInt) r.getDataBuffer()).getData();
sppsm = ((SinglePixelPackedSampleModel) r.getSampleModel());
int scan = sppsm.getScanlineStride();

// per-pixel access code
buf[y * scan + x] = /* data for x,y */

And if you want to work on a subimage, or a manually created 
BufferedImage, then the following should cover all of these bases with 
only a couple more lines in the setup code:


// one-time setup
Raster r = img.getRaster();
SinglePixelPackedSampleModel sppsm;
int buf[] = ((DataBufferInt) r.getDataBuffer()).getData();
sppsm = ((SinglePixelPackedSampleModel) r.getSampleModel());
int scan = sppsm.getScanlineStride();
int sampX = r.getSampleModelTranslateX();
int sampY = r.getSampleModelTranslateY();
int off = - (sampY * scan + sampX);

// per-pixel access code
buf[off + y * scan + x] = /* data for x,y */

...jim

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Why does BufferedImage setRGB consumes memory?

2008-04-15 Thread java2d
Hello Jim,

thanks a lot for the very comprehensive reply! It did perfectly answers all my 
questions and even a few more ;) Glad to understand the strange memory 
consumption a bit better now. It feels always better to understand the true 
nature of an unknown phenomen!

Thanks again!
Ingo

PS: I very much liked the idea of colors beeing represented by calculating 
Fibonacci numbers and composing a pixel by distributing its bits using a 
reversible scrambling algorithm, and finally storing them into an SQL database 
on another continent. It sounds like something amazon would like to have a 
patent on (if such an image could be created with one-click).
[Message sent by forum member 'chaose71' (chaose71)]

http://forums.java.net/jive/thread.jspa?messageID=269348

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Native text rasterizer and translucent graphics

2008-04-15 Thread Phil Race

The first line is LCD text, the second line is greyscale.
The problem is that we do not have loops - in either software
or hardware, that work for LCD text with the composite you have specified.
There's an open bug on this: 6274808.

-phil.


[EMAIL PROTECTED] wrote:

Reposting from Swing  AWT forum since it was suggested that this is a better 
place.

It looks like the new native text rasterizer is not used when the current 
graphics composite is translucent. Here is the test app that i'm running on 
Vista SP1 with 6u10 b14:

[code]
package test;
 
import java.awt.*;

import java.util.*;
 
import javax.swing.*;
 
public class TextRenderingPanel extends JPanel {
 
	private static Map desktopHints(Graphics2D g2) {

Toolkit toolkit = Toolkit.getDefaultToolkit();
GraphicsDevice device = g2.getDeviceConfiguration().getDevice();
Map desktopHints = (Map) toolkit
.getDesktopProperty(awt.font.desktophints);
// It is possible to get a non-empty map but with disabled AA.
if (desktopHints != null) {
Object aaHint = desktopHints

.get(RenderingHints.KEY_TEXT_ANTIALIASING);
if ((aaHint == RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)
|| (aaHint == 
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) {
desktopHints = null;
}
}
return desktopHints;
}
 
	@Override

protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();

Map desktopHints = desktopHints(g2d);
if (desktopHints != null  !desktopHints.isEmpty()) {
g2d.addRenderingHints(desktopHints);
}

g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.black);
g2d.setFont(new Font(Segoe UI, Font.PLAIN, 12));
g2d.drawString(Text rendering, 10, 30);
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
workaroundBug6576507(g2d);
g2d.drawString(Text rendering, 10, 60);
g2d.dispose();
}

public static void workaroundBug6576507(Graphics graphics) {
Font font = graphics.getFont();
font = font.deriveFont(font.getStyle(), font.getSize2D());
graphics.setFont(font);
}
 
 
	public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame(Text rendering);
frame.add(new TextRenderingPanel(), 
BorderLayout.CENTER);
frame.setSize(300, 200);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
 
}

[/code]


Running this you can see that the 'e's on the second line of text do not come 
from the same rasterizer as the 'e's on the first line of text. Is this the 
expected result, and if so, would i have to create a temporary image, render 
the full-opacity text there and then render that image back (with translucency) 
to get consistent rendering?

Note that I have to use deriveFont as the workaround for bug 6576507 as 
suggested in [1]. Doesn't look like the fix in JDK 7 was backported to 6u10.

Last thing - letter 'g' is one pixel narrower than in the real native 
rendering (from the title pane of the same frame).

Thanks
Kirill 


[1] http://forums.java.net/jive/thread.jspa?threadID=28226
[Message sent by forum member 'kirillcool' (kirillcool)]

http://forums.java.net/jive/thread.jspa?messageID=268874

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Native text rasterizer and translucent graphics

2008-04-15 Thread Dmitri Trembovetski

Phil Race wrote:

The first line is LCD text, the second line is greyscale.
The problem is that we do not have loops - in either software
or hardware, that work for LCD text with the composite you have specified.
There's an open bug on this: 6274808.


  Note that this bug mentions that complex clip is
  another restriction. This is only the case for
  sw pipelines, the hw ones (ogl,d3d) can handle
  lcd AA text with complex clip.

  Thanks,
Dmitri




-phil.


[EMAIL PROTECTED] wrote:
Reposting from Swing  AWT forum since it was suggested that this is 
a better place.


It looks like the new native text rasterizer is not used when the 
current graphics composite is translucent. Here is the test app that 
i'm running on Vista SP1 with 6u10 b14:


[code]
package test;
 
import java.awt.*;

import java.util.*;
 
import javax.swing.*;
 
public class TextRenderingPanel extends JPanel {
 
private static Map desktopHints(Graphics2D g2) {

Toolkit toolkit = Toolkit.getDefaultToolkit();
GraphicsDevice device = g2.getDeviceConfiguration().getDevice();
Map desktopHints = (Map) toolkit
.getDesktopProperty(awt.font.desktophints);
// It is possible to get a non-empty map but with disabled AA.
if (desktopHints != null) {
Object aaHint = desktopHints
.get(RenderingHints.KEY_TEXT_ANTIALIASING);
if ((aaHint == RenderingHints.VALUE_TEXT_ANTIALIAS_OFF)
|| (aaHint == 
RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT)) {

desktopHints = null;
}
}
return desktopHints;
}
 
@Override

protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
   
Map desktopHints = desktopHints(g2d);

if (desktopHints != null  !desktopHints.isEmpty()) {
g2d.addRenderingHints(desktopHints);
}
   
g2d.setColor(Color.white);

g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.black);
g2d.setFont(new Font(Segoe UI, Font.PLAIN, 12));
g2d.drawString(Text rendering, 10, 30);
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
workaroundBug6576507(g2d);
g2d.drawString(Text rendering, 10, 60);
g2d.dispose();
}

public static void workaroundBug6576507(Graphics graphics) {

Font font = graphics.getFont();
font = font.deriveFont(font.getStyle(), font.getSize2D());
graphics.setFont(font);
}
 
 
public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame(Text rendering);
frame.add(new TextRenderingPanel(), BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
 
}

[/code]


Running this you can see that the 'e's on the second line of text do 
not come from the same rasterizer as the 'e's on the first line of 
text. Is this the expected result, and if so, would i have to create a 
temporary image, render the full-opacity text there and then render 
that image back (with translucency) to get consistent rendering?


Note that I have to use deriveFont as the workaround for bug 6576507 
as suggested in [1]. Doesn't look like the fix in JDK 7 was backported 
to 6u10.


Last thing - letter 'g' is one pixel narrower than in the real 
native rendering (from the title pane of the same frame).


Thanks
Kirill
[1] http://forums.java.net/jive/thread.jspa?threadID=28226
[Message sent by forum member 'kirillcool' (kirillcool)]

http://forums.java.net/jive/thread.jspa?messageID=268874

=== 

To unsubscribe, send email to [EMAIL PROTECTED] and include in the 
body
of the message signoff JAVA2D-INTEREST.  For general help, send 
email to

[EMAIL PROTECTED] and include in the body of the message help.


===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Native text rasterizer and translucent graphics

2008-04-15 Thread java2d
Phil,

Would that be fixed in the final 6u10?

Thanks
Kirill
[Message sent by forum member 'kirillcool' (kirillcool)]

http://forums.java.net/jive/thread.jspa?messageID=269392

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] Native text rasterizer and translucent graphics

2008-04-15 Thread java2d
Would you suggest emulating translucent text by interpolating the full color 
with the background color (using full opacity)?
[Message sent by forum member 'kirillcool' (kirillcool)]

http://forums.java.net/jive/thread.jspa?messageID=269400

===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.