Abuse,
Thanks for your thoughts. In my mind, what you said makes perfect sense, I just wish Java2D felt the same way. One of the symptoms I failed to mention before is that when the frame/canvas is straddling the two GraphicDevice’s the CPU usage increases considerably. So I thought surely the AutomImages must be losing their ability to be hardware accelerated possibly because the AutoImage has to be copied to the correct GraphicsDevice which would account for the higher CPU usage. Unfortunately, this doesn’t seem to be the case.
Anyway, as far as the animation freezing, I discovered that as soon as the frame/canvas intersects a different GraphicDevice other than the one it was created on, I have to recreate the BufferStrategy. Now whether this is an issue with the display driver or the BufferStrategy or by design I can’t say, but this is the only way I can keep the animation from freezing when a GraphicDevice context switch occurs.
As far as the higher cpu usage goes when the canvas instersects two GraphicsConfigurations, again I’m stumped for an explanation. As theorized, I tried creating an AutoImage for each GraphicsConfiguration from each GraphicsDevice. Then based upon the image’s draw location, I would draw the appropriate AutoImage that corresponded to the correct GraphicsConfiguration. Doing this added a little complexity in that I now had to convert the AutoImage’s user space coordinates into device space coordinates. However, doing all of this seemed to provide no benefit.
Anyway, it seems that Java2D is doing some work for the programmer behind the scenes in that an AutoImage created on one GraphicsConfiguration WILL draw on another GraphicsConfiguration as long as the BufferStrategy is recreated as I mentioned above. Also, as noted, dividing one canvas between two GraphicsConfigurations does not seem to work well at all.
Here are a few code samples just in case. Perhaps I’m doing something horribly wrong.
Here I’m initializing each AutoImage for each GraphicsConfiguration:
static public GraphicsDevice[] graphicsDeviceList = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()
public void initGraphics(int imageType) throws OutOfMemoryError
{
compWidth = (int)compDimensions.getWidth();
compHeight = (int)compDimensions.getHeight();
volatileImageVector.clear();
for (int x=0;x<graphicsDeviceList.length;x++)
{
GraphicsConfiguration gConfig = graphicsDeviceList[x].getDefaultConfiguration();
switch(imageType)
{
case TickerConstants.VOLATILE:
try
{
VolatileImage volatileImage = gConfig.createCompatibleVolatileImage(compWidth, compHeight);
volatileImageVector.add(volatileImage);
restoreVolatile(gConfig, volatileImage);
}
catch(OutOfMemoryError e)
{
this.flush();
e.printStackTrace();
throw e;
}
break;
case TickerConstants.AUTO:
try
{
autoImageVector.add(gConfig.createCompatibleImage(compWidth, compWidth, Transparency.OPAQUE));
}
catch(OutOfMemoryError e)
{
this.flush();
e.printStackTrace();
throw e;
}
restoreAutoImage(x);
break;
}
}
graphicsInitialized = true;
}
And Here I’m rendering the AutoImages for each GraphicsConfiguration:
public void render(Graphics2D g2d)
{
int drawX = (int)getDrawLocX();
int drawY = (int)getDrawLocY();
if (graphicsInitialized == false)
{
try
{
initGraphics(getImageType());
}
catch(OutOfMemoryError e)
{
flush();
e.printStackTrace();
if (initListener != null)
{
initListener.handleMemoryError(e);
}
}
}
switch(getImageType())
{
case TickerConstants.VOLATILE:
for (int x=0;x<volatileImageVector.size();x++)
{
VolatileImage volatileBuffer = (VolatileImage)volatileImageVector.elementAt(x);
for(;;)
{
g2d.drawImage(volatileBuffer, drawX, drawY, null);
if (isSelected())
{
renderHilite(g2d, drawX, drawY);
}
if(volatileBuffer.contentsLost())
{
restoreVolatile(g2d.getDeviceConfiguration(), volatileBuffer);
}
else
{
break;
}
}
}
break;
case TickerConstants.AUTO:
for(int x=0;x<autoImageVector.size();x++)
{
BufferedImage bufferedImage = (BufferedImage)autoImageVector.elementAt(x);
if (graphicsDeviceList[x].getDefaultConfiguration().getBounds().contains(getVirtualBounds()))
{
g2d.drawImage(bufferedImage, (int)getDrawLocX(), (int)getDrawLocY(), null);
}
if (isSelected())
{
renderHilite(g2d, drawX, drawY);
}
}
break;
}
}