1 /*
   2  * Copyright (c) 2011, 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 test.com.sun.javafx.sg.prism;
  27 
  28 import javafx.scene.Group;
  29 import javafx.scene.Node;
  30 import javafx.scene.Scene;
  31 import javafx.scene.shape.Rectangle;
  32 import com.sun.javafx.geom.BaseBounds;
  33 import com.sun.javafx.geom.DirtyRegionContainer;
  34 import com.sun.javafx.geom.DirtyRegionPool;
  35 import com.sun.javafx.geom.RectBounds;
  36 import com.sun.javafx.geom.transform.BaseTransform;
  37 import com.sun.javafx.sg.prism.NGNode;
  38 import com.sun.javafx.sg.prism.NGNode;
  39 import com.sun.scenario.effect.Blend;
  40 import com.sun.scenario.effect.Bloom;
  41 import com.sun.scenario.effect.BoxBlur;
  42 import com.sun.scenario.effect.BoxShadow;
  43 import com.sun.scenario.effect.ColorAdjust;
  44 import com.sun.scenario.effect.Crop;
  45 import com.sun.scenario.effect.DropShadow;
  46 import com.sun.scenario.effect.Effect;
  47 import com.sun.scenario.effect.GaussianBlur;
  48 import com.sun.scenario.effect.GeneralShadow;
  49 import com.sun.scenario.effect.Glow;
  50 import com.sun.scenario.effect.InnerShadow;
  51 import com.sun.scenario.effect.MotionBlur;
  52 import com.sun.scenario.effect.Offset;
  53 import com.sun.scenario.effect.SepiaTone;
  54 import junit.framework.Assert;
  55 import org.junit.Test;
  56 
  57 public class EffectDirtyRegionTest {
  58 
  59     DirtyRegionContainer drc;
  60     DirtyRegionContainer drcExpected;
  61     DirtyRegionPool drp;
  62     Effect effect;
  63     NGNode g1bn;
  64     NGNode gbn;
  65 
  66     @Test
  67     public void dropShadowTest() {
  68         setupTest();
  69 
  70         effect = new DropShadow();
  71 
  72         drc.deriveWithNewRegions(new RectBounds[]
  73             {
  74                 new RectBounds(50, 50, 60, 60)
  75             });
  76         g1bn.setEffect(effect);
  77         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
  78         drcExpected.deriveWithNewRegions(new RectBounds[]
  79             {
  80                 new RectBounds(40, 40, 70, 70)
  81             });
  82         compareResult(drcExpected, drc);
  83 
  84         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
  85         gbn.setEffect(effect);
  86         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
  87         drcExpected.deriveWithNewRegions(new RectBounds[]
  88             {
  89                 new RectBounds(30, 30, 90, 90)
  90             });
  91         compareResult(drcExpected, drc);
  92     }
  93 
  94     @Test
  95     public void colorAdjustTest() {
  96         setupTest();
  97 
  98         effect = new ColorAdjust();
  99 
 100         drc.deriveWithNewRegions(new RectBounds[]
 101             {
 102                 new RectBounds(50, 50, 60, 60)
 103             });
 104         g1bn.setEffect(effect);
 105         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 106         drcExpected.deriveWithNewRegions(new RectBounds[]
 107             {
 108                 new RectBounds(50, 50, 60, 60)
 109             });
 110         compareResult(drcExpected, drc);
 111 
 112         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 113         gbn.setEffect(effect);
 114         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 115         drcExpected.deriveWithNewRegions(new RectBounds[]
 116             {
 117                 new RectBounds(50, 50, 60, 60),
 118                 new RectBounds(70, 70, 80, 80)
 119             });
 120         compareResult(drcExpected, drc);
 121     }
 122 
 123     @Test
 124     public void bloomTest() {
 125         setupTest();
 126 
 127         effect = new Bloom();
 128 
 129         drc.deriveWithNewRegions(new RectBounds[]
 130             {
 131                 new RectBounds(50, 50, 60, 60)
 132             });
 133         g1bn.setEffect(effect);
 134         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 135         drcExpected.deriveWithNewRegions(new RectBounds[]
 136             {
 137                 new RectBounds(50, 50, 60, 60)
 138             });
 139         compareResult(drcExpected, drc);
 140 
 141         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 142         gbn.setEffect(effect);
 143         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 144         drcExpected.deriveWithNewRegions(new RectBounds[]
 145             {
 146                 new RectBounds(50, 50, 80, 80)
 147             });
 148         compareResult(drcExpected, drc);
 149     }
 150 
 151     @Test
 152     public void blendTest() {
 153         setupTest();
 154 
 155         effect = new Blend(Blend.Mode.ADD, new DropShadow(), new ColorAdjust());
 156 
 157         drc.deriveWithNewRegions(new RectBounds[]
 158             {
 159                 new RectBounds(50, 50, 60, 60)
 160             });
 161         g1bn.setEffect(effect);
 162         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 163         drcExpected.deriveWithNewRegions(new RectBounds[]
 164             {
 165                 new RectBounds(40, 40, 70, 70)
 166             });
 167         compareResult(drcExpected, drc);
 168 
 169         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 170         gbn.setEffect(effect);
 171         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 172         drcExpected.deriveWithNewRegions(new RectBounds[]
 173             {
 174                 new RectBounds(30, 30, 90, 90)
 175             });
 176         compareResult(drcExpected, drc);
 177     }
 178 
 179     @Test
 180     public void boxBlurTest() {
 181         setupTest();
 182 
 183         effect = new BoxBlur(10, 5, 3);
 184 
 185         drc.deriveWithNewRegions(new RectBounds[]
 186             {
 187                 new RectBounds(50, 50, 60, 60)
 188             });
 189         g1bn.setEffect(effect);
 190         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 191         drcExpected.deriveWithNewRegions(new RectBounds[]
 192             {
 193                 new RectBounds(36, 44, 74, 66)
 194             });
 195         compareResult(drcExpected, drc);
 196 
 197         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 198         gbn.setEffect(effect);
 199         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 200         drcExpected.deriveWithNewRegions(new RectBounds[]
 201             {
 202                 new RectBounds(22, 38, 88, 72),
 203                 new RectBounds(56, 64, 94, 86)
 204             });
 205         compareResult(drcExpected, drc);
 206     }
 207 
 208     @Test
 209     public void gausianBlurTest() {
 210         setupTest();
 211 
 212         effect = new GaussianBlur(5);
 213 
 214         drc.deriveWithNewRegions(new RectBounds[]
 215             {
 216                 new RectBounds(50, 50, 60, 60)
 217             });
 218         g1bn.setEffect(effect);
 219         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 220         drcExpected.deriveWithNewRegions(new RectBounds[]
 221             {
 222                 new RectBounds(45, 45, 65, 65)
 223             });
 224         compareResult(drcExpected, drc);
 225 
 226         ((GaussianBlur)effect).setRadius(2);
 227         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 228         gbn.setEffect(effect);
 229         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 230         drcExpected.deriveWithNewRegions(new RectBounds[]
 231             {
 232                 new RectBounds(43, 43, 67, 67),
 233                 new RectBounds(68, 68, 82, 82)
 234             });
 235         compareResult(drcExpected, drc);
 236     }
 237 
 238     @Test
 239     public void glowTest() {
 240         setupTest();
 241 
 242         effect = new Glow();
 243 
 244         drc.deriveWithNewRegions(new RectBounds[]
 245             {
 246                 new RectBounds(50, 50, 60, 60)
 247             });
 248         g1bn.setEffect(effect);
 249         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 250         drcExpected.deriveWithNewRegions(new RectBounds[]
 251             {
 252                 new RectBounds(50, 50, 60, 60)
 253             });
 254         compareResult(drcExpected, drc);
 255 
 256         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 257         gbn.setEffect(effect);
 258         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 259         drcExpected.deriveWithNewRegions(new RectBounds[]
 260             {
 261                 new RectBounds(50, 50, 80, 80)
 262             });
 263         compareResult(drcExpected, drc);
 264     }
 265 
 266     @Test
 267     public void innerShadowTest() {
 268         setupTest();
 269 
 270         effect = new InnerShadow();
 271 
 272         drc.deriveWithNewRegions(new RectBounds[]
 273             {
 274                 new RectBounds(50, 50, 60, 60)
 275             });
 276         g1bn.setEffect(effect);
 277         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 278         drcExpected.deriveWithNewRegions(new RectBounds[]
 279             {
 280                 new RectBounds(40, 40, 70, 70)
 281             });
 282         compareResult(drcExpected, drc);
 283 
 284         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 285         gbn.setEffect(effect);
 286         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 287         drcExpected.deriveWithNewRegions(new RectBounds[]
 288             {
 289                 new RectBounds(30, 30, 90, 90)
 290             });
 291         compareResult(drcExpected, drc);
 292     }
 293 
 294     @Test
 295     public void motionBlurTest() {
 296         setupTest();
 297 
 298         effect = new MotionBlur();
 299 
 300         drc.deriveWithNewRegions(new RectBounds[]
 301             {
 302                 new RectBounds(50, 50, 60, 60)
 303             });
 304         g1bn.setEffect(effect);
 305         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 306         drcExpected.deriveWithNewRegions(new RectBounds[]
 307             {
 308                 new RectBounds(40, 50, 70, 60)
 309             });
 310         compareResult(drcExpected, drc);
 311 
 312         ((MotionBlur)effect).setAngle((float) Math.toRadians(90));
 313         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 314         gbn.setEffect(effect);
 315         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 316         drcExpected.deriveWithNewRegions(new RectBounds[]
 317             {
 318                 new RectBounds(39, 40, 71, 70),
 319                 new RectBounds(69, 60, 81, 90)
 320             });
 321         compareResult(drcExpected, drc);
 322     }
 323 
 324     @Test
 325     public void sepiaToneTest() {
 326         setupTest();
 327 
 328         effect = new SepiaTone();
 329 
 330         drc.deriveWithNewRegions(new RectBounds[]
 331             {
 332                 new RectBounds(50, 50, 60, 60)
 333             });
 334         g1bn.setEffect(effect);
 335         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 336         drcExpected.deriveWithNewRegions(new RectBounds[]
 337             {
 338                 new RectBounds(50, 50, 60, 60)
 339             });
 340         compareResult(drcExpected, drc);
 341 
 342         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 343         gbn.setEffect(effect);
 344         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 345         drcExpected.deriveWithNewRegions(new RectBounds[]
 346             {
 347                 new RectBounds(50, 50, 60, 60),
 348                 new RectBounds(70, 70, 80, 80)
 349             });
 350         compareResult(drcExpected, drc);
 351     }
 352 
 353     @Test
 354     public void boxShadowTest() {
 355         setupTest();
 356 
 357         effect = new BoxShadow();
 358         ((BoxShadow) effect).setHorizontalSize(10);
 359 
 360         drc.deriveWithNewRegions(new RectBounds[]
 361             {
 362                 new RectBounds(50, 50, 60, 60)
 363             });
 364         g1bn.setEffect(effect);
 365         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 366         drcExpected.deriveWithNewRegions(new RectBounds[]
 367             {
 368                 new RectBounds(45, 50, 65, 60)
 369             });
 370         compareResult(drcExpected, drc);
 371 
 372         ((BoxShadow) effect).setHorizontalSize(0);
 373         ((BoxShadow) effect).setVerticalSize(10);
 374         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 375         gbn.setEffect(effect);
 376         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 377         drcExpected.deriveWithNewRegions(new RectBounds[]
 378             {
 379                 new RectBounds(45, 45, 65, 65),
 380                 new RectBounds(70, 65, 80, 85)
 381             });
 382         compareResult(drcExpected, drc);
 383     }
 384 
 385     @Test
 386     public void generalShadowTest() {
 387         setupTest();
 388 
 389         effect = new GeneralShadow();
 390 
 391         drc.deriveWithNewRegions(new RectBounds[]
 392             {
 393                 new RectBounds(50, 50, 60, 60)
 394             });
 395         g1bn.setEffect(effect);
 396         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 397         drcExpected.deriveWithNewRegions(new RectBounds[]
 398             {
 399                 new RectBounds(40, 40, 70, 70)
 400             });
 401         compareResult(drcExpected, drc);
 402 
 403         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 404         gbn.setEffect(effect);
 405         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 406         drcExpected.deriveWithNewRegions(new RectBounds[]
 407             {
 408                 new RectBounds(30, 30, 90, 90)
 409             });
 410         compareResult(drcExpected, drc);
 411     }
 412 
 413     @Test
 414     public void cropTest() {
 415         setupTest();
 416 
 417         effect = new Crop(new DropShadow());
 418 
 419         drc.deriveWithNewRegions(new RectBounds[]
 420             {
 421                 new RectBounds(50, 50, 60, 60)
 422             });
 423         g1bn.setEffect(effect);
 424         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 425         drcExpected.deriveWithNewRegions(new RectBounds[]
 426             {
 427                 new RectBounds(50, 50, 60, 60)
 428             });
 429         compareResult(drcExpected, drc);
 430 
 431         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 432         gbn.setEffect(effect);
 433         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 434         drcExpected.deriveWithNewRegions(new RectBounds[]
 435             {
 436                 new RectBounds(50, 50, 80, 80)
 437             });
 438         compareResult(drcExpected, drc);
 439     }
 440 
 441     @Test
 442     public void offsetTest() {
 443         setupTest();
 444 
 445         effect = new Offset(10, -10, new DropShadow());
 446 
 447         drc.deriveWithNewRegions(new RectBounds[]
 448             {
 449                 new RectBounds(50, 50, 60, 60)
 450             });
 451         g1bn.setEffect(effect);
 452         g1bn.applyEffect(g1bn.getEffectFilter(), drc, drp);
 453         drcExpected.deriveWithNewRegions(new RectBounds[]
 454             {
 455                 new RectBounds(50, 30, 80, 60)
 456             });
 457         compareResult(drcExpected, drc);
 458 
 459         drc.addDirtyRegion(new RectBounds(70, 70, 80, 80));
 460         gbn.setEffect(effect);
 461         gbn.applyEffect(gbn.getEffectFilter(), drc, drp);
 462         drcExpected.deriveWithNewRegions(new RectBounds[]
 463             {
 464                 new RectBounds(50, 10, 100, 80)
 465             });
 466         compareResult(drcExpected, drc);
 467     }
 468 
 469     private void setupTest() {
 470         drc = new DirtyRegionContainer(6);
 471         drcExpected = new DirtyRegionContainer(6);
 472         drp = new DirtyRegionPool(4);
 473 
 474         Node g1 = group(new Rectangle(50, 50, 10, 10));
 475         g1bn = getBaseNode(g1);
 476         Node g = group(g1, new Rectangle(70, 70, 10, 10));
 477         gbn = getBaseNode(g);
 478     }
 479 
 480     private void compareResult(DirtyRegionContainer expected, DirtyRegionContainer computed) {
 481         for (int i = 0; i < computed.size(); i++) {
 482             Assert.assertEquals(expected.getDirtyRegion(i), computed.getDirtyRegion(i));
 483         }
 484     }
 485 
 486     public static NGNode getBaseNode(Node n) {
 487         Scene.impl_setAllowPGAccess(true);
 488         // Eeek, this is gross! I have to use reflection to invoke this
 489         // method so that bounds are updated...
 490         try {
 491             java.lang.reflect.Method method = Node.class.getDeclaredMethod("updateBounds");
 492             method.setAccessible(true);
 493             method.invoke(n);
 494         } catch (Exception e) {
 495             throw new RuntimeException("Failed to update bounds", e);
 496         }
 497         n.impl_updatePeer();
 498         NGNode bn = n.impl_getPeer();
 499         Scene.impl_setAllowPGAccess(false);
 500         return bn;
 501     }
 502 
 503     public static Node group(Node... n) {
 504         Group g = new Group(n);
 505         return g;
 506     }
 507 
 508     public static BaseBounds getBounds(Node n, BaseTransform tx) {
 509         NGNode pgn = getBaseNode(n);
 510         return pgn.getContentBounds(new RectBounds(), tx);
 511     }
 512 }