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