Canvas blowing up (was Re: JavaFX Media issues)

Scott Palmer swpalmer at
Fri Aug 9 09:17:37 PDT 2013

That's okay for a quick hack.  In the case of a video preview surface, I
will be explicitly setting the value for every pixel from a ByteBuffer.
 You could save the extra step of doing a rectFill or clearRect if you knew
that every pixel was about to be overwritten.  It's a reasonable
optimization.. but as a fix for this issue it's still only a half-fix hack.

"If pulses are not happening, we still need to remember these scribbles so
we can draw the right result."

No.  If pulses are not happening you need to block or force a pulse
somehow. Otherwise I don't see how having the unbounded queue is ever going
to be 100% reliable.

Since we are talking about painting to the Canvas surface as opposed to
directly modifying the scene graph, why does the painting have to happen
"later" when a pulse occurs?  It's not like you have any other thread
writing to the Canvas.  Why can't the Platform thread actually *do* the
scribbles,and the pulse just refreshes the portion of the Canvas that is
visible on the screen?  Is it some D3D/OpenGL multi-threading complication?



On Fri, Aug 9, 2013 at 11:43 AM, <steve.x.northover at> wrote:

> This is a great idea.  We should just enter a tweak and do it.  If the
> area that is being cleared is larger than the current size of the canvas,
> we can throw away all pending draw commands.
> Steve
> On 09/08/2013 11:23 AM, Richard Bair wrote:
>> I mean, it looks like it is working for a few seconds,
>>> but then as the memory fills with the Canvas backlog it can lead to the
>>> GC
>>> using a lot more CPU, thus reducing the ability for Canvas to process its
>>> command queue even further, well it just collapses in on itself  and
>>> dies.
>> Forking the thread.
>> The problem with Canvas is that if you have a canvas and you scribble on
>> it, and then scribble on it some more, and then scribble on it some more,
>> then in order for us to get the right result in the end, we need to replay
>> all those scribbles in order. If pulses are not happening, we still need to
>> remember these scribbles so we can draw the right result.
>> BUT, if you issue a command to the canvas which will cause it to "clear"
>> all its contents, then we could throw away any previously buffered data.
>> Right now the only way to do that would be a fillRect with a solid fill
>> where the fillRect encompasses the entire canvas area, or a clearRect where
>> the clearRect encompasses the entire canvas area.
>> This seems like a very simple fix. GraphicsContext.clearRect and
>> GraphicsContext.fillRect should both (under the right conditions) throw
>> away the previously buffered commands. Then all you have to do is be sure
>> to make one of these calls (likely just a clearRect) before each frame, and
>> we'll never buffer more than a single frame's worth of data. We could also
>> add a "clear" method which is "clearRect(0, 0, w, h)" to make this more
>> foolproof, and then document it as a best practice to clear the canvas
>> before each rendering if you intend to redraw the entire thing on each
>> frame.
>> If you're making use of manually operated "dirty rects" so that you only
>> clear the damaged area to repaint, then we couldn't employ this technique
>> and we'd have to buffer 'till kingdom come. So we still need a mechanism
>> exposed in the scene graph of "liveness" and associated events so that when
>> the scene is no longer live (for example, when minimized) you could stop
>> your animation timer, but for your specific media use case this isn't as
>> important.
>> Richard

More information about the openjfx-dev mailing list