larael / javacv

Automatically exported from code.google.com/p/javacv
GNU General Public License v2.0
0 stars 0 forks source link

CanvasFrame blanks out #212

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
CanvasFrame turns blank in certain situations. For instance on Windows 7 if you 
move frame between multiple monitors, its content disappears. On Ubuntu, 
CanvasFrame frequently starts blank, or the last open frame is blank.

Original issue reported on code.google.com by jarek.li...@gmail.com on 22 Jun 2012 at 1:18

GoogleCodeExporter commented 9 years ago
Can you check that it does not happen if we use BufferStrategy as in this 
tutorial?
http://docs.oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html
without the fullscreen flag obviously, thanks

Original comment by samuel.a...@gmail.com on 22 Jun 2012 at 9:00

GoogleCodeExporter commented 9 years ago
Just noticed that following the javadoc recommendation and setting 
-Dsun.java2d.opengl=True (Windows 7) leads to blank CanvasFrame from the start.

Interestingly if you disable DirectDraw, -Dsun.java2d.noddraw=true (Windows 7), 
you can move CanvasFrame between monitors without problems. In other words, a 
workaround for blank CanvasFrame on windows is to use -Dsun.java2d.noddraw=true 
on command line.

Original comment by jarek.li...@gmail.com on 23 Jun 2012 at 3:23

GoogleCodeExporter commented 9 years ago
Ok, but does this happen with BufferStrategy as used in the tutorial, or just 
with CanvasFrame?

Original comment by samuel.a...@gmail.com on 24 Jun 2012 at 1:28

GoogleCodeExporter commented 9 years ago
Not sure what you are asking about. Isn’t `CanvasFrame` using the 
`BufferStrategy`? Are you asking if it is using it correctly?

I am not sure if I completely follow what `CanvasFrame` does. In my case I am 
displaying a static image calling `showImage(…)`, like most of the OpenCV2 
Cookbook examples, which in certain situations shows a blank frame.

The puzzling part for me is `paint()` implemented in line 178 of `CanvasFrame`:
http://code.google.com/p/javacv/source/browse/src/main/java/com/googlecode/javac
v/CanvasFrame.java#178
It only calls to `bufferStrategy.show()`. `show()` makes next available buffer 
visible. The puzzle for me is that I do not see anything that creates buffer 
content. For instance, if you are using 2 buffers, call to `showImage(…)` 
first renders to a buffer provided by `BufferStrategy` then through call to 
`releaseGraphics()` calls `show()` that switches the buffers
http://code.google.com/p/javacv/source/browse/src/main/java/com/googlecode/javac
v/CanvasFrame.java#316
At this point image should be on the screen, but if for some reason 
`canvas.paint()` is called (line 178) an uninitialized buffer is shown on the 
screen, additionally screen buffer may be destroyed especially if hardware 
acceleration is used. It may be flipping empty buffers. I may be missing 
something, but I do not see anywhere in `CanvasFrame` a place where buffer 
content is recreated.

The tutorial may not be relevant in this scenario. It gives examples of 
infinite loop creation and displaying buffers. Situation here is that a buffer 
is rendered once and displayed but never recreated. Out of two buffers only one 
is rendered. It is not re-rendered even when it is invalidated. Am I missing 
something?

Original comment by jarek.li...@gmail.com on 24 Jun 2012 at 6:13

GoogleCodeExporter commented 9 years ago
Ah, I think I get it. You would it to buffer images like a JLabel or something? 
That incurs overhead, and we can use JLabel for that

Original comment by samuel.a...@gmail.com on 24 Jun 2012 at 6:38

GoogleCodeExporter commented 9 years ago
I do not mean JLabel.

Can you reproduce the issue?

The problem here is that when buffer content is lost (for instance a hardware 
accelerated CanvasFrame is maximized, moved between screens, ...), call to 
show() is not going to display anything, because the buffer no longer contains 
the rendered image. It has to be re-rendered.

To avoid overhead, simply check if the buffer still has correct content calling 
'bufferStrategy.contentsLost()' and render only if needed (as suggested by the 
tutorial).

To test this I have recreated CanvasFrame in the javacv.examples as 
CanvasFrameEx. Tested on Windows, works fine, `render()` is being called if 
content was lost. But does not work on Linux, there `contentLost()` is always 
`false`. There must be something else going on on Linux. On Linux adding 
-Dsun.java2d.opengl=True seems to improve things, but not completely, some 
images still start blank. The problem is intermittent, though frequent.

Compare CanvasFrameEx to its initial check in version that should be exactly 
the same as CanvasFrame, but some formatting.

Original comment by jarek.li...@gmail.com on 25 Jun 2012 at 12:00

GoogleCodeExporter commented 9 years ago
This still does not restore anything that is drawn manually in the 
BufferStrategy, so this would only confuse users further IMO...

Other than the obvious "sometimes the buffers get lost when shuffling things 
around" thing, I have no problem on Linux here with the NVIDIA drivers, but I 
wouldn't know for other drivers. Which graphics card are your using?

Original comment by samuel.a...@gmail.com on 25 Jun 2012 at 1:13

GoogleCodeExporter commented 9 years ago
Can you reproduce the issue on Linux?
Can you reproduce the issue on Windows?

CanvasFrameEx works perfect for me on Windows, CanvasFrame does not. 

Original comment by jarek.li...@gmail.com on 25 Jun 2012 at 2:57

GoogleCodeExporter commented 9 years ago
Yes, I am aware of this "issue" of losing the image. However, the NVIDIA 
drivers under Linux do not work as bad as you describe. I am guessing it's a 
bug in the video drivers you are using under Linux.

If you try to call CanvasFrameEx.createGraphics() and draw something with that, 
you will notice your drawings will disappear, so, no, it does not work 
perfectly... :(

Original comment by samuel.a...@gmail.com on 25 Jun 2012 at 2:01

GoogleCodeExporter commented 9 years ago
I figured out a workaround that doesn't impose additional overhead for the 
common case. Let me know if it works alright on your end, thanks!
http://javacv.googlecode.com/git/src/main/java/com/googlecode/javacv/CanvasFrame
.java

BTW, under Linux, you might want to try "-Dsun.java2d.xrender=True". It should 
work better since Linux video drivers tend to have good support for XRender...

Original comment by samuel.a...@gmail.com on 29 Jun 2012 at 2:13

GoogleCodeExporter commented 9 years ago
I've just released JavaCV 0.2. It should work better now as explained above. 
Let me know if you still have some problems though, thanks!

Original comment by samuel.a...@gmail.com on 22 Jul 2012 at 12:45