Closed GoogleCodeExporter closed 9 years ago
I'm also getting a flood of this error:
ERROR [AWT-EventQueue-0] (BlackenPanel.java:290) - Dropped an paintComponent
update -- didn't come through refresh()
Original comment by jgmath2...@gmail.com
on 15 Sep 2012 at 6:08
I know what's going on.
An ancestor element is displaying itself with the expectation that the UI will
refresh itself.
I don't understand _why_, though. It really sounds like Swing is refusing to
double-buffer. Since Swing is supposed to double-buffer by default, that would
be severely broken on a number of levels.
Is this with Oracle's Java 7 or with the Apple's Java that ships with Mac OS X?
I thought I'd heard that Apple hadn't yet switched to Java 7.
Original comment by yam...@gmail.com
on 21 Sep 2012 at 4:41
Original comment by yam...@gmail.com
on 21 Sep 2012 at 5:01
I think I have fixed this issue.
Can you try out the version I have attached? (It's the "stumble" example.)
Thanks!
Steven Black
Original comment by yam...@gmail.com
on 21 Sep 2012 at 6:01
Attachments:
I ran the jar you made and the problem is still there. If I out of the window
and back I see the game for a moment then it goes back to grey.
I'm using Oracle's java 7 for OS X. It's not part of an OS X system update but
you can download it from Oracle.
I noticed that putting refresh_all=true; as the first line of
paintComponent(...) in BlackenPanel.java fixes the problem, but I'm assuming
there are performance implications there.
Original comment by jgmath2...@gmail.com
on 21 Sep 2012 at 6:37
The example I included should display _something_, but it may be a little
"glitchy". I'll include another attachment when I have the last of the issues
worked out.
Original comment by yam...@gmail.com
on 21 Sep 2012 at 6:50
Here's what your example looks like:
Original comment by jgmath2...@gmail.com
on 21 Sep 2012 at 10:49
Attachments:
Original comment by yam...@gmail.com
on 21 Sep 2012 at 1:51
The new example should not be putting out the "Dropped an paintComponent update
-- didn't come through refresh()" messages -- can you confirm that? Is it
throwing an exception now?
What is the exact output of (in a Terminal window):
which java ; java -version
The punctuation is first a semicolon (";") and then a single dash ("-").
Thanks!
Steven Black
Original comment by yam...@gmail.com
on 21 Sep 2012 at 1:57
In OS/X you set which java to use by going through java preferences, then the
OS sets up the symbolic links.
Here's the info:
jgauci-macbookpro:stumble-1.2-2012-09-21 jgauci$ which java
/usr/bin/java
jgauci-macbookpro:stumble-1.2-2012-09-21 jgauci$ java -version
java version "1.7.0_10-ea"
Java(TM) SE Runtime Environment (build 1.7.0_10-ea-b07)
Java HotSpot(TM) 64-Bit Server VM (build 23.6-b02, mixed mode)
Here's what the console prints when I run it:
jgauci-macbookpro:stumble-1.2-2012-09-21 jgauci$ java -jar
stumble-1.2-SNAPSHOT.jar
DEBUG [main] (SwingTerminal.java:751) - Setting font to null
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 93 ms / Average: 93 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 1 ms / Average: 47 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 62 ms / Average: 54 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 35 ms / Average: 44 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 71 ms / Average: 57 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 0 ms / Average: 28 ms
DEBUG [AWT-EventQueue-0] (EventListener.java:300) - Undefined Key:
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=157,keyText=Meta,keyChar=Undefined
keyChar,modifiers=Meta,extModifiers=Meta,keyLocation=KEY_LOCATION_LEFT,rawCode=0
,primaryLevelUnicode=0,scancode=0,extendedKeyCode=0x0] on
com.googlecode.blacken.swing.BlackenPanel[,0,0,1176x694,layout=java.awt.FlowLayo
ut,alignmentX=0.0,alignmentY=0.0,border=,flags=9,maximumSize=,minimumSize=,prefe
rredSize=]
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 38 ms / Average: 33 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 51 ms / Average: 42 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 23 ms / Average: 32 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 11 ms / Average: 21 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 10 ms / Average: 15 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 0 ms / Average: 7 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 15 ms / Average: 11 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 6 ms / Average: 8 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 13 ms / Average: 10 ms
INFO [AWT-EventQueue-0] (BlackenPanel.java:463) - Panel update speed: 0 ms / Average: 5 ms
I did some digging on my own and it looks like OS/X is clearing the panel each
frame before paintComponent is called. Maybe double buffering isn't supported
on macs? As I mentioned before, forcing refresh_all to true fixes it.
Original comment by jgmath2...@gmail.com
on 21 Sep 2012 at 3:35
Yes, actually you cannot prevent the OS from clearing your component before a
repaint in a cross-platform way. Look at this stackoverflow for more info:
http://stackoverflow.com/questions/3289336/swing-active-rendering-efficiency-or-
how-to-combine-active-rendering-with-gui-wi
Original comment by jgmath2...@gmail.com
on 21 Sep 2012 at 3:46
Sorry, somehow I missed your comment saying that refresh_all=true solved the
issue yesterday.
I've seen some other comments that point that perhaps double-buffering isn't
supported in Mac OS X -- Mac OS X compensates by being "accelerated."
With the refresh_all fix in place, are you generally getting a "Panel update
speed" that jumps between 0 and ~15 ms? (After start up.) Toward the end it
looks like that's what it is doing.
If that's the case then we're not seeing any slowdown. I can special-case Mac
OS X until I can track down the proper cross-platform way to tell if I need to
use this approach or not.
I'm already special-casing a Windows 7 vertical maximize bug. (It also shows up
with NetBeans.) I don't have the Windows-specific check in the version you're
using -- this is why the window contents flickers on mouse entry. (I'm going to
see if I can remove the flicker even in Windows as that flicker only started
showing up when I made a change for this bug.)
Good old Java, right once and test everywhere... :/
Original comment by yam...@gmail.com
on 21 Sep 2012 at 10:31
Actually I think a better approach would be to draw to an offscreen buffer and
in paintComponent just paint that buffer like they do in that stackoverflow
link I sent you. Basically you will end up implementing your own double
buffering, but then the OS is free to redraw the window when someone maximizes
it, shrinks it, etc. without paying a huge performance hit.
Original comment by jgmath2...@gmail.com
on 22 Sep 2012 at 4:31
Manual double-buffering like that is _super_ slow. Like 50 to 100x as slow.
(Instead of updates of 0-15ms it was ~0.3 seconds per frame.) The Blacken 1.0
line used manual double-buffering like that and only the fact that I totally
ignored refresh requests caused it to feel remotely responsive. Seriously.
And that's on Windows where they actualy normally do double-buffering. Even the
standard Mac OS X double-buffering is super slow in comparison -- they
recommend against any double-buffering and instead writing directly to the
screen. (Different Stack Overflow thread.)
It would be a massive step backward that would only (potentially) help the Mac
OS X space -- and if you're getting speeds of 0-15 ms I don't even know that it
would actually help that space. The whole reason they don't do double-buffering
by default in Mac OS X is that you're not supposed to need it. Why manually
implement something I'm not supposed to need?
With Blacken the OS isn't "free" to redraw the screen when it's resized anyway.
The screen is always refreshed completely on a resize -- because the font
and/or the number of rows or columns change. This means you just double the
performance impact of these operations because instead of doing it once, you're
doing it once and blitting the result.
That article you mentioned doesn't actually relate, as that's about combining
active rendering with widgets -- Blacken doesn't use any widgets. To further
highlight the issues with the buffer approach, that very article you mention
says, "The Mac implementation doesn't seem to support hardware acceleration
properly, which makes repainting the background image to the output window a
tedious task, depending of course on the size of the window."
With active rendering the rendering speed is nearly constant with the number of
cells on screen. Rendering in a very large window as fast as it is in a very
small window. This is something that is _not_ true once you start using a
manual buffer and blitting the results. (I was seeing a blit-size penalty when
I used the manual double-buffer approach.)
This is further backed up by Java gaming-related articles that also advocate
active rendering as being the only solution to good performance.
I've seen active rendering speeds average under 5 ms a frame. Okay, 15 ms is
three times that, but it is still better than manual double-buffering any day
of the week.
I'm going to make a new archive and I want you to try it and tell me the speeds.
Actually, I'm going to implement this first (the author is wrong about the need
to use BufferStrategy with Swing, but this bit looks useful):
http://jamesgames.org/resources/double_buffer/double_buffering_and_active_render
ing.html#OverridingRepaintManager
Original comment by yam...@gmail.com
on 23 Sep 2012 at 2:45
Well, overriding the repaint manager is definitely the way to stop refreshing
the window in a cross-platform manner.
A roguelike is sort of a poor fit of a totally actively rendered approach. I
looked at it, but in the end I think the partial active rendering I'm doing is
a better fit.
I get ~5 ms of slowdown copying the precomputed data so I can handle redraws
that are not triggered by the main game logic. (Regardless of window size.)
This gets me support for all of the rendering requests that are still passed
through when "setIgnoreRepaint(true)" is enabled -- in fact I don't know that
ignoring any repaint requests gain us anything anymore. (You saw these
"ignored" in the initial version.)
I may be able to cut some of that overhead but that's not enough to be a
priority right now.
Original comment by yam...@gmail.com
on 23 Sep 2012 at 3:30
Attachments:
Yeah, I was able to entirely remove the 5-6 ms overhead I had just added
working on this ticket.
Original comment by yam...@gmail.com
on 23 Sep 2012 at 4:01
I'm attaching what I'm about to check in.
It appears to be faster than before I started working on this ticket.
The Mac OS X fix is in place -- but only for Mac OS X. (Though when in place on
Windows it only decreased the speed by ~1-2 ms on the long cycles. -- Still
under 10 ms on average for me.)
The Windows 7 fix has also been set to only apply to Windows 7 and it has been
fixed so it doesn't visibly flicker the font as much.
Part of this fix included responding to more update events. What I'm checking
in now doesn't ignore any repaint requests. This should clear up some edge
conditions that were annoying.
Original comment by yam...@gmail.com
on 23 Sep 2012 at 7:51
Attachments:
There were some things that shook loose from the fixes around this ticket. I
had created some minor display issues that I wanted to resolve.
I'm attaching the current results of my work. With a full repaint it is now
averaging 5 ms.
More interestingly, I have a bug in the logic which only repaints a part of the
window, so even in Windows it is currently doing a full repaint.
How does it work for you? I have it marked "fixed" because I _think_ it is
fixed, but I'd love to mark it "verified" because it is confirmed that the
solution works well.
Cheers,
Steven Black
Original comment by yam...@gmail.com
on 24 Sep 2012 at 7:11
Attachments:
Nice! it looks like this version works fine.
Original comment by jgmath2...@gmail.com
on 24 Sep 2012 at 5:12
Fantastic!
Thanks again for helping me with this issue.
Original comment by yam...@gmail.com
on 25 Sep 2012 at 8:34
Original issue reported on code.google.com by
jgmath2...@gmail.com
on 15 Sep 2012 at 3:36Attachments: