Skip to main content

[JAVA2D] Question about recommended render loop for BufferStrategy...

3 replies [Last post]
Anonymous

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Ken Warner

Ken Warner wrote:

According to the documentation on:
http://java.sun.com/javase/6/docs/api/java/awt/image/BufferStrategy.html

One is supposed to
do {
Graphics graphics = strategy.getDrawGraphics();
//render here
graphics.dispose();
} while (strategy.contentsRestored());

So I did that where I render:
do {
do {
bg = (Graphics2D)bs.getDrawGraphics();
mis.newPixels(pixels, cm, 0, thisW); //MemoryImageSource
bg.drawImage(canvasImage, 0, 0, thisW, thisH, this);
bg.dispose();
} while (bs.contentsRestored());
bs.show();
} while (bs.contentsLost());

So I'm disposing of bg -- the BufferStrategy graphics after I render.

The question is --

how come I can still use the buffer graphics (bg)
at other times to draw stuff.

My applet draws onto the BufferStrategy (bs) in many other places at
various times. And it works after I have dispose()'ed of the
buffergraphics (bg) and the loop above is the only place I getDrawGraphics();

For example -- here's my paint() method -- no problem -- no drawGraphics.

public void paint(Graphics g)
{
//System.err.println("paint()");
bg.drawImage(canvasImage, 0, 0, thisW, thisH, this);
bs.show();
}

paint() should fail but it works just fine.

I don't understand how paint can drawImage if bg is disposed.

Ken

Dmitri Trembovetski wrote:
>
>
> Ken Warner wrote:
>
>> Hi Dmitri,
I don't call repaint() from my code ever. I have ignoreRepaint() set for
>> the Canvas component. paint() is only called from the AWT eventloop on
>> expose and events like that -- do I understand that right?
The loop below is called from my own looping thread when I get some
>> newPixels for my MemoryImageSource. I have not seen any problems.
But I know that my applet is not accelerated on my machine. It only
>> has unaccelerated bitblt from the BufferStrategy. I can't test
>> real acceleration. My machine is too old.
What I'm trying to say -- clumsily -- is that I believe that only one
>> thread at a time could render to my buffer -- I think...
>
>
> OK.. Then what's the question, again? I'm sorry, I'm just
> not following.
>
> Thanks,
> Dmitri
>
>
Ken
Dmitri Trembovetski wrote:
> Hi Ken,
>> first of all, rendering to the same graphics context from
>>> multiple thread is not a good idea. Java2D does not
>>> guarantee thread safety, and doing so could
>>> lead to unpredictable results (and even crashes due
>>> to bugs in our code). So, please don't do that.
>> As to your question why it "works" - you just got
>>> lucky and the paint on EDT executed while another
>>> thread was in between the getDrawGraphics() and dispose().
>> After the dispose() all rendering operations to a
>>> graphics context become no-ops, so by definition you
>>> would only see something rendered the paint event
>>> happened to be while the graphics was still valid.
>> Thank you,
>>> Dmitri
>>> Java2D Team

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Dmitri Trembovetski

If you can put together a complete test which shows
that you can render to a Graphics object after it's
been disposed (and stuff shows up in the destination),
that would be a bug.

If you can, please send the test over. Otherwise it
is hard to tell what could be wrong.

Thanks,
Dmitri

Ken Warner wrote:
> Ken Warner wrote:
>
> According to the documentation on:
> http://java.sun.com/javase/6/docs/api/java/awt/image/BufferStrategy.html
>
>
> One is supposed to
> do {
> Graphics graphics = strategy.getDrawGraphics();
> //render here
> graphics.dispose();
> } while (strategy.contentsRestored());
>
> So I did that where I render:
> do {
> do {
> bg = (Graphics2D)bs.getDrawGraphics();
> mis.newPixels(pixels, cm, 0, thisW); //MemoryImageSource
> bg.drawImage(canvasImage, 0, 0, thisW, thisH, this);
> bg.dispose();
> } while (bs.contentsRestored());
> bs.show();
> } while (bs.contentsLost());
>
> So I'm disposing of bg -- the BufferStrategy graphics after I render.
>
> The question is --
>
> how come I can still use the buffer graphics (bg)
> at other times to draw stuff.
>
> My applet draws onto the BufferStrategy (bs) in many other places at
> various times. And it works after I have dispose()'ed of the
> buffergraphics (bg) and the loop above is the only place I
> getDrawGraphics();
>
> For example -- here's my paint() method -- no problem -- no drawGraphics.
>
> public void paint(Graphics g)
> {
> //System.err.println("paint()");
> bg.drawImage(canvasImage, 0, 0, thisW, thisH, this);
> bs.show();
> }
>
> paint() should fail but it works just fine.
>
> I don't understand how paint can drawImage if bg is disposed.
>
> Ken
>
>
> Dmitri Trembovetski wrote:
>>
>>
>> Ken Warner wrote:
>>
>>> Hi Dmitri,
> I don't call repaint() from my code ever. I have ignoreRepaint() set for
>>> the Canvas component. paint() is only called from the AWT eventloop on
>>> expose and events like that -- do I understand that right?
> The loop below is called from my own looping thread when I get some
>>> newPixels for my MemoryImageSource. I have not seen any problems.
> But I know that my applet is not accelerated on my machine. It only
>>> has unaccelerated bitblt from the BufferStrategy. I can't test
>>> real acceleration. My machine is too old.
> What I'm trying to say -- clumsily -- is that I believe that only one
>>> thread at a time could render to my buffer -- I think...
>>
>>
>> OK.. Then what's the question, again? I'm sorry, I'm just
>> not following.
>>
>> Thanks,
>> Dmitri
>>
>>
> Ken
> Dmitri Trembovetski wrote:
>> Hi Ken,
>>> first of all, rendering to the same graphics context from
>>>> multiple thread is not a good idea. Java2D does not
>>>> guarantee thread safety, and doing so could
>>>> lead to unpredictable results (and even crashes due
>>>> to bugs in our code). So, please don't do that.
>>> As to your question why it "works" - you just got
>>>> lucky and the paint on EDT executed while another
>>>> thread was in between the getDrawGraphics() and dispose().
>>> After the dispose() all rendering operations to a
>>>> graphics context become no-ops, so by definition you
>>>> would only see something rendered the paint event
>>>> happened to be while the graphics was still valid.
>>> Thank you,
>>>> Dmitri
>>>> Java2D Team
>
> ===========================================================================
> To unsubscribe, send email to listserv@java.sun.com and include in the body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Ken Warner

I'll have one available by tomorrow am.

Thanks for your time.

Ken

Dmitri Trembovetski wrote:
> If you can put together a complete test which shows
> that you can render to a Graphics object after it's
> been disposed (and stuff shows up in the destination),
> that would be a bug.
>
> If you can, please send the test over. Otherwise it
> is hard to tell what could be wrong.
>
> Thanks,
> Dmitri
>
>
> Ken Warner wrote:
>
>> Ken Warner wrote:
>>
>> According to the documentation on:
>> http://java.sun.com/javase/6/docs/api/java/awt/image/BufferStrategy.html
>>
>>
>> One is supposed to
>> do {
>> Graphics graphics = strategy.getDrawGraphics();
>> //render here
>> graphics.dispose();
>> } while (strategy.contentsRestored());
>>
>> So I did that where I render:
>> do {
>> do {
>> bg = (Graphics2D)bs.getDrawGraphics();
>> mis.newPixels(pixels, cm, 0, thisW); //MemoryImageSource
>> bg.drawImage(canvasImage, 0, 0, thisW, thisH, this);
>> bg.dispose();
>> } while (bs.contentsRestored());
>> bs.show();
>> } while (bs.contentsLost());
>>
>> So I'm disposing of bg -- the BufferStrategy graphics after I render.
>>
>> The question is --
>>
>> how come I can still use the buffer graphics (bg)
>> at other times to draw stuff.
>>
>> My applet draws onto the BufferStrategy (bs) in many other places at
>> various times. And it works after I have dispose()'ed of the
>> buffergraphics (bg) and the loop above is the only place I
>> getDrawGraphics();
>>
>> For example -- here's my paint() method -- no problem -- no drawGraphics.
>>
>> public void paint(Graphics g)
>> {
>> //System.err.println("paint()");
>> bg.drawImage(canvasImage, 0, 0, thisW, thisH, this);
>> bs.show();
>> }
>>
>> paint() should fail but it works just fine.
>>
>> I don't understand how paint can drawImage if bg is disposed.
>>
>> Ken
>>
>>
>> Dmitri Trembovetski wrote:
>>
>>>
>>>
>>> Ken Warner wrote:
>>>
>>>> Hi Dmitri,
>>
>> I don't call repaint() from my code ever. I have ignoreRepaint() set for
>>
>>>> the Canvas component. paint() is only called from the AWT eventloop on
>>>> expose and events like that -- do I understand that right?
>>
>> The loop below is called from my own looping thread when I get some
>>
>>>> newPixels for my MemoryImageSource. I have not seen any problems.
>>
>> But I know that my applet is not accelerated on my machine. It only
>>
>>>> has unaccelerated bitblt from the BufferStrategy. I can't test
>>>> real acceleration. My machine is too old.
>>
>> What I'm trying to say -- clumsily -- is that I believe that only one
>>
>>>> thread at a time could render to my buffer -- I think...
>>>
>>>
>>>
>>> OK.. Then what's the question, again? I'm sorry, I'm just
>>> not following.
>>>
>>> Thanks,
>>> Dmitri
>>>
>>>
>> Ken
>> Dmitri Trembovetski wrote:
>>
>>> Hi Ken,
>>>
>>>> first of all, rendering to the same graphics context from
>>>>
>>>>> multiple thread is not a good idea. Java2D does not
>>>>> guarantee thread safety, and doing so could
>>>>> lead to unpredictable results (and even crashes due
>>>>> to bugs in our code). So, please don't do that.
>>>>
>>>> As to your question why it "works" - you just got
>>>>
>>>>> lucky and the paint on EDT executed while another
>>>>> thread was in between the getDrawGraphics() and dispose().
>>>>
>>>> After the dispose() all rendering operations to a
>>>>
>>>>> graphics context become no-ops, so by definition you
>>>>> would only see something rendered the paint event
>>>>> happened to be while the graphics was still valid.
>>>>
>>>> Thank you,
>>>>
>>>>> Dmitri
>>>>> Java2D Team
>>
>>
>> ===========================================================================
>>
>> To unsubscribe, send email to listserv@java.sun.com and include in the
>> body
>> of the message "signoff JAVA2D-INTEREST". For general help, send
>> email to
>> listserv@java.sun.com and include in the body of the message "help".
>
>
> ===========================================================================
> To unsubscribe, send email to listserv@java.sun.com and include in the body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".
>
>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".