1 /*
   2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.sg.prism;
  27 
  28 import com.sun.javafx.geom.RectBounds;
  29 import com.sun.javafx.geom.transform.BaseTransform;
  30 import com.sun.javafx.geom.transform.GeneralTransform3D;
  31 import org.junit.Test;
  32 import static org.junit.Assert.assertEquals;
  33 import static org.junit.Assert.assertSame;
  34 import static org.junit.Assert.assertTrue;
  35 
  36 /**
  37  *
  38  */
  39 public class OcclusionCullingTest extends NGTestBase {
  40 
  41 
  42     @Test
  43     public void testRectangleOcclusion() {
  44         final TestNGRectangle root = createRectangle(0, 0, 50, 50);
  45         TestNGGroup group = createGroup(
  46                 createRectangle(0, 0, 100, 100), root);
  47         NodePath rootPath = new NodePath();
  48         group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
  49         TestGraphics g = new TestGraphics();
  50         g.setRenderRoot(rootPath);
  51         group.render(g);
  52         assertRoot(rootPath, root);
  53         checkRootRendering(group, rootPath);
  54     }
  55 
  56     @Test
  57     public void testGroupOcclusion() {
  58         final TestNGRectangle root = createRectangle(0, 0, 50, 50);
  59         TestNGGroup group = createGroup(createGroup(
  60                 createRectangle(0, 0, 100, 100)), createGroup(root));
  61         NodePath rootPath = new NodePath();
  62         group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
  63         TestGraphics g = new TestGraphics();
  64         g.setRenderRoot(rootPath);
  65         group.render(g);
  66         assertRoot(rootPath, root);
  67         checkRootRendering(group, rootPath);
  68     }
  69 
  70     @Test
  71     public void testRegionOcclusion() {
  72         final TestNGRegion root = createRegion(50, 50);
  73         TestNGGroup group = createGroup(
  74                 createRegion(100, 100), root);
  75         NodePath rootPath = new NodePath();
  76         group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
  77         TestGraphics g = new TestGraphics();
  78         g.setRenderRoot(rootPath);
  79         group.render(g);
  80         assertRoot(rootPath, root);
  81         checkRootRendering(group, rootPath);
  82     }
  83 
  84     @Test
  85     public void testPresetRegionOcclusion() {
  86         final TestNGRegion root = createRegion(100, 100);
  87         final TestNGRegion other = createRegion(50, 50);
  88         TestNGGroup group = createGroup(
  89                 root, other);
  90         other.setOpaqueInsets(30, 30, 0, 0);
  91         NodePath rootPath = new NodePath();
  92         group.getRenderRoot(rootPath, new RectBounds(20, 20, 30, 30), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
  93         TestGraphics g = new TestGraphics();
  94         g.setRenderRoot(rootPath);
  95         group.render(g);
  96         assertRoot(rootPath, root);
  97         checkRootRendering(group, rootPath);
  98     }
  99 
 100     @Test
 101     public void test2SameRectanglesOcclusion() {
 102         final TestNGRectangle root = createRectangle(10, 10, 100, 100);
 103         TestNGGroup group = createGroup(
 104                 createGroup(createRectangle(10, 10, 100, 100), createRectangle(20, 20, 20, 20)),
 105                 createGroup(root));
 106         NodePath rootPath = new NodePath();
 107         group.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 108         TestGraphics g = new TestGraphics();
 109         g.setRenderRoot(rootPath);
 110         group.render(g);
 111         assertRoot(rootPath, root);
 112         checkRootRendering(group, rootPath);
 113     }
 114 
 115     @Test
 116     public void test2SameRectanglesOcclusionWithRootNotDirty() {
 117         final TestNGRectangle root = createRectangle(10, 10, 100, 100);
 118         final TestNGGroup rootParent = createGroup(root);
 119         TestNGGroup group = createGroup(
 120                 createGroup(createRectangle(10, 10, 100, 100), createRectangle(20, 20, 20, 20)), rootParent);
 121 
 122         group.dirty =  NGNode.DirtyFlag.CLEAN; // need to clean default dirty flags
 123         rootParent.dirty = NGNode.DirtyFlag.CLEAN;
 124         rootParent.childDirty = false;
 125         root.dirty = NGNode.DirtyFlag.CLEAN;
 126         root.childDirty = false;
 127         NodePath rootPath = new NodePath();
 128         group.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 129         assertTrue(rootPath.isEmpty());
 130 
 131         final TestNGRectangle dirtySibling = createRectangle(0,0,10,10);
 132         rootParent.add(-1, dirtySibling);
 133         rootPath = new NodePath();
 134         group.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 135         assertRoot(rootPath, root);
 136     }
 137 
 138     @Test
 139     public void testTransparentRegionWithChildren() {
 140         final TestNGRectangle root = createRectangle(10, 10, 100, 100);
 141         final TestNGGroup rootParent = createGroup(root);
 142         TestNGRegion region = createTransparentRegion(0, 0, 100, 100,
 143                 createGroup(createRectangle(10, 10, 100, 100), createRectangle(20, 20, 20, 20)), rootParent);
 144 
 145         region.dirty =  NGNode.DirtyFlag.CLEAN; // need to clean default dirty flags
 146         rootParent.dirty = NGNode.DirtyFlag.CLEAN;
 147         rootParent.childDirty = false;
 148         root.dirty = NGNode.DirtyFlag.CLEAN;
 149         root.childDirty = false;
 150         NodePath rootPath = new NodePath();
 151         region.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 152         assertTrue(rootPath.isEmpty());
 153 
 154         final TestNGRectangle dirtySibling = createRectangle(0,0,10,10);
 155         rootParent.add(-1,dirtySibling);
 156         rootPath = new NodePath();
 157         region.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 158         assertRoot(rootPath, root);
 159     }
 160 
 161     @Test
 162     public void testOpaqueRegion() {
 163         final TestNGRectangle rect = createRectangle(10, 10, 100, 100);
 164         TestNGRegion region = createOpaqueRegion(0, 0, 200, 200, rect);
 165         TestNGGroup root = createGroup(region);
 166 
 167         NodePath rootPath = new NodePath();
 168         root.getRenderRoot(rootPath, new RectBounds(10, 10, 100, 100), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 169         assertRoot(rootPath, rect);
 170 
 171         rootPath.clear();
 172         root.getRenderRoot(rootPath, new RectBounds(5, 5, 150, 150), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 173         assertRoot(rootPath, region);
 174         TestGraphics g = new TestGraphics();
 175         g.setRenderRoot(rootPath);
 176         root.render(g);
 177         checkRootRendering(root, rootPath);
 178 
 179         rootPath.clear();
 180         root.getRenderRoot(rootPath, new RectBounds(-5, -5, 150, 150), -1, BaseTransform.IDENTITY_TRANSFORM, new GeneralTransform3D());
 181         assertRoot(rootPath, root);
 182     }
 183 
 184     private void checkRootRendering(TestNGNode node, NodePath root) {
 185         assertTrue(node.rendered());
 186         if (node instanceof TestNGGroup) {
 187             if (root.hasNext()) {
 188                 boolean foundRoot = false;
 189                 root.next();
 190                 for (NGNode p : ((TestNGGroup)node).getChildren()) {
 191                     TestNGNode n = (TestNGNode) p;
 192                     if (n == root.getCurrentNode()) {
 193                         foundRoot = true;
 194                         checkRootRendering(n, root);
 195                         continue;
 196                     }
 197                     checkRendered(n, foundRoot);
 198                 }
 199             } else {
 200                 for (NGNode p : ((TestNGGroup)node).getChildren()) {
 201                     checkRendered((TestNGNode)p, true);
 202                 }
 203             }
 204         }
 205     }
 206 
 207     private void checkRendered(TestNGNode node, boolean rendered) {
 208         assertEquals(rendered, node.rendered());
 209         if (node instanceof TestNGGroup) {
 210              for (NGNode p : ((TestNGGroup)node).getChildren()) {
 211                  checkRendered((TestNGNode)p, rendered);
 212              }
 213         }
 214     }
 215 
 216     private void assertRoot(NodePath rootPath, final NGNode root) {
 217         rootPath.reset();
 218         while(rootPath.hasNext()) {
 219             rootPath.next();
 220         }
 221         assertSame(root, rootPath.getCurrentNode());
 222         rootPath.reset();
 223     }
 224 
 225 
 226 }