diff options
author | Sven Göthel <[email protected]> | 2024-02-17 20:26:10 +0100 |
---|---|---|
committer | Sven Göthel <[email protected]> | 2024-02-17 20:26:10 +0100 |
commit | 8bb2f6dec8ab731b07387b947715fa1959c680e4 (patch) | |
tree | 673236ebd39cc69b05579522c118010571b205f4 /src/graphui/classes/jogamp/graph/ui/TreeTool.java | |
parent | 82288c112e910feae10ef3cfcded50e35395ed2b (diff) |
Bug 1489: Lock-Free Double-Buffered 'renderedShapes' causes data-race between rendering & input-edt, use synchronized tripple-buffering
Tripple-buffering _almost_ produces zero data-race collisions,
however .. it still does rarely -> hence synchronize on the used ArrayList<>.
This adds a minimal chance for blocking the input-EDT,
but gives correct code & results.
Double-buffered 'renderedShapes' was introduced to resolve Bug 1489
in commit 5f9fb7159fa33bc979e5050d384b6939658049bd
This solution is tested by passing '-swapInterval 0' via CommandlineOptions for FontView01, UIMediaGrid01 ..,
i.e. rendering faster than picking and hence provoking the data-race condition.
Diffstat (limited to 'src/graphui/classes/jogamp/graph/ui/TreeTool.java')
-rw-r--r-- | src/graphui/classes/jogamp/graph/ui/TreeTool.java | 46 |
1 files changed, 24 insertions, 22 deletions
diff --git a/src/graphui/classes/jogamp/graph/ui/TreeTool.java b/src/graphui/classes/jogamp/graph/ui/TreeTool.java index 1309775a0..d225ead1f 100644 --- a/src/graphui/classes/jogamp/graph/ui/TreeTool.java +++ b/src/graphui/classes/jogamp/graph/ui/TreeTool.java @@ -174,36 +174,38 @@ public class TreeTool { } } private static boolean forAllRenderedAscn(final Container cont, final PMVMatrix4f pmv, final Visitor2 v) { - final List<Shape> shapes = cont.getRenderedShapes(); boolean res = false; - - for(int i=0; !res && i<shapes.size(); ++i) { - final Shape s = shapes.get(i); - pmv.pushMv(); - s.applyMatToMv(pmv); - res = v.visit(s, pmv); - if( !res && s instanceof Container ) { - final Container c = (Container)s; - res = forAllRenderedAscn(c, pmv, v); + final List<Shape> shapes = cont.getRenderedShapes(); + synchronized( shapes ) { // tripple-buffering is just almost enough + for(int i=0; !res && i<shapes.size(); ++i) { + final Shape s = shapes.get(i); + pmv.pushMv(); + s.applyMatToMv(pmv); + res = v.visit(s, pmv); + if( !res && s instanceof Container ) { + final Container c = (Container)s; + res = forAllRenderedAscn(c, pmv, v); + } + pmv.popMv(); } - pmv.popMv(); } return res; } private static boolean forAllRenderedDesc(final Container cont, final PMVMatrix4f pmv, final Visitor2 v) { - final List<Shape> shapes = cont.getRenderedShapes(); boolean res = false; - - for(int i=shapes.size()-1; !res && i>=0; --i) { - final Shape s = shapes.get(i); - pmv.pushMv(); - s.applyMatToMv(pmv); - res = v.visit(s, pmv); - if( !res && s instanceof Container ) { - final Container c = (Container)s; - res = forAllRenderedDesc(c, pmv, v); + final List<Shape> shapes = cont.getRenderedShapes(); + synchronized( shapes ) { // tripple-buffering is just almost enough + for(int i=shapes.size()-1; !res && i>=0; --i) { + final Shape s = shapes.get(i); + pmv.pushMv(); + s.applyMatToMv(pmv); + res = v.visit(s, pmv); + if( !res && s instanceof Container ) { + final Container c = (Container)s; + res = forAllRenderedDesc(c, pmv, v); + } + pmv.popMv(); } - pmv.popMv(); } return res; } |