WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Patch
31885_patcht.txt (text/plain), 142.37 KB, created by
Simon Fraser (smfr)
on 2009-12-11 16:20:40 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2009-12-11 16:20:40 PST
Size:
142.37 KB
patch
obsolete
>diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index d1c5cab..457c212 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,5 +1,88 @@ > 2009-12-11 Simon Fraser <simon.fraser@apple.com> > >+ Reviewed by NOBODY (OOPS!). >+ >+ Support reflections on composited layers >+ https://bugs.webkit.org/show_bug.cgi?id=31885 >+ >+ Tests for reflections on compositing layers. >+ >+ * compositing/reflections/animation-inside-reflection.html: Added. >+ * compositing/reflections/compositing-change-inside-reflection.html: Added. >+ * compositing/reflections/deeply-nested-reflections.html: Added. >+ * compositing/reflections/masked-reflection-on-composited.html: Added. >+ * compositing/reflections/nested-reflection-anchor-point.html: Added. >+ * compositing/reflections/nested-reflection-animated.html: Added. >+ * compositing/reflections/nested-reflection-mask-change.html: Added. >+ * compositing/reflections/nested-reflection-on-overflow.html: Added. >+ * compositing/reflections/nested-reflection-opacity.html: Added. >+ * compositing/reflections/nested-reflection-size-change.html: Added. >+ * compositing/reflections/nested-reflection-transformed.html: Added. >+ * compositing/reflections/nested-reflection-transition.html: Added. >+ * compositing/reflections/nested-reflection.html: Added. >+ * compositing/reflections/reflection-on-composited.html: >+ * compositing/reflections/reflection-opacity.html: Added. >+ * compositing/reflections/reflection-ordering.html: Added. >+ * compositing/reflections/reflection-positioning.html: Added. >+ * compositing/reflections/reflection-testing.html: Added. >+ * compositing/reflections/transform-inside-reflection.html: Added. >+ * platform/mac/compositing/reflections/animation-inside-reflection-expected.checksum: Added. >+ * platform/mac/compositing/reflections/animation-inside-reflection-expected.png: Added. >+ * platform/mac/compositing/reflections/animation-inside-reflection-expected.txt: Added. >+ * platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.checksum: Added. >+ * platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.png: Added. >+ * platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.txt: Added. >+ * platform/mac/compositing/reflections/deeply-nested-reflections-expected.checksum: Added. >+ * platform/mac/compositing/reflections/deeply-nested-reflections-expected.png: Added. >+ * platform/mac/compositing/reflections/deeply-nested-reflections-expected.txt: Added. >+ * platform/mac/compositing/reflections/masked-reflection-on-composited-expected.checksum: Added. >+ * platform/mac/compositing/reflections/masked-reflection-on-composited-expected.png: Added. >+ * platform/mac/compositing/reflections/masked-reflection-on-composited-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-animated-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-animated-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-animated-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-mask-change-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-mask-change-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-mask-change-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-opacity-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-opacity-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-opacity-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-size-change-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-size-change-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-size-change-expected.txt: Added. >+ * platform/mac/compositing/reflections/nested-reflection-transition-expected.checksum: Added. >+ * platform/mac/compositing/reflections/nested-reflection-transition-expected.png: Added. >+ * platform/mac/compositing/reflections/nested-reflection-transition-expected.txt: Added. >+ * platform/mac/compositing/reflections/reflection-on-composited-expected.checksum: >+ * platform/mac/compositing/reflections/reflection-on-composited-expected.png: >+ * platform/mac/compositing/reflections/reflection-on-composited-expected.txt: >+ * platform/mac/compositing/reflections/reflection-opacity-expected.checksum: Added. >+ * platform/mac/compositing/reflections/reflection-opacity-expected.png: Added. >+ * platform/mac/compositing/reflections/reflection-opacity-expected.txt: Added. >+ * platform/mac/compositing/reflections/reflection-ordering-expected.checksum: Added. >+ * platform/mac/compositing/reflections/reflection-ordering-expected.png: Added. >+ * platform/mac/compositing/reflections/reflection-ordering-expected.txt: Added. >+ * platform/mac/compositing/reflections/reflection-positioning-expected.checksum: Added. >+ * platform/mac/compositing/reflections/reflection-positioning-expected.png: Added. >+ * platform/mac/compositing/reflections/reflection-positioning-expected.txt: Added. >+ * platform/mac/compositing/reflections/reflection-testing-expected.checksum: Added. >+ * platform/mac/compositing/reflections/reflection-testing-expected.png: Added. >+ * platform/mac/compositing/reflections/reflection-testing-expected.txt: Added. >+ * platform/mac/compositing/reflections/transform-inside-reflection-expected.checksum: Added. >+ * platform/mac/compositing/reflections/transform-inside-reflection-expected.png: Added. >+ * platform/mac/compositing/reflections/transform-inside-reflection-expected.txt: Added. >+ >+2009-12-11 Simon Fraser <simon.fraser@apple.com> >+ > Reviewed by Darin Adler. > > Negative values for animation-delay are ignored (treated as zero) >diff --git a/LayoutTests/compositing/reflections/animation-inside-reflection.html b/LayoutTests/compositing/reflections/animation-inside-reflection.html >new file mode 100644 >index 0000000..73e9e3e >--- /dev/null >+++ b/LayoutTests/compositing/reflections/animation-inside-reflection.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 240px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ text-align: center; >+ font-size: 50pt; >+ border: 2px solid blue; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ #animated { >+ margin: 10px; >+ width: 80px; >+ height: 80px; >+ background-color: green; >+ } >+ >+ #animated.animated { >+ -webkit-animation: swing 1s linear 1; >+ } >+ >+ /* for manual testing */ >+ #animated:hover { >+ -webkit-animation-play-state: paused; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ @-webkit-keyframes swing { >+ from { -webkit-transform: rotate(0deg); } >+ to { -webkit-transform: rotate(90deg); } >+ } >+ </style> >+ <script src="../../animations/animation-test-helpers.js" type="text/javascript" charset="utf-8"></script> >+ <script type="text/javascript" charset="utf-8"> >+ const expectedValues = [ >+ // [animation-name, time, element-id, property, expected-value, tolerance] >+ [null, 0.5, "animated", "webkitTransform.0", 0.76, 0.1], >+ ]; >+ >+ function startAnimation() >+ { >+ document.getElementById('animated').className = 'animated'; >+ } >+ >+ runAnimationTest(expectedValues, startAnimation, 'load', false, true /* pixel test */); >+ </script> >+ </head> >+<body> >+ <p>The top left box, and all reflections should be rotated 45deg.</p> >+ <div class="outer"> >+ <div id="inner" class="inner"> >+ <div id="animated"></div> >+ </div> >+ </div> >+ <div id="result"></div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/compositing-change-inside-reflection.html b/LayoutTests/compositing/reflections/compositing-change-inside-reflection.html >new file mode 100644 >index 0000000..85dfd45 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/compositing-change-inside-reflection.html >@@ -0,0 +1,66 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style type="text/css" media="screen"> >+ div { >+ -webkit-box-sizing: border-box; >+ } >+ .reflected { >+ position: absolute; >+ height: 120px; >+ width: 120px; >+ margin-bottom: 120px; >+ border: 1px solid black; >+ -webkit-box-reflect: below 2px; >+ } >+ >+ #inner { >+ height: 100px; >+ width: 100px; >+ margin: 10px; >+ background-color: green; >+ } >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ .container { >+ position: relative; >+ } >+ #indicator { >+ position: absolute; >+ top: 131px; >+ left: 11px; >+ height: 100px; >+ width: 100px; >+ background-color: red; >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ if (window.layoutTestController) >+ layoutTestController.waitUntilDone(); >+ >+ function doTest() >+ { >+ window.setTimeout(function() { >+ document.getElementById('inner').className = 'composited'; >+ if (window.layoutTestController) >+ layoutTestController.notifyDone(); >+ }, 0); >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+</head> >+<body> >+ >+<p>Test dynamically created compositing layer inside reflection. You should see no red below.</p> >+<div class="container"> >+ <div id="indicator"></div> >+ <div class="reflected compositing"> >+ <div id="inner"></div> >+ </div> >+</div> >+ >+</body> >+</html> >diff --git a/LayoutTests/compositing/reflections/deeply-nested-reflections.html b/LayoutTests/compositing/reflections/deeply-nested-reflections.html >new file mode 100644 >index 0000000..99c3d8d >--- /dev/null >+++ b/LayoutTests/compositing/reflections/deeply-nested-reflections.html >@@ -0,0 +1,72 @@ >+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" >+ "http://www.w3.org/TR/html4/strict.dtd"> >+ >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ >+ <style type="text/css" media="screen"> >+ >+ div { >+ -webkit-box-sizing: border-box; >+ border: 1px solid black; >+ margin: 2px; >+ } >+ >+ .level4 { >+ width: 234px; >+ height: 240px; >+ border-color: black; >+ -webkit-box-reflect: below 4px; >+ } >+ >+ .level3 { >+ width: 228px; >+ height: 234px; >+ border-color: orange; >+ -webkit-box-reflect: right 4px; >+ } >+ >+ .level2 { >+ width: 222px; >+ height: 112px; >+ border-color: blue; >+ -webkit-box-reflect: below 4px; >+ } >+ >+ .level1 { >+ width: 106px; >+ height: 106px; >+ border-color: red; >+ -webkit-box-reflect: right 4px; >+ } >+ >+ .box { >+ width: 100px; >+ height: 100px; >+ text-align: center; >+ font-size: 48pt; >+ background-color: green; >+ } >+ .compositing { >+ -webkit-transform: translateZ(0); >+ } >+ >+ </style> >+ >+</head> >+<body> >+ >+ <p>Deeply nested reflections.</p> >+ <div class="level4"> >+ <div class="level3"> >+ <div class="level2"> >+ <div class="level1"> >+ <div class="compositing box">C</div> >+ </div> >+ </div> >+ </div> >+ </div> >+ >+</body> >+</html> >diff --git a/LayoutTests/compositing/reflections/masked-reflection-on-composited.html b/LayoutTests/compositing/reflections/masked-reflection-on-composited.html >new file mode 100644 >index 0000000..dde9fee >--- /dev/null >+++ b/LayoutTests/compositing/reflections/masked-reflection-on-composited.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style type="text/css" media="screen"> >+ .box { >+ height: 100px; >+ width: 100px; >+ margin: 20px; >+ margin-bottom: 120px; >+ background-color: green; >+ } >+ >+ .reflected { >+ -webkit-box-reflect: below 2px >+ -webkit-gradient(linear, left top, left bottom, from(transparent), to(white)); >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ </style> >+</head> >+<body> >+ >+<p>Reflection should be masked with gradient.</p> >+<div class="reflected composited box"> >+</div> >+ >+</body> >+</html> >diff --git a/LayoutTests/compositing/reflections/nested-reflection-anchor-point.html b/LayoutTests/compositing/reflections/nested-reflection-anchor-point.html >new file mode 100644 >index 0000000..7f5a679 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-anchor-point.html >@@ -0,0 +1,52 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px 60px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ -webkit-transform: rotate3d(0, 0, 1, 20deg); >+ } >+ >+ .changed { >+ -webkit-transform-origin: top left; >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ if (window.layoutTestController) >+ layoutTestController.waitUntilDone(); >+ >+ function doTest() >+ { >+ window.setTimeout(function() { >+ document.getElementById('inner').className = 'inner composited changed'; >+ if (window.layoutTestController) >+ layoutTestController.notifyDone(); >+ }, 0); >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+ <p>Left and right sides should look symmetrical.</p> >+ <div class="outer composited"> >+ <div id="inner" class="inner composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection-animated.html b/LayoutTests/compositing/reflections/nested-reflection-animated.html >new file mode 100644 >index 0000000..1a972a4 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-animated.html >@@ -0,0 +1,65 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px 100px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .inner.animated { >+ -webkit-animation: swing 1s linear 1 alternate; >+ } >+ >+ .inner:hover { >+ -webkit-animation-play-state: paused; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ @-webkit-keyframes swing { >+ from { -webkit-transform: rotate(0deg); } >+ to { -webkit-transform: rotate(90deg); } >+ } >+ </style> >+ <script src="../../animations/animation-test-helpers.js" type="text/javascript" charset="utf-8"></script> >+ <script type="text/javascript" charset="utf-8"> >+ const expectedValues = [ >+ // [animation-name, time, element-id, property, expected-value, tolerance] >+ [null, 0.5, "inner", "webkitTransform.0", 0.76, 0.1], >+ ]; >+ >+ function startAnimation() >+ { >+ document.getElementById('inner').className = 'inner composited animated'; >+ } >+ >+ runAnimationTest(expectedValues, startAnimation, 'load', false, true /* pixel test */); >+ </script> >+ </head> >+<body> >+ <p>Animation on original and reflection should both be paused half way through, giving 45deg rotation.</p> >+ <div class="outer composited"> >+ <div id="inner" class="inner composited"> >+ 1 >+ </div> >+ </div> >+ <div id="result"></div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection-mask-change.html b/LayoutTests/compositing/reflections/nested-reflection-mask-change.html >new file mode 100644 >index 0000000..1b836de >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-mask-change.html >@@ -0,0 +1,55 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ .masked { >+ -webkit-mask: -webkit-gradient(linear, left top, right top, from(transparent), to(white)); >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ if (window.layoutTestController) >+ layoutTestController.waitUntilDone(); >+ >+ function doTest() >+ { >+ window.setTimeout(function() { >+ document.getElementById('inner').className = 'inner composited masked'; >+ if (window.layoutTestController) >+ layoutTestController.notifyDone(); >+ }, 0); >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+<p>The four green squares should all have the mask applied.</p> >+ <div class="outer box composited"> >+ <div id="inner" class="inner composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >diff --git a/LayoutTests/compositing/reflections/nested-reflection-on-overflow.html b/LayoutTests/compositing/reflections/nested-reflection-on-overflow.html >new file mode 100644 >index 0000000..cbf67ee >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-on-overflow.html >@@ -0,0 +1,48 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ .overflow { >+ position: relative; >+ overflow: scroll; >+ width: 100%; >+ height: 100%; >+ z-index: 0; >+ } >+ .content { >+ height: 500px; >+ } >+ </style> >+ </head> >+<body> >+<p>You should see the original and three copies of the green box with text.</p> >+ <div class="outer composited"> >+ <div class="inner composited"> >+ <div class="overflow"> >+ <div class="content composited">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</div> >+ </div> >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection-opacity.html b/LayoutTests/compositing/reflections/nested-reflection-opacity.html >new file mode 100644 >index 0000000..e37477b >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-opacity.html >@@ -0,0 +1,51 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ if (window.layoutTestController) >+ layoutTestController.waitUntilDone(); >+ >+ function doTest() >+ { >+ window.setTimeout(function() { >+ document.getElementById('inner').style.opacity = '0.5'; >+ if (window.layoutTestController) >+ layoutTestController.notifyDone(); >+ }, 0); >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+<p>The four green squares should look equally transparent.</p> >+ <div class="outer box composited"> >+ <div id="inner" class="inner box composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection-size-change.html b/LayoutTests/compositing/reflections/nested-reflection-size-change.html >new file mode 100644 >index 0000000..5a479d5 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-size-change.html >@@ -0,0 +1,55 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 140px; >+ height: 270px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .bigger { >+ width: 120px; >+ height: 120px; >+ } >+ .composited { >+ -webkit-transform: rotate3d(0, 0, 1, 0); >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ if (window.layoutTestController) >+ layoutTestController.waitUntilDone(); >+ >+ function doTest() >+ { >+ window.setTimeout(function() { >+ document.getElementById('inner').className = 'inner composited bigger'; >+ if (window.layoutTestController) >+ layoutTestController.notifyDone(); >+ }, 0); >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+<p>The four green squares should all be lined up.</p> >+ <div class="outer box composited"> >+ <div id="inner" class="inner box composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection-transformed.html b/LayoutTests/compositing/reflections/nested-reflection-transformed.html >new file mode 100644 >index 0000000..2d9af15 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-transformed.html >@@ -0,0 +1,44 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ function doTest() >+ { >+ document.getElementById('inner').style.webkitTransform = 'rotate(10deg)'; >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+ <p>Test transform change on reflected elements. Left and right side should be symmetrical.</p> >+ <div class="outer composited"> >+ <div id="inner" class="inner composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection-transition.html b/LayoutTests/compositing/reflections/nested-reflection-transition.html >new file mode 100644 >index 0000000..ab2c975 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection-transition.html >@@ -0,0 +1,62 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .reflected { >+ width: 100px; >+ height: 100px; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ #inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-transition: -webkit-transform 1s linear; >+ } >+ >+ .rotated { >+ -webkit-transform: rotate(90deg); >+ } >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ </style> >+ <script src="../../transitions/transition-test-helpers.js" type="text/javascript" charset="utf-8"></script> >+ <script type="text/javascript" charset="utf-8"> >+ >+ const expectedValues = [ >+ // [time, element-id, property, expected-value, tolerance] >+ [0.5, 'inner', '-webkit-transform.1', 0.76, 0.1], >+ ]; >+ >+ function setupTest() >+ { >+ document.getElementById('inner').className = 'rotated'; >+ } >+ runTransitionTest(expectedValues, setupTest, true /* use pause API */, true /* pixel test */); >+ </script> >+ </head> >+<body> >+ <div class="outer composited"> >+ <div class="reflected composited"> >+ <div id="inner"> >+ 1 >+ </div> >+ </div> >+ </div> >+ <div id="result"></div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/nested-reflection.html b/LayoutTests/compositing/reflections/nested-reflection.html >new file mode 100644 >index 0000000..027301c >--- /dev/null >+++ b/LayoutTests/compositing/reflections/nested-reflection.html >@@ -0,0 +1,38 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ </style> >+ </head> >+<body> >+<p>You should see the original and three copies of the blue box.</p> >+ <div class="outer composited"> >+ <div class="inner composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/reflection-on-composited.html b/LayoutTests/compositing/reflections/reflection-on-composited.html >index df69bee..185cefe 100644 >--- a/LayoutTests/compositing/reflections/reflection-on-composited.html >+++ b/LayoutTests/compositing/reflections/reflection-on-composited.html >@@ -14,8 +14,12 @@ > background-color: gray; > -webkit-box-reflect: below 2px; > } >+ .reflected:hover { >+ width: 216px; >+ -webkit-transform-origin: top left; >+ } > .transformed { >- -webkit-transform: rotate3d(0, 0, 1, 0); >+ -webkit-transform: rotate3d(0, 0, 1, 0deg); > } > </style> > </head> >@@ -23,9 +27,9 @@ > > <div class="transformed reflected">Here is some text</div> > >-<div id="container" class="transformed"> >+<!-- <div id="container" class="transformed"> > <div class="reflected">Here is some text</div> >-</div> >+</div> --> > > </body> > </html> >diff --git a/LayoutTests/compositing/reflections/reflection-opacity.html b/LayoutTests/compositing/reflections/reflection-opacity.html >new file mode 100644 >index 0000000..740c2f3 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/reflection-opacity.html >@@ -0,0 +1,36 @@ >+<!DOCTYPE HTML> >+<html> >+ <head> >+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"> >+ <style type="text/css" media="screen"> >+ >+ div { >+ -webkit-box-sizing: border-box; >+ } >+ .reflected { >+ position: relative; >+ width: 150px; >+ height: 100px; >+ background-color: green; >+ opacity: 0.5; >+ -webkit-box-reflect: below -50px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ function doTest() { >+ document.getElementById('inner').className = 'inner moved box'; >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+ >+ <p>Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and reflection should not be visible.</p> >+ <div class="reflected composited"> >+ </div> >+ >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/reflection-ordering.html b/LayoutTests/compositing/reflections/reflection-ordering.html >new file mode 100644 >index 0000000..86cb534 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/reflection-ordering.html >@@ -0,0 +1,32 @@ >+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >+ "http://www.w3.org/TR/html4/loose.dtd"> >+ >+<html lang="en"> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <title>Reflections Ordering</title> >+ <style type="text/css" media="screen"> >+ .reflected { >+ height: 100px; >+ width: 200px; >+ margin: 20px; >+ border: 10px solid black; >+ font-size: 18pt; >+ text-align: center; >+ background-color: white; >+ -webkit-transform: translateZ(0); >+ -webkit-box-reflect: below -80px; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ </style> >+</head> >+<body> >+ >+<p>You should see a black rectangle divided into two parts; the top part should be taller (reflection should be behind original).</p> >+<div class="reflected composited">Contents</div> >+ >+</body> >+</html> >diff --git a/LayoutTests/compositing/reflections/reflection-positioning.html b/LayoutTests/compositing/reflections/reflection-positioning.html >new file mode 100644 >index 0000000..46d4a91 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/reflection-positioning.html >@@ -0,0 +1,67 @@ >+<!DOCTYPE HTML> >+<html> >+ <head> >+ <meta http-equiv="Content-type" content="text/html; charset=utf-8"> >+ <style type="text/css" media="screen"> >+ >+ div { >+ -webkit-box-sizing: border-box; >+ } >+ .container { >+ position: absolute; >+ left: 20px; >+ top: 50px; >+ } >+ .reflected { >+ position: relative; >+ width: 150px; >+ height: 120px; >+ border: 1px solid black; >+ -webkit-box-reflect: below 6px; >+ } >+ >+ .box { >+ width: 100px; >+ height: 100px; >+ } >+ >+ .inner { >+ position: absolute; >+ top: 10px; >+ left: 10px; >+ background-color: green; >+ } >+ >+ .composited { >+ -webkit-transform: translateZ(0); >+ } >+ >+ .inner.moved { >+ left: 25px; >+ } >+ >+ #indicator { >+ position: absolute; >+ top: 135px; >+ left: 26px; >+ background-color: red; >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ function doTest() { >+ document.getElementById('inner').className = 'inner moved box'; >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+ >+ <p>Position of reflected layer should update correctly. You should see no red below.</p> >+ <div class="container"> >+ <div id="indicator" class="box"></div> >+ <div class="reflected composited"> >+ <div id="inner" class="inner box"> >+ </div> >+ </div> >+ </div> >+ >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/reflection-testing.html b/LayoutTests/compositing/reflections/reflection-testing.html >new file mode 100644 >index 0000000..f70e3ce >--- /dev/null >+++ b/LayoutTests/compositing/reflections/reflection-testing.html >@@ -0,0 +1,51 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ body { >+ height: 5000px; >+ } >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ position: relative; >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ body:hover .inner { >+ height: 200px; >+ } >+ >+ .composited { >+ -webkit-transform: rotate3d(0, 0, 1, 0); >+ } >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ function doTest() >+ { >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+<p>The four green squares should look equally transparent.</p> >+ <div class="outer box composited"> >+ <div id="inner" class="inner box composited"> >+ 1 >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/compositing/reflections/transform-inside-reflection.html b/LayoutTests/compositing/reflections/transform-inside-reflection.html >new file mode 100644 >index 0000000..1c627e2 >--- /dev/null >+++ b/LayoutTests/compositing/reflections/transform-inside-reflection.html >@@ -0,0 +1,48 @@ >+<!DOCTYPE html> >+<html> >+<head> >+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> >+ <style> >+ .outer { >+ width: 120px; >+ height: 230px; >+ margin: 20px; >+ border: 1px solid black; >+ -webkit-box-reflect: right 10px; >+ } >+ >+ .inner { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ border: 1px solid black; >+ -webkit-box-reflect: below 10px; >+ } >+ >+ #transformed { >+ margin: 10px; >+ width: 80px; >+ height: 80px; >+ background-color: green; >+ text-align: center; >+ font-size: 50pt; >+ } >+ >+ </style> >+ <script type="text/javascript" charset="utf-8"> >+ function doTest() >+ { >+ document.getElementById('transformed').style.webkitTransform = 'rotate3d(0, 0, 1, 10deg)'; >+ } >+ window.addEventListener('load', doTest, false); >+ </script> >+ </head> >+<body> >+ <p>Transform inside nested reflections should be applied correctly. You should see four rotated green boxes, as mirror images of each other.</p> >+ <div class="outer"> >+ <div id="inner" class="inner"> >+ <div id="transformed"></div> >+ </div> >+ </div> >+</body> >+</html> >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.checksum >new file mode 100644 >index 0000000..a5d07e8 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.checksum >@@ -0,0 +1 @@ >+ea33c0bbca464fee15d9631b1629f872 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.png b/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.png >new file mode 100644 >index 0000000..93bb217 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.txt b/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.txt >new file mode 100644 >index 0000000..cbf4f58 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/animation-inside-reflection-expected.txt >@@ -0,0 +1,18 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x342 >+ RenderBlock {HTML} at (0,0) size 800x342 >+ RenderBody {BODY} at (8,16) size 784x318 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 379x18 >+ text run at (0,0) width 379: "The top left box, and all reflections should be rotated 45deg." >+ RenderBlock {DIV} at (0,300) size 784x18 >+ RenderText {#text} at (0,0) size 625x18 >+ text run at (0,0) width 625: "PASS - \"webkitTransform.0\" property for \"animated\" element at 0.5s saw something close to: 0.76" >+ RenderBR {BR} at (625,0) size 0x18 >+layer at (28,54) size 122x242 >+ RenderBlock {DIV} at (20,38) size 122x242 [border: (1px solid #000000)] >+layer at (39,65) size 104x104 >+ RenderBlock {DIV} at (11,11) size 104x104 [border: (2px solid #0000FF)] >+layer at (51,77) size 80x80 >+ RenderBlock {DIV} at (12,12) size 80x80 [bgcolor=#008000] >diff --git a/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.checksum >new file mode 100644 >index 0000000..cfc3802 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.checksum >@@ -0,0 +1 @@ >+69c20dc2fc88b068c61207608eef0190 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.png b/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.png >new file mode 100644 >index 0000000..70ff394 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.txt b/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.txt >new file mode 100644 >index 0000000..bcd4edc >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/compositing-change-inside-reflection-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x50 >+ RenderBlock {HTML} at (0,0) size 800x50 >+ RenderBody {BODY} at (8,16) size 784x18 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 574x18 >+ text run at (0,0) width 574: "Test dynamically created compositing layer inside reflection. You should see no red below." >+layer at (19,181) size 100x100 >+ RenderBlock (positioned) {DIV} at (11,131) size 100x100 [bgcolor=#FF0000] >+layer at (8,50) size 120x120 >+ RenderBlock (positioned) {DIV} at (0,0) size 120x120 [border: (1px solid #000000)] >+layer at (19,61) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >diff --git a/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.checksum >new file mode 100644 >index 0000000..b3979d8 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.checksum >@@ -0,0 +1 @@ >+14aa41bab0c9af314a403bf555b276ab >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.png b/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.png >new file mode 100644 >index 0000000..30a1eac >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.txt b/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.txt >new file mode 100644 >index 0000000..41b3849 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/deeply-nested-reflections-expected.txt >@@ -0,0 +1,20 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x298 >+ RenderBlock {HTML} at (0,0) size 800x298 >+ RenderBody {BODY} at (8,16) size 784x274 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 163x18 >+ text run at (0,0) width 163: "Deeply nested reflections." >+layer at (10,50) size 234x240 >+ RenderBlock {DIV} at (2,34) size 234x240 [border: (1px solid #000000)] >+layer at (13,53) size 228x234 >+ RenderBlock {DIV} at (3,3) size 228x234 [border: (1px solid #FFA500)] >+layer at (16,56) size 222x112 >+ RenderBlock {DIV} at (3,3) size 222x112 [border: (1px solid #0000FF)] >+layer at (19,59) size 106x106 >+ RenderBlock {DIV} at (3,3) size 106x106 [border: (1px solid #FF0000)] >+layer at (22,62) size 100x100 >+ RenderBlock {DIV} at (3,3) size 100x100 [bgcolor=#008000] [border: (1px solid #000000)] >+ RenderText {#text} at (28,1) size 43x74 >+ text run at (28,1) width 43: "C" >diff --git a/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.checksum >new file mode 100644 >index 0000000..78b8f57 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.checksum >@@ -0,0 +1 @@ >+15849b2e215bbc6fb5a526d8867f4b71 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.png b/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.png >new file mode 100644 >index 0000000..e59e4c4 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.txt b/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.txt >new file mode 100644 >index 0000000..20021c0 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/masked-reflection-on-composited-expected.txt >@@ -0,0 +1,10 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x274 >+ RenderBlock {HTML} at (0,0) size 800x274 >+ RenderBody {BODY} at (8,16) size 784x138 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 273x18 >+ text run at (0,0) width 273: "Reflection should be masked with gradient." >+layer at (28,54) size 100x100 >+ RenderBlock {DIV} at (20,38) size 100x100 [bgcolor=#008000] >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.checksum >new file mode 100644 >index 0000000..29f40c6 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.checksum >@@ -0,0 +1 @@ >+ac58aeca26db80e701f0069fe38a9a57 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.png >new file mode 100644 >index 0000000..e8b0e07 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.txt >new file mode 100644 >index 0000000..9ad0675 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-anchor-point-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x306 >+ RenderBlock {HTML} at (0,0) size 800x306 >+ RenderBody {BODY} at (8,16) size 784x270 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 283x18 >+ text run at (0,0) width 283: "Left and right sides should look symmetrical." >+layer at (68,54) size 122x232 >+ RenderBlock {DIV} at (60,38) size 122x232 [border: (1px solid #000000)] >+layer at (79,65) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.checksum >new file mode 100644 >index 0000000..3097b9d >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.checksum >@@ -0,0 +1 @@ >+ed1d81654bf1f288636073e7e01f42f9 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.png >new file mode 100644 >index 0000000..131750b >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.txt >new file mode 100644 >index 0000000..e7781f4 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-animated-expected.txt >@@ -0,0 +1,18 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x332 >+ RenderBlock {HTML} at (0,0) size 800x332 >+ RenderBody {BODY} at (8,16) size 784x308 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 633x18 >+ text run at (0,0) width 633: "Animation on original and reflection should both be paused half way through, giving 45deg rotation." >+ RenderBlock {DIV} at (0,290) size 784x18 >+ RenderText {#text} at (0,0) size 600x18 >+ text run at (0,0) width 600: "PASS - \"webkitTransform.0\" property for \"inner\" element at 0.5s saw something close to: 0.76" >+ RenderBR {BR} at (600,0) size 0x18 >+layer at (108,54) size 122x232 >+ RenderBlock {DIV} at (100,38) size 122x232 [border: (1px solid #000000)] >+layer at (119,65) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.checksum >new file mode 100644 >index 0000000..53207c6 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.checksum >@@ -0,0 +1 @@ >+eed68807ff77668f5488a4ef8f1c60ee >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.png >new file mode 100644 >index 0000000..ebd1d7e >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.txt >new file mode 100644 >index 0000000..94e3c73 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x306 >+ RenderBlock {HTML} at (0,0) size 800x306 >+ RenderBody {BODY} at (8,16) size 784x270 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 382x18 >+ text run at (0,0) width 382: "You should see the original and three copies of the blue box." >+layer at (28,54) size 122x232 >+ RenderBlock {DIV} at (20,38) size 122x232 [border: (1px solid #000000)] >+layer at (39,65) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.checksum >new file mode 100644 >index 0000000..ae08179 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.checksum >@@ -0,0 +1 @@ >+be1c6ffd368b11f86c851a525932f8bd >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.png >new file mode 100644 >index 0000000..0a739f6 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.txt >new file mode 100644 >index 0000000..fb3db39 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-mask-change-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x306 >+ RenderBlock {HTML} at (0,0) size 800x306 >+ RenderBody {BODY} at (8,16) size 784x270 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 358x18 >+ text run at (0,0) width 358: "The four green squares should all have the mask applied." >+layer at (28,54) size 122x232 >+ RenderBlock {DIV} at (20,38) size 122x232 [border: (1px solid #000000)] >+layer at (39,65) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.checksum >new file mode 100644 >index 0000000..220dc60 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.checksum >@@ -0,0 +1 @@ >+e2d1e67675cb568e4f0d4b1cda8b3c60 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.png >new file mode 100644 >index 0000000..48c90ba >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.txt >new file mode 100644 >index 0000000..44adf53 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-on-overflow-expected.txt >@@ -0,0 +1,40 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x306 >+ RenderBlock {HTML} at (0,0) size 800x306 >+ RenderBody {BODY} at (8,16) size 784x270 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 449x18 >+ text run at (0,0) width 449: "You should see the original and three copies of the green box with text." >+layer at (28,54) size 122x232 >+ RenderBlock {DIV} at (20,38) size 122x232 [border: (1px solid #000000)] >+layer at (39,65) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+layer at (39,65) size 100x100 clip at (39,65) size 85x85 scrollHeight 500 >+ RenderBlock (relative positioned) {DIV} at (0,0) size 100x100 >+layer at (39,65) size 85x500 backgroundClip at (39,65) size 85x85 clip at (39,65) size 85x85 outlineClip at (39,65) size 85x85 >+ RenderBlock {DIV} at (0,0) size 85x500 >+ RenderText {#text} at (0,0) size 84x414 >+ text run at (0,0) width 84: "Lorem ipsum" >+ text run at (0,18) width 51: "dolor sit" >+ text run at (0,36) width 34: "amet," >+ text run at (0,54) width 71: "consectetur" >+ text run at (0,72) width 68: "adipisicing" >+ text run at (0,90) width 68: "elit, sed do" >+ text run at (0,108) width 53: "eiusmod" >+ text run at (0,126) width 44: "tempor" >+ text run at (0,144) width 79: "incididunt ut" >+ text run at (0,162) width 54: "labore et" >+ text run at (0,180) width 40: "dolore" >+ text run at (0,198) width 42: "magna" >+ text run at (0,216) width 62: "aliqua. Ut" >+ text run at (0,234) width 50: "enim ad" >+ text run at (0,252) width 40: "minim" >+ text run at (0,270) width 80: "veniam, quis" >+ text run at (0,288) width 47: "nostrud" >+ text run at (0,306) width 73: "exercitation" >+ text run at (0,324) width 50: "ullamco" >+ text run at (0,342) width 84: "laboris nisi ut" >+ text run at (0,360) width 80: "aliquip ex ea" >+ text run at (0,378) width 63: "commodo" >+ text run at (0,396) width 67: "consequat." >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.checksum >new file mode 100644 >index 0000000..a5f32d0 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.checksum >@@ -0,0 +1 @@ >+78648ad1c5504cbfce7d01f8237d6d5e >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.png >new file mode 100644 >index 0000000..79e0e0f >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.txt >new file mode 100644 >index 0000000..e8d074b >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-opacity-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x306 >+ RenderBlock {HTML} at (0,0) size 800x306 >+ RenderBody {BODY} at (8,16) size 784x270 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 350x18 >+ text run at (0,0) width 350: "The four green squares should look equally transparent." >+layer at (28,54) size 122x232 >+ RenderBlock {DIV} at (20,38) size 122x232 [border: (1px solid #000000)] >+layer at (39,65) size 100x100 >+ RenderBlock {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.checksum >new file mode 100644 >index 0000000..2baaa1a >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.checksum >@@ -0,0 +1 @@ >+2604f00941aac6e26ba2b5cdd7901fd3 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.png >new file mode 100644 >index 0000000..175c3bc >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.txt >new file mode 100644 >index 0000000..906f630 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-size-change-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x346 >+ RenderBlock {HTML} at (0,0) size 800x346 >+ RenderBody {BODY} at (8,16) size 784x310 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 288x18 >+ text run at (0,0) width 288: "The four green squares should all be lined up." >+layer at (28,54) size 142x272 >+ RenderBlock {DIV} at (20,38) size 142x272 [border: (1px solid #000000)] >+layer at (39,65) size 120x120 >+ RenderBlock {DIV} at (11,11) size 120x120 [bgcolor=#008000] >+ RenderText {#text} at (43,0) size 34x77 >+ text run at (43,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.checksum >new file mode 100644 >index 0000000..f354c22 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.checksum >@@ -0,0 +1 @@ >+8ddce67d9714a9b649ebc1127d6d6fee >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.png b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.png >new file mode 100644 >index 0000000..6aa1879 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.txt b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.txt >new file mode 100644 >index 0000000..cdca8b5 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/nested-reflection-transition-expected.txt >@@ -0,0 +1,17 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x298 >+ RenderBlock {HTML} at (0,0) size 800x298 >+ RenderBody {BODY} at (8,20) size 784x270 >+ RenderBlock {DIV} at (0,252) size 784x18 >+ RenderText {#text} at (0,0) size 604x18 >+ text run at (0,0) width 604: "PASS - \"-webkit-transform.1\" property for \"inner\" element at 0.5s saw something close to: 0.76" >+ RenderBR {BR} at (604,0) size 0x18 >+layer at (28,20) size 122x232 >+ RenderBlock {DIV} at (20,0) size 122x232 [border: (1px solid #000000)] >+layer at (29,31) size 100x100 >+ RenderBlock {DIV} at (1,11) size 100x100 >+layer at (39,31) size 100x100 >+ RenderBlock {DIV} at (10,0) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.checksum >index 6c061f3..ba175c7 100644 >--- a/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.checksum >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.checksum >@@ -1 +1 @@ >-c34a4726ede3579f9374d4abc97b0209 >\ No newline at end of file >+216f3ee1f00a4e8ebf05229adb132276 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.png b/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.png >index b21997c..ea9cf99 100644 >Binary files a/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.png and b/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.txt b/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.txt >index 2f83929..46b65f5 100644 >--- a/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.txt >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-on-composited-expected.txt >@@ -1,15 +1,9 @@ > layer at (0,0) size 800x600 > RenderView at (0,0) size 800x600 >-layer at (0,0) size 800x460 >- RenderBlock {HTML} at (0,0) size 800x460 >- RenderBody {BODY} at (8,20) size 784x320 >+layer at (0,0) size 800x240 >+ RenderBlock {HTML} at (0,0) size 800x240 >+ RenderBody {BODY} at (8,20) size 784x100 > layer at (28,20) size 200x100 > RenderBlock {DIV} at (20,0) size 200x100 [bgcolor=#808080] > RenderText {#text} at (0,0) size 109x18 > text run at (0,0) width 109: "Here is some text" >-layer at (8,240) size 784x100 >- RenderBlock {DIV} at (0,220) size 784x100 >-layer at (28,240) size 200x100 >- RenderBlock {DIV} at (20,0) size 200x100 [bgcolor=#808080] >- RenderText {#text} at (0,0) size 109x18 >- text run at (0,0) width 109: "Here is some text" >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.checksum >new file mode 100644 >index 0000000..5be42f8 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.checksum >@@ -0,0 +1 @@ >+f4cbdf8ddfceb02d9676acc0b099f5c3 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.png b/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.png >new file mode 100644 >index 0000000..b3da2a2 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.txt b/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.txt >new file mode 100644 >index 0000000..9460a00 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-opacity-expected.txt >@@ -0,0 +1,12 @@ >+CONSOLE MESSAGE: line 26: TypeError: Result of expression 'document.getElementById('inner')' [null] is not an object. >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x176 >+ RenderBlock {HTML} at (0,0) size 800x176 >+ RenderBody {BODY} at (8,16) size 784x152 >+ RenderBlock {P} at (0,0) size 784x36 >+ RenderText {#text} at (0,0) size 777x36 >+ text run at (0,0) width 777: "Opacity should be applied after reflection, so you should see a green rectangle below. The overlap between the original and" >+ text run at (0,18) width 197: "reflection should not be visible." >+layer at (8,68) size 150x100 >+ RenderBlock (relative positioned) {DIV} at (0,52) size 150x100 [bgcolor=#008000] >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.checksum >new file mode 100644 >index 0000000..fb08bb8 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.checksum >@@ -0,0 +1 @@ >+bed35423b662d03dcbca0a54ea6d0068 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.png b/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.png >new file mode 100644 >index 0000000..4362c40 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.txt b/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.txt >new file mode 100644 >index 0000000..22f6ced >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-ordering-expected.txt >@@ -0,0 +1,12 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x194 >+ RenderBlock {HTML} at (0,0) size 800x194 >+ RenderBody {BODY} at (8,16) size 784x158 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 769x18 >+ text run at (0,0) width 769: "You should see a black rectangle divided into two parts; the top part should be taller (reflection should be behind original)." >+layer at (28,54) size 220x120 >+ RenderBlock {DIV} at (20,38) size 220x120 [bgcolor=#FFFFFF] [border: (10px solid #000000)] >+ RenderText {#text} at (67,10) size 86x28 >+ text run at (67,10) width 86: "Contents" >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.checksum >new file mode 100644 >index 0000000..fc6d50e >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.checksum >@@ -0,0 +1 @@ >+d91382247bac1f2beb87462ae8ee1b1c >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.png b/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.png >new file mode 100644 >index 0000000..c865535 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.txt b/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.txt >new file mode 100644 >index 0000000..24a810e >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-positioning-expected.txt >@@ -0,0 +1,16 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x50 >+ RenderBlock {HTML} at (0,0) size 800x50 >+ RenderBody {BODY} at (8,16) size 784x18 >+ RenderBlock {P} at (0,0) size 784x18 >+ RenderText {#text} at (0,0) size 509x18 >+ text run at (0,0) width 509: "Position of reflected layer should update correctly. You should see no red below." >+layer at (20,50) size 150x120 >+ RenderBlock (positioned) {DIV} at (20,50) size 150x120 >+layer at (46,185) size 100x100 >+ RenderBlock (positioned) {DIV} at (26,135) size 100x100 [bgcolor=#FF0000] >+layer at (20,50) size 150x120 >+ RenderBlock (relative positioned) {DIV} at (0,0) size 150x120 [border: (1px solid #000000)] >+layer at (46,61) size 100x100 >+ RenderBlock (positioned) {DIV} at (26,11) size 100x100 [bgcolor=#008000] >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.checksum >new file mode 100644 >index 0000000..eeff3d2 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.checksum >@@ -0,0 +1 @@ >+998ed1ee344270e3be42bad3caeeb984 >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.png b/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.png >new file mode 100644 >index 0000000..3bacbbd >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.txt b/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.txt >new file mode 100644 >index 0000000..dcfbdb1 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/reflection-testing-expected.txt >@@ -0,0 +1,14 @@ >+layer at (0,0) size 785x5024 >+ RenderView at (0,0) size 785x600 >+layer at (0,0) size 785x5024 >+ RenderBlock {HTML} at (0,0) size 785x5024 >+ RenderBody {BODY} at (8,16) size 769x5000 >+ RenderBlock {P} at (0,0) size 769x18 >+ RenderText {#text} at (0,0) size 350x18 >+ text run at (0,0) width 350: "The four green squares should look equally transparent." >+layer at (28,54) size 122x232 >+ RenderBlock {DIV} at (20,38) size 122x232 [border: (1px solid #000000)] >+layer at (39,65) size 100x100 >+ RenderBlock (relative positioned) {DIV} at (11,11) size 100x100 [bgcolor=#008000] >+ RenderText {#text} at (33,0) size 34x77 >+ text run at (33,0) width 34: "1" >diff --git a/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.checksum >new file mode 100644 >index 0000000..3417b43 >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.checksum >@@ -0,0 +1 @@ >+bdecf46beb596b45dbe5137c2405510c >\ No newline at end of file >diff --git a/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.png b/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.png >new file mode 100644 >index 0000000..b65a366 >Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.png differ >diff --git a/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.txt b/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.txt >new file mode 100644 >index 0000000..6d8850b >--- /dev/null >+++ b/LayoutTests/platform/mac/compositing/reflections/transform-inside-reflection-expected.txt >@@ -0,0 +1,15 @@ >+layer at (0,0) size 800x600 >+ RenderView at (0,0) size 800x600 >+layer at (0,0) size 800x324 >+ RenderBlock {HTML} at (0,0) size 800x324 >+ RenderBody {BODY} at (8,16) size 784x288 >+ RenderBlock {P} at (0,0) size 784x36 >+ RenderText {#text} at (0,0) size 769x36 >+ text run at (0,0) width 769: "Transform inside nested reflections should be applied correctly. You should see four rotated green boxes, as mirror images" >+ text run at (0,18) width 86: "of each other." >+layer at (28,72) size 122x232 >+ RenderBlock {DIV} at (20,56) size 122x232 [border: (1px solid #000000)] >+layer at (39,83) size 102x102 >+ RenderBlock {DIV} at (11,11) size 102x102 [border: (1px solid #000000)] >+layer at (50,94) size 80x80 >+ RenderBlock {DIV} at (11,11) size 80x80 [bgcolor=#008000] >diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog >index 24bc842..3887dc3 100644 >--- a/WebCore/ChangeLog >+++ b/WebCore/ChangeLog >@@ -1,5 +1,254 @@ > 2009-12-11 Simon Fraser <simon.fraser@apple.com> > >+ Reviewed by NOBODY (OOPS!). >+ >+ Support reflections on composited layers >+ https://bugs.webkit.org/show_bug.cgi?id=31885 >+ >+ Implement reflections (via -webkit-box-reflect:) on compositing layers. >+ >+ We add to the GraphicsLayer the notion of having a replica, and being a replicated layer. >+ The replica layer is not parented in the tree, but referenced by another layer. >+ RenderLayerBacking sets this up when it finds RenderLayers for reflections. >+ >+ GraphicsLayerCA implements rendering of replica layers by cloning CA layers, >+ and copying their properties, including animations and contents. Deep reflections >+ are supported by a hash of clone layers on each GraphicsLayerCA, indexed by >+ the path down the tree to each replica instance. >+ >+ When GraphicsLayerCA properties are changed, in most cases the clones must also >+ be updated. >+ >+ Tests: compositing/reflections/animation-inside-reflection.html >+ compositing/reflections/compositing-change-inside-reflection.html >+ compositing/reflections/deeply-nested-reflections.html >+ compositing/reflections/masked-reflection-on-composited.html >+ compositing/reflections/nested-reflection-anchor-point.html >+ compositing/reflections/nested-reflection-animated.html >+ compositing/reflections/nested-reflection-mask-change.html >+ compositing/reflections/nested-reflection-on-overflow.html >+ compositing/reflections/nested-reflection-opacity.html >+ compositing/reflections/nested-reflection-size-change.html >+ compositing/reflections/nested-reflection-transformed.html >+ compositing/reflections/nested-reflection-transition.html >+ compositing/reflections/nested-reflection.html >+ compositing/reflections/reflection-opacity.html >+ compositing/reflections/reflection-ordering.html >+ compositing/reflections/reflection-positioning.html >+ compositing/reflections/reflection-testing.html >+ compositing/reflections/transform-inside-reflection.html >+ >+ * platform/graphics/GraphicsLayer.h: >+ (WebCore::GraphicsLayer::isReplicated): Returns true when this layer has a replicated layer. >+ (WebCore::GraphicsLayer::replicatedLayerPosition): >+ (WebCore::GraphicsLayer::setReplicatedLayerPosition): The position of the replica layer must be >+ special-cased; we cannot just copy the position of the original. >+ (WebCore::GraphicsLayer::didDisplay): Method that indicates that the contents of the layer changed, >+ which gives us a chance to update clone layers. >+ (WebCore::GraphicsLayer::replicaLayer): reference to the replica layer. >+ (WebCore::GraphicsLayer::replicatedLayer): reference to the layer that this (replica) layer is replicating. >+ (WebCore::GraphicsLayer::setReplicatedLayer): >+ >+ * platform/graphics/GraphicsLayer.cpp: >+ (WebCore::GraphicsLayer::GraphicsLayer): >+ (WebCore::GraphicsLayer::setReplicatedByLayer): Hook up a replica with its replicated layer. >+ (WebCore::GraphicsLayer::dumpProperties): >+ >+ * platform/graphics/mac/GraphicsLayerCA.h: >+ (WebCore::GraphicsLayerCA::primaryLayer): Returns a CALayer, since structural layers may not be WebLayers. >+ (WebCore::GraphicsLayerCA::isReplicatedRootClone): Given a cloneID (string representation of the path to a clone >+ down the tree, which is a bitstring of 1 (replica), or 0 (non-replica)), returns true if this ID represents the >+ root of a replica tree. >+ (WebCore::GraphicsLayerCA::primaryLayerClones): Returns a pointer to the hash map of clones of the primary layers. >+ >+ (WebCore::GraphicsLayerCA::ReplicaState::ReplicaState): Small struct used to track original/clone branching >+ down the tree during recursion, to build cloneID paths. >+ >+ (WebCore::GraphicsLayerCA::hasCloneLayers): returns true if this layer has clone layers. >+ >+ * platform/graphics/mac/GraphicsLayerCA.mm: >+ (WebCore::GraphicsLayerCA::~GraphicsLayerCA): remove the clone layers. >+ (WebCore::GraphicsLayerCA::setChildren): call noteSublayersChanged() since we may have to update replicas too. >+ (WebCore::GraphicsLayerCA::addChild): ditto >+ (WebCore::GraphicsLayerCA::addChildAtIndex): ditto >+ (WebCore::GraphicsLayerCA::addChildBelow): ditto >+ (WebCore::GraphicsLayerCA::addChildAbove): ditto >+ (WebCore::GraphicsLayerCA::replaceChild): ditto >+ (WebCore::GraphicsLayerCA::removeFromParent): ditto >+ (WebCore::GraphicsLayerCA::setMaskLayer): call propagateLayerChangeToReplicas() >+ (WebCore::GraphicsLayerCA::setReplicatedLayer): note replica changed. >+ (WebCore::GraphicsLayerCA::setReplicatedByLayer): ditto >+ (WebCore::GraphicsLayerCA::setContentsToImage): call noteSublayersChanged() >+ (WebCore::GraphicsLayerCA::setContentsToVideo): call noteSublayersChanged() >+ (WebCore::GraphicsLayerCA::didDisplay): here is our chance to copy updated contents to clone layers. >+ (WebCore::GraphicsLayerCA::recursiveCommitChanges): >+ (WebCore::GraphicsLayerCA::commitLayerChangesBeforeSublayers): pre-order commit, for things that need to be >+ committed before we recurse on children. >+ (WebCore::GraphicsLayerCA::commitLayerChangesAfterSublayers): post-order commit, for things that need to be >+ committed after we recurse on children, like clones. >+ (WebCore::GraphicsLayerCA::updateLayerNames): New method to match the other 'update' methods. >+ (WebCore::GraphicsLayerCA::updateSublayerList): Insert replica layers into the hierarchy. >+ (WebCore::GraphicsLayerCA::updateLayerPosition): update clones. >+ (WebCore::GraphicsLayerCA::updateLayerSize): ditto >+ (WebCore::GraphicsLayerCA::updateAnchorPoint): ditto >+ (WebCore::GraphicsLayerCA::updateTransform): ditto >+ (WebCore::GraphicsLayerCA::updateChildrenTransform): ditto >+ (WebCore::GraphicsLayerCA::updateMasksToBounds): ditto >+ (WebCore::GraphicsLayerCA::updateContentsOpaque): ditto >+ (WebCore::GraphicsLayerCA::updateBackfaceVisibility): ditto >+ (WebCore::GraphicsLayerCA::updateStructuralLayer): call ensureStructuralLayer() >+ (WebCore::moveAnimation): utility to move a CAAnimation from one layer to another. >+ (WebCore::GraphicsLayerCA::ensureStructuralLayer): refactored code which creates enclosing CALayers for reflection >+ flattening, or CATransformLayers for preserve-3d. >+ (WebCore::GraphicsLayerCA::structuralLayerPurpose): indicates why we need a structural layer. >+ (WebCore::GraphicsLayerCA::updateLayerDrawsContent): update clones >+ (WebCore::GraphicsLayerCA::updateContentsImage): ditto >+ (WebCore::GraphicsLayerCA::updateContentsRect): ditto >+ (WebCore::GraphicsLayerCA::updateMaskLayer): ditto >+ (WebCore::GraphicsLayerCA::updateReplicatedLayers): This is where we ask for the tree of layers for the replica >+ and its children, and attach them as sublayers. >+ (WebCore::GraphicsLayerCA::ReplicaState::cloneID): Build a bitstring from the array of original/clone values; this >+ string serves to identify clones in the hash map. >+ (WebCore::GraphicsLayerCA::replicatedLayerRoot): Request the tree of clone layers, set its position and transform, >+ and return it. >+ (WebCore::GraphicsLayerCA::setAnimationOnLayer): update clones >+ (WebCore::GraphicsLayerCA::removeAnimationFromLayer): ditto >+ (WebCore::GraphicsLayerCA::pauseAnimationOnLayer): ditto >+ (WebCore::GraphicsLayerCA::setContentsToGraphicsContext3D): udpate sublayers. >+ (WebCore::GraphicsLayerCA::suspendAnimations): update clones. >+ (WebCore::GraphicsLayerCA::resumeAnimations): ditto >+ (WebCore::GraphicsLayerCA::animatedLayerClones): return the hash map for clones of the appropriate layer for the given property. >+ (WebCore::GraphicsLayerCA::ensureCloneLayers): create and return clones for the CALayers for this layer. >+ (WebCore::GraphicsLayerCA::removeCloneLayers): clear out the clone layers. >+ (WebCore::GraphicsLayerCA::positionForCloneRootLayer): the root of a clonal subtree needs its position and transform to be special-cased, >+ since it doesn't just copy those properties from the original. >+ (WebCore::GraphicsLayerCA::propagateLayerChangeToReplicas): push the change flags onto the replica. >+ (WebCore::GraphicsLayerCA::fetchCloneLayers): recurse down sublayers, creating clones of the CALayers along the way, and returning >+ the root of the clone tree. >+ (WebCore::copyAnimation): utility to copy an animation from one layer to another. Animations can be shared between layers. >+ (WebCore::GraphicsLayerCA::cloneLayer): utility to clone a CALayer, copying those properties which GraphicsLayerCA makes use of >+ (WebCore::GraphicsLayerCA::setOpacityInternal): push opacity changes to clones. >+ (WebCore::GraphicsLayerCA::updateOpacityOnLayer): ditto >+ (WebCore::GraphicsLayerCA::noteSublayersChanged): set the ChildrenChanged flag, and proprate changes to the replica, if any. >+ >+ * platform/graphics/mac/WebLayer.mm: >+ (-[WebLayer display]): override -display so we know when to update the contents of clone layers >+ >+ * platform/graphics/mac/WebTiledLayer.mm: >+ (-[WebTiledLayer display]): ditto. >+ >+ * rendering/RenderLayer.h: add flag to say if this layer represents a reflection >+ (WebCore::RenderLayer::isReflection): >+ (WebCore::RenderLayer::setIsReflection): >+ >+ * rendering/RenderLayer.cpp: >+ (WebCore::RenderLayer::RenderLayer): initialize m_isReflection >+ (WebCore::RenderLayer::updateReflectionStyle): call setIsReflection >+ >+ * rendering/RenderLayerBacking.cpp: >+ (WebCore::RenderLayerBacking::createGraphicsLayer): Put a name on the reflection layer. >+ (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): Hook up the GraphicsLayers for the reflection. >+ (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Reflection overrides preserve-3d (you have to flatten to reflect). >+ Also hook up updating the reflection layer geometry, and the relica position. >+ >+ (WebCore::RenderLayerBacking::paintIntoLayer): We no longer paint the reflection in software. >+ >+ * rendering/RenderLayerCompositor.cpp: >+ (WebCore::RenderLayerCompositor::computeCompositingRequirements): Hook reflection layers into the compositing logic. >+ (WebCore::RenderLayerCompositor::canAccelerateVideoRendering): No longer have to push video into software if it's reflected. >+ (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Update the bounds of the reflection layer. >+ (WebCore::RenderLayerCompositor::updateCompositingDescendantGeometry): ditto >+ (WebCore::RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing): a compositing descendant forces >+ a reflection ancestor to composite now. >+ >+2009-11-25 Simon Fraser <simon.fraser@apple.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Optimize the hierarchy rebuilding of compositing layers >+ https://bugs.webkit.org/show_bug.cgi?id=31879 >+ >+ When updating the compositing layer hierarchy, instead of removing all >+ child layers and then re-adding them one by one, build a vector of child >+ layers, and set them in one go. >+ >+ * platform/graphics/GraphicsLayer.h: >+ * platform/graphics/GraphicsLayer.cpp: >+ (WebCore::GraphicsLayer::setChildren): New method that takes a Vector of child >+ GraphicsLayers. >+ >+ * platform/graphics/mac/GraphicsLayerCA.h: Override setChildren(). >+ * platform/graphics/win/GraphicsLayerCACF.h: Ditto. >+ * platform/graphics/mac/GraphicsLayerCA.mm: >+ (WebCore::GraphicsLayerCA::setChildren): Implement setChildren() to >+ set the bit that notes that sublayers changed. >+ * platform/graphics/win/GraphicsLayerCACF.cpp: >+ (WebCore::GraphicsLayerCACF::setChildren): Implement setChildren() to >+ udpate sublayers, with a note that this is not efficient. >+ >+ * rendering/RenderLayerCompositor.h: >+ * rendering/RenderLayerCompositor.cpp: >+ (WebCore::RenderLayerCompositor::updateCompositingLayers): >+ When updating compositing layers, use the faster updateLayerTreeGeometry() if >+ we know that no layer hierarchy changes are needed, and, at the root, use >+ the vector returned from rebuildCompositingLayerTree() to attach the root >+ layer. >+ (WebCore::RenderLayerCompositor::rebuildCompositingLayerTree): Changed to >+ collect child layers into Vectors of GraphicsLayers, which can be set as >+ layer childen in one go. >+ (WebCore::RenderLayerCompositor::updateLayerTreeGeometry): Split out from >+ rebuildCompositingLayerTree() for simplicity, and called when we just need to >+ update layer geometry, without doing any reparenting. >+ >+2009-11-25 Simon Fraser <simon.fraser@apple.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Support reflections on composited layers >+ https://bugs.webkit.org/show_bug.cgi?id=31885 >+ >+ First part of supporting composited reflections on compositing layers. >+ >+ Rename the m_transformLayer member variable to m_structuralLayer, since it >+ will get used both for transform layers (for preserve-3d) and to hold a flattening >+ layer related to reflections, both of which have similar requirements, and are >+ mutually exclusive. >+ >+ * platform/graphics/mac/GraphicsLayerCA.h: >+ primaryLayer(), hostLayerForSublayers() and layerForSuperlayer() all now return >+ a CALayer, since m_structuralLayer isn't always a WebLayer. >+ >+ * platform/graphics/mac/GraphicsLayerCA.mm: >+ (WebCore::GraphicsLayerCA::commitLayerChanges): >+ updateLayerPreserves3D() renamed to updateStructuralLayer() >+ >+ (WebCore::GraphicsLayerCA::updateLayerNames): >+ New "update" method for updating layer names. >+ >+ (WebCore::GraphicsLayerCA::updateSublayerList): >+ m_transformLayer -> m_structuralLayer. Also minor refactor to only >+ allocate newSublayers in one place. >+ >+ (WebCore::GraphicsLayerCA::updateLayerSize): >+ (WebCore::GraphicsLayerCA::removeAnimationFromLayer): >+ (WebCore::GraphicsLayerCA::hostLayerForSublayers): >+ (WebCore::GraphicsLayerCA::layerForSuperlayer): >+ m_transformLayer -> m_structuralLayer >+ >+ (WebCore::GraphicsLayerCA::updateStructuralLayer): >+ Call ensureStructuralLayer() which handles any deltas to the >+ structural layer type. >+ >+ (WebCore::GraphicsLayerCA::ensureStructuralLayer): >+ Handle changes to the structural layer requirements >+ >+ (WebCore::GraphicsLayerCA::structuralLayerPurpose): >+ Return an enum describing the purpose of the structural layer; for now >+ this only returns NoStructuralLayer or StructuralLayerForPreserves3D, but >+ will in future also have a value related to reflections. >+ >+2009-12-11 Simon Fraser <simon.fraser@apple.com> >+ > Reviewed by Darin Adler. > > Support reflections on composited layers >diff --git a/WebCore/platform/graphics/GraphicsLayer.cpp b/WebCore/platform/graphics/GraphicsLayer.cpp >index e215097..2336d0b 100644 >--- a/WebCore/platform/graphics/GraphicsLayer.cpp >+++ b/WebCore/platform/graphics/GraphicsLayer.cpp >@@ -72,6 +72,8 @@ GraphicsLayer::GraphicsLayer(GraphicsLayerClient* client) > , m_contentsOrientation(CompositingCoordinatesTopDown) > , m_parent(0) > , m_maskLayer(0) >+ , m_replicaLayer(0) >+ , m_replicatedLayer(0) > , m_repaintCount(0) > { > } >@@ -214,6 +216,14 @@ void GraphicsLayer::removeFromParent() > } > } > >+void GraphicsLayer::setReplicatedByLayer(GraphicsLayer* layer) >+{ >+ if (layer) >+ layer->setReplicatedLayer(this); >+ >+ m_replicaLayer = layer; >+} >+ > void GraphicsLayer::setBackgroundColor(const Color& color) > { > m_backgroundColor = color; >@@ -454,14 +464,27 @@ void GraphicsLayer::dumpProperties(TextStream& ts, int indent) const > } > ts << ")\n"; > >- writeIndent(ts, indent + 1); >- ts << "(children " << m_children.size() << "\n"; >+ if (m_replicaLayer) { >+ writeIndent(ts, indent + 1); >+ ts << "(replica layer " << m_replicaLayer << ")\n"; >+ m_replicaLayer->dumpLayer(ts, indent+2); >+ } >+ >+ if (m_replicatedLayer) { >+ writeIndent(ts, indent + 1); >+ ts << "(replicated layer " << m_replicatedLayer << ")\n"; >+ } > >- unsigned i; >- for (i = 0; i < m_children.size(); i++) >- m_children[i]->dumpLayer(ts, indent+2); >- writeIndent(ts, indent + 1); >- ts << ")\n"; >+ if (m_children.size()) { >+ writeIndent(ts, indent + 1); >+ ts << "(children " << m_children.size() << "\n"; >+ >+ unsigned i; >+ for (i = 0; i < m_children.size(); i++) >+ m_children[i]->dumpLayer(ts, indent+2); >+ writeIndent(ts, indent + 1); >+ ts << ")\n"; >+ } > } > > } // namespace WebCore >diff --git a/WebCore/platform/graphics/GraphicsLayer.h b/WebCore/platform/graphics/GraphicsLayer.h >index 1ad7a1e..006b270 100644 >--- a/WebCore/platform/graphics/GraphicsLayer.h >+++ b/WebCore/platform/graphics/GraphicsLayer.h >@@ -198,6 +198,14 @@ public: > GraphicsLayer* maskLayer() const { return m_maskLayer; } > virtual void setMaskLayer(GraphicsLayer* layer) { m_maskLayer = layer; } > >+ // The given layer will replicate this layer and its children; the replica renders behind this layer. >+ virtual void setReplicatedByLayer(GraphicsLayer*); >+ // Whether this layer is being replicated by another layer. >+ bool isReplicated() const { return m_replicaLayer != 0; } >+ >+ const FloatPoint& replicatedLayerPosition() const { return m_replicatedLayerPosition; } >+ void setReplicatedLayerPosition(const FloatPoint& p) { m_replicatedLayerPosition = p; } >+ > // Offset is origin of the renderer minus origin of the graphics layer (so either zero or negative). > IntSize offsetFromRenderer() const { return m_offsetFromRenderer; } > void setOffsetFromRenderer(const IntSize& offset) { m_offsetFromRenderer = offset; } >@@ -279,6 +287,8 @@ public: > #endif > // Callback from the underlying graphics system to draw layer contents. > void paintGraphicsLayerContents(GraphicsContext&, const IntRect& clip); >+ // Callback from the underlying graphics system when the layer has been displayed >+ virtual void didDisplay() { } > > virtual PlatformLayer* platformLayer() const { return 0; } > >@@ -327,6 +337,12 @@ protected: > > virtual void setOpacityInternal(float) { } > >+ // The layer that replicates this layer (if any). >+ GraphicsLayer* replicaLayer() const { return m_replicaLayer; } >+ // The layer being replicated. >+ GraphicsLayer* replicatedLayer() const { return m_replicatedLayer; } >+ virtual void setReplicatedLayer(GraphicsLayer* layer) { m_replicatedLayer = layer; } >+ > GraphicsLayer(GraphicsLayerClient*); > > void dumpProperties(TextStream&, int indent) const; >@@ -365,6 +381,11 @@ protected: > > GraphicsLayer* m_maskLayer; // Reference to mask layer. We don't own this. > >+ GraphicsLayer* m_replicaLayer; // A layer that replicates this layer. We only allow one, for now. >+ // The replica is not parented; this is the primary reference to it. >+ GraphicsLayer* m_replicatedLayer; // For a replica layer, a reference to the original layer. >+ FloatPoint m_replicatedLayerPosition; // For a replica layer, the position of the replica. >+ > IntRect m_contentsRect; > > int m_repaintCount; >diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.h b/WebCore/platform/graphics/mac/GraphicsLayerCA.h >index 9ad7f04..82b5b0e 100644 >--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.h >+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.h >@@ -63,6 +63,7 @@ public: > virtual void removeFromParent(); > > virtual void setMaskLayer(GraphicsLayer*); >+ virtual void setReplicatedLayer(GraphicsLayer*); > > virtual void setPosition(const FloatPoint&); > virtual void setAnchorPoint(const FloatPoint3D&); >@@ -115,8 +116,9 @@ public: > > virtual void setGeometryOrientation(CompositingCoordinatesOrientation); > >+ virtual void didDisplay(); >+ > void recursiveCommitChanges(); >- void commitLayerChanges(); > > virtual void syncCompositingState(); > >@@ -131,6 +133,13 @@ private: > CALayer* layerForSuperlayer() const; > CALayer* animatedLayer(AnimatedPropertyID property) const; > >+ typedef String CloneID; // identifier for a given clone, based on original/replica branching down the tree. >+ static bool isReplicatedRootClone(const CloneID& cloneID) { return cloneID[0] & 1; } >+ >+ typedef HashMap<CloneID, RetainPtr<CALayer> > LayerMap; >+ LayerMap* primaryLayerClones() const { return m_structuralLayer.get() ? m_structuralLayerClones.get() : m_layerClones.get(); } >+ LayerMap* animatedLayerClones(AnimatedPropertyID property) const; >+ > bool createAnimationFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset); > bool createTransformAnimationsFromKeyframes(const KeyframeValueList&, const Animation*, const String& keyframesName, double timeOffset, const IntSize& boxSize); > >@@ -152,6 +161,9 @@ private: > return m_runningKeyframeAnimations.find(keyframesName) != m_runningKeyframeAnimations.end(); > } > >+ void commitLayerChangesBeforeSublayers(); >+ void commitLayerChangesAfterSublayers(); >+ > bool requiresTiledLayer(const FloatSize&) const; > void swapFromOrToTiledLayer(bool useTiledLayer); > >@@ -160,6 +172,69 @@ private: > > void setupContentsLayer(CALayer*); > CALayer* contentsLayer() const { return m_contentsLayer.get(); } >+ >+ virtual void setReplicatedByLayer(GraphicsLayer*); >+ >+ // Used to track the path down the tree for replica layers. >+ struct ReplicaState { >+ static const size_t maxReplicaDepth = 16; >+ enum ReplicaBranchType { ChildBranch = 0, ReplicaBranch = 1 }; >+ ReplicaState(ReplicaBranchType firstBranch) >+ : m_replicaDepth(0) >+ { >+ push(firstBranch); >+ } >+ >+ // Called as we walk down the tree to build replicas. >+ void push(ReplicaBranchType branchType) >+ { >+ m_replicaBranches.append(branchType); >+ if (branchType == ReplicaBranch) >+ ++m_replicaDepth; >+ } >+ >+ void setBranchType(ReplicaBranchType branchType) >+ { >+ ASSERT(!m_replicaBranches.isEmpty()); >+ >+ if (m_replicaBranches.last() != branchType) { >+ if (branchType == ReplicaBranch) >+ ++m_replicaDepth; >+ else >+ --m_replicaDepth; >+ } >+ >+ m_replicaBranches.last() = branchType; >+ } >+ >+ void pop() >+ { >+ if (m_replicaBranches.last() == ReplicaBranch) >+ --m_replicaDepth; >+ m_replicaBranches.removeLast(); >+ } >+ >+ size_t depth() const { return m_replicaBranches.size(); } >+ size_t replicaDepth() const { return m_replicaDepth; } >+ >+ CloneID cloneID() const; >+ >+ private: >+ Vector<ReplicaBranchType> m_replicaBranches; >+ size_t m_replicaDepth; >+ }; >+ CALayer* replicatedLayerRoot(ReplicaState&); >+ >+ enum CloneLevel { RootCloneLevel, IntermediateCloneLevel }; >+ CALayer* fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState&, CloneLevel); >+ void ensureCloneLayers(CloneID index, CALayer*& primaryLayer, CALayer*& structuralLayer, CALayer*& contentsLayer, CloneLevel); >+ CALayer* cloneLayer(CALayer*, CloneLevel); >+ >+ bool hasCloneLayers() const { return m_layerClones; } >+ void removeCloneLayers(); >+ FloatPoint positionForCloneRootLayer() const; >+ >+ void propagateLayerChangeToReplicas(); > > // All these "update" methods will be called inside a BEGIN_BLOCK_OBJC_EXCEPTIONS/END_BLOCK_OBJC_EXCEPTIONS block. > void updateLayerNames(); >@@ -184,6 +259,7 @@ private: > void updateContentsRect(); > void updateGeometryOrientation(); > void updateMaskLayer(); >+ void updateReplicatedLayers(); > > void updateLayerAnimations(); > >@@ -224,10 +300,12 @@ private: > #endif > ContentsRectChanged = 1 << 20, > GeometryOrientationChanged = 1 << 21, >- MaskLayerChanged = 1 << 22 >+ MaskLayerChanged = 1 << 22, >+ ReplicatedLayerChanged = 1 << 23 > }; > typedef unsigned LayerChangeFlags; > void noteLayerPropertyChanged(LayerChangeFlags flags); >+ void noteSublayersChanged(); > > void repaintLayerDirtyRects(); > >@@ -235,6 +313,11 @@ private: > RetainPtr<CALayer> m_structuralLayer; // A layer used for structual reasons, like preserves-3d or replica-flattening. Is the parent of m_layer. > RetainPtr<CALayer> m_contentsLayer; // A layer used for inner content, like image and video > >+ // References to clones of our layers, for replicated layers. >+ OwnPtr<LayerMap> m_layerClones; >+ OwnPtr<LayerMap> m_structuralLayerClones; >+ OwnPtr<LayerMap> m_contentsLayerClones; >+ > enum ContentsLayerPurpose { > NoContentsLayer = 0, > ContentsLayerForImage, >diff --git a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm >index e32f3e7..404996f 100644 >--- a/WebCore/platform/graphics/mac/GraphicsLayerCA.mm >+++ b/WebCore/platform/graphics/mac/GraphicsLayerCA.mm >@@ -86,6 +86,10 @@ static double mediaTimeToCurrentTime(CFTimeInterval t) > > } // namespace WebCore > >+@interface CALayer(Private) >+- (void)setContentsChanged; >+@end >+ > @interface WebAnimationDelegate : NSObject { > WebCore::GraphicsLayerCA* m_graphicsLayer; > } >@@ -395,6 +399,9 @@ GraphicsLayerCA::~GraphicsLayerCA() > // animationDidStart: can fire after this, so we need to clear out the layer on the delegate. > [m_animationDelegate.get() setLayer:0]; > >+ // Release the clone layers inside the exception-handling block. >+ removeCloneLayers(); >+ > END_BLOCK_OBJC_EXCEPTIONS > } > >@@ -414,7 +421,7 @@ bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children) > { > bool childrenChanged = GraphicsLayer::setChildren(children); > if (childrenChanged) >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > > return childrenChanged; > } >@@ -422,31 +429,31 @@ bool GraphicsLayerCA::setChildren(const Vector<GraphicsLayer*>& children) > void GraphicsLayerCA::addChild(GraphicsLayer* childLayer) > { > GraphicsLayer::addChild(childLayer); >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > } > > void GraphicsLayerCA::addChildAtIndex(GraphicsLayer* childLayer, int index) > { > GraphicsLayer::addChildAtIndex(childLayer, index); >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > } > > void GraphicsLayerCA::addChildBelow(GraphicsLayer* childLayer, GraphicsLayer* sibling) > { > GraphicsLayer::addChildBelow(childLayer, sibling); >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > } > > void GraphicsLayerCA::addChildAbove(GraphicsLayer* childLayer, GraphicsLayer* sibling) > { > GraphicsLayer::addChildAbove(childLayer, sibling); >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > } > > bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newChild) > { > if (GraphicsLayer::replaceChild(oldChild, newChild)) { >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > return true; > } > return false; >@@ -455,7 +462,7 @@ bool GraphicsLayerCA::replaceChild(GraphicsLayer* oldChild, GraphicsLayer* newCh > void GraphicsLayerCA::removeFromParent() > { > if (m_parent) >- static_cast<GraphicsLayerCA*>(m_parent)->noteLayerPropertyChanged(ChildrenChanged); >+ static_cast<GraphicsLayerCA*>(m_parent)->noteSublayersChanged(); > GraphicsLayer::removeFromParent(); > } > >@@ -466,6 +473,30 @@ void GraphicsLayerCA::setMaskLayer(GraphicsLayer* layer) > > GraphicsLayer::setMaskLayer(layer); > noteLayerPropertyChanged(MaskLayerChanged); >+ >+ propagateLayerChangeToReplicas(); >+ >+ if (m_replicatedLayer) >+ static_cast<GraphicsLayerCA*>(m_replicatedLayer)->propagateLayerChangeToReplicas(); >+} >+ >+void GraphicsLayerCA::setReplicatedLayer(GraphicsLayer* layer) >+{ >+ if (layer == m_replicatedLayer) >+ return; >+ >+ GraphicsLayer::setReplicatedLayer(layer); >+ noteLayerPropertyChanged(ReplicatedLayerChanged); >+} >+ >+void GraphicsLayerCA::setReplicatedByLayer(GraphicsLayer* layer) >+{ >+ if (layer == m_replicaLayer) >+ return; >+ >+ GraphicsLayer::setReplicatedByLayer(layer); >+ noteSublayersChanged(); >+ noteLayerPropertyChanged(ReplicatedLayerChanged); > } > > void GraphicsLayerCA::setPosition(const FloatPoint& point) >@@ -513,22 +544,6 @@ void GraphicsLayerCA::setChildrenTransform(const TransformationMatrix& t) > noteLayerPropertyChanged(ChildrenTransformChanged); > } > >-static void moveAnimation(AnimatedPropertyID property, CALayer* fromLayer, CALayer* toLayer) >-{ >- for (int index = 0; ; ++index) { >- String animName = animationIdentifier(property, index); >- >- CAAnimation* anim = [fromLayer animationForKey:animName]; >- if (!anim) >- break; >- >- [anim retain]; >- [fromLayer removeAnimationForKey:animName]; >- [toLayer addAnimation:anim forKey:animName]; >- [anim release]; >- } >-} >- > void GraphicsLayerCA::setPreserves3D(bool preserves3D) > { > if (preserves3D == m_preserves3D) >@@ -717,12 +732,12 @@ void GraphicsLayerCA::setContentsToImage(Image* image) > } > m_contentsLayerPurpose = ContentsLayerForImage; > if (!m_contentsLayer) >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > } else { > m_pendingContentsImage = 0; > m_contentsLayerPurpose = NoContentsLayer; > if (m_contentsLayer) >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > } > > noteLayerPropertyChanged(ContentsImageChanged); >@@ -731,7 +746,7 @@ void GraphicsLayerCA::setContentsToImage(Image* image) > void GraphicsLayerCA::setContentsToVideo(PlatformLayer* videoLayer) > { > if (videoLayer != m_contentsLayer.get()) >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > > m_contentsLayer = videoLayer; > noteLayerPropertyChanged(ContentsVideoChanged); >@@ -761,6 +776,23 @@ void GraphicsLayerCA::setGeometryOrientation(CompositingCoordinatesOrientation o > #endif > } > >+void GraphicsLayerCA::didDisplay() >+{ >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currClone = it->second.get(); >+ if (!currClone) >+ continue; >+ >+ if ([currClone contents] != [m_layer.get() contents]) >+ [currClone setContents:[m_layer.get() contents]]; >+ else >+ [currClone setContentsChanged]; >+ } >+ } >+} >+ > void GraphicsLayerCA::syncCompositingState() > { > recursiveCommitChanges(); >@@ -768,10 +800,10 @@ void GraphicsLayerCA::syncCompositingState() > > void GraphicsLayerCA::recursiveCommitChanges() > { >- commitLayerChanges(); >+ commitLayerChangesBeforeSublayers(); > > if (m_maskLayer) >- static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChanges(); >+ static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesBeforeSublayers(); > > const Vector<GraphicsLayer*>& childLayers = children(); > size_t numChildren = childLayers.size(); >@@ -779,9 +811,17 @@ void GraphicsLayerCA::recursiveCommitChanges() > GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]); > curChild->recursiveCommitChanges(); > } >+ >+ if (m_replicaLayer) >+ static_cast<GraphicsLayerCA*>(m_replicaLayer)->recursiveCommitChanges(); >+ >+ if (m_maskLayer) >+ static_cast<GraphicsLayerCA*>(m_maskLayer)->commitLayerChangesAfterSublayers(); >+ >+ commitLayerChangesAfterSublayers(); > } > >-void GraphicsLayerCA::commitLayerChanges() >+void GraphicsLayerCA::commitLayerChangesBeforeSublayers() > { > if (!m_uncommittedChanges) > return; >@@ -789,7 +829,7 @@ void GraphicsLayerCA::commitLayerChanges() > BEGIN_BLOCK_OBJC_EXCEPTIONS > > // Need to handle Preserves3DChanged first, because it affects which layers subsequent properties are applied to >- if (m_uncommittedChanges & Preserves3DChanged) >+ if (m_uncommittedChanges & (Preserves3DChanged | ReplicatedLayerChanged)) > updateStructuralLayer(); > > if (m_uncommittedChanges & NameChanged) >@@ -857,6 +897,19 @@ void GraphicsLayerCA::commitLayerChanges() > if (m_uncommittedChanges & MaskLayerChanged) > updateMaskLayer(); > >+ END_BLOCK_OBJC_EXCEPTIONS >+} >+ >+void GraphicsLayerCA::commitLayerChangesAfterSublayers() >+{ >+ if (!m_uncommittedChanges) >+ return; >+ >+ BEGIN_BLOCK_OBJC_EXCEPTIONS >+ >+ if (m_uncommittedChanges & ReplicatedLayerChanged) >+ updateReplicatedLayers(); >+ > m_uncommittedChanges = NoChange; > END_BLOCK_OBJC_EXCEPTIONS > } >@@ -881,11 +934,13 @@ void GraphicsLayerCA::updateSublayerList() > NSMutableArray* newSublayers = nil; > > const Vector<GraphicsLayer*>& childLayers = children(); >- > if (m_structuralLayer || m_contentsLayer || childLayers.size() > 0) { > newSublayers = [[NSMutableArray alloc] init]; > > if (m_structuralLayer) { >+ // Add the replica layer first. >+ if (m_replicaLayer) >+ [newSublayers addObject:static_cast<GraphicsLayerCA*>(m_replicaLayer)->primaryLayer()]; > // Add the primary layer. Even if we have negative z-order children, the primary layer always comes behind. > [newSublayers addObject:m_layer.get()]; > } else if (m_contentsLayer) { >@@ -904,7 +959,7 @@ void GraphicsLayerCA::updateSublayerList() > > [newSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; > } >- >+ > if (m_structuralLayer) { > safeSetSublayers(m_structuralLayer.get(), newSublayers); > >@@ -927,6 +982,20 @@ void GraphicsLayerCA::updateLayerPosition() > m_position.y() + m_anchorPoint.y() * m_size.height()); > > [primaryLayer() setPosition:posPoint]; >+ >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CGPoint clonePosition = posPoint; >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) { >+ // Maintain the special-case position for the root of a clone subtree, >+ // which we set up in replicatedLayerRoot(). >+ clonePosition = positionForCloneRootLayer(); >+ } >+ CALayer* currLayer = it->second.get(); >+ [currLayer setPosition:clonePosition]; >+ } >+ } > } > > void GraphicsLayerCA::updateLayerSize() >@@ -934,10 +1003,22 @@ void GraphicsLayerCA::updateLayerSize() > CGRect rect = CGRectMake(0, 0, m_size.width(), m_size.height()); > if (m_structuralLayer) { > [m_structuralLayer.get() setBounds:rect]; >+ >+ if (LayerMap* layerCloneMap = m_structuralLayerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) >+ [it->second.get() setBounds:rect]; >+ } > > // The anchor of the contents layer is always at 0.5, 0.5, so the position is center-relative. > CGPoint centerPoint = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f); > [m_layer.get() setPosition:centerPoint]; >+ >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) >+ [it->second.get() setPosition:centerPoint]; >+ } > } > > bool needTiledLayer = requiresTiledLayer(m_size); >@@ -945,6 +1026,11 @@ void GraphicsLayerCA::updateLayerSize() > swapFromOrToTiledLayer(needTiledLayer); > > [m_layer.get() setBounds:rect]; >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) >+ [it->second.get() setBounds:rect]; >+ } > > // Contents transform may depend on height. > updateContentsTransform(); >@@ -962,6 +1048,18 @@ void GraphicsLayerCA::updateAnchorPoint() > #if HAVE_MODERN_QUARTZCORE > [primaryLayer() setAnchorPointZ:m_anchorPoint.z()]; > #endif >+ >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setAnchorPoint:FloatPoint(m_anchorPoint.x(), m_anchorPoint.y())]; >+#if HAVE_MODERN_QUARTZCORE >+ [currLayer setAnchorPointZ:m_anchorPoint.z()]; >+#endif >+ } >+ } >+ > updateLayerPosition(); > } > >@@ -970,6 +1068,19 @@ void GraphicsLayerCA::updateTransform() > CATransform3D transform; > copyTransform(transform, m_transform); > [primaryLayer() setTransform:transform]; >+ >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) { >+ // Maintain the special-case transform for the root of a clone subtree, >+ // which we set up in replicatedLayerRoot(). >+ [currLayer setTransform:CATransform3DIdentity]; >+ } else >+ [currLayer setTransform:transform]; >+ } >+ } > } > > void GraphicsLayerCA::updateChildrenTransform() >@@ -977,22 +1088,55 @@ void GraphicsLayerCA::updateChildrenTransform() > CATransform3D transform; > copyTransform(transform, m_childrenTransform); > [primaryLayer() setSublayerTransform:transform]; >+ >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setSublayerTransform:transform]; >+ } >+ } > } > > void GraphicsLayerCA::updateMasksToBounds() > { > [m_layer.get() setMasksToBounds:m_masksToBounds]; >+ >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setMasksToBounds:m_masksToBounds]; >+ } >+ } >+ > updateDebugIndicators(); > } > > void GraphicsLayerCA::updateContentsOpaque() > { > [m_layer.get() setOpaque:m_contentsOpaque]; >+ >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setOpaque:m_contentsOpaque]; >+ } >+ } > } > > void GraphicsLayerCA::updateBackfaceVisibility() > { > [m_layer.get() setDoubleSided:m_backfaceVisibility]; >+ >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setDoubleSided:m_backfaceVisibility]; >+ } >+ } > } > > void GraphicsLayerCA::updateStructuralLayer() >@@ -1000,6 +1144,22 @@ void GraphicsLayerCA::updateStructuralLayer() > ensureStructuralLayer(structuralLayerPurpose()); > } > >+static void moveAnimation(AnimatedPropertyID property, CALayer* fromLayer, CALayer* toLayer) >+{ >+ for (int index = 0; ; ++index) { >+ String animName = animationIdentifier(property, index); >+ >+ CAAnimation* anim = [fromLayer animationForKey:animName]; >+ if (!anim) >+ break; >+ >+ [anim retain]; >+ [fromLayer removeAnimationForKey:animName]; >+ [toLayer addAnimation:anim forKey:animName]; >+ [anim release]; >+ } >+} >+ > void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose) > { > if (purpose == NoStructuralLayer) { >@@ -1009,10 +1169,12 @@ void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose) > [[m_structuralLayer.get() superlayer] replaceSublayer:m_structuralLayer.get() with:m_layer.get()]; > > moveAnimation(AnimatedPropertyWebkitTransform, m_structuralLayer.get(), m_layer.get()); >+ moveAnimation(AnimatedPropertyOpacity, m_structuralLayer.get(), m_layer.get()); > > // Release the structural layer. > m_structuralLayer = 0; > >+ // Update the properties of m_layer now that we no loner have a structural layer. > updateLayerPosition(); > updateLayerSize(); > updateAnchorPoint(); >@@ -1057,20 +1219,18 @@ void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose) > > updateLayerNames(); > >- // Copy the position from this layer. >+ // Update the properties of the structural layer. > updateLayerPosition(); > updateLayerSize(); > updateAnchorPoint(); > updateTransform(); > updateChildrenTransform(); > >+ // Set properties of m_layer to their default values, since these are expressed on on the structural layer. > CGPoint point = CGPointMake(m_size.width() / 2.0f, m_size.height() / 2.0f); > [m_layer.get() setPosition:point]; >- > [m_layer.get() setAnchorPoint:CGPointMake(0.5f, 0.5f)]; > [m_layer.get() setTransform:CATransform3DIdentity]; >- >- // Set the old layer to opacity of 1. Further down we will set the opacity on the transform layer. > [m_layer.get() setOpacity:1]; > > // Move this layer to be a child of the transform layer. >@@ -1078,9 +1238,9 @@ void GraphicsLayerCA::ensureStructuralLayer(StructuralLayerPurpose purpose) > [m_structuralLayer.get() addSublayer:m_layer.get()]; > > moveAnimation(AnimatedPropertyWebkitTransform, m_layer.get(), m_structuralLayer.get()); >+ moveAnimation(AnimatedPropertyOpacity, m_layer.get(), m_structuralLayer.get()); > > updateSublayerList(); >- > updateOpacityOnLayer(); > } > >@@ -1089,6 +1249,9 @@ GraphicsLayerCA::StructuralLayerPurpose GraphicsLayerCA::structuralLayerPurpose( > if (preserves3D()) > return StructuralLayerForPreserves3D; > >+ if (isReplicated()) >+ return StructuralLayerForReplicaFlattening; >+ > return NoStructuralLayer; > } > >@@ -1103,6 +1266,8 @@ void GraphicsLayerCA::updateLayerDrawsContent() > else > [m_layer.get() setContents:nil]; > >+ // FIXME: update clones >+ > updateDebugIndicators(); > } > >@@ -1138,6 +1303,12 @@ void GraphicsLayerCA::updateContentsImage() > #endif > [m_contentsLayer.get() setContents:(id)m_pendingContentsImage.get()]; > m_pendingContentsImage = 0; >+ >+ if (m_contentsLayerClones) { >+ LayerMap::const_iterator end = m_contentsLayerClones->end(); >+ for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) >+ [it->second.get() setContents:[m_contentsLayer.get() contents]]; >+ } > > updateContentsRect(); > } else { >@@ -1182,6 +1353,15 @@ void GraphicsLayerCA::updateContentsRect() > > [m_contentsLayer.get() setPosition:point]; > [m_contentsLayer.get() setBounds:rect]; >+ >+ if (m_contentsLayerClones) { >+ LayerMap::const_iterator end = m_contentsLayerClones->end(); >+ for (LayerMap::const_iterator it = m_contentsLayerClones->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setPosition:point]; >+ [currLayer setBounds:rect]; >+ } >+ } > } > > void GraphicsLayerCA::updateGeometryOrientation() >@@ -1205,6 +1385,72 @@ void GraphicsLayerCA::updateMaskLayer() > { > CALayer* maskCALayer = m_maskLayer ? m_maskLayer->platformLayer() : 0; > [m_layer.get() setMask:maskCALayer]; >+ >+ LayerMap* maskLayerCloneMap = m_maskLayer ? static_cast<GraphicsLayerCA*>(m_maskLayer)->primaryLayerClones() : 0; >+ >+ if (LayerMap* layerCloneMap = m_layerClones.get()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ >+ CALayer* maskClone = maskLayerCloneMap ? maskLayerCloneMap->get(it->first).get() : 0; >+ [currLayer setMask:maskClone]; >+ } >+ } >+} >+ >+void GraphicsLayerCA::updateReplicatedLayers() >+{ >+ // Clone the descendants of the replicated layer, and parent under us. >+ ReplicaState replicaState(ReplicaState::ReplicaBranch); >+ >+ CALayer* replicaRoot = replicatedLayerRoot(replicaState); >+ if (!replicaRoot) >+ return; >+ >+ if (m_structuralLayer) >+ [m_structuralLayer.get() insertSublayer:replicaRoot atIndex:0]; >+ else >+ [m_layer.get() insertSublayer:replicaRoot atIndex:0]; >+} >+ >+// For now, this assumes that layers only ever have one replica, so replicaIndices contains only 0 and 1. >+GraphicsLayerCA::CloneID GraphicsLayerCA::ReplicaState::cloneID() const >+{ >+ size_t depth = m_replicaBranches.size(); >+ >+ const size_t bitsPerUChar = sizeof(UChar) * 8; >+ size_t vectorSize = (depth + bitsPerUChar - 1) / bitsPerUChar; >+ >+ Vector<UChar> result(vectorSize); >+ result.fill(0); >+ >+ // Create a string from the bit sequence which we can use to identify the clone. >+ // Note that the string may contain embedded nulls, but that's OK. >+ for (size_t i = 0; i < depth; ++i) { >+ UChar& currChar = result[i / bitsPerUChar]; >+ currChar = (currChar << 1) | m_replicaBranches[i]; >+ } >+ >+ return String::adopt(result); >+} >+ >+CALayer* GraphicsLayerCA::replicatedLayerRoot(ReplicaState& replicaState) >+{ >+ // Limit replica nesting, to avoid 2^N explosion of replica layers. >+ if (!m_replicatedLayer || replicaState.replicaDepth() == ReplicaState::maxReplicaDepth) >+ return nil; >+ >+ GraphicsLayerCA* replicatedLayer = static_cast<GraphicsLayerCA*>(m_replicatedLayer); >+ >+ CALayer* clonedLayerRoot = replicatedLayer->fetchCloneLayers(this, replicaState, RootCloneLevel); >+ FloatPoint cloneRootPosition = replicatedLayer->positionForCloneRootLayer(); >+ >+ // Replica root has no offset or transform >+ [clonedLayerRoot setPosition:cloneRootPosition]; >+ [clonedLayerRoot setTransform:CATransform3DIdentity]; >+ >+ return clonedLayerRoot; > } > > void GraphicsLayerCA::updateLayerAnimations() >@@ -1290,6 +1536,18 @@ void GraphicsLayerCA::setAnimationOnLayer(CAPropertyAnimation* caAnim, AnimatedP > > [layer removeAnimationForKey:animationName]; > [layer addAnimation:caAnim forKey:animationName]; >+ >+ if (LayerMap* layerCloneMap = animatedLayerClones(property)) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ // Skip immediate replicas, since they move with the original. >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) >+ continue; >+ CALayer* currLayer = it->second.get(); >+ [currLayer removeAnimationForKey:animationName]; >+ [currLayer addAnimation:caAnim forKey:animationName]; >+ } >+ } > } > > // Workaround for <rdar://problem/7311367> >@@ -1318,6 +1576,18 @@ bool GraphicsLayerCA::removeAnimationFromLayer(AnimatedPropertyID property, int > > [layer removeAnimationForKey:animationName]; > bug7311367Workaround(m_structuralLayer.get(), m_transform); >+ >+ if (LayerMap* layerCloneMap = animatedLayerClones(property)) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ // Skip immediate replicas, since they move with the original. >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) >+ continue; >+ >+ CALayer* currLayer = it->second.get(); >+ [currLayer removeAnimationForKey:animationName]; >+ } >+ } > return true; > } > >@@ -1371,6 +1641,18 @@ void GraphicsLayerCA::pauseAnimationOnLayer(AnimatedPropertyID property, int ind > [pausedAnim setTimeOffset:timeOffset]; > > [layer addAnimation:pausedAnim forKey:animationName]; // This will replace the running animation. >+ >+ // Pause the animations on the clones too. >+ if (LayerMap* layerCloneMap = animatedLayerClones(property)) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ // Skip immediate replicas, since they move with the original. >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) >+ continue; >+ CALayer* currLayer = it->second.get(); >+ [currLayer addAnimation:pausedAnim forKey:animationName]; >+ } >+ } > } > > #if ENABLE(3D_CANVAS) >@@ -1385,7 +1667,7 @@ void GraphicsLayerCA::setContentsToGraphicsContext3D(const GraphicsContext3D* gr > m_platformGraphicsContext3D = context; > m_platformTexture = texture; > >- noteLayerPropertyChanged(ChildrenChanged); >+ noteSublayersChanged(); > > BEGIN_BLOCK_OBJC_EXCEPTIONS > >@@ -1711,12 +1993,32 @@ void GraphicsLayerCA::suspendAnimations(double time) > double t = currentTimeToMediaTime(time ? time : currentTime()); > [primaryLayer() setSpeed:0]; > [primaryLayer() setTimeOffset:t]; >+ >+ // Suspend the animations on the clones too. >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setSpeed:0 ]; >+ [currLayer setTimeOffset:t]; >+ } >+ } > } > > void GraphicsLayerCA::resumeAnimations() > { > [primaryLayer() setSpeed:1]; > [primaryLayer() setTimeOffset:0]; >+ >+ // Resume the animations on the clones too. >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ CALayer* currLayer = it->second.get(); >+ [currLayer setSpeed:1]; >+ [currLayer setTimeOffset:0]; >+ } >+ } > } > > CALayer* GraphicsLayerCA::hostLayerForSublayers() const >@@ -1734,6 +2036,11 @@ CALayer* GraphicsLayerCA::animatedLayer(AnimatedPropertyID property) const > return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayer.get() : primaryLayer(); > } > >+GraphicsLayerCA::LayerMap* GraphicsLayerCA::animatedLayerClones(AnimatedPropertyID property) const >+{ >+ return (property == AnimatedPropertyBackgroundColor) ? m_contentsLayerClones.get() : primaryLayerClones(); >+} >+ > PlatformLayer* GraphicsLayerCA::platformLayer() const > { > return primaryLayer(); >@@ -1892,9 +2199,256 @@ void GraphicsLayerCA::setupContentsLayer(CALayer* contentsLayer) > } > } > >+void GraphicsLayerCA::ensureCloneLayers(CloneID cloneID, CALayer*& primaryLayer, CALayer*& structuralLayer, CALayer*& contentsLayer, CloneLevel cloneLevel) >+{ >+ structuralLayer = nil; >+ contentsLayer = nil; >+ >+ if (!m_layerClones) >+ m_layerClones = new LayerMap; >+ >+ if (!m_structuralLayerClones && m_structuralLayer) >+ m_structuralLayerClones = new LayerMap; >+ >+ if (!m_contentsLayerClones && m_contentsLayer) >+ m_contentsLayerClones = new LayerMap; >+ >+ // If we have the layers already, return them. >+ LayerMap::const_iterator it = m_layerClones->find(cloneID); >+ LayerMap::const_iterator end = m_layerClones->end(); >+ if (it != end) { >+ primaryLayer = it->second.get(); >+ >+ if (m_structuralLayerClones) >+ structuralLayer = m_structuralLayerClones->get(cloneID).get(); >+ >+ if (m_contentsLayerClones) >+ contentsLayer = m_contentsLayerClones->get(cloneID).get(); >+ >+ return; >+ } >+ >+ // Create clones of the primary layer, and the structural and contents layers if we have them. >+ primaryLayer = cloneLayer(m_layer.get(), cloneLevel); >+ >+#ifndef NDEBUG >+ [primaryLayer setName:[NSString stringWithFormat:@"Clone %d of layer %@", cloneID[0], m_layer.get()]]; >+#endif >+ m_layerClones->set(cloneID, primaryLayer); >+ >+ if (m_structuralLayer) { >+ structuralLayer = cloneLayer(m_structuralLayer.get(), cloneLevel); >+#ifndef NDEBUG >+ [structuralLayer setName:[NSString stringWithFormat:@"Clone %d of layer %@", cloneID[0], m_structuralLayer.get()]]; >+#endif >+ m_structuralLayerClones->set(cloneID, structuralLayer); >+ } >+ >+ if (m_contentsLayer) { >+ contentsLayer = cloneLayer(m_contentsLayer.get(), cloneLevel); >+#ifndef NDEBUG >+ [contentsLayer setName:[NSString stringWithFormat:@"Clone %d of layer %@", cloneID[0], m_contentsLayer.get()]]; >+#endif >+ m_contentsLayerClones->set(cloneID, contentsLayer); >+ } >+} >+ >+void GraphicsLayerCA::removeCloneLayers() >+{ >+ m_layerClones = 0; >+ m_structuralLayerClones = 0; >+ m_contentsLayerClones = 0; >+} >+ >+FloatPoint GraphicsLayerCA::positionForCloneRootLayer() const >+{ >+ // This can get called during a sync when we've just removed the m_replicaLayer. >+ if (!m_replicaLayer) >+ return FloatPoint(); >+ >+ FloatPoint replicaPosition = m_replicaLayer->replicatedLayerPosition(); >+ return FloatPoint(replicaPosition.x() + m_anchorPoint.x() * m_size.width(), >+ replicaPosition.y() + m_anchorPoint.y() * m_size.height()); >+} >+ >+void GraphicsLayerCA::propagateLayerChangeToReplicas() >+{ >+ for (GraphicsLayer* currLayer = this; currLayer; currLayer = currLayer->parent()) { >+ GraphicsLayerCA* currLayerCA = static_cast<GraphicsLayerCA*>(currLayer); >+ if (!currLayerCA->hasCloneLayers()) >+ break; >+ >+ if (currLayerCA->replicaLayer()) >+ static_cast<GraphicsLayerCA*>(currLayerCA->replicaLayer())->noteLayerPropertyChanged(ReplicatedLayerChanged); >+ } >+} >+ >+CALayer* GraphicsLayerCA::fetchCloneLayers(GraphicsLayer* replicaRoot, ReplicaState& replicaState, CloneLevel cloneLevel) >+{ >+ CALayer* primaryLayer; >+ CALayer* structuralLayer; >+ CALayer* contentsLayer; >+ ensureCloneLayers(replicaState.cloneID(), primaryLayer, structuralLayer, contentsLayer, cloneLevel); >+ >+ if (m_maskLayer) { >+ CALayer* maskClone = static_cast<GraphicsLayerCA*>(m_maskLayer)->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel); >+ [primaryLayer setMask:maskClone]; >+ } >+ >+ if (m_replicatedLayer) { >+ // We are a replica being asked for clones of our layers. >+ CALayer* replicaRoot = replicatedLayerRoot(replicaState); >+ if (!replicaRoot) >+ return nil; >+ >+ if (structuralLayer) { >+ [structuralLayer insertSublayer:replicaRoot atIndex:0]; >+ return structuralLayer; >+ } >+ >+ [primaryLayer insertSublayer:replicaRoot atIndex:0]; >+ return primaryLayer; >+ } >+ >+ const Vector<GraphicsLayer*>& childLayers = children(); >+ NSMutableArray* clonalSublayers = nil; >+ >+ CALayer* replicaLayer = nil; >+ if (m_replicaLayer && m_replicaLayer != replicaRoot) { >+ // We have nested replicas. Ask the replica layer for a clone of its contents. >+ replicaState.setBranchType(ReplicaState::ReplicaBranch); >+ replicaLayer = static_cast<GraphicsLayerCA*>(m_replicaLayer)->fetchCloneLayers(replicaRoot, replicaState, RootCloneLevel); >+ replicaState.setBranchType(ReplicaState::ChildBranch); >+ } >+ >+ if (replicaLayer || structuralLayer || contentsLayer || childLayers.size() > 0) { >+ clonalSublayers = [[NSMutableArray alloc] init]; >+ >+ if (structuralLayer) { >+ // Replicas render behind the actual layer content. >+ if (replicaLayer) >+ [clonalSublayers addObject:replicaLayer]; >+ >+ // Add the primary layer next. Even if we have negative z-order children, the primary layer always comes behind. >+ [clonalSublayers addObject:primaryLayer]; >+ } else if (contentsLayer) { >+ // FIXME: add the contents layer in the correct order with negative z-order children. >+ // This does not cause visible rendering issues because currently contents layers are only used >+ // for replaced elements that don't have children. >+ [clonalSublayers addObject:contentsLayer]; >+ } >+ >+ replicaState.push(ReplicaState::ChildBranch); >+ >+ size_t numChildren = childLayers.size(); >+ for (size_t i = 0; i < numChildren; ++i) { >+ GraphicsLayerCA* curChild = static_cast<GraphicsLayerCA*>(childLayers[i]); >+ >+ CALayer* childLayer = curChild->fetchCloneLayers(replicaRoot, replicaState, IntermediateCloneLevel); >+ if (childLayer) >+ [clonalSublayers addObject:childLayer]; >+ } >+ >+ replicaState.pop(); >+ >+ [clonalSublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)]; >+ } >+ >+ CALayer* result; >+ if (structuralLayer) { >+ [structuralLayer setSublayers:clonalSublayers]; >+ >+ if (contentsLayer) { >+ // If we have a transform layer, then the contents layer is parented in the >+ // primary layer (which is itself a child of the transform layer). >+ [primaryLayer setSublayers:nil]; >+ [primaryLayer addSublayer:contentsLayer]; >+ } >+ >+ result = structuralLayer; >+ } else { >+ [primaryLayer setSublayers:clonalSublayers]; >+ result = primaryLayer; >+ } >+ >+ [clonalSublayers release]; >+ return result; >+} >+ >+ >+static void copyAnimation(AnimatedPropertyID property, CALayer* fromLayer, CALayer* toLayer) >+{ >+ for (int index = 0; ; ++index) { >+ String animName = animationIdentifier(property, index); >+ >+ CAAnimation* anim = [fromLayer animationForKey:animName]; >+ if (!anim) >+ break; >+ >+ [toLayer addAnimation:anim forKey:animName]; >+ } >+} >+ >+CALayer* GraphicsLayerCA::cloneLayer(CALayer* layer, CloneLevel cloneLevel) >+{ >+ static Class transformLayerClass = NSClassFromString(@"CATransformLayer"); >+ CALayer* newLayer = nil; >+ if ([layer isKindOfClass:transformLayerClass]) >+ newLayer = [transformLayerClass layer]; >+ else >+ newLayer = [CALayer layer]; >+ >+ [newLayer setStyle:[NSDictionary dictionaryWithObject:nullActionsDictionary() forKey:@"actions"]]; >+ >+ [newLayer setPosition:[layer position]]; >+ [newLayer setBounds:[layer bounds]]; >+ [newLayer setAnchorPoint:[layer anchorPoint]]; >+#if HAVE_MODERN_QUARTZCORE >+ [newLayer setAnchorPointZ:[layer anchorPointZ]]; >+#endif >+ [newLayer setTransform:[layer transform]]; >+ [newLayer setSublayerTransform:[layer sublayerTransform]]; >+ [newLayer setContents:[layer contents]]; >+ [newLayer setMasksToBounds:[layer masksToBounds]]; >+ [newLayer setDoubleSided:[layer isDoubleSided]]; >+ [newLayer setOpaque:[layer isOpaque]]; >+ [newLayer setBackgroundColor:[layer backgroundColor]]; >+ >+ if (cloneLevel == IntermediateCloneLevel) { >+ [newLayer setOpacity:[layer opacity]]; >+ copyAnimation(AnimatedPropertyWebkitTransform, layer, newLayer); >+ copyAnimation(AnimatedPropertyOpacity, layer, newLayer); >+ } >+ >+ if (showDebugBorders()) { >+ setLayerBorderColor(newLayer, Color(255, 122, 251)); >+ [newLayer setBorderWidth:2]; >+ } >+ >+ return newLayer; >+} >+ > void GraphicsLayerCA::setOpacityInternal(float accumulatedOpacity) > { >- [(preserves3D() ? m_layer.get() : primaryLayer()) setOpacity:accumulatedOpacity]; >+ LayerMap* layerCloneMap = 0; >+ >+ if (preserves3D()) { >+ [m_layer.get() setOpacity:accumulatedOpacity]; >+ layerCloneMap = m_layerClones.get(); >+ } else { >+ [primaryLayer() setOpacity:accumulatedOpacity]; >+ layerCloneMap = primaryLayerClones(); >+ } >+ >+ if (layerCloneMap) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) >+ continue; >+ CALayer* currLayer = it->second.get(); >+ [currLayer setOpacity:m_opacity]; >+ } >+ } > } > > void GraphicsLayerCA::updateOpacityOnLayer() >@@ -1905,9 +2459,27 @@ void GraphicsLayerCA::updateOpacityOnLayer() > distributeOpacity(parent() ? parent()->accumulatedOpacity() : 1); > #else > [primaryLayer() setOpacity:m_opacity]; >+ >+ if (LayerMap* layerCloneMap = primaryLayerClones()) { >+ LayerMap::const_iterator end = layerCloneMap->end(); >+ for (LayerMap::const_iterator it = layerCloneMap->begin(); it != end; ++it) { >+ if (m_replicaLayer && isReplicatedRootClone(it->first)) >+ continue; >+ >+ CALayer* currLayer = it->second.get(); >+ [currLayer setOpacity:m_opacity]; >+ } >+ >+ } > #endif > } > >+void GraphicsLayerCA::noteSublayersChanged() >+{ >+ noteLayerPropertyChanged(ChildrenChanged); >+ propagateLayerChangeToReplicas(); >+} >+ > void GraphicsLayerCA::noteLayerPropertyChanged(LayerChangeFlags flags) > { > if (!m_uncommittedChanges && m_client) >diff --git a/WebCore/platform/graphics/mac/WebLayer.mm b/WebCore/platform/graphics/mac/WebLayer.mm >index 56b28e6..eb57e33 100644 >--- a/WebCore/platform/graphics/mac/WebLayer.mm >+++ b/WebCore/platform/graphics/mac/WebLayer.mm >@@ -153,6 +153,13 @@ using namespace WebCore; > } > } > >+- (void)display >+{ >+ [super display]; >+ if (m_layerOwner) >+ m_layerOwner->didDisplay(); >+} >+ > - (void)drawInContext:(CGContextRef)context > { > [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:context]; >diff --git a/WebCore/platform/graphics/mac/WebTiledLayer.mm b/WebCore/platform/graphics/mac/WebTiledLayer.mm >index a1f5693..6b2d035 100644 >--- a/WebCore/platform/graphics/mac/WebTiledLayer.mm >+++ b/WebCore/platform/graphics/mac/WebTiledLayer.mm >@@ -92,6 +92,13 @@ using namespace WebCore; > } > } > >+- (void)display >+{ >+ [super display]; >+ if (m_layerOwner) >+ m_layerOwner->didDisplay(); >+} >+ > - (void)drawInContext:(CGContextRef)ctx > { > [WebLayer drawContents:m_layerOwner ofLayer:self intoContext:ctx]; >diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp >index 819afc7..17449dc 100644 >--- a/WebCore/rendering/RenderLayer.cpp >+++ b/WebCore/rendering/RenderLayer.cpp >@@ -154,6 +154,7 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer) > , m_zOrderListsDirty(true) > , m_normalFlowListDirty(true) > , m_isNormalFlowOnly(shouldBeNormalFlowOnly()) >+ , m_isReflection(false) > , m_usedTransparency(false) > , m_paintingInsideReflection(false) > , m_inOverflowRelayout(false) >@@ -3448,6 +3449,8 @@ void RenderLayer::updateReflectionStyle() > newStyle->setMaskBoxImage(renderer()->style()->boxReflect()->mask()); > > m_reflection->setStyle(newStyle.release()); >+ >+ reflectionLayer()->setIsReflection(); > } > > } // namespace WebCore >diff --git a/WebCore/rendering/RenderLayer.h b/WebCore/rendering/RenderLayer.h >index af64fc4..03c97d7 100644 >--- a/WebCore/rendering/RenderLayer.h >+++ b/WebCore/rendering/RenderLayer.h >@@ -205,6 +205,8 @@ public: > void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, PaintBehavior); > > bool hasReflection() const { return renderer()->hasReflection(); } >+ bool isReflection() const { return m_isReflection; } >+ void setIsReflection(bool b = true) { m_isReflection = b; } > RenderReplica* reflection() const { return m_reflection; } > RenderLayer* reflectionLayer() const; > >@@ -613,6 +615,7 @@ protected: > bool m_zOrderListsDirty : 1; > bool m_normalFlowListDirty: 1; > bool m_isNormalFlowOnly : 1; >+ bool m_isReflection : 1; > > bool m_usedTransparency : 1; // Tracks whether we need to close a transparent layer, i.e., whether > // we ended up painting this layer or any descendants (and therefore need to >diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp >index 8c092c6..a1fb69e 100644 >--- a/WebCore/rendering/RenderLayerBacking.cpp >+++ b/WebCore/rendering/RenderLayerBacking.cpp >@@ -90,7 +90,9 @@ void RenderLayerBacking::createGraphicsLayer() > else > m_graphicsLayer->setName(renderer()->renderName()); > } >- } else >+ } else if (m_owningLayer->isReflection()) >+ m_graphicsLayer->setName("Reflection"); >+ else > m_graphicsLayer->setName("Anonymous Node"); > #endif // NDEBUG > >@@ -186,6 +188,14 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration() > if (updateMaskLayer(m_owningLayer->renderer()->hasMask())) > m_graphicsLayer->setMaskLayer(m_maskLayer.get()); > >+ if (m_owningLayer->hasReflection()) { >+ if (m_owningLayer->reflectionLayer()->backing()) { >+ GraphicsLayer* reflectionLayer = m_owningLayer->reflectionLayer()->backing()->graphicsLayer(); >+ m_graphicsLayer->setReplicatedByLayer(reflectionLayer); >+ } >+ } else >+ m_graphicsLayer->setReplicatedByLayer(0); >+ > m_hasDirectlyCompositedContent = false; > if (canUseDirectCompositing()) { > if (renderer()->isImage()) { >@@ -229,7 +239,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() > updateLayerOpacity(renderer()->style()); > > RenderStyle* style = renderer()->style(); >- m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D); >+ m_graphicsLayer->setPreserves3D(style->transformStyle3D() == TransformStyle3DPreserve3D && !renderer()->hasReflection()); > m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible); > > RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer(); >@@ -353,6 +363,19 @@ void RenderLayerBacking::updateGraphicsLayerGeometry() > m_graphicsLayer->setContentsRect(contentsBox()); > if (!m_hasDirectlyCompositedContent) > m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow() && !m_artificiallyInflatedBounds); >+ >+ if (m_owningLayer->isReflection()) >+ m_graphicsLayer->setDrawsContent(false); >+ >+ if (m_owningLayer->reflectionLayer() && m_owningLayer->reflectionLayer()->isComposited()) { >+ RenderLayerBacking* reflectionBacking = m_owningLayer->reflectionLayer()->backing(); >+ reflectionBacking->updateGraphicsLayerGeometry(); >+ >+ // The reflection layer has the bounds of m_owningLayer->reflectionLayer(), >+ // but the reflected layer is the bounds of this layer, so we need to position it appropriately. >+ FloatRect reflectedLayerBounds = compositedBounds(); >+ reflectionBacking->graphicsLayer()->setReplicatedLayerPosition(reflectedLayerBounds.location()); >+ } > } > > void RenderLayerBacking::updateInternalHierarchy() >@@ -864,14 +887,6 @@ void RenderLayerBacking::paintIntoLayer(RenderLayer* rootLayer, GraphicsContext* > > m_owningLayer->updateLayerListsIfNeeded(); > >- // Paint the reflection first if we have one. >- if (m_owningLayer->hasReflection()) { >- // Mark that we are now inside replica painting. >- m_owningLayer->setPaintingInsideReflection(true); >- m_owningLayer->reflectionLayer()->paintLayer(rootLayer, context, paintDirtyRect, paintBehavior, paintingRoot, 0, RenderLayer::PaintLayerPaintingReflection); >- m_owningLayer->setPaintingInsideReflection(false); >- } >- > // Calculate the clip rects we should use. > IntRect layerBounds, damageRect, clipRectToApply, outlineRect; > m_owningLayer->calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply, outlineRect); >diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp >index 2f5e267..144fa7e 100644 >--- a/WebCore/rendering/RenderLayerCompositor.cpp >+++ b/WebCore/rendering/RenderLayerCompositor.cpp >@@ -533,6 +533,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O > addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds); > } > >+ if (layer->reflectionLayer()) >+ layer->reflectionLayer()->setMustOverlapCompositedLayers(needsToBeComposited(layer)); >+ > // Subsequent layers in the parent stacking context also need to composite. > if (childState.m_subtreeIsCompositing) > compositingState.m_subtreeIsCompositing = true; >@@ -549,6 +552,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* layer, O > // Update backing now, so that we can use isComposited() reliably during tree traversal in rebuildCompositingLayerTree(). > if (updateBacking(layer, CompositingChangeRepaintNow)) > layersChanged = true; >+ >+ if (layer->reflectionLayer() && updateLayerCompositingState(layer->reflectionLayer(), CompositingChangeRepaintNow)) >+ layersChanged = true; > } > > void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer) >@@ -595,9 +601,7 @@ void RenderLayerCompositor::parentInRootLayer(RenderLayer* layer) > #if ENABLE(VIDEO) > bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const > { >- // FIXME: ideally we need to look at all ancestors for mask or video. But for now, >- // just bail on the obvious cases. >- if (o->hasReflection() || !m_hasAcceleratedCompositing) >+ if (!m_hasAcceleratedCompositing) > return false; > > return o->supportsAcceleratedRendering(); >@@ -615,6 +619,10 @@ void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, cons > // The compositing state of all our children has been updated already, so now > // we can compute and cache the composited bounds for this layer. > layerBacking->updateCompositedBounds(); >+ >+ if (layer->reflectionLayer()) >+ layer->reflectionLayer()->backing()->updateCompositedBounds(); >+ > layerBacking->updateGraphicsLayerConfiguration(); > layerBacking->updateGraphicsLayerGeometry(); > >@@ -730,12 +738,19 @@ void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayer* com > if (layer != compositingAncestor) { > if (RenderLayerBacking* layerBacking = layer->backing()) { > layerBacking->updateCompositedBounds(); >+ >+ if (layer->reflectionLayer()) >+ layer->reflectionLayer()->backing()->updateCompositedBounds(); >+ > layerBacking->updateGraphicsLayerGeometry(); > if (updateDepth == RenderLayerBacking::CompositingChildren) > return; > } > } > >+ if (layer->reflectionLayer()) >+ updateCompositingDescendantGeometry(compositingAncestor, layer->reflectionLayer(), updateDepth); >+ > if (!layer->hasCompositingDescendant()) > return; > >@@ -983,7 +998,7 @@ bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* render > > bool RenderLayerCompositor::requiresCompositingWhenDescendantsAreCompositing(RenderObject* renderer) const > { >- return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask(); >+ return renderer->hasTransform() || renderer->isTransparent() || renderer->hasMask() || renderer->hasReflection(); > } > > // If an element has negative z-index children, those children render in front of the
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 31885
:
43871
|
44716
|
44718
|
46706