Modified: trunk/Source/WebCore/ChangeLog (112331 => 112332)
--- trunk/Source/WebCore/ChangeLog 2012-03-27 23:39:44 UTC (rev 112331)
+++ trunk/Source/WebCore/ChangeLog 2012-03-27 23:49:04 UTC (rev 112332)
@@ -1,3 +1,31 @@
+2012-03-27 Dana Jansens <[email protected]>
+
+ [chromium] Unknown transforms should be treated as non-axis aligned on main thread
+ https://bugs.webkit.org/show_bug.cgi?id=82370
+
+ Reviewed by Adrienne Walker.
+
+ On main thread, animating transforms have "unknown" values as they are changing
+ out of sync on the impl thread. So treat them as non-axis-aligned since they
+ may be, when deciding to create a render surface.
+
+ In addition, since surfaces are cheap on main thread, create one for all layers
+ with animating transforms and a drawing descendant, as this allows paint culling
+ within the layer's subtree (the animated transform won't affect drawTransforms
+ inside the subtree).
+
+ Also renamed the layerIsInAnimatingSubtreeFor* to animatingTransformTo*.
+ The old name made me pause and think what it meant and I'm the one who
+ created it. Hopefully this is more clear.
+
+ Unit test: CCLayerTreeHostCommonTest.verifyAnimationsForRenderSurfaceHierarchy
+
+ * platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp:
+ (WebCore::transformToParentIsKnown):
+ (WebCore):
+ (WebCore::subtreeShouldRenderToSeparateSurface):
+ (WebCore::calculateDrawTransformsAndVisibilityInternal):
+
2012-03-27 Dirk Pranke <[email protected]>
Re-land r112277; reverting it doesn't seem to have fixed anything.
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp (112331 => 112332)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp 2012-03-27 23:39:44 UTC (rev 112331)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCLayerTreeHostCommon.cpp 2012-03-27 23:49:04 UTC (rev 112332)
@@ -139,6 +139,16 @@
return layer->opacity() == 1 && !layer->opacityIsAnimating();
}
+static inline bool transformToParentIsKnown(CCLayerImpl*)
+{
+ return true;
+}
+
+static inline bool transformToParentIsKnown(LayerChromium* layer)
+{
+ return !layer->transformIsAnimating();
+}
+
template<typename LayerType>
static bool subtreeShouldRenderToSeparateSurface(LayerType* layer, bool axisAlignedWithRespectToParent)
{
@@ -171,6 +181,12 @@
if (layer->parent() && layer->parent()->preserves3D() && !layer->preserves3D() && descendantDrawsContent)
return true;
+ // On the main thread side, animating transforms are unknown, and may cause a RenderSurface on the impl side.
+ // Since they are cheap, we create a rendersurface for all animating transforms to cover these cases, and so
+ // that we can consider descendants as not animating relative to their target to aid culling.
+ if (!transformToParentIsKnown(layer) && descendantDrawsContent)
+ return true;
+
// If the layer clips its descendants but it is not axis-aligned with respect to its parent.
if (layer->masksToBounds() && !axisAlignedWithRespectToParent && descendantDrawsContent)
return true;
@@ -315,11 +331,11 @@
TransformationMatrix combinedTransform = parentMatrix;
combinedTransform = combinedTransform.multiply(layerLocalTransform);
- bool layerIsInAnimatingSubtreeForSurface = layer->transformIsAnimating();
- bool layerIsInAnimatingSubtreeForScreen = layer->transformIsAnimating();
+ bool animatingTransformToTarget = layer->transformIsAnimating();
+ bool animatingTransformToScreen = animatingTransformToTarget;
if (layer->parent()) {
- layerIsInAnimatingSubtreeForSurface |= layer->parent()->drawTransformIsAnimating();
- layerIsInAnimatingSubtreeForScreen |= layer->parent()->screenSpaceTransformIsAnimating();
+ animatingTransformToTarget |= layer->parent()->drawTransformIsAnimating();
+ animatingTransformToScreen |= layer->parent()->screenSpaceTransformIsAnimating();
}
FloatRect layerRect(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height(), layer->bounds().width(), layer->bounds().height());
@@ -356,11 +372,11 @@
surfaceOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
renderSurface->setOriginTransform(surfaceOriginTransform);
- renderSurface->setTargetSurfaceTransformsAreAnimating(layerIsInAnimatingSubtreeForSurface);
- renderSurface->setScreenSpaceTransformsAreAnimating(layerIsInAnimatingSubtreeForScreen);
- layerIsInAnimatingSubtreeForSurface = false;
- layer->setDrawTransformIsAnimating(layerIsInAnimatingSubtreeForSurface);
- layer->setScreenSpaceTransformIsAnimating(layerIsInAnimatingSubtreeForScreen);
+ renderSurface->setTargetSurfaceTransformsAreAnimating(animatingTransformToTarget);
+ renderSurface->setScreenSpaceTransformsAreAnimating(animatingTransformToScreen);
+ animatingTransformToTarget = false;
+ layer->setDrawTransformIsAnimating(animatingTransformToTarget);
+ layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen);
// Update the aggregate hierarchy matrix to include the transform of the newly created RenderSurface.
nextHierarchyMatrix.multiply(surfaceOriginTransform);
@@ -387,8 +403,8 @@
renderSurfaceLayerList.append(layer);
} else {
layer->setDrawTransform(combinedTransform);
- layer->setDrawTransformIsAnimating(layerIsInAnimatingSubtreeForSurface);
- layer->setScreenSpaceTransformIsAnimating(layerIsInAnimatingSubtreeForScreen);
+ layer->setDrawTransformIsAnimating(animatingTransformToTarget);
+ layer->setScreenSpaceTransformIsAnimating(animatingTransformToScreen);
transformedLayerRect = enclosingIntRect(layer->drawTransform().mapRect(layerRect));
layer->setDrawOpacity(drawOpacity);
Modified: trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp (112331 => 112332)
--- trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp 2012-03-27 23:39:44 UTC (rev 112331)
+++ trunk/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp 2012-03-27 23:49:04 UTC (rev 112332)
@@ -676,9 +676,8 @@
// In combination with descendantDrawsContent, opacity != 1 forces the layer to have a new renderSurface.
addOpacityTransitionToController(*renderSurface1->layerAnimationController(), 10, 1, 0, false);
- addOpacityTransitionToController(*renderSurface2->layerAnimationController(), 10, 1, 0, false);
- // Also put an animation on a layer without descendants.
+ // Also put an animated opacity on a layer without descendants.
addOpacityTransitionToController(*grandChildOfRoot->layerAnimationController(), 10, 1, 0, false);
TransformationMatrix layerTransform;
@@ -686,10 +685,11 @@
TransformationMatrix sublayerTransform;
sublayerTransform.scale3d(10.0, 1.0, 1.0);
- // Put transform animations on child, renderSurface2, grandChildOfRoot, and grandChildOfRS2
- addAnimatedTransformToController(*childOfRoot->layerAnimationController(), 10, 30, 0);
+ // In combination with descendantDrawsContent, an animated transform forces the layer to have a new renderSurface.
+ addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0);
+
+ // Also put transform animations on grandChildOfRoot, and grandChildOfRS2
addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0);
- addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0);
addAnimatedTransformToController(*grandChildOfRS2->layerAnimationController(), 10, 30, 0);
setLayerPropertiesForTesting(parent.get(), layerTransform, sublayerTransform, FloatPoint(0.25f, 0.0f), FloatPoint(2.5f, 0.0f), IntSize(10, 10), false);
@@ -742,14 +742,14 @@
EXPECT_FALSE(childOfRS1->drawOpacityIsAnimating());
EXPECT_FALSE(grandChildOfRS1->drawOpacityIsAnimating());
EXPECT_FALSE(renderSurface2->drawOpacityIsAnimating());
- EXPECT_TRUE(renderSurface2->renderSurface()->drawOpacityIsAnimating());
+ EXPECT_FALSE(renderSurface2->renderSurface()->drawOpacityIsAnimating());
EXPECT_FALSE(childOfRS2->drawOpacityIsAnimating());
EXPECT_FALSE(grandChildOfRS2->drawOpacityIsAnimating());
// Verify drawTransformsAnimatingInTarget values
//
EXPECT_FALSE(parent->drawTransformIsAnimating());
- EXPECT_TRUE(childOfRoot->drawTransformIsAnimating());
+ EXPECT_FALSE(childOfRoot->drawTransformIsAnimating());
EXPECT_TRUE(grandChildOfRoot->drawTransformIsAnimating());
EXPECT_FALSE(renderSurface1->drawTransformIsAnimating());
EXPECT_FALSE(renderSurface1->renderSurface()->targetSurfaceTransformsAreAnimating());
@@ -763,7 +763,7 @@
// Verify drawTransformsAnimatingInScreen values
//
EXPECT_FALSE(parent->screenSpaceTransformIsAnimating());
- EXPECT_TRUE(childOfRoot->screenSpaceTransformIsAnimating());
+ EXPECT_FALSE(childOfRoot->screenSpaceTransformIsAnimating());
EXPECT_TRUE(grandChildOfRoot->screenSpaceTransformIsAnimating());
EXPECT_FALSE(renderSurface1->screenSpaceTransformIsAnimating());
EXPECT_FALSE(renderSurface1->renderSurface()->screenSpaceTransformsAreAnimating());