Skip to main content

SGRenderCache Update Bug

2 replies [Last post]
Anonymous

I found a bug in scenegraph where the cache would prevent update of
nested components in the case where there are translations and bounds
changes happening in parallel.

I've attached a stand-alone JavaFX Script example (CacheTest.fx) that
can be used to reproduce the problem. This example may seem contrived,
but it is actually distilled down from a real-world example I stumbled
on while developing WidgetFX, JavaFX Desktop Widget
Platform .

When you run the example notice that during the animation the blue
rectangle does not resize properly. To see the expected results, flip
the cache property to false and rerun the example.

Here is a candidate fix that solves this problem:
|--- src/com/sun/scenario/scenegraph/SGRenderCache.java (revision 306)
+++ src/com/sun/scenario/scenegraph/SGRenderCache.java (working copy)
@@ -187,7 +187,7 @@
@Override
void markDirty(int state) {
super.markDirty(state);
- if ((state & DIRTY_TRANSFORM) != 0) {
+ if (state == DIRTY_TRANSFORM) {
checkXform = true;
} else {
// TODO - mark the image dirty for VISUAL changes and reuse it|

My theory is that prior to this change, if you had a combination of
dirty flags (some for transform and some for bounds), it would be
treated as a transform dirty check. If this check passed, then it would
not clear the cache, resulting in a stale image.

I've also attached the fix as a patch file (cachefix.diff) that can be
applied to the scenegraph trunk.

Tell me if there is anything else I can do to help.

Cheers,
--Steve

[att1.html]
Index: src/com/sun/scenario/scenegraph/SGRenderCache.java
===================================================================
--- src/com/sun/scenario/scenegraph/SGRenderCache.java (revision 306)
+++ src/com/sun/scenario/scenegraph/SGRenderCache.java (working copy)
@@ -187,7 +187,7 @@
@Override
void markDirty(int state) {
super.markDirty(state);
- if ((state & DIRTY_TRANSFORM) != 0) {
+ if (state == DIRTY_TRANSFORM) {
checkXform = true;
} else {
// TODO - mark the image dirty for VISUAL changes and reuse it
/*
* CacheTest.fx
*
* Created on Jul 19, 2008, 8:10:25 PM
*/

package org.widgetfx;

import javafx.application.*;
import javafx.scene.*;
import javafx.animation.*;
import javafx.scene.paint.Color;
import javafx.scene.geometry.Rectangle;

/**
* Simple test case to exercise the scenegraph cache.
* This is not automated, because it depends on visual feedback.
* - Expected: The rectangle should resize with the window
* - Actual (before fix): The rectangle doesn't resize during animation
*
* @author Stephen Chin
*/
var width = 200;
var width2 = 200;

Timeline {
repeatCount: Timeline.INDEFINITE
autoReverse: true
keyFrames: [
KeyFrame {time: 1s, values: [
width => 400 tween Interpolator.EASEBOTH,
width2 => 400 tween Interpolator.EASEBOTH
]}
]
}.start();

Frame {
width: bind width
visible: true
stage: Stage {
content: [
Group {
cache: true
content: Rectangle {width: bind width2, height: 100, fill: Color.BLUE}
horizontalAlignment: HorizontalAlignment.CENTER
translateX: bind width / 2
}
]
}
}

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net

Reply viewing options

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

This will fix the situation at hand, but cause other problems. The test
for the TRANSFORM bit really does need to be a bit test as it can often
come with other bits set which are harmless with respect to whether or
not a transform check is sufficient. The problem is that there are
other bits which trump the transform check which are not noticed by this
test.

Your fix will correctly avoid the transform check optimization if
another bit is set which trumps this optimization, but it will also
remove the optimization if any other harmless bits are set.

What we need is more along the lines of:

if (TX bit is set && are not set) {
checkXform = true;
} ...

I'll have to do some investigation to figure out what those "worse bits"
are, but I'm catching up on 10 days of back email today... :-(

...jim

Stephen Chin wrote:
> I found a bug in scenegraph where the cache would prevent update of
> nested components in the case where there are translations and bounds
> changes happening in parallel.
>
> I've attached a stand-alone JavaFX Script example (CacheTest.fx) that
> can be used to reproduce the problem. This example may seem contrived,
> but it is actually distilled down from a real-world example I stumbled
> on while developing WidgetFX, JavaFX Desktop Widget
> Platform
.
>
> When you run the example notice that during the animation the blue
> rectangle does not resize properly. To see the expected results, flip
> the cache property to false and rerun the example.
>
> Here is a candidate fix that solves this problem:
> |--- src/com/sun/scenario/scenegraph/SGRenderCache.java (revision 306)
> +++ src/com/sun/scenario/scenegraph/SGRenderCache.java (working copy)
> @@ -187,7 +187,7 @@
> @Override
> void markDirty(int state) {
> super.markDirty(state);
> - if ((state & DIRTY_TRANSFORM) != 0) {
> + if (state == DIRTY_TRANSFORM) {
> checkXform = true;
> } else {
> // TODO - mark the image dirty for VISUAL changes and reuse it|
>
> My theory is that prior to this change, if you had a combination of
> dirty flags (some for transform and some for bounds), it would be
> treated as a transform dirty check. If this check passed, then it would
> not clear the cache, resulting in a stale image.
>
> I've also attached the fix as a patch file (cachefix.diff) that can be
> applied to the scenegraph trunk.
>
> Tell me if there is anything else I can do to help.
>
> Cheers,
> --Steve
>
>
>
> ------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
> For additional commands, e-mail: dev-help@scenegraph.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net

Stephen Chin

Thanks for picking this one up, Jim.

I was going for the simplest fix that would work, but did notice some
placeholders in the code for future work in this area.

I would be happy to run a more involved fix through my full application
if you want the additional validation.

Cheers,
--Steve
(from my work e-mail)

-----Original Message-----
From: Jim.A.Graham@Sun.COM [mailto:Jim.A.Graham@Sun.COM]
Sent: Monday, July 21, 2008 12:49 PM
To: dev@scenegraph.dev.java.net
Subject: Re: SGRenderCache Update Bug

This will fix the situation at hand, but cause other problems. The test

for the TRANSFORM bit really does need to be a bit test as it can often
come with other bits set which are harmless with respect to whether or
not a transform check is sufficient. The problem is that there are
other bits which trump the transform check which are not noticed by this

test.

Your fix will correctly avoid the transform check optimization if
another bit is set which trumps this optimization, but it will also
remove the optimization if any other harmless bits are set.

What we need is more along the lines of:

if (TX bit is set && are not set) {
checkXform = true;
} ...

I'll have to do some investigation to figure out what those "worse bits"

are, but I'm catching up on 10 days of back email today... :-(

...jim

Stephen Chin wrote:
> I found a bug in scenegraph where the cache would prevent update of
> nested components in the case where there are translations and bounds
> changes happening in parallel.
>
> I've attached a stand-alone JavaFX Script example (CacheTest.fx) that
> can be used to reproduce the problem. This example may seem
contrived,
> but it is actually distilled down from a real-world example I stumbled

> on while developing WidgetFX, JavaFX Desktop Widget
> Platform
.
>
> When you run the example notice that during the animation the blue
> rectangle does not resize properly. To see the expected results, flip

> the cache property to false and rerun the example.
>
> Here is a candidate fix that solves this problem:
> |--- src/com/sun/scenario/scenegraph/SGRenderCache.java (revision
306)
> +++ src/com/sun/scenario/scenegraph/SGRenderCache.java (working
copy)
> @@ -187,7 +187,7 @@
> @Override
> void markDirty(int state) {
> super.markDirty(state);
> - if ((state & DIRTY_TRANSFORM) != 0) {
> + if (state == DIRTY_TRANSFORM) {
> checkXform = true;
> } else {
> // TODO - mark the image dirty for VISUAL changes and
reuse it|
>
> My theory is that prior to this change, if you had a combination of
> dirty flags (some for transform and some for bounds), it would be
> treated as a transform dirty check. If this check passed, then it
would
> not clear the cache, resulting in a stale image.
>
> I've also attached the fix as a patch file (cachefix.diff) that can be

> applied to the scenegraph trunk.
>
> Tell me if there is anything else I can do to help.
>
> Cheers,
> --Steve
>
>
>
>
------------------------------------------------------------------------
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
> For additional commands, e-mail: dev-help@scenegraph.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@scenegraph.dev.java.net
For additional commands, e-mail: dev-help@scenegraph.dev.java.net