summaryrefslogtreecommitdiff
path: root/Source/WebKit/chromium/tests
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-25 15:09:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-25 15:09:11 +0200
commita89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd (patch)
treeb7abd9f49ae1d4d2e426a5883bfccd42b8e2ee12 /Source/WebKit/chromium/tests
parent8d473cf9743f1d30a16a27114e93bd5af5648d23 (diff)
downloadqtwebkit-a89b2ebb8e192c5e8cea21079bda2ee2c0c7dddd.tar.gz
Imported WebKit commit eb5c1b8fe4d4b1b90b5137433fc58a91da0e6878 (http://svn.webkit.org/repository/webkit/trunk@118516)
Diffstat (limited to 'Source/WebKit/chromium/tests')
-rw-r--r--Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp48
-rw-r--r--Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp28
-rw-r--r--Source/WebKit/chromium/tests/CCLayerImplTest.cpp7
-rw-r--r--Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp389
-rw-r--r--Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp362
-rw-r--r--Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp49
-rwxr-xr-xSource/WebKit/chromium/tests/FakeCCLayerTreeHostClient.h2
-rw-r--r--Source/WebKit/chromium/tests/FilterOperationsTest.cpp93
-rw-r--r--Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp1
-rw-r--r--Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp107
-rw-r--r--Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp12
-rw-r--r--Source/WebKit/chromium/tests/IDBFakeBackingStore.h74
-rw-r--r--Source/WebKit/chromium/tests/IDBKeyPathTest.cpp4
-rw-r--r--Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp128
-rw-r--r--Source/WebKit/chromium/tests/LayerChromiumTest.cpp1
-rw-r--r--Source/WebKit/chromium/tests/PlatformContextSkiaTest.cpp4
-rw-r--r--Source/WebKit/chromium/tests/WebFrameTest.cpp39
-rw-r--r--Source/WebKit/chromium/tests/WebLayerTest.cpp2
-rw-r--r--Source/WebKit/chromium/tests/WebLayerTreeViewTest.cpp220
-rw-r--r--Source/WebKit/chromium/tests/WebTransformationMatrixTest.cpp332
-rw-r--r--Source/WebKit/chromium/tests/data/fixed_layout.html1
21 files changed, 1766 insertions, 137 deletions
diff --git a/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp b/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
index 11a88784b..bbea971dd 100644
--- a/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
+++ b/Source/WebKit/chromium/tests/CCDamageTrackerTest.cpp
@@ -33,8 +33,11 @@
#include "cc/CCMathUtil.h"
#include "cc/CCSingleThreadProxy.h"
#include <gtest/gtest.h>
+#include <public/WebFilterOperation.h>
+#include <public/WebFilterOperations.h>
using namespace WebCore;
+using namespace WebKit;
using namespace WTF;
using namespace WebKitTests;
@@ -364,8 +367,8 @@ TEST_F(CCDamageTrackerTest, verifyDamageForBlurredSurface)
OwnPtr<CCLayerImpl> root = createAndSetUpTestTreeWithOneSurface();
CCLayerImpl* child = root->children()[0].get();
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(5, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(5));
int outsetTop, outsetRight, outsetBottom, outsetLeft;
filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
root->setFilters(filters);
@@ -391,8 +394,11 @@ TEST_F(CCDamageTrackerTest, verifyDamageForBackgroundBlurredChild)
CCLayerImpl* child1 = root->children()[0].get();
CCLayerImpl* child2 = root->children()[1].get();
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(2, WebCore::Fixed), FilterOperation::BLUR));
+ // Allow us to set damage on child1 too.
+ child1->setDrawsContent(true);
+
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(2));
int outsetTop, outsetRight, outsetBottom, outsetLeft;
filters.getOutsets(outsetTop, outsetRight, outsetBottom, outsetLeft);
child1->setBackgroundFilters(filters);
@@ -432,7 +438,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForBackgroundBlurredChild)
expectedDamageRect.expand(outsetLeft, outsetTop);
EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
- // CASE 3: Setting this update rect outside the contentBounds of the blurred
+ // CASE 3: Setting this update rect outside the blurred contentBounds of the blurred
// child1 will not cause it to be expanded.
root->setUpdateRect(FloatRect(30, 30, 2, 2));
@@ -444,7 +450,22 @@ TEST_F(CCDamageTrackerTest, verifyDamageForBackgroundBlurredChild)
expectedDamageRect = FloatRect(30, 30, 2, 2);
EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
- // CASE 4: Setting the update rect on child2, which is above child1, will
+ // CASE 4: Setting this update rect inside the blurred contentBounds but outside the
+ // original contentBounds of the blurred child1 will cause it to be expanded.
+ root->setUpdateRect(FloatRect(99, 99, 1, 1));
+
+ emulateDrawingOneFrame(root.get());
+
+ rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ // Damage on the root should be: position of updateRect (99, 99), expanded
+ // by the blurring on child1, but since it is 1 pixel outside the layer, the
+ // expanding should be reduced by 1.
+ expectedDamageRect = FloatRect(99, 99, 1, 1);
+ expectedDamageRect.move(-outsetLeft + 1, -outsetTop + 1);
+ expectedDamageRect.expand(outsetLeft + outsetRight - 1, outsetTop + outsetBottom - 1);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+ // CASE 5: Setting the update rect on child2, which is above child1, will
// not get blurred by child1, so it does not need to get expanded.
child2->setUpdateRect(FloatRect(0, 0, 1, 1));
@@ -454,6 +475,19 @@ TEST_F(CCDamageTrackerTest, verifyDamageForBackgroundBlurredChild)
// Damage on child2 should be: position of updateRect offset by the child's position (11, 11), and not expanded by anything.
expectedDamageRect = FloatRect(11, 11, 1, 1);
EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
+
+ // CASE 6: Setting the update rect on child1 will also blur the damage, so
+ // that any pixels needed for the blur are redrawn in the current frame.
+ child1->setUpdateRect(FloatRect(0, 0, 1, 1));
+
+ emulateDrawingOneFrame(root.get());
+
+ rootDamageRect = root->renderSurface()->damageTracker()->currentDamageRect();
+ // Damage on child1 should be: position of updateRect offset by the child's position (100, 100), and expanded by the damage.
+ expectedDamageRect = FloatRect(100, 100, 1, 1);
+ expectedDamageRect.move(-outsetLeft, -outsetTop);
+ expectedDamageRect.expand(outsetLeft + outsetRight, outsetTop + outsetBottom);
+ EXPECT_FLOAT_RECT_EQ(expectedDamageRect, rootDamageRect);
}
TEST_F(CCDamageTrackerTest, verifyDamageForAddingAndRemovingLayer)
@@ -1018,7 +1052,7 @@ TEST_F(CCDamageTrackerTest, verifyDamageForEmptyLayerList)
ASSERT_TRUE(root->renderSurface() == root->targetRenderSurface());
CCRenderSurface* targetSurface = root->renderSurface();
targetSurface->clearLayerList();
- targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), false, IntRect(), 0, FilterOperations());
+ targetSurface->damageTracker()->updateDamageTrackingState(targetSurface->layerList(), targetSurface->owningLayerId(), false, IntRect(), 0, WebFilterOperations());
FloatRect damageRect = targetSurface->damageTracker()->currentDamageRect();
EXPECT_TRUE(damageRect.isEmpty());
diff --git a/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp b/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp
index 1d5409f98..827194bbc 100644
--- a/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp
+++ b/Source/WebKit/chromium/tests/CCLayerAnimationControllerTest.cpp
@@ -747,4 +747,32 @@ TEST(CCLayerAnimationControllerTest, AbortAGroupedAnimation)
EXPECT_EQ(0.75, dummy.opacity());
}
+TEST(CCLayerAnimationControllerTest, ForceSyncWhenSynchronizedStartTimeNeeded)
+{
+ FakeLayerAnimationControllerClient dummyImpl;
+ OwnPtr<CCLayerAnimationController> controllerImpl(CCLayerAnimationController::create(&dummyImpl));
+ OwnPtr<CCAnimationEventsVector> events(adoptPtr(new CCAnimationEventsVector));
+ FakeLayerAnimationControllerClient dummy;
+ OwnPtr<CCLayerAnimationController> controller(
+ CCLayerAnimationController::create(&dummy));
+
+ OwnPtr<CCActiveAnimation> toAdd(createActiveAnimation(adoptPtr(new FakeFloatTransition(2, 0, 1)), 0, CCActiveAnimation::Opacity));
+ toAdd->setNeedsSynchronizedStartTime(true);
+ controller->add(toAdd.release());
+
+ controller->animate(0, 0);
+ EXPECT_TRUE(controller->hasActiveAnimation());
+ CCActiveAnimation* activeAnimation = controller->getActiveAnimation(0, CCActiveAnimation::Opacity);
+ EXPECT_TRUE(activeAnimation);
+ EXPECT_TRUE(activeAnimation->needsSynchronizedStartTime());
+
+ controller->setForceSync();
+
+ controller->pushAnimationUpdatesTo(controllerImpl.get());
+
+ activeAnimation = controllerImpl->getActiveAnimation(0, CCActiveAnimation::Opacity);
+ EXPECT_TRUE(activeAnimation);
+ EXPECT_EQ(CCActiveAnimation::WaitingForTargetAvailability, activeAnimation->runState());
+}
+
} // namespace
diff --git a/Source/WebKit/chromium/tests/CCLayerImplTest.cpp b/Source/WebKit/chromium/tests/CCLayerImplTest.cpp
index 36c1082b7..f5259e1cf 100644
--- a/Source/WebKit/chromium/tests/CCLayerImplTest.cpp
+++ b/Source/WebKit/chromium/tests/CCLayerImplTest.cpp
@@ -29,7 +29,10 @@
#include "cc/CCSingleThreadProxy.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <public/WebFilterOperation.h>
+#include <public/WebFilterOperations.h>
+using namespace WebKit;
using namespace WebCore;
namespace {
@@ -85,8 +88,8 @@ TEST(CCLayerImplTest, verifyLayerChangesAreTrackedProperly)
Color arbitraryColor = Color(10, 20, 30);
TransformationMatrix arbitraryTransform;
arbitraryTransform.scale3d(0.1, 0.2, 0.3);
- FilterOperations arbitraryFilters;
- arbitraryFilters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::OPACITY));
+ WebFilterOperations arbitraryFilters;
+ arbitraryFilters.append(WebFilterOperation::createOpacityFilter(0.5));
// Changing these properties affects the entire subtree of layers.
EXECUTE_AND_VERIFY_SUBTREE_CHANGED(root->setAnchorPoint(arbitraryFloatPoint));
diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp
index d243aee4a..17e570199 100644
--- a/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp
+++ b/Source/WebKit/chromium/tests/CCLayerTreeHostCommonTest.cpp
@@ -581,6 +581,37 @@ TEST(CCLayerTreeHostCommonTest, verifyRenderSurfaceListForTransparentChild)
EXPECT_EQ(parent->drawableContentRect(), IntRect());
}
+TEST(CCLayerTreeHostCommonTest, verifyForceRenderSurface)
+{
+ RefPtr<LayerChromium> parent = LayerChromium::create();
+ RefPtr<LayerChromium> renderSurface1 = LayerChromium::create();
+ RefPtr<LayerChromiumWithForcedDrawsContent> child = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ renderSurface1->setForceRenderSurface(true);
+
+ const TransformationMatrix identityMatrix;
+ setLayerPropertiesForTesting(renderSurface1.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
+ setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint::zero(), FloatPoint::zero(), IntSize(10, 10), false);
+
+ parent->createRenderSurface();
+ parent->setClipRect(IntRect(0, 0, 10, 10));
+ parent->addChild(renderSurface1);
+ renderSurface1->addChild(child);
+
+ Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+ Vector<RefPtr<LayerChromium> > dummyLayerList;
+ int dummyMaxTextureSize = 512;
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+ EXPECT_TRUE(renderSurface1->renderSurface());
+ EXPECT_EQ(renderSurfaceLayerList.size(), 1U);
+
+ renderSurfaceLayerList.clear();
+ renderSurface1->setForceRenderSurface(false);
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+ EXPECT_FALSE(renderSurface1->renderSurface());
+ EXPECT_EQ(renderSurfaceLayerList.size(), 0U);
+}
+
TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfaces)
{
// The entire subtree of layers that are outside the clipRect should be culled away,
@@ -700,6 +731,78 @@ TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsRenderSurfacesCrashRepro)
EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
}
+TEST(CCLayerTreeHostCommonTest, verifyClipRectCullsSurfaceWithoutVisibleContent)
+{
+ // When a renderSurface has a clipRect, it is used to clip the contentRect
+ // of the surface. When the renderSurface is animating its transforms, then
+ // the contentRect's position in the clipRect is not defined on the main
+ // thread, and its contentRect should not be clipped.
+
+ // The test tree is set up as follows:
+ // - parent is a container layer that masksToBounds=true to cause clipping.
+ // - child is a renderSurface, which has a clipRect set to the bounds of the parent.
+ // - grandChild is a renderSurface, and the only visible content in child. It is positioned outside of the clipRect from parent.
+
+ // In this configuration, grandChild should be outside the clipped
+ // contentRect of the child, making grandChild not appear in the
+ // renderSurfaceLayerList. However, when we place an animation on the child,
+ // this clipping should be avoided and we should keep the grandChild
+ // in the renderSurfaceLayerList.
+
+ const TransformationMatrix identityMatrix;
+ RefPtr<LayerChromium> parent = LayerChromium::create();
+ RefPtr<LayerChromium> child = LayerChromium::create();
+ RefPtr<LayerChromium> grandChild = LayerChromium::create();
+ RefPtr<LayerChromiumWithForcedDrawsContent> leafNode = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ parent->addChild(child);
+ child->addChild(grandChild);
+ grandChild->addChild(leafNode);
+
+ setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(child.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(20, 20), false);
+ setLayerPropertiesForTesting(grandChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(200, 200), IntSize(10, 10), false);
+ setLayerPropertiesForTesting(leafNode.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(10, 10), false);
+
+ parent->setMasksToBounds(true);
+ child->setOpacity(0.4f);
+ grandChild->setOpacity(0.4f);
+
+ Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+ Vector<RefPtr<LayerChromium> > dummyLayerList;
+ int dummyMaxTextureSize = 512;
+
+ parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+ parent->createRenderSurface();
+ renderSurfaceLayerList.append(parent.get());
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+ // Without an animation, we should cull child and grandChild from the renderSurfaceLayerList.
+ ASSERT_EQ(1U, renderSurfaceLayerList.size());
+ EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+
+ // Now put an animating transform on child.
+ addAnimatedTransformToController(*child->layerAnimationController(), 10, 30, 0);
+
+ parent->clearRenderSurface();
+ child->clearRenderSurface();
+ grandChild->clearRenderSurface();
+ renderSurfaceLayerList.clear();
+ dummyLayerList.clear();
+
+ parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+ parent->createRenderSurface();
+ renderSurfaceLayerList.append(parent.get());
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+ // With an animating transform, we should keep child and grandChild in the renderSurfaceLayerList.
+ ASSERT_EQ(3U, renderSurfaceLayerList.size());
+ EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+ EXPECT_EQ(child->id(), renderSurfaceLayerList[1]->id());
+ EXPECT_EQ(grandChild->id(), renderSurfaceLayerList[2]->id());
+}
+
TEST(CCLayerTreeHostCommonTest, verifyClipRectIsPropagatedCorrectlyToLayers)
{
// Verify that layers get the appropriate clipRects when their parent masksToBounds is true.
@@ -874,8 +977,9 @@ TEST(CCLayerTreeHostCommonTest, verifyAnimationsForRenderSurfaceHierarchy)
TransformationMatrix sublayerTransform;
sublayerTransform.scale3d(10.0, 1.0, 1.0);
- // In combination with descendantDrawsContent, an animated transform forces the layer to have a new renderSurface.
+ // In combination with descendantDrawsContent and masksToBounds, an animated transform forces the layer to have a new renderSurface.
addAnimatedTransformToController(*renderSurface2->layerAnimationController(), 10, 30, 0);
+ renderSurface2->setMasksToBounds(true);
// Also put transform animations on grandChildOfRoot, and grandChildOfRS2
addAnimatedTransformToController(*grandChildOfRoot->layerAnimationController(), 10, 30, 0);
@@ -1238,9 +1342,208 @@ TEST(CCLayerTreeHostCommonTest, verifyVisibleRectForPerspectiveUnprojection)
EXPECT_INT_RECT_EQ(expected, actual);
}
-TEST(CCLayerTreeHostCommonTest, verifyBackFaceCulling)
+TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithoutPreserves3d)
{
- // Verify that layers are appropriately culled when their back face is showing and they are not double sided.
+ // Verify the behavior of back-face culling when there are no preserve-3d layers. Note
+ // that 3d transforms still apply in this case, but they are "flattened" to each
+ // parent layer according to current W3C spec.
+
+ const TransformationMatrix identityMatrix;
+ RefPtr<LayerChromium> parent = LayerChromium::create();
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+
+ parent->createRenderSurface();
+ parent->addChild(frontFacingChild);
+ parent->addChild(backFacingChild);
+ parent->addChild(frontFacingSurface);
+ parent->addChild(backFacingSurface);
+ frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
+ frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
+ backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
+ backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
+
+ // Nothing is double-sided
+ frontFacingChild->setDoubleSided(false);
+ backFacingChild->setDoubleSided(false);
+ frontFacingSurface->setDoubleSided(false);
+ backFacingSurface->setDoubleSided(false);
+ frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
+ backFacingChildOfFrontFacingSurface->setDoubleSided(false);
+ frontFacingChildOfBackFacingSurface->setDoubleSided(false);
+ backFacingChildOfBackFacingSurface->setDoubleSided(false);
+
+ TransformationMatrix backfaceMatrix;
+ backfaceMatrix.translate(50, 50);
+ backfaceMatrix.rotate3d(0, 1, 0, 180);
+ backfaceMatrix.translate(-50, -50);
+
+ // Having a descendant and opacity will force these to have render surfaces.
+ frontFacingSurface->setOpacity(0.5f);
+ backFacingSurface->setOpacity(0.5f);
+
+ // Nothing preserves 3d. According to current W3C CSS Transforms spec, these layers
+ // should blindly use their own local transforms to determine back-face culling.
+ setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+
+ Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+ Vector<RefPtr<LayerChromium> > dummyLayerList;
+ int dummyMaxTextureSize = 512;
+ parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
+ parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+ renderSurfaceLayerList.append(parent.get());
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+ // Verify which renderSurfaces were created.
+ EXPECT_FALSE(frontFacingChild->renderSurface());
+ EXPECT_FALSE(backFacingChild->renderSurface());
+ EXPECT_TRUE(frontFacingSurface->renderSurface());
+ EXPECT_TRUE(backFacingSurface->renderSurface());
+ EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
+ EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
+ EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
+ EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
+
+ // Verify the renderSurfaceLayerList.
+ ASSERT_EQ(3u, renderSurfaceLayerList.size());
+ EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
+ // Even though the back facing surface LAYER gets culled, the other descendants should still be added, so the SURFACE should not be culled.
+ EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[2]->id());
+
+ // Verify root surface's layerList.
+ ASSERT_EQ(3u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
+ EXPECT_EQ(backFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[2]->id());
+
+ // Verify frontFacingSurface's layerList.
+ ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
+ EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
+
+ // Verify backFacingSurface's layerList; its own layer should be culled from the surface list.
+ ASSERT_EQ(1u, renderSurfaceLayerList[2]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingChildOfBackFacingSurface->id(), renderSurfaceLayerList[2]->renderSurface()->layerList()[0]->id());
+}
+
+TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3d)
+{
+ // Verify the behavior of back-face culling when preserves-3d transform style is used.
+
+ const TransformationMatrix identityMatrix;
+ RefPtr<LayerChromium> parent = LayerChromium::create();
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChild = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfFrontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingChildOfBackFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> dummyReplicaLayer2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+
+ parent->createRenderSurface();
+ parent->addChild(frontFacingChild);
+ parent->addChild(backFacingChild);
+ parent->addChild(frontFacingSurface);
+ parent->addChild(backFacingSurface);
+ frontFacingSurface->addChild(frontFacingChildOfFrontFacingSurface);
+ frontFacingSurface->addChild(backFacingChildOfFrontFacingSurface);
+ backFacingSurface->addChild(frontFacingChildOfBackFacingSurface);
+ backFacingSurface->addChild(backFacingChildOfBackFacingSurface);
+
+ // Nothing is double-sided
+ frontFacingChild->setDoubleSided(false);
+ backFacingChild->setDoubleSided(false);
+ frontFacingSurface->setDoubleSided(false);
+ backFacingSurface->setDoubleSided(false);
+ frontFacingChildOfFrontFacingSurface->setDoubleSided(false);
+ backFacingChildOfFrontFacingSurface->setDoubleSided(false);
+ frontFacingChildOfBackFacingSurface->setDoubleSided(false);
+ backFacingChildOfBackFacingSurface->setDoubleSided(false);
+
+ TransformationMatrix backfaceMatrix;
+ backfaceMatrix.translate(50, 50);
+ backfaceMatrix.rotate3d(0, 1, 0, 180);
+ backfaceMatrix.translate(-50, -50);
+
+ // Opacity will not force creation of renderSurfaces in this case because of the
+ // preserve-3d transform style. Instead, an example of when a surface would be
+ // created with preserve-3d is when there is a replica layer.
+ frontFacingSurface->setReplicaLayer(dummyReplicaLayer1.get());
+ backFacingSurface->setReplicaLayer(dummyReplicaLayer2.get());
+
+ // Each surface creates its own new 3d rendering context (as defined by W3C spec).
+ // According to current W3C CSS Transforms spec, layers in a 3d rendering context
+ // should use the transform with respect to that context. This 3d rendering context
+ // occurs when (a) parent's transform style is flat and (b) the layer's transform
+ // style is preserve-3d.
+ setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // parent transform style is flat.
+ setLayerPropertiesForTesting(frontFacingChild.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
+ setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // surface transform style is preserve-3d.
+ setLayerPropertiesForTesting(frontFacingChildOfFrontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingChildOfFrontFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(frontFacingChildOfBackFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(backFacingChildOfBackFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+
+ Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+ Vector<RefPtr<LayerChromium> > dummyLayerList;
+ int dummyMaxTextureSize = 512;
+ parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
+ parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+ renderSurfaceLayerList.append(parent.get());
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+ // Verify which renderSurfaces were created.
+ EXPECT_FALSE(frontFacingChild->renderSurface());
+ EXPECT_FALSE(backFacingChild->renderSurface());
+ EXPECT_TRUE(frontFacingSurface->renderSurface());
+ EXPECT_FALSE(backFacingSurface->renderSurface());
+ EXPECT_FALSE(frontFacingChildOfFrontFacingSurface->renderSurface());
+ EXPECT_FALSE(backFacingChildOfFrontFacingSurface->renderSurface());
+ EXPECT_FALSE(frontFacingChildOfBackFacingSurface->renderSurface());
+ EXPECT_FALSE(backFacingChildOfBackFacingSurface->renderSurface());
+
+ // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
+ ASSERT_EQ(2u, renderSurfaceLayerList.size());
+ EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
+
+ // Verify root surface's layerList.
+ ASSERT_EQ(2u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingChild->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[1]->id());
+
+ // Verify frontFacingSurface's layerList.
+ ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
+ EXPECT_EQ(frontFacingChildOfFrontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
+}
+
+TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithAnimatingTransforms)
+{
+ // Verify that layers are appropriately culled when their back face is showing and
+ // they are not double sided, while animations are going on.
//
// Layers that are animating do not get culled on the main thread, as their transforms should be
// treated as "unknown" so we can not be sure that their back face is really showing.
@@ -1273,15 +1576,16 @@ TEST(CCLayerTreeHostCommonTest, verifyBackFaceCulling)
backfaceMatrix.rotate3d(0, 1, 0, 180);
backfaceMatrix.translate(-50, -50);
- // Having a descendent, and animating transforms, will make the animatingSurface own a render surface.
+ // Having a descendant that draws, masksToBounds, and animating transforms, will make the animatingSurface own a render surface.
addAnimatedTransformToController(*animatingSurface->layerAnimationController(), 10, 30, 0);
+ animatingSurface->setMasksToBounds(true);
// This is just an animating layer, not a surface.
addAnimatedTransformToController(*animatingChild->layerAnimationController(), 10, 30, 0);
- setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true);
+ setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
setLayerPropertiesForTesting(child.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
setLayerPropertiesForTesting(animatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
- setLayerPropertiesForTesting(childOfAnimatingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(childOfAnimatingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
setLayerPropertiesForTesting(animatingChild.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
@@ -1318,11 +1622,74 @@ TEST(CCLayerTreeHostCommonTest, verifyBackFaceCulling)
EXPECT_FALSE(child2->visibleLayerRect().isEmpty());
- // But if the back face is visible, then the visibleLayerRect should be empty.
- EXPECT_TRUE(animatingChild->visibleLayerRect().isEmpty());
- EXPECT_TRUE(animatingSurface->visibleLayerRect().isEmpty());
- // And any layers in the subtree should not be considered visible either.
- EXPECT_TRUE(childOfAnimatingSurface->visibleLayerRect().isEmpty());
+ // The animating layers should have a visibleLayerRect that represents the area of the front face that is within the viewport.
+ EXPECT_EQ(animatingChild->visibleLayerRect(), IntRect(IntPoint(), animatingChild->contentBounds()));
+ EXPECT_EQ(animatingSurface->visibleLayerRect(), IntRect(IntPoint(), animatingSurface->contentBounds()));
+ // And layers in the subtree of the animating layer should have valid visibleLayerRects also.
+ EXPECT_EQ(childOfAnimatingSurface->visibleLayerRect(), IntRect(IntPoint(), childOfAnimatingSurface->contentBounds()));
+}
+
+TEST(CCLayerTreeHostCommonTest, verifyBackFaceCullingWithPreserves3dForFlatteningSurface)
+{
+ // Verify the behavior of back-face culling for a renderSurface that is created
+ // when it flattens its subtree, and its parent has preserves-3d.
+
+ const TransformationMatrix identityMatrix;
+ RefPtr<LayerChromium> parent = LayerChromium::create();
+ RefPtr<LayerChromiumWithForcedDrawsContent> frontFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> backFacingSurface = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> child1 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+ RefPtr<LayerChromiumWithForcedDrawsContent> child2 = adoptRef(new LayerChromiumWithForcedDrawsContent());
+
+ parent->createRenderSurface();
+ parent->addChild(frontFacingSurface);
+ parent->addChild(backFacingSurface);
+ frontFacingSurface->addChild(child1);
+ backFacingSurface->addChild(child2);
+
+ // RenderSurfaces are not double-sided
+ frontFacingSurface->setDoubleSided(false);
+ backFacingSurface->setDoubleSided(false);
+
+ TransformationMatrix backfaceMatrix;
+ backfaceMatrix.translate(50, 50);
+ backfaceMatrix.rotate3d(0, 1, 0, 180);
+ backfaceMatrix.translate(-50, -50);
+
+ setLayerPropertiesForTesting(parent.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), true); // parent transform style is preserve3d.
+ setLayerPropertiesForTesting(frontFacingSurface.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
+ setLayerPropertiesForTesting(backFacingSurface.get(), backfaceMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false); // surface transform style is flat.
+ setLayerPropertiesForTesting(child1.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+ setLayerPropertiesForTesting(child2.get(), identityMatrix, identityMatrix, FloatPoint(0, 0), FloatPoint(0, 0), IntSize(100, 100), false);
+
+ Vector<RefPtr<LayerChromium> > renderSurfaceLayerList;
+ Vector<RefPtr<LayerChromium> > dummyLayerList;
+ int dummyMaxTextureSize = 512;
+ parent->renderSurface()->setContentRect(IntRect(IntPoint(), parent->bounds()));
+ parent->setClipRect(IntRect(IntPoint::zero(), parent->bounds()));
+ renderSurfaceLayerList.append(parent.get());
+
+ CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(parent.get(), parent.get(), identityMatrix, identityMatrix, renderSurfaceLayerList, dummyLayerList, dummyMaxTextureSize);
+
+ // Verify which renderSurfaces were created.
+ EXPECT_TRUE(frontFacingSurface->renderSurface());
+ EXPECT_FALSE(backFacingSurface->renderSurface()); // because it should be culled
+ EXPECT_FALSE(child1->renderSurface());
+ EXPECT_FALSE(child2->renderSurface());
+
+ // Verify the renderSurfaceLayerList. The back-facing surface should be culled.
+ ASSERT_EQ(2u, renderSurfaceLayerList.size());
+ EXPECT_EQ(parent->id(), renderSurfaceLayerList[0]->id());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->id());
+
+ // Verify root surface's layerList.
+ ASSERT_EQ(1u, renderSurfaceLayerList[0]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[0]->renderSurface()->layerList()[0]->id());
+
+ // Verify frontFacingSurface's layerList.
+ ASSERT_EQ(2u, renderSurfaceLayerList[1]->renderSurface()->layerList().size());
+ EXPECT_EQ(frontFacingSurface->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[0]->id());
+ EXPECT_EQ(child1->id(), renderSurfaceLayerList[1]->renderSurface()->layerList()[1]->id());
}
// FIXME:
diff --git a/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp b/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
index 77a3b8264..9e28a5b82 100644
--- a/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
+++ b/Source/WebKit/chromium/tests/CCLayerTreeHostTest.cpp
@@ -31,7 +31,6 @@
#include "CCTiledLayerTestCommon.h"
#include "CompositorFakeWebGraphicsContext3D.h"
#include "ContentLayerChromium.h"
-#include "FilterOperations.h"
#include "GraphicsContext3DPrivate.h"
#include "LayerChromium.h"
#include "TextureManager.h"
@@ -49,8 +48,12 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <public/Platform.h>
+#include <public/WebFilterOperation.h>
+#include <public/WebFilterOperations.h>
+#include <wtf/Locker.h>
#include <wtf/MainThread.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/ThreadingPrimitives.h>
#include <wtf/Vector.h>
using namespace WebCore;
@@ -79,7 +82,9 @@ public:
virtual void updateAnimations(double monotonicTime) { }
virtual void layout() { }
virtual void didRecreateContext(bool succeded) { }
+ virtual void didCommit() { }
virtual void didCommitAndDrawFrame() { }
+ virtual void scheduleComposite() { }
// Implementation of CCLayerAnimationDelegate
virtual void notifyAnimationStarted(double time) { }
@@ -131,6 +136,11 @@ protected:
m_testHooks->animateLayers(this, monotonicTime);
}
+ virtual double lowFrequencyAnimationInterval() const
+ {
+ return 1.0 / 60;
+ }
+
private:
MockLayerTreeHostImpl(TestHooks* testHooks, const CCSettings& settings, CCLayerTreeHostImplClient* client)
: CCLayerTreeHostImpl(settings, client)
@@ -239,6 +249,10 @@ public:
{
}
+ virtual void didBeginFrame() OVERRIDE
+ {
+ }
+
virtual void updateAnimations(double monotonicTime) OVERRIDE
{
m_testHooks->updateAnimations(monotonicTime);
@@ -264,8 +278,13 @@ public:
return GraphicsContext3DPrivate::createGraphicsContextFromWebContext(webContext.release(), GraphicsContext3D::RenderDirectlyToHostWindow);
}
+ virtual void willCommit() OVERRIDE
+ {
+ }
+
virtual void didCommit() OVERRIDE
{
+ m_testHooks->didCommit();
}
virtual void didCommitAndDrawFrame() OVERRIDE
@@ -284,6 +303,7 @@ public:
virtual void scheduleComposite() OVERRIDE
{
+ m_testHooks->scheduleComposite();
}
private:
@@ -367,10 +387,22 @@ protected:
CCLayerTreeHostTest()
: m_beginning(false)
, m_endWhenBeginReturns(false)
- , m_timedOut(false) { }
+ , m_timedOut(false)
+ , m_finished(false)
+ , m_scheduled(false)
+ , m_started(false)
+ { }
void doBeginTest();
+ virtual void scheduleComposite()
+ {
+ if (!m_started || m_scheduled || m_finished)
+ return;
+ m_scheduled = true;
+ callOnMainThread(&CCLayerTreeHostTest::dispatchComposite, this);
+ }
+
static void onEndTest(void* self)
{
ASSERT(isMainThread());
@@ -380,8 +412,12 @@ protected:
static void dispatchSetNeedsAnimate(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost)
test->m_layerTreeHost->setNeedsAnimate();
}
@@ -389,8 +425,12 @@ protected:
static void dispatchAddInstantAnimation(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 0, 0, 0.5, false);
}
@@ -398,8 +438,12 @@ protected:
static void dispatchAddAnimation(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost && test->m_layerTreeHost->rootLayer())
addOpacityTransitionToLayer(*test->m_layerTreeHost->rootLayer(), 10, 0, 0.5, true);
}
@@ -407,8 +451,12 @@ protected:
static void dispatchSetNeedsAnimateAndCommit(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost) {
test->m_layerTreeHost->setNeedsAnimate();
test->m_layerTreeHost->setNeedsCommit();
@@ -418,26 +466,38 @@ protected:
static void dispatchSetNeedsCommit(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT_TRUE(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost)
test->m_layerTreeHost->setNeedsCommit();
}
static void dispatchAcquireLayerTextures(void* self)
{
- ASSERT(isMainThread());
- CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
- ASSERT_TRUE(test);
- if (test->m_layerTreeHost)
- test->m_layerTreeHost->acquireLayerTextures();
+ ASSERT(isMainThread());
+
+ CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+ ASSERT_TRUE(test);
+ if (test->m_finished)
+ return;
+
+ if (test->m_layerTreeHost)
+ test->m_layerTreeHost->acquireLayerTextures();
}
static void dispatchSetNeedsRedraw(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT_TRUE(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost)
test->m_layerTreeHost->setNeedsRedraw();
}
@@ -445,8 +505,12 @@ protected:
static void dispatchSetVisible(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost)
test->m_layerTreeHost->setVisible(true);
}
@@ -454,12 +518,26 @@ protected:
static void dispatchSetInvisible(void* self)
{
ASSERT(isMainThread());
+
CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
ASSERT(test);
+ if (test->m_finished)
+ return;
+
if (test->m_layerTreeHost)
test->m_layerTreeHost->setVisible(false);
}
+ static void dispatchComposite(void* self)
+ {
+ CCLayerTreeHostTest* test = static_cast<CCLayerTreeHostTest*>(self);
+ ASSERT(isMainThread());
+ ASSERT(test);
+ test->m_scheduled = false;
+ if (test->m_layerTreeHost && !test->m_finished)
+ test->m_layerTreeHost->composite();
+ }
+
class TimeoutTask : public WebThread::Task {
public:
explicit TimeoutTask(CCLayerTreeHostTest* test)
@@ -547,6 +625,9 @@ private:
bool m_beginning;
bool m_endWhenBeginReturns;
bool m_timedOut;
+ bool m_finished;
+ bool m_scheduled;
+ bool m_started;
OwnPtr<WebThread> m_webThread;
RefPtr<CCScopedThreadProxy> m_mainThreadProxy;
@@ -565,6 +646,7 @@ void CCLayerTreeHostTest::doBeginTest()
rootLayer->setLayerTreeHost(m_layerTreeHost.get());
m_layerTreeHost->setSurfaceReady();
+ m_started = true;
m_beginning = true;
beginTest();
m_beginning = false;
@@ -574,6 +656,8 @@ void CCLayerTreeHostTest::doBeginTest()
void CCLayerTreeHostTest::endTest()
{
+ m_finished = true;
+
// If we are called from the CCThread, re-call endTest on the main thread.
if (!isMainThread())
m_mainThreadProxy->postTask(createCCThreadTask(this, &CCLayerTreeHostTest::endTest));
@@ -856,7 +940,6 @@ TEST_F(CCLayerTreeHostTestSetNeedsRedraw, runMultiThread)
}
// If the layerTreeHost says it can't draw, then we should not try to draw.
-// FIXME: Make this run in single threaded mode too. http://crbug.com/127481
class CCLayerTreeHostTestCanDrawBlocksDrawing : public CCLayerTreeHostTestThreadOnly {
public:
CCLayerTreeHostTestCanDrawBlocksDrawing()
@@ -866,6 +949,7 @@ public:
virtual void beginTest()
{
+ postSetNeedsCommitToMainThread();
}
virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
@@ -883,7 +967,7 @@ public:
}
}
- virtual void didCommitAndDrawFrame()
+ virtual void didCommit()
{
m_numCommits++;
if (m_numCommits == 1) {
@@ -893,10 +977,10 @@ public:
OwnArrayPtr<char> pixels(adoptArrayPtr(new char[4]));
m_layerTreeHost->compositeAndReadback(static_cast<void*>(pixels.get()), IntRect(0, 0, 1, 1));
} else if (m_numCommits == 2) {
+ m_layerTreeHost->setNeedsRedraw();
m_layerTreeHost->setNeedsCommit();
- m_layerTreeHost->finishAllRendering();
+ } else
endTest();
- }
}
virtual void afterTest()
@@ -907,10 +991,7 @@ private:
int m_numCommits;
};
-TEST_F(CCLayerTreeHostTestCanDrawBlocksDrawing, runMultiThread)
-{
- runTestThreaded();
-}
+SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestCanDrawBlocksDrawing)
// beginLayerWrite should prevent draws from executing until a commit occurs
class CCLayerTreeHostTestWriteLayersRedraw : public CCLayerTreeHostTestThreadOnly {
@@ -930,8 +1011,8 @@ public:
virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
{
- EXPECT_EQ(1, impl->sourceFrameNumber());
m_numDraws++;
+ EXPECT_EQ(m_numDraws, m_numCommits);
}
virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl*)
@@ -942,7 +1023,6 @@ public:
virtual void afterTest()
{
- EXPECT_EQ(0, m_numDraws);
EXPECT_EQ(1, m_numCommits);
}
@@ -1148,7 +1228,10 @@ public:
postAddAnimationToMainThread();
}
- virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
+ // Use willAnimateLayers to set visible false before the animation runs and
+ // causes a commit, so we block the second visible animate in single-thread
+ // mode.
+ virtual void willAnimateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
{
if (m_numAnimates < 2) {
if (!m_numAnimates) {
@@ -1185,7 +1268,10 @@ public:
virtual void animateLayers(CCLayerTreeHostImpl* layerTreeHostImpl, double monotonicTime)
{
- const CCFloatAnimationCurve* curve = m_layerTreeHost->rootLayer()->layerAnimationController()->getActiveAnimation(0, CCActiveAnimation::Opacity)->curve()->toFloatAnimationCurve();
+ const CCActiveAnimation* animation = m_layerTreeHost->rootLayer()->layerAnimationController()->getActiveAnimation(0, CCActiveAnimation::Opacity);
+ if (!animation)
+ return;
+ const CCFloatAnimationCurve* curve = animation->curve()->toFloatAnimationCurve();
float startOpacity = curve->getValue(0);
float endOpacity = curve->getValue(curve->duration());
float linearlyInterpolatedOpacity = 0.25 * endOpacity + 0.75 * startOpacity;
@@ -1353,11 +1439,11 @@ public:
root->setMaxScrollPosition(IntSize(100, 100));
root->scrollBy(m_scrollAmount);
- if (impl->frameNumber() == 1) {
+ if (!impl->sourceFrameNumber()) {
EXPECT_EQ(root->scrollPosition(), m_initialScroll);
EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
postSetNeedsCommitToMainThread();
- } else if (impl->frameNumber() == 2) {
+ } else if (impl->sourceFrameNumber() == 1) {
EXPECT_EQ(root->scrollPosition(), m_secondScroll);
EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
endTest();
@@ -1420,21 +1506,25 @@ public:
root->setScrollable(true);
root->setMaxScrollPosition(IntSize(100, 100));
- if (impl->frameNumber() == 1) {
+ if (!impl->sourceFrameNumber() && impl->frameNumber() == 1) {
+ // First draw after first commit.
EXPECT_EQ(root->scrollDelta(), IntSize());
root->scrollBy(m_scrollAmount);
EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
EXPECT_EQ(root->scrollPosition(), m_initialScroll);
postSetNeedsRedrawToMainThread();
- } else if (impl->frameNumber() == 2) {
+ } else if (!impl->sourceFrameNumber() && impl->frameNumber() == 2) {
+ // Second draw after first commit.
EXPECT_EQ(root->scrollDelta(), m_scrollAmount);
root->scrollBy(m_scrollAmount);
EXPECT_EQ(root->scrollDelta(), m_scrollAmount + m_scrollAmount);
EXPECT_EQ(root->scrollPosition(), m_initialScroll);
postSetNeedsCommitToMainThread();
- } else if (impl->frameNumber() == 3) {
+ } else if (impl->sourceFrameNumber() == 1) {
+ // Third or later draw after second commit.
+ EXPECT_GE(impl->frameNumber(), 3);
EXPECT_EQ(root->scrollDelta(), IntSize());
EXPECT_EQ(root->scrollPosition(), m_initialScroll + m_scrollAmount + m_scrollAmount);
endTest();
@@ -1495,6 +1585,113 @@ TEST_F(CCLayerTreeHostTestCommit, runTest)
runTest(true);
}
+class CCLayerTreeHostTestVisibilityAndAllocationControlDrawing : public CCLayerTreeHostTest {
+public:
+
+ CCLayerTreeHostTestVisibilityAndAllocationControlDrawing() { }
+
+ virtual void beginTest()
+ {
+ postSetNeedsCommitToMainThread();
+ }
+
+ virtual void didCommitAndDrawFrame()
+ {
+ int lastFrame = m_layerTreeHost->frameNumber() - 1;
+
+ // These frames should draw.
+ switch (lastFrame) {
+ case 0:
+ // Set the tree invisible, this should not draw.
+ m_layerTreeHost->setVisible(false);
+ break;
+ case 2:
+ // Set the tree invisible and give a non-visible allocation, this
+ // should not draw.
+ m_layerTreeHost->setVisible(false);
+ m_layerTreeHost->setContentsMemoryAllocationLimitBytes(0);
+ break;
+ case 5:
+ // Give a memory allocation not for display, but while we are
+ // visible. This should not be used and we should remain
+ // ready for display and it should draw.
+ m_layerTreeHost->setContentsMemoryAllocationLimitBytes(0);
+ break;
+ case 6:
+ endTest();
+ break;
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+ }
+
+ virtual void didCommit()
+ {
+ int lastFrame = m_layerTreeHost->frameNumber() - 1;
+
+ // These frames should not draw.
+ switch (lastFrame) {
+ case 1:
+ // Set the tree visible, this should draw.
+ m_layerTreeHost->setVisible(true);
+ break;
+ case 3:
+ // Set visible without giving a visible memory allocation, this
+ // shouldn't make the impl side ready for display, so it should
+ // not draw.
+ m_layerTreeHost->setVisible(true);
+ break;
+ case 4:
+ // Now give a memory allocation for display, this should draw.
+ m_layerTreeHost->setContentsMemoryAllocationLimitBytes(1);
+ break;
+ }
+ }
+
+ virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
+ {
+ switch (impl->sourceFrameNumber()) {
+ case 0:
+ // The host starts out visible and able to display before we do any commit.
+ EXPECT_TRUE(impl->visible());
+ EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
+ break;
+ case 1:
+ // We still have a memory allocation for display.
+ EXPECT_FALSE(impl->visible());
+ EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
+ break;
+ case 2:
+ EXPECT_TRUE(impl->visible());
+ EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
+ break;
+ case 3:
+ EXPECT_FALSE(impl->visible());
+ EXPECT_FALSE(impl->sourceFrameCanBeDrawn());
+ break;
+ case 4:
+ EXPECT_TRUE(impl->visible());
+ EXPECT_FALSE(impl->sourceFrameCanBeDrawn());
+ break;
+ case 5:
+ EXPECT_TRUE(impl->visible());
+ EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
+ break;
+ case 6:
+ EXPECT_TRUE(impl->visible());
+ EXPECT_TRUE(impl->sourceFrameCanBeDrawn());
+ break;
+ }
+ }
+
+ virtual void afterTest()
+ {
+ }
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestVisibilityAndAllocationControlDrawing)
+
// Verifies that startPageScaleAnimation events propagate correctly from CCLayerTreeHost to
// CCLayerTreeHostImpl in the MT compositor.
class CCLayerTreeHostTestStartPageScaleAnimation : public CCLayerTreeHostTest {
@@ -1542,9 +1739,8 @@ public:
virtual void commitCompleteOnCCThread(CCLayerTreeHostImpl* impl)
{
impl->processScrollDeltas();
- // We get one commit before the first draw, and the animation doesn't happen until the second draw,
- // so results available on the third commit.
- if (impl->frameNumber() == 2) {
+ // We get one commit before the first draw, and the animation doesn't happen until the second draw.
+ if (impl->sourceFrameNumber() == 1) {
EXPECT_EQ(1.25, impl->pageScale());
endTest();
} else
@@ -1699,53 +1895,6 @@ TEST_F(CCLayerTreeHostTestOpacityChange, runMultiThread)
runTest(true);
}
-class CCLayerTreeHostTestSetViewportSize : public CCLayerTreeHostTest {
-public:
-
- CCLayerTreeHostTestSetViewportSize()
- : m_numCommits(0)
- , m_numDraws(0)
- {
- }
-
- virtual void beginTest()
- {
- IntSize viewportSize(10, 10);
- layerTreeHost()->setViewportSize(viewportSize);
-
- CCTextureUpdater updater;
- layerTreeHost()->updateLayers(updater);
-
- EXPECT_EQ(viewportSize, layerTreeHost()->viewportSize());
- EXPECT_EQ(TextureManager::highLimitBytes(viewportSize), layerTreeHost()->contentsTextureManager()->maxMemoryLimitBytes());
- EXPECT_EQ(TextureManager::reclaimLimitBytes(viewportSize), layerTreeHost()->contentsTextureManager()->preferredMemoryLimitBytes());
-
- // setViewportSize() should not call TextureManager::setMaxMemoryLimitBytes() or TextureManager::setPreferredMemoryLimitBytes()
- // if the viewport size is not changed.
- IntSize fakeSize(5, 5);
- layerTreeHost()->contentsTextureManager()->setMaxMemoryLimitBytes(TextureManager::highLimitBytes(fakeSize));
- layerTreeHost()->contentsTextureManager()->setPreferredMemoryLimitBytes(TextureManager::reclaimLimitBytes(fakeSize));
- layerTreeHost()->setViewportSize(viewportSize);
- EXPECT_EQ(TextureManager::highLimitBytes(fakeSize), layerTreeHost()->contentsTextureManager()->maxMemoryLimitBytes());
- EXPECT_EQ(TextureManager::reclaimLimitBytes(fakeSize), layerTreeHost()->contentsTextureManager()->preferredMemoryLimitBytes());
-
- endTest();
- }
-
- virtual void afterTest()
- {
- }
-
-private:
- int m_numCommits;
- int m_numDraws;
-};
-
-TEST_F(CCLayerTreeHostTestSetViewportSize, runSingleThread)
-{
- runTest(false);
-}
-
class MockContentLayerDelegate : public ContentLayerDelegate {
public:
bool drawsContent() const { return true; }
@@ -2373,8 +2522,8 @@ public:
setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
{
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::OPACITY));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createOpacityFilter(0.5));
child->setFilters(filters);
}
@@ -2401,8 +2550,8 @@ public:
setTestLayerPropertiesForTesting(child2.get(), rootLayer.get(), identityMatrix, FloatPoint(0, 0), FloatPoint(10, 70), IntSize(500, 500), true);
{
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(10, WebCore::Percent), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(10));
child->setFilters(filters);
}
@@ -2580,15 +2729,15 @@ public:
root->setMaxScrollPosition(IntSize(100, 100));
// Check that a fractional scroll delta is correctly accumulated over multiple commits.
- if (impl->frameNumber() == 1) {
+ if (!impl->sourceFrameNumber()) {
EXPECT_EQ(root->scrollPosition(), IntPoint(0, 0));
EXPECT_EQ(root->scrollDelta(), FloatSize(0, 0));
postSetNeedsCommitToMainThread();
- } else if (impl->frameNumber() == 2) {
+ } else if (impl->sourceFrameNumber() == 1) {
EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount));
EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(m_scrollAmount.width(), 1), 0));
postSetNeedsCommitToMainThread();
- } else if (impl->frameNumber() == 3) {
+ } else if (impl->sourceFrameNumber() == 2) {
EXPECT_EQ(root->scrollPosition(), flooredIntPoint(m_scrollAmount + m_scrollAmount));
EXPECT_EQ(root->scrollDelta(), FloatSize(fmod(2 * m_scrollAmount.width(), 1), 0));
endTest();
@@ -2614,4 +2763,55 @@ TEST_F(CCLayerTreeHostTestFractionalScroll, runMultiThread)
runTestThreaded();
}
+class CCLayerTreeHostTestFinishAllRendering : public CCLayerTreeHostTest {
+public:
+ CCLayerTreeHostTestFinishAllRendering()
+ : m_once(false)
+ , m_mutex()
+ , m_drawCount(0)
+ {
+ }
+
+ virtual void beginTest()
+ {
+ m_layerTreeHost->setNeedsRedraw();
+ }
+
+ virtual void didCommitAndDrawFrame()
+ {
+ if (m_once)
+ return;
+ m_once = true;
+ m_layerTreeHost->setNeedsRedraw();
+ m_layerTreeHost->acquireLayerTextures();
+ {
+ Locker<Mutex> lock(m_mutex);
+ m_drawCount = 0;
+ }
+ m_layerTreeHost->finishAllRendering();
+ {
+ Locker<Mutex> lock(m_mutex);
+ EXPECT_EQ(0, m_drawCount);
+ }
+ endTest();
+ }
+
+ virtual void drawLayersOnCCThread(CCLayerTreeHostImpl* impl)
+ {
+ Locker<Mutex> lock(m_mutex);
+ ++m_drawCount;
+ }
+
+ virtual void afterTest()
+ {
+ }
+private:
+
+ bool m_once;
+ Mutex m_mutex;
+ int m_drawCount;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(CCLayerTreeHostTestFinishAllRendering)
+
} // namespace
diff --git a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
index 891c305b0..976dc3f29 100644
--- a/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
+++ b/Source/WebKit/chromium/tests/CCOcclusionTrackerTest.cpp
@@ -28,7 +28,6 @@
#include "CCAnimationTestCommon.h"
#include "CCOcclusionTrackerTestCommon.h"
-#include "FilterOperations.h"
#include "LayerChromium.h"
#include "Region.h"
#include "TransformationMatrix.h"
@@ -37,11 +36,13 @@
#include "cc/CCLayerImpl.h"
#include "cc/CCLayerTreeHostCommon.h"
#include "cc/CCSingleThreadProxy.h"
-
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include <public/WebFilterOperation.h>
+#include <public/WebFilterOperations.h>
using namespace WebCore;
+using namespace WebKit;
using namespace WebKitTests;
#define EXPECT_EQ_RECT(a, b) \
@@ -199,8 +200,8 @@ protected:
typename Types::LayerType* createSurface(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds)
{
typename Types::LayerType* layer = createLayer(parent, transform, position, bounds);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
layer->setFilters(filters);
return layer;
}
@@ -246,8 +247,8 @@ protected:
typename Types::ContentLayerType* createDrawingSurface(typename Types::LayerType* parent, const TransformationMatrix& transform, const FloatPoint& position, const IntSize& bounds, bool opaque)
{
typename Types::ContentLayerType* layer = createDrawingLayer(parent, transform, position, bounds, opaque);
- FilterOperations filters;
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
layer->setFilters(filters);
return layer;
}
@@ -1221,16 +1222,16 @@ protected:
typename Types::ContentLayerType* opaqueLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
typename Types::ContentLayerType* opacityLayer = this->createDrawingLayer(parent, layerTransform, FloatPoint(30, 30), IntSize(500, 500), true);
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(10, WebCore::Percent), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(10));
blurLayer->setFilters(filters);
- filters.operations().clear();
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::GRAYSCALE));
+ filters.clear();
+ filters.append(WebFilterOperation::createGrayscaleFilter(0.5));
opaqueLayer->setFilters(filters);
- filters.operations().clear();
- filters.operations().append(BasicComponentTransferFilterOperation::create(0.5, FilterOperation::OPACITY));
+ filters.clear();
+ filters.append(WebFilterOperation::createOpacityFilter(0.5));
opacityLayer->setFilters(filters);
this->calcDrawEtc(parent);
@@ -2495,8 +2496,8 @@ protected:
typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
// Filters make the layer own a surface.
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(10, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(10));
filteredSurface->setBackgroundFilters(filters);
// Save the distance of influence for the blur effect.
@@ -2616,8 +2617,8 @@ protected:
typename Types::LayerType* occludingLayerAbove = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(100, 100), IntSize(50, 50), true);
// Filters make the layers own surfaces.
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(3));
filteredSurface1->setBackgroundFilters(filters);
filteredSurface2->setBackgroundFilters(filters);
@@ -2681,8 +2682,8 @@ protected:
typename Types::LayerType* occludingLayer5 = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(250, 50), IntSize(50, 50), true);
// Filters make the layer own a surface. This filter is large enough that it goes outside the bottom of the clippingSurface.
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(12, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(12));
filteredSurface->setBackgroundFilters(filters);
// Save the distance of influence for the blur effect.
@@ -2804,8 +2805,8 @@ protected:
this->createReplicaLayer(filteredSurface, this->identityMatrix, FloatPoint(300, 0), IntSize());
// Filters make the layer own a surface.
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(3));
filteredSurface->setBackgroundFilters(filters);
this->calcDrawEtc(parent);
@@ -2853,8 +2854,8 @@ protected:
typename Types::LayerType* aboveReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 50), IntSize(50, 50), true);
// Filters make the layer own a surface.
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(3));
filteredSurface->setBackgroundFilters(filters);
this->calcDrawEtc(parent);
@@ -2903,8 +2904,8 @@ protected:
typename Types::LayerType* besideReplicaLayer = this->createDrawingLayer(parent, this->identityMatrix, FloatPoint(200, 40), IntSize(10, 10), true);
// Filters make the layer own a surface.
- FilterOperations filters;
- filters.operations().append(BlurFilterOperation::create(Length(3, WebCore::Fixed), FilterOperation::BLUR));
+ WebFilterOperations filters;
+ filters.append(WebFilterOperation::createBlurFilter(3));
filteredSurface->setBackgroundFilters(filters);
// Save the distance of influence for the blur effect.
diff --git a/Source/WebKit/chromium/tests/FakeCCLayerTreeHostClient.h b/Source/WebKit/chromium/tests/FakeCCLayerTreeHostClient.h
index 513fd0cbc..992509c4f 100755
--- a/Source/WebKit/chromium/tests/FakeCCLayerTreeHostClient.h
+++ b/Source/WebKit/chromium/tests/FakeCCLayerTreeHostClient.h
@@ -35,6 +35,7 @@ namespace WebCore {
class FakeCCLayerTreeHostClient : public CCLayerTreeHostClient {
public:
virtual void willBeginFrame() OVERRIDE { }
+ virtual void didBeginFrame() OVERRIDE { }
virtual void updateAnimations(double monotonicFrameBeginTime) OVERRIDE { }
virtual void layout() OVERRIDE { }
virtual void applyScrollAndScale(const IntSize& scrollDelta, float pageScale) OVERRIDE { }
@@ -44,6 +45,7 @@ public:
return createCompositorMockGraphicsContext3D(attrs);
}
virtual void didRecreateContext(bool success) OVERRIDE { }
+ virtual void willCommit() OVERRIDE { }
virtual void didCommit() OVERRIDE { }
virtual void didCommitAndDrawFrame() OVERRIDE { }
virtual void didCompleteSwapBuffers() OVERRIDE { }
diff --git a/Source/WebKit/chromium/tests/FilterOperationsTest.cpp b/Source/WebKit/chromium/tests/FilterOperationsTest.cpp
new file mode 100644
index 000000000..8a3c5d8a1
--- /dev/null
+++ b/Source/WebKit/chromium/tests/FilterOperationsTest.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "FilterOperations.h"
+
+#include <gtest/gtest.h>
+#include <public/WebFilterOperation.h>
+#include <public/WebFilterOperations.h>
+
+using namespace WebCore;
+using namespace WebKit;
+
+namespace {
+
+TEST(FilterOperationsTest, getOutsetsBlur)
+{
+ FilterOperations ops;
+ ops.operations().append(BlurFilterOperation::create(Length(20.0, WebCore::Fixed), FilterOperation::BLUR));
+ EXPECT_TRUE(ops.hasOutsets());
+ int top, right, bottom, left;
+ top = right = bottom = left = 0;
+ ops.getOutsets(top, right, bottom, left);
+ EXPECT_EQ(57, top);
+ EXPECT_EQ(57, right);
+ EXPECT_EQ(57, bottom);
+ EXPECT_EQ(57, left);
+}
+
+TEST(FilterOperationsTest, getOutsetsDropShadow)
+{
+ FilterOperations ops;
+ ops.operations().append(DropShadowFilterOperation::create(IntPoint(3, 8), 20, Color(1, 2, 3), FilterOperation::DROP_SHADOW));
+ EXPECT_TRUE(ops.hasOutsets());
+ int top, right, bottom, left;
+ top = right = bottom = left = 0;
+ ops.getOutsets(top, right, bottom, left);
+ EXPECT_EQ(49, top);
+ EXPECT_EQ(60, right);
+ EXPECT_EQ(65, bottom);
+ EXPECT_EQ(54, left);
+}
+
+TEST(WebFilterOperationsTest, getOutsetsBlur)
+{
+ WebFilterOperations ops;
+ ops.append(WebFilterOperation::createBlurFilter(20));
+ int top, right, bottom, left;
+ top = right = bottom = left = 0;
+ ops.getOutsets(top, right, bottom, left);
+ EXPECT_EQ(57, top);
+ EXPECT_EQ(57, right);
+ EXPECT_EQ(57, bottom);
+ EXPECT_EQ(57, left);
+}
+
+TEST(WebFilterOperationsTest, getOutsetsDropShadow)
+{
+ WebFilterOperations ops;
+ ops.append(WebFilterOperation::createDropShadowFilter(WebPoint(3, 8), 20, 0));
+ int top, right, bottom, left;
+ top = right = bottom = left = 0;
+ ops.getOutsets(top, right, bottom, left);
+ EXPECT_EQ(49, top);
+ EXPECT_EQ(60, right);
+ EXPECT_EQ(65, bottom);
+ EXPECT_EQ(54, left);
+}
+
+}
+
diff --git a/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp b/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp
index 39ad32621..b7aa85746 100644
--- a/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp
+++ b/Source/WebKit/chromium/tests/GraphicsLayerChromiumTest.cpp
@@ -28,6 +28,7 @@
#include "CCAnimationTestCommon.h"
#include "GraphicsLayer.h"
+#include "LayerChromium.h"
#include <gtest/gtest.h>
#include <wtf/PassOwnPtr.h>
diff --git a/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp b/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp
new file mode 100644
index 000000000..6c78aa53c
--- /dev/null
+++ b/Source/WebKit/chromium/tests/IDBAbortOnCorruptTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "IDBFactoryBackendImpl.h"
+#include "IDBFakeBackingStore.h"
+#include "SecurityOrigin.h"
+#include <gtest/gtest.h>
+#include <wtf/Vector.h>
+
+#if ENABLE(INDEXED_DATABASE)
+
+using namespace WebCore;
+
+namespace {
+
+class MockIDBCallbacks : public IDBCallbacks {
+public:
+ MockIDBCallbacks() : m_wasErrorCalled(false) { }
+
+ virtual ~MockIDBCallbacks()
+ {
+ EXPECT_TRUE(m_wasErrorCalled);
+ }
+ virtual void onError(PassRefPtr<IDBDatabaseError>)
+ {
+ m_wasErrorCalled = true;
+ }
+ virtual void onSuccess(PassRefPtr<DOMStringList>) { }
+ virtual void onSuccess(PassRefPtr<IDBCursorBackendInterface>) { }
+ virtual void onSuccess(PassRefPtr<IDBDatabaseBackendInterface>)
+ {
+ EXPECT_TRUE(false);
+ }
+ virtual void onSuccess(PassRefPtr<IDBKey>) { }
+ virtual void onSuccess(PassRefPtr<IDBTransactionBackendInterface>) { }
+ virtual void onSuccess(PassRefPtr<SerializedScriptValue>) { }
+ virtual void onSuccessWithContinuation() { }
+ virtual void onSuccessWithPrefetch(const Vector<RefPtr<IDBKey> >&, const Vector<RefPtr<IDBKey> >&, const Vector<RefPtr<SerializedScriptValue> >&) { }
+ virtual void onBlocked() { }
+private:
+ bool m_wasErrorCalled;
+};
+
+class FailingBackingStore : public IDBFakeBackingStore {
+public:
+ virtual ~FailingBackingStore() { }
+ static PassRefPtr<IDBBackingStore> open()
+ {
+ return adoptRef(new FailingBackingStore);
+ }
+ virtual bool createIDBDatabaseMetaData(const String&, const String&, int64_t&)
+ {
+ return false;
+ }
+};
+
+class FailingIDBFactoryBackendImpl : public IDBFactoryBackendImpl {
+public:
+ virtual ~FailingIDBFactoryBackendImpl() { }
+ static PassRefPtr<FailingIDBFactoryBackendImpl> create()
+ {
+ return adoptRef(new FailingIDBFactoryBackendImpl);
+ }
+ virtual void removeIDBDatabaseBackend(const WTF::String &) { }
+
+protected:
+ virtual PassRefPtr<IDBBackingStore> openBackingStore(PassRefPtr<SecurityOrigin> prpOrigin, const String& dataDir)
+ {
+ return FailingBackingStore::open();
+ }
+};
+
+TEST(IDBAbortTest, TheTest)
+{
+ RefPtr<IDBFactoryBackendImpl> factory = FailingIDBFactoryBackendImpl::create();
+ const String& name = "db name";
+ MockIDBCallbacks callbacks;
+ RefPtr<SecurityOrigin> origin = SecurityOrigin::create("http", "localhost", 81);
+ factory->open(name, &callbacks, origin, 0 /*Frame*/, String() /*path*/);
+}
+
+} // namespace
+
+#endif // ENABLE(INDEXED_DATABASE)
diff --git a/Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp b/Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp
index d60295a5f..c1351850d 100644
--- a/Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp
+++ b/Source/WebKit/chromium/tests/IDBBindingUtilitiesTest.cpp
@@ -41,10 +41,8 @@ namespace {
PassRefPtr<IDBKey> checkKeyFromValueAndKeyPathInternal(SerializedScriptValue* value, const String& keyPath)
{
- Vector<String> idbKeyPath;
- IDBKeyPathParseError parseError;
- IDBParseKeyPath(keyPath, idbKeyPath, parseError);
- EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
+ IDBKeyPath idbKeyPath(keyPath);
+ EXPECT_TRUE(idbKeyPath.isValid());
return createIDBKeyFromSerializedValueAndKeyPath(value, idbKeyPath);
}
@@ -56,10 +54,8 @@ void checkKeyPathNullValue(SerializedScriptValue* value, const String& keyPath)
PassRefPtr<SerializedScriptValue> injectKey(PassRefPtr<IDBKey> key, PassRefPtr<SerializedScriptValue> value, const String& keyPath)
{
- Vector<String> idbKeyPath;
- IDBKeyPathParseError parseError;
- IDBParseKeyPath(keyPath, idbKeyPath, parseError);
- EXPECT_EQ(IDBKeyPathParseErrorNone, parseError);
+ IDBKeyPath idbKeyPath(keyPath);
+ EXPECT_TRUE(idbKeyPath.isValid());
return injectIDBKeyIntoSerializedValue(key, value, idbKeyPath);
}
diff --git a/Source/WebKit/chromium/tests/IDBFakeBackingStore.h b/Source/WebKit/chromium/tests/IDBFakeBackingStore.h
new file mode 100644
index 000000000..ed894cb19
--- /dev/null
+++ b/Source/WebKit/chromium/tests/IDBFakeBackingStore.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef IDBFakeBackingStore_h
+#define IDBFakeBackingStore_h
+
+#include "IDBBackingStore.h"
+
+namespace WebCore {
+
+class IDBFakeBackingStore : public IDBBackingStore {
+public:
+ virtual void getDatabaseNames(Vector<String>& foundNames) OVERRIDE { }
+ virtual bool getIDBDatabaseMetaData(const String& name, String& foundVersion, int64_t& foundId) OVERRIDE { return false; }
+ virtual bool createIDBDatabaseMetaData(const String& name, const String& version, int64_t& rowId) OVERRIDE { return true; }
+ virtual bool updateIDBDatabaseMetaData(int64_t rowId, const String& version) OVERRIDE { return false; }
+ virtual bool deleteDatabase(const String& name) OVERRIDE { return false; }
+
+ virtual void getObjectStores(int64_t databaseId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundAutoIncrementFlags) OVERRIDE { }
+ virtual bool createObjectStore(int64_t databaseId, const String& name, const IDBKeyPath& keyPath, bool autoIncrement, int64_t& assignedObjectStoreId) OVERRIDE { return false; }
+ virtual void deleteObjectStore(int64_t databaseId, int64_t objectStoreId) OVERRIDE { }
+
+ virtual PassRefPtr<ObjectStoreRecordIdentifier> createInvalidRecordIdentifier() OVERRIDE { return PassRefPtr<ObjectStoreRecordIdentifier>(); }
+
+ virtual String getObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey&) OVERRIDE { return String(); }
+ virtual bool putObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, ObjectStoreRecordIdentifier*) OVERRIDE { return false; }
+ virtual void clearObjectStore(int64_t databaseId, int64_t objectStoreId) OVERRIDE { }
+ virtual void deleteObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, const ObjectStoreRecordIdentifier*) OVERRIDE { }
+ virtual int64_t nextAutoIncrementNumber(int64_t databaseId, int64_t objectStoreId) OVERRIDE { return 0.0; }
+ virtual bool keyExistsInObjectStore(int64_t databaseId, int64_t objectStoreId, const IDBKey&, ObjectStoreRecordIdentifier* foundRecordIdentifier) OVERRIDE { return false; }
+
+ virtual bool forEachObjectStoreRecord(int64_t databaseId, int64_t objectStoreId, ObjectStoreRecordCallback&) OVERRIDE { return false; }
+
+ virtual void getIndexes(int64_t databaseId, int64_t objectStoreId, Vector<int64_t>& foundIds, Vector<String>& foundNames, Vector<IDBKeyPath>& foundKeyPaths, Vector<bool>& foundUniqueFlags, Vector<bool>& foundMultiEntryFlags) OVERRIDE { }
+ virtual bool createIndex(int64_t databaseId, int64_t objectStoreId, const String& name, const IDBKeyPath& keyPath, bool isUnique, bool isMultiEntry, int64_t& indexId) OVERRIDE { return false; }
+ virtual void deleteIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId) OVERRIDE { }
+ virtual bool putIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&, const ObjectStoreRecordIdentifier*) OVERRIDE { return false; }
+ virtual bool deleteIndexDataForRecord(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const ObjectStoreRecordIdentifier*) OVERRIDE { return false; }
+ virtual String getObjectViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&) OVERRIDE { return String(); }
+ virtual PassRefPtr<IDBKey> getPrimaryKeyViaIndex(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKey&) OVERRIDE { return PassRefPtr<IDBKey>(); }
+ virtual bool keyExistsInIndex(int64_t databaseid, int64_t objectStoreId, int64_t indexId, const IDBKey& indexKey, RefPtr<IDBKey>& foundPrimaryKey) OVERRIDE { return false; }
+
+ virtual PassRefPtr<Cursor> openObjectStoreCursor(int64_t databaseId, int64_t objectStoreId, const IDBKeyRange*, IDBCursor::Direction) OVERRIDE { return PassRefPtr<Cursor>(); }
+ virtual PassRefPtr<Cursor> openIndexKeyCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IDBCursor::Direction) OVERRIDE { return PassRefPtr<Cursor>(); }
+ virtual PassRefPtr<Cursor> openIndexCursor(int64_t databaseId, int64_t objectStoreId, int64_t indexId, const IDBKeyRange*, IDBCursor::Direction) OVERRIDE { return PassRefPtr<Cursor>(); }
+
+ virtual PassRefPtr<Transaction> createTransaction() OVERRIDE { return PassRefPtr<Transaction>(); }
+};
+
+} // namespace WebCore
+
+#endif // IDBFakeBackingStore_h
diff --git a/Source/WebKit/chromium/tests/IDBKeyPathTest.cpp b/Source/WebKit/chromium/tests/IDBKeyPathTest.cpp
index e2fdaebc2..7d662c009 100644
--- a/Source/WebKit/chromium/tests/IDBKeyPathTest.cpp
+++ b/Source/WebKit/chromium/tests/IDBKeyPathTest.cpp
@@ -37,6 +37,10 @@ namespace {
void checkKeyPath(const String& keyPath, const Vector<String>& expected, int parserError)
{
+ IDBKeyPath idbKeyPath(keyPath);
+ ASSERT_EQ(idbKeyPath.type(), IDBKeyPath::StringType);
+ ASSERT_EQ(idbKeyPath.isValid(), (parserError == IDBKeyPathParseErrorNone));
+
IDBKeyPathParseError error;
Vector<String> keyPathElements;
IDBParseKeyPath(keyPath, keyPathElements, error);
diff --git a/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp b/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp
index eb9962d58..8f5b8ef01 100644
--- a/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp
+++ b/Source/WebKit/chromium/tests/IDBLevelDBCodingTest.cpp
@@ -30,6 +30,7 @@
#if USE(LEVELDB)
#include "IDBKey.h"
+#include "IDBKeyPath.h"
#include "LevelDBSlice.h"
#include <gtest/gtest.h>
#include <wtf/Vector.h>
@@ -418,6 +419,133 @@ TEST(IDBLevelDBCodingTest, EncodeDecodeIDBKey)
EXPECT_EQ(0, decodeIDBKey(v.data(), v.data() + v.size() - 1, decodedKey));
}
+TEST(IDBLevelDBCodingTest, EncodeIDBKeyPath)
+{
+ const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
+ const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
+ {
+ IDBKeyPath keyPath;
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::NullType);
+ Vector<char> v = encodeIDBKeyPath(keyPath);
+ EXPECT_EQ(v.size(), 3U);
+ EXPECT_EQ(v[0], kIDBKeyPathTypeCodedByte1);
+ EXPECT_EQ(v[1], kIDBKeyPathTypeCodedByte2);
+ EXPECT_EQ(v[2], IDBKeyPath::NullType);
+ }
+
+ {
+ Vector<String> testCases;
+ testCases.append("");
+ testCases.append("foo");
+ testCases.append("foo.bar");
+
+ for (size_t i = 0; i < testCases.size(); ++i) {
+ IDBKeyPath keyPath = IDBKeyPath(testCases[i]);
+ Vector<char> v = encodeIDBKeyPath(keyPath);
+ EXPECT_EQ(v.size(), encodeStringWithLength(testCases[i]).size() + 3);
+ const char* p = v.data();
+ const char* limit = v.data() + v.size();
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1);
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2);
+ EXPECT_EQ(*p++, IDBKeyPath::StringType);
+ String string;
+ p = decodeStringWithLength(p, limit, string);
+ EXPECT_EQ(string, testCases[i]);
+ EXPECT_EQ(p, limit);
+ }
+ }
+
+ {
+ Vector<String> testCase;
+ testCase.append("");
+ testCase.append("foo");
+ testCase.append("foo.bar");
+
+ IDBKeyPath keyPath(testCase);
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::ArrayType);
+ Vector<char> v = encodeIDBKeyPath(keyPath);
+ const char* p = v.data();
+ const char* limit = v.data() + v.size();
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte1);
+ EXPECT_EQ(*p++, kIDBKeyPathTypeCodedByte2);
+ EXPECT_EQ(*p++, IDBKeyPath::ArrayType);
+ int64_t count;
+ p = decodeVarInt(p, limit, count);
+ EXPECT_EQ(count, static_cast<int64_t>(testCase.size()));
+ for (size_t i = 0; i < static_cast<size_t>(count); ++i) {
+ String string;
+ p = decodeStringWithLength(p, limit, string);
+ EXPECT_EQ(string, testCase[i]);
+ }
+ EXPECT_EQ(p, limit);
+ }
+}
+
+TEST(IDBLevelDBCodingTest, DecodeIDBKeyPath)
+{
+ const unsigned char kIDBKeyPathTypeCodedByte1 = 0;
+ const unsigned char kIDBKeyPathTypeCodedByte2 = 0;
+ {
+ // Legacy encoding of string key paths.
+ Vector<String> testCases;
+ testCases.append("");
+ testCases.append("foo");
+ testCases.append("foo.bar");
+
+ for (size_t i = 0; i < testCases.size(); ++i) {
+ Vector<char> v = encodeString(testCases[i]);
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::StringType);
+ EXPECT_EQ(testCases[i], keyPath.string());
+ }
+ }
+ {
+ Vector<char> v;
+ v.append(kIDBKeyPathTypeCodedByte1);
+ v.append(kIDBKeyPathTypeCodedByte2);
+ v.append(IDBKeyPath::NullType);
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::NullType);
+ EXPECT_TRUE(keyPath.isNull());
+ }
+ {
+ Vector<String> testCases;
+ testCases.append("");
+ testCases.append("foo");
+ testCases.append("foo.bar");
+
+ for (size_t i = 0; i < testCases.size(); ++i) {
+ Vector<char> v;
+ v.append(kIDBKeyPathTypeCodedByte1);
+ v.append(kIDBKeyPathTypeCodedByte2);
+ v.append(IDBKeyPath::StringType);
+ v.append(encodeStringWithLength(testCases[i]));
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::StringType);
+ EXPECT_EQ(testCases[i], keyPath.string());
+ }
+ }
+ {
+ Vector<String> testCase;
+ testCase.append("");
+ testCase.append("foo");
+ testCase.append("foo.bar");
+
+ Vector<char> v;
+ v.append(kIDBKeyPathTypeCodedByte1);
+ v.append(kIDBKeyPathTypeCodedByte2);
+ v.append(IDBKeyPath::ArrayType);
+ v.append(encodeVarInt(testCase.size()));
+ for (size_t i = 0; i < testCase.size(); ++i)
+ v.append(encodeStringWithLength(testCase[i]));
+ IDBKeyPath keyPath = decodeIDBKeyPath(v.data(), v.data() + v.size());
+ EXPECT_EQ(keyPath.type(), IDBKeyPath::ArrayType);
+ EXPECT_EQ(keyPath.array().size(), testCase.size());
+ for (size_t i = 0; i < testCase.size(); ++i)
+ EXPECT_EQ(keyPath.array()[i], testCase[i]);
+ }
+}
+
TEST(IDBLevelDBCodingTest, ExtractAndCompareIDBKeys)
{
Vector<RefPtr<IDBKey> > keys;
diff --git a/Source/WebKit/chromium/tests/LayerChromiumTest.cpp b/Source/WebKit/chromium/tests/LayerChromiumTest.cpp
index a93eac7fa..491d48db5 100644
--- a/Source/WebKit/chromium/tests/LayerChromiumTest.cpp
+++ b/Source/WebKit/chromium/tests/LayerChromiumTest.cpp
@@ -522,6 +522,7 @@ TEST_F(LayerChromiumTest, checkPropertyChangeCausesCorrectBehavior)
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDoubleSided(false));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDebugName("Test Layer"));
EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setDrawCheckerboardForMissingTiles(!testLayer->drawCheckerboardForMissingTiles()));
+ EXECUTE_AND_VERIFY_SET_NEEDS_COMMIT_BEHAVIOR(1, testLayer->setForceRenderSurface(true));
// The above tests should not have caused a change to the needsDisplay flag.
EXPECT_FALSE(testLayer->needsDisplay());
diff --git a/Source/WebKit/chromium/tests/PlatformContextSkiaTest.cpp b/Source/WebKit/chromium/tests/PlatformContextSkiaTest.cpp
index 721f1fabb..eb2c07512 100644
--- a/Source/WebKit/chromium/tests/PlatformContextSkiaTest.cpp
+++ b/Source/WebKit/chromium/tests/PlatformContextSkiaTest.cpp
@@ -724,7 +724,7 @@ TEST(PlatformContextSkiaTest, UnboundedDrawsAreClipped)
context.setStrokeStyle(SolidStroke);
// Make skia unable to compute fast bounds for our paths.
- Vector<float> dashArray;
+ DashArray dashArray;
dashArray.append(1);
dashArray.append(0);
context.setLineDash(dashArray, 0);
@@ -771,7 +771,7 @@ TEST(PlatformContextSkiaTest, PreserveOpaqueOnlyMattersForFirstLayer)
context.setStrokeStyle(SolidStroke);
// Make skia unable to compute fast bounds for our paths.
- Vector<float> dashArray;
+ DashArray dashArray;
dashArray.append(1);
dashArray.append(0);
context.setLineDash(dashArray, 0);
diff --git a/Source/WebKit/chromium/tests/WebFrameTest.cpp b/Source/WebKit/chromium/tests/WebFrameTest.cpp
index 74251f3e8..a6ab77fc1 100644
--- a/Source/WebKit/chromium/tests/WebFrameTest.cpp
+++ b/Source/WebKit/chromium/tests/WebFrameTest.cpp
@@ -34,11 +34,13 @@
#include "Frame.h"
#include "FrameTestHelpers.h"
+#include "FrameView.h"
#include "ResourceError.h"
#include "WebDocument.h"
#include "WebFindOptions.h"
#include "WebFormElement.h"
#include "WebFrameClient.h"
+#include "WebFrameImpl.h"
#include "WebRange.h"
#include "WebScriptSource.h"
#include "WebSearchableFormData.h"
@@ -243,6 +245,43 @@ TEST_F(WebFrameTest, DeviceScaleFactorUsesDefaultWithoutViewportTag)
// Force the layout to happen before leaving the test.
webView->mainFrame()->contentAsText(1024).utf8();
}
+
+TEST_F(WebFrameTest, FixedLayoutInitializeAtMinimumPageScale)
+{
+ registerMockedHttpURLLoad("fixed_layout.html");
+
+ FixedLayoutTestWebViewClient client;
+ client.m_screenInfo.horizontalDPI = 160;
+ int viewportWidth = 640;
+ int viewportHeight = 480;
+ client.m_windowRect = WebRect(0, 0, viewportWidth, viewportHeight);
+
+ // Make sure we initialize to minimum scale, even if the window size
+ // only becomes available after the load begins.
+ WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(FrameTestHelpers::createWebViewAndLoad(m_baseURL + "fixed_layout.html", true, 0, &client));
+ webViewImpl->enableFixedLayoutMode(true);
+ webViewImpl->settings()->setViewportEnabled(true);
+ webViewImpl->resize(WebSize(viewportWidth, viewportHeight));
+
+ int defaultFixedLayoutWidth = 980;
+ float minimumPageScaleFactor = viewportWidth / (float) defaultFixedLayoutWidth;
+ EXPECT_EQ(minimumPageScaleFactor, webViewImpl->pageScaleFactor());
+
+ // Assume the user has pinch zoomed to page scale factor 2.
+ float userPinchPageScaleFactor = 2;
+ webViewImpl->setPageScaleFactorPreservingScrollOffset(userPinchPageScaleFactor);
+ webViewImpl->mainFrameImpl()->frameView()->layout();
+
+ // Make sure we don't reset to initial scale if the page continues to load.
+ bool isNewNavigation;
+ webViewImpl->didCommitLoad(&isNewNavigation, false);
+ webViewImpl->didChangeContentsSize();
+ EXPECT_EQ(userPinchPageScaleFactor, webViewImpl->pageScaleFactor());
+
+ // Make sure we don't reset to initial scale if the viewport size changes.
+ webViewImpl->resize(WebSize(viewportWidth, viewportHeight + 100));
+ EXPECT_EQ(userPinchPageScaleFactor, webViewImpl->pageScaleFactor());
+}
#endif
#if ENABLE(GESTURE_EVENTS)
diff --git a/Source/WebKit/chromium/tests/WebLayerTest.cpp b/Source/WebKit/chromium/tests/WebLayerTest.cpp
index 7c0831f90..8fc7c93bd 100644
--- a/Source/WebKit/chromium/tests/WebLayerTest.cpp
+++ b/Source/WebKit/chromium/tests/WebLayerTest.cpp
@@ -53,10 +53,12 @@ public:
MOCK_METHOD0(scheduleComposite, void());
virtual void updateAnimations(double frameBeginTime) { }
+ virtual void didBeginFrame() { }
virtual void layout() { }
virtual void applyScrollAndScale(const WebSize& scrollDelta, float scaleFactor) { }
virtual WebGraphicsContext3D* createContext3D() { return CompositorFakeWebGraphicsContext3D::create(WebGraphicsContext3D::Attributes()).leakPtr(); }
virtual void didRebindGraphicsContext(bool success) { }
+ virtual void willCommit() { }
virtual void didCommitAndDrawFrame() { }
virtual void didCompleteSwapBuffers() { }
};
diff --git a/Source/WebKit/chromium/tests/WebLayerTreeViewTest.cpp b/Source/WebKit/chromium/tests/WebLayerTreeViewTest.cpp
new file mode 100644
index 000000000..2df259f76
--- /dev/null
+++ b/Source/WebKit/chromium/tests/WebLayerTreeViewTest.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "platform/WebLayerTreeView.h"
+
+#include "CompositorFakeWebGraphicsContext3D.h"
+#include "WebCompositor.h"
+#include "public/WebLayer.h"
+#include "public/WebLayerTreeViewClient.h"
+#include "public/WebThread.h"
+#include <gmock/gmock.h>
+#include <public/Platform.h>
+
+using namespace WebKit;
+using testing::Mock;
+using testing::Test;
+
+namespace {
+
+class MockWebLayerTreeViewClient : public WebLayerTreeViewClient {
+public:
+ virtual void scheduleComposite() OVERRIDE { }
+ virtual void updateAnimations(double frameBeginTime) OVERRIDE { }
+ MOCK_METHOD0(willBeginFrame, void());
+ MOCK_METHOD0(didBeginFrame, void());
+ virtual void layout() OVERRIDE { }
+ virtual void applyScrollAndScale(const WebSize& scrollDelta, float scaleFactor) OVERRIDE { }
+ virtual WebGraphicsContext3D* createContext3D() OVERRIDE { return CompositorFakeWebGraphicsContext3D::create(WebGraphicsContext3D::Attributes()).leakPtr(); }
+ virtual void didRebindGraphicsContext(bool success) OVERRIDE { }
+ MOCK_METHOD0(willCommit, void());
+ MOCK_METHOD0(didCommit, void());
+ virtual void didCommitAndDrawFrame() OVERRIDE { }
+ virtual void didCompleteSwapBuffers() OVERRIDE { }
+};
+
+class MockWebLayerTreeViewClientForThreadedTests : public MockWebLayerTreeViewClient {
+public:
+ virtual void didBeginFrame() OVERRIDE
+ {
+ WebKit::Platform::current()->currentThread()->exitRunLoop();
+ MockWebLayerTreeViewClient::didBeginFrame();
+ }
+};
+
+class WebLayerTreeViewTestBase : public Test {
+protected:
+ virtual void initializeCompositor() = 0;
+ virtual WebLayerTreeViewClient* client() = 0;
+
+public:
+ virtual void SetUp()
+ {
+ initializeCompositor();
+ m_rootLayer = WebLayer::create();
+ EXPECT_TRUE(m_view.initialize(client(), m_rootLayer, WebLayerTreeView::Settings()));
+ m_view.setSurfaceReady();
+ }
+
+ virtual void TearDown()
+ {
+ Mock::VerifyAndClearExpectations(client());
+
+ m_view.setRootLayer(0);
+ m_rootLayer.reset();
+ m_view.reset();
+ WebKit::WebCompositor::shutdown();
+ }
+
+protected:
+ WebLayer m_rootLayer;
+ WebLayerTreeView m_view;
+};
+
+class WebLayerTreeViewSingleThreadTest : public WebLayerTreeViewTestBase {
+protected:
+ void composite()
+ {
+ m_view.composite();
+ }
+
+ virtual void initializeCompositor() OVERRIDE
+ {
+ WebKit::WebCompositor::initialize(0);
+ }
+
+ virtual WebLayerTreeViewClient* client() OVERRIDE
+ {
+ return &m_client;
+ }
+
+ MockWebLayerTreeViewClient m_client;
+};
+
+class CancelableTaskWrapper : public RefCounted<CancelableTaskWrapper> {
+ class Task : public WebThread::Task {
+ public:
+ Task(CancelableTaskWrapper* cancelableTask)
+ : m_cancelableTask(cancelableTask)
+ {
+ }
+
+ private:
+ virtual void run() OVERRIDE
+ {
+ m_cancelableTask->runIfNotCanceled();
+ }
+
+ RefPtr<CancelableTaskWrapper> m_cancelableTask;
+ };
+
+public:
+ CancelableTaskWrapper(PassOwnPtr<WebThread::Task> task)
+ : m_task(task)
+ {
+ }
+
+ void cancel()
+ {
+ m_task.clear();
+ }
+
+ WebThread::Task* createTask()
+ {
+ ASSERT(m_task);
+ return new Task(this);
+ }
+
+ void runIfNotCanceled()
+ {
+ if (!m_task)
+ return;
+ m_task->run();
+ m_task.clear();
+ }
+
+private:
+ OwnPtr<WebThread::Task> m_task;
+};
+
+class WebLayerTreeViewThreadedTest : public WebLayerTreeViewTestBase {
+protected:
+ class TimeoutTask : public WebThread::Task {
+ virtual void run() OVERRIDE
+ {
+ WebKit::Platform::current()->currentThread()->exitRunLoop();
+ }
+ };
+
+ void composite()
+ {
+ m_view.setNeedsRedraw();
+ RefPtr<CancelableTaskWrapper> timeoutTask = adoptRef(new CancelableTaskWrapper(adoptPtr(new TimeoutTask())));
+ WebKit::Platform::current()->currentThread()->postDelayedTask(timeoutTask->createTask(), 5000);
+ WebKit::Platform::current()->currentThread()->enterRunLoop();
+ timeoutTask->cancel();
+ m_view.finishAllRendering();
+ }
+
+ virtual void initializeCompositor() OVERRIDE
+ {
+ m_webThread = adoptPtr(WebKit::Platform::current()->createThread("WebLayerTreeViewTest"));
+ WebCompositor::initialize(m_webThread.get());
+ }
+
+ virtual WebLayerTreeViewClient* client() OVERRIDE
+ {
+ return &m_client;
+ }
+
+ MockWebLayerTreeViewClientForThreadedTests m_client;
+ OwnPtr<WebThread> m_webThread;
+};
+
+TEST_F(WebLayerTreeViewSingleThreadTest, InstrumentationCallbacks)
+{
+ ::testing::InSequence dummy;
+
+ EXPECT_CALL(m_client, willCommit());
+ EXPECT_CALL(m_client, didCommit());
+ EXPECT_CALL(m_client, didBeginFrame());
+
+ composite();
+}
+
+TEST_F(WebLayerTreeViewThreadedTest, InstrumentationCallbacks)
+{
+ ::testing::InSequence dummy;
+
+ EXPECT_CALL(m_client, willBeginFrame());
+ EXPECT_CALL(m_client, willCommit());
+ EXPECT_CALL(m_client, didCommit());
+ EXPECT_CALL(m_client, didBeginFrame());
+
+ composite();
+}
+
+} // namespace
diff --git a/Source/WebKit/chromium/tests/WebTransformationMatrixTest.cpp b/Source/WebKit/chromium/tests/WebTransformationMatrixTest.cpp
index af291698a..2888e0d7c 100644
--- a/Source/WebKit/chromium/tests/WebTransformationMatrixTest.cpp
+++ b/Source/WebKit/chromium/tests/WebTransformationMatrixTest.cpp
@@ -24,9 +24,11 @@
#include "config.h"
-#include "../../../../Platform/chromium/public/WebTransformationMatrix.h"
+#include <public/WebTransformationMatrix.h>
+#include "CCLayerTreeTestCommon.h"
#include <gtest/gtest.h>
+#include <wtf/MathExtras.h>
#define EXPECT_ROW1_EQ(a, b, c, d, matrix) \
EXPECT_FLOAT_EQ((a), (matrix).m11()); \
@@ -74,6 +76,7 @@
EXPECT_NEAR((d), (matrix).m43(), (errorThreshold));
#define ERROR_THRESHOLD 1e-14
+#define LOOSE_ERROR_THRESHOLD 1e-7
using namespace WebKit;
@@ -926,7 +929,7 @@ TEST(WebTransformationMatrixTest, verifyIsIdentityOrTranslation)
EXPECT_FALSE(A.isIdentityOrTranslation());
}
-TEST(WebTransformationMatrixTest, isIntegerTranslation)
+TEST(WebTransformationMatrixTest, verifyIsIntegerTranslation)
{
WebTransformationMatrix A;
@@ -953,4 +956,329 @@ TEST(WebTransformationMatrixTest, isIntegerTranslation)
EXPECT_TRUE(A.isIntegerTranslation());
}
+TEST(WebTransformationMatrixTest, verifyBlendForTranslation)
+{
+ WebTransformationMatrix from;
+ from.translate3d(100, 200, 100);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.translate3d(200, 100, 300);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ to.makeIdentity();
+ to.translate3d(200, 100, 300);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_EQ(1, 0, 0, 125, to);
+ EXPECT_ROW2_EQ(0, 1, 0, 175, to);
+ EXPECT_ROW3_EQ(0, 0, 1, 150, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.translate3d(200, 100, 300);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_EQ(1, 0, 0, 150, to);
+ EXPECT_ROW2_EQ(0, 1, 0, 150, to);
+ EXPECT_ROW3_EQ(0, 0, 1, 200, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.translate3d(200, 100, 300);
+ to.blend(from, 1);
+ EXPECT_ROW1_EQ(1, 0, 0, 200, to);
+ EXPECT_ROW2_EQ(0, 1, 0, 100, to);
+ EXPECT_ROW3_EQ(0, 0, 1, 300, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+TEST(WebTransformationMatrixTest, verifyBlendForScale)
+{
+ WebTransformationMatrix from;
+ from.scale3d(100, 200, 100);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.scale3d(200, 100, 300);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ to.makeIdentity();
+ to.scale3d(200, 100, 300);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_EQ(125, 0, 0, 0, to);
+ EXPECT_ROW2_EQ(0, 175, 0, 0, to);
+ EXPECT_ROW3_EQ(0, 0, 150, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.scale3d(200, 100, 300);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_EQ(150, 0, 0, 0, to);
+ EXPECT_ROW2_EQ(0, 150, 0, 0, to);
+ EXPECT_ROW3_EQ(0, 0, 200, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.scale3d(200, 100, 300);
+ to.blend(from, 1);
+ EXPECT_ROW1_EQ(200, 0, 0, 0, to);
+ EXPECT_ROW2_EQ(0, 100, 0, 0, to);
+ EXPECT_ROW3_EQ(0, 0, 300, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+TEST(WebTransformationMatrixTest, verifyBlendForSkewX)
+{
+ WebTransformationMatrix from;
+ from.skewX(0);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.skewX(45);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ to.makeIdentity();
+ to.skewX(45);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_EQ(1, 0.5, 0, 0, to);
+ EXPECT_ROW2_EQ(0, 1, 0, 0, to);
+ EXPECT_ROW3_EQ(0, 0, 1, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.skewX(45);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_EQ(1, 0.25, 0, 0, to);
+ EXPECT_ROW2_EQ(0, 1, 0, 0, to);
+ EXPECT_ROW3_EQ(0, 0, 1, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.skewX(45);
+ to.blend(from, 1);
+ EXPECT_ROW1_EQ(1, 1, 0, 0, to);
+ EXPECT_ROW2_EQ(0, 1, 0, 0, to);
+ EXPECT_ROW3_EQ(0, 0, 1, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+TEST(WebTransformationMatrixTest, verifyBlendForSkewY)
+{
+ // NOTE CAREFULLY: Decomposition of skew and rotation terms of the matrix is
+ // inherently underconstrained, and so it does not always compute the originally
+ // intended skew parameters. The current implementation uses QR decomposition, which
+ // decomposes the shear into a rotation + non-uniform scale.
+ //
+ // It is unlikely that the decomposition implementation will need to change very
+ // often, so to get any test coverage, the compromise is to verify the exact matrix
+ // that the blend() operation produces.
+ //
+ // This problem also potentially exists for skewX, but the current QR decomposition
+ // implementation just happens to decompose those test matrices intuitively.
+
+ WebTransformationMatrix from;
+ from.skewY(0);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.skewY(45);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ to.makeIdentity();
+ to.skewY(45);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_NEAR(1.0823489449280947471976333, 0.0464370719145053845178239, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0.2152925909665224513123150, 0.9541702441750861130032035, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_EQ(0, 0, 1, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.skewY(45);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_NEAR(1.1152212925809066312865525, 0.0676495144007326631996335, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0.4619397844342648662419037, 0.9519009045724774464858342, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_EQ(0, 0, 1, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ // Unfortunately, this case suffers from uncomfortably large precision error.
+ to.makeIdentity();
+ to.skewY(45);
+ to.blend(from, 1);
+ EXPECT_ROW1_NEAR(1, 0, 0, 0, to, LOOSE_ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(1, 1, 0, 0, to, LOOSE_ERROR_THRESHOLD);
+ EXPECT_ROW3_EQ(0, 0, 1, 0, to);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutX)
+{
+ // Even though blending uses quaternions, axis-aligned rotations should blend the same
+ // with quaternions or Euler angles. So we can test rotation blending by comparing
+ // against manually specified matrices from Euler angles.
+
+ WebTransformationMatrix from;
+ from.rotate3d(1, 0, 0, 0);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.rotate3d(1, 0, 0, 90);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ double expectedRotationAngle = 22.5 * piDouble / 180.0;
+ to.makeIdentity();
+ to.rotate3d(1, 0, 0, 90);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0, cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(0, sin(expectedRotationAngle), cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ expectedRotationAngle = 45.0 * piDouble / 180.0;
+ to.makeIdentity();
+ to.rotate3d(1, 0, 0, 90);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0, cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(0, sin(expectedRotationAngle), cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.rotate3d(1, 0, 0, 90);
+ to.blend(from, 1);
+ EXPECT_ROW1_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0, 0, -1, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutY)
+{
+ WebTransformationMatrix from;
+ from.rotate3d(0, 1, 0, 0);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.rotate3d(0, 1, 0, 90);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ double expectedRotationAngle = 22.5 * piDouble / 180.0;
+ to.makeIdentity();
+ to.rotate3d(0, 1, 0, 90);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_NEAR(cos(expectedRotationAngle), 0, sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(-sin(expectedRotationAngle), 0, cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ expectedRotationAngle = 45.0 * piDouble / 180.0;
+ to.makeIdentity();
+ to.rotate3d(0, 1, 0, 90);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_NEAR(cos(expectedRotationAngle), 0, sin(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(-sin(expectedRotationAngle), 0, cos(expectedRotationAngle), 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.rotate3d(0, 1, 0, 90);
+ to.blend(from, 1);
+ EXPECT_ROW1_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(0, 1, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(-1, 0, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+TEST(WebTransformationMatrixTest, verifyBlendForRotationAboutZ)
+{
+ WebTransformationMatrix from;
+ from.rotate3d(0, 0, 1, 0);
+
+ WebTransformationMatrix to;
+
+ to.makeIdentity();
+ to.rotate3d(0, 0, 1, 90);
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ double expectedRotationAngle = 22.5 * piDouble / 180.0;
+ to.makeIdentity();
+ to.rotate3d(0, 0, 1, 90);
+ to.blend(from, 0.25);
+ EXPECT_ROW1_NEAR(cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(sin(expectedRotationAngle), cos(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ expectedRotationAngle = 45.0 * piDouble / 180.0;
+ to.makeIdentity();
+ to.rotate3d(0, 0, 1, 90);
+ to.blend(from, 0.5);
+ EXPECT_ROW1_NEAR(cos(expectedRotationAngle), -sin(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(sin(expectedRotationAngle), cos(expectedRotationAngle), 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+
+ to.makeIdentity();
+ to.rotate3d(0, 0, 1, 90);
+ to.blend(from, 1);
+ EXPECT_ROW1_NEAR(0, -1, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW2_NEAR(1, 0, 0, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW3_NEAR(0, 0, 1, 0, to, ERROR_THRESHOLD);
+ EXPECT_ROW4_EQ(0, 0, 0, 1, to);
+}
+
+
+TEST(WebTransformationMatrixTest, verifyBlendForCompositeTransform)
+{
+ // Verify that the blending was done with a decomposition in correct order by blending
+ // a composite transform.
+ // Using matrix x vector notation (Ax = b, where x is column vector), the ordering should be:
+ // perspective * translation * rotation * skew * scale
+ //
+ // It is not as important (or meaningful) to check intermediate interpolations; order
+ // of operations will be tested well enough by the end cases that are easier to
+ // specify.
+
+ WebTransformationMatrix from;
+ WebTransformationMatrix to;
+
+ WebTransformationMatrix expectedEndOfAnimation;
+ expectedEndOfAnimation.applyPerspective(1);
+ expectedEndOfAnimation.translate3d(10, 20, 30);
+ expectedEndOfAnimation.rotate3d(0, 0, 1, 25);
+ expectedEndOfAnimation.skewY(45);
+ expectedEndOfAnimation.scale3d(6, 7, 8);
+
+ to = expectedEndOfAnimation;
+ to.blend(from, 0);
+ EXPECT_TRANSFORMATION_MATRIX_EQ(from, to);
+
+ to = expectedEndOfAnimation;
+ to.blend(from, 1);
+
+ // Recomposing the matrix results in a normalized matrix, so to verify we need to
+ // normalize the expectedEndOfAnimation before comparing elements. Normalizing means
+ // dividing everything by expectedEndOfAnimation.m44().
+ WebTransformationMatrix normalizedExpectedEndOfAnimation = expectedEndOfAnimation;
+ WebTransformationMatrix normalizationMatrix;
+ normalizationMatrix.setM11(1 / expectedEndOfAnimation.m44());
+ normalizationMatrix.setM22(1 / expectedEndOfAnimation.m44());
+ normalizationMatrix.setM33(1 / expectedEndOfAnimation.m44());
+ normalizationMatrix.setM44(1 / expectedEndOfAnimation.m44());
+ normalizedExpectedEndOfAnimation.multiply(normalizationMatrix);
+
+ EXPECT_TRANSFORMATION_MATRIX_EQ(normalizedExpectedEndOfAnimation, to);
+}
+
} // namespace
diff --git a/Source/WebKit/chromium/tests/data/fixed_layout.html b/Source/WebKit/chromium/tests/data/fixed_layout.html
new file mode 100644
index 000000000..a89cecae9
--- /dev/null
+++ b/Source/WebKit/chromium/tests/data/fixed_layout.html
@@ -0,0 +1 @@
+<body>Ordinary non-mobile page</body>