diff --git a/content/base/public/nsIContent.h b/content/base/public/nsIContent.h index 0747b76fef8..07871d8cb8f 100644 --- a/content/base/public/nsIContent.h +++ b/content/base/public/nsIContent.h @@ -11,7 +11,6 @@ #include "nsChangeHint.h" #include "nsINode.h" #include "nsIDocument.h" // for IsInHTMLDocument -#include "nsCSSProperty.h" // Forward declarations class nsIAtom; diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 162ebf17f70..497d293b4b9 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -1291,8 +1291,6 @@ private: NodeMayHaveDOMMutationObserver, // Set if node is Content NodeIsContent, - // Set if the node has animations or transitions - ElementHasAnimations, // Guard value BooleanFlagCount }; @@ -1358,8 +1356,6 @@ public: bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); } void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); } void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); } - bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); } - void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); } protected: void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); } void SetInDocument() { SetBoolFlag(IsInDocument); } diff --git a/content/smil/nsSMILKeySpline.h b/content/smil/nsSMILKeySpline.h index 40122fd1f44..2891a018e90 100644 --- a/content/smil/nsSMILKeySpline.h +++ b/content/smil/nsSMILKeySpline.h @@ -26,11 +26,6 @@ public: Init(aX1, aY1, aX2, aY2); } - double X1() const { return mX1; } - double Y1() const { return mY1; } - double X2() const { return mX2; } - double Y2() const { return mY2; } - void Init(double aX1, double aY1, double aX2, double aY2); diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 4c920a73901..7eabc9f9848 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -17,7 +17,6 @@ #include "nsPrintfCString.h" #include "mozilla/Util.h" #include "LayerSorter.h" -#include "AnimationCommon.h" using namespace mozilla::layers; using namespace mozilla::gfx; @@ -221,244 +220,6 @@ LayerManager::CreateAsynchronousImageContainer() //-------------------------------------------------- // Layer -Layer::Layer(LayerManager* aManager, void* aImplData) : - mManager(aManager), - mParent(nullptr), - mNextSibling(nullptr), - mPrevSibling(nullptr), - mImplData(aImplData), - mMaskLayer(nullptr), - mXScale(1.0f), - mYScale(1.0f), - mOpacity(1.0), - mContentFlags(0), - mUseClipRect(false), - mUseTileSourceRect(false), - mIsFixedPosition(false), - mDebugColorIndex(0) -{} - -Layer::~Layer() -{} - -void -Layer::AddAnimation(const Animation& aAnimation) -{ - if (!AsShadowableLayer() || !AsShadowableLayer()->HasShadow()) - return; - - MOZ_ASSERT(aAnimation.segments().Length() >= 1); - - mAnimations.AppendElement(aAnimation); - Mutated(); -} - -void -Layer::ClearAnimations() -{ - mAnimations.Clear(); - mAnimationData.Clear(); - Mutated(); -} - -static nsCSSValueList* -CreateCSSValueList(const InfallibleTArray& aFunctions) -{ - nsAutoPtr result; - nsCSSValueList** resultTail = getter_Transfers(result); - for (PRUint32 i = 0; i < aFunctions.Length(); i++) { - nsRefPtr arr; - switch (aFunctions[i].type()) { - case TransformFunction::TRotationX: - { - float theta = aFunctions[i].get_RotationX().radians(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatex, resultTail); - arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian); - break; - } - case TransformFunction::TRotationY: - { - float theta = aFunctions[i].get_RotationY().radians(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatey, resultTail); - arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian); - break; - } - case TransformFunction::TRotationZ: - { - float theta = aFunctions[i].get_RotationZ().radians(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatez, resultTail); - arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian); - break; - } - case TransformFunction::TRotation: - { - float theta = aFunctions[i].get_Rotation().radians(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotate, resultTail); - arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian); - break; - } - case TransformFunction::TRotation3D: - { - float x = aFunctions[i].get_Rotation3D().x(); - float y = aFunctions[i].get_Rotation3D().y(); - float z = aFunctions[i].get_Rotation3D().z(); - float theta = aFunctions[i].get_Rotation3D().radians(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotate3d, resultTail); - arr->Item(1).SetFloatValue(x, eCSSUnit_Number); - arr->Item(2).SetFloatValue(y, eCSSUnit_Number); - arr->Item(3).SetFloatValue(z, eCSSUnit_Number); - arr->Item(4).SetFloatValue(theta, eCSSUnit_Radian); - break; - } - case TransformFunction::TScale: - { - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_scale3d, resultTail); - arr->Item(1).SetFloatValue(aFunctions[i].get_Scale().x(), eCSSUnit_Number); - arr->Item(2).SetFloatValue(aFunctions[i].get_Scale().y(), eCSSUnit_Number); - arr->Item(3).SetFloatValue(aFunctions[i].get_Scale().z(), eCSSUnit_Number); - break; - } - case TransformFunction::TTranslation: - { - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_translate3d, resultTail); - arr->Item(1).SetFloatValue(aFunctions[i].get_Translation().x(), eCSSUnit_Pixel); - arr->Item(2).SetFloatValue(aFunctions[i].get_Translation().y(), eCSSUnit_Pixel); - arr->Item(3).SetFloatValue(aFunctions[i].get_Translation().z(), eCSSUnit_Pixel); - break; - } - case TransformFunction::TSkewX: - { - float x = aFunctions[i].get_SkewX().x(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_skewx, resultTail); - arr->Item(1).SetFloatValue(x, eCSSUnit_Number); - break; - } - case TransformFunction::TSkewY: - { - float y = aFunctions[i].get_SkewY().y(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_skewy, resultTail); - arr->Item(1).SetFloatValue(y, eCSSUnit_Number); - break; - } - case TransformFunction::TTransformMatrix: - { - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_matrix3d, resultTail); - const gfx3DMatrix& matrix = aFunctions[i].get_TransformMatrix().value(); - arr->Item(1).SetFloatValue(matrix._11, eCSSUnit_Number); - arr->Item(2).SetFloatValue(matrix._12, eCSSUnit_Number); - arr->Item(3).SetFloatValue(matrix._13, eCSSUnit_Number); - arr->Item(4).SetFloatValue(matrix._14, eCSSUnit_Number); - arr->Item(5).SetFloatValue(matrix._21, eCSSUnit_Number); - arr->Item(6).SetFloatValue(matrix._22, eCSSUnit_Number); - arr->Item(7).SetFloatValue(matrix._23, eCSSUnit_Number); - arr->Item(8).SetFloatValue(matrix._24, eCSSUnit_Number); - arr->Item(9).SetFloatValue(matrix._31, eCSSUnit_Number); - arr->Item(10).SetFloatValue(matrix._32, eCSSUnit_Number); - arr->Item(11).SetFloatValue(matrix._33, eCSSUnit_Number); - arr->Item(12).SetFloatValue(matrix._34, eCSSUnit_Number); - arr->Item(13).SetFloatValue(matrix._41, eCSSUnit_Number); - arr->Item(14).SetFloatValue(matrix._42, eCSSUnit_Number); - arr->Item(15).SetFloatValue(matrix._43, eCSSUnit_Number); - arr->Item(16).SetFloatValue(matrix._44, eCSSUnit_Number); - break; - } - case TransformFunction::TPerspective: - { - float perspective = aFunctions[i].get_Perspective().value(); - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_perspective, resultTail); - arr->Item(1).SetFloatValue(perspective, eCSSUnit_Pixel); - break; - } - default: - NS_ASSERTION(false, "All functions should be implemented?"); - } - } - return result.forget(); -} - -void -Layer::SetAnimations(const AnimationArray& aAnimations) -{ - mAnimations = aAnimations; - mAnimationData.Clear(); - for (PRUint32 i = 0; i < mAnimations.Length(); i++) { - AnimData data; - InfallibleTArray* functions = - &data.mFunctions; - nsTArray segments = mAnimations.ElementAt(i).segments(); - for (PRUint32 j = 0; j < segments.Length(); j++) { - TimingFunction tf = segments.ElementAt(j).sampleFn(); - css::ComputedTimingFunction* ctf = functions->AppendElement(); - switch (tf.type()) { - case TimingFunction::TCubicBezierFunction: { - CubicBezierFunction cbf = tf.get_CubicBezierFunction(); - ctf->Init(nsTimingFunction(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2())); - break; - } - default: { - NS_ASSERTION(tf.type() == TimingFunction::TStepFunction, - "Function must be bezier or step"); - StepFunction sf = tf.get_StepFunction(); - nsTimingFunction::Type type = sf.type() == 1 ? nsTimingFunction::StepStart - : nsTimingFunction::StepEnd; - ctf->Init(nsTimingFunction(type, sf.steps())); - break; - } - } - } - - // Precompute the nsStyleAnimation::Values that we need if this is a transform - // animation. - InfallibleTArray* startValues = - &data.mStartValues; - InfallibleTArray* endValues = - &data.mEndValues; - for (PRUint32 j = 0; j < mAnimations[i].segments().Length(); j++) { - const AnimationSegment& segment = mAnimations[i].segments()[j]; - if (segment.endState().type() == Animatable::TArrayOfTransformFunction) { - const InfallibleTArray& startFunctions = - segment.startState().get_ArrayOfTransformFunction(); - nsStyleAnimation::Value startValue; - nsCSSValueList* startList; - if (startFunctions.Length() > 0) { - startList = CreateCSSValueList(startFunctions); - } else { - startList = new nsCSSValueList(); - startList->mValue.SetNoneValue(); - } - startValue.SetAndAdoptCSSValueListValue(startList, nsStyleAnimation::eUnit_Transform); - startValues->AppendElement(startValue); - - const InfallibleTArray& endFunctions = - segment.endState().get_ArrayOfTransformFunction(); - nsStyleAnimation::Value endValue; - nsCSSValueList* endList; - if (endFunctions.Length() > 0) { - endList = CreateCSSValueList(endFunctions); - } else { - endList = new nsCSSValueList(); - endList->mValue.SetNoneValue(); - } - endValue.SetAndAdoptCSSValueListValue(endList, nsStyleAnimation::eUnit_Transform); - endValues->AppendElement(endValue); - } else { - NS_ASSERTION(segment.endState().type() == Animatable::TOpacity, - "Unknown Animatable type"); - nsStyleAnimation::Value startValue; - startValue.SetFloatValue(segment.startState().get_Opacity().value()); - startValues->AppendElement(startValue); - - nsStyleAnimation::Value endValue; - endValue.SetFloatValue(segment.endState().get_Opacity().value()); - endValues->AppendElement(endValue); - } - } - mAnimationData.AppendElement(data); - } - - Mutated(); -} - bool Layer::CanUseOpaqueSurface() { @@ -543,7 +304,7 @@ Layer::SnapTransform(const gfx3DMatrix& aTransform, return result; } -nsIntRect +nsIntRect Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect, const gfxMatrix* aWorldTransform) { @@ -600,42 +361,21 @@ Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect, return currentClip.Intersect(scissor); } -const gfx3DMatrix -Layer::GetTransform() -{ - gfx3DMatrix transform = mTransform; - transform.Scale(mXScale, mYScale, 1); - return transform; -} - -const gfx3DMatrix +const gfx3DMatrix& Layer::GetLocalTransform() -{ - gfx3DMatrix transform; - if (ShadowLayer* shadow = AsShadowLayer()) { - transform = shadow->GetShadowTransform(); - } else { - transform = mTransform; - } - transform.Scale(mXScale, mYScale, 1); - return transform; -} - -const float -Layer::GetLocalOpacity() { if (ShadowLayer* shadow = AsShadowLayer()) - return shadow->GetShadowOpacity(); - return mOpacity; + return shadow->GetShadowTransform(); + return mTransform; } float Layer::GetEffectiveOpacity() { - float opacity = GetLocalOpacity(); + float opacity = GetOpacity(); for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface(); c = c->GetParent()) { - opacity *= c->GetLocalOpacity(); + opacity *= c->GetOpacity(); } return opacity; } @@ -1050,7 +790,7 @@ void LayerManager::Dump(FILE* aFile, const char* aPrefix) { FILE* file = FILEOrDefault(aFile); - + fprintf(file, "
", pfx.get()); return; } - + fprintf(file, "
    "); GetRoot()->Dump(file, pfx.get()); fprintf(file, "
"); @@ -1201,5 +941,5 @@ LayerManager::PrintInfo(nsACString& aTo, const char* aPrefix) PRLogModuleInfo* LayerManager::sLog; -} // namespace layers +} // namespace layers } // namespace mozilla diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 9ae26bf9bf8..79257b8d069 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -18,7 +18,6 @@ #include "gfxPattern.h" #include "nsTArray.h" #include "nsThreadUtils.h" -#include "nsStyleAnimation.h" #include "LayersBackend.h" #include "mozilla/gfx/2D.h" #include "mozilla/TimeStamp.h" @@ -44,14 +43,8 @@ namespace gl { class GLContext; } -namespace css { -class ComputedTimingFunction; -} - namespace layers { -class Animation; -class CommonLayerAttributes; class Layer; class ThebesLayer; class ContainerLayer; @@ -537,13 +530,6 @@ private: }; class ThebesLayer; -typedef InfallibleTArray AnimationArray; - -struct AnimData { - InfallibleTArray mStartValues; - InfallibleTArray mEndValues; - InfallibleTArray mFunctions; -}; /** * A Layer represents anything that can be rendered onto a destination @@ -565,7 +551,7 @@ public: TYPE_THEBES }; - virtual ~Layer(); + virtual ~Layer() {} /** * Returns the LayerManager this Layer belongs to. Note that the layer @@ -716,19 +702,12 @@ public: * XXX Currently only transformations corresponding to 2D affine transforms * are supported. */ - void SetBaseTransform(const gfx3DMatrix& aMatrix) + void SetTransform(const gfx3DMatrix& aMatrix) { mTransform = aMatrix; Mutated(); } - void SetScale(float aXScale, float aYScale) - { - mXScale = aXScale; - mYScale = aYScale; - Mutated(); - } - /** * CONSTRUCTION PHASE ONLY * A layer is "fixed position" when it draws content from a content @@ -737,14 +716,6 @@ public: */ void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; } - // Call AddAnimation to add an animation to this layer from layout code. - void AddAnimation(const Animation& aAnimation); - // ClearAnimations clears animations on this layer. - void ClearAnimations(); - // This is only called when the layer tree is updated. Do not call this from - // layout code. To add an animation to this layer, use AddAnimation. - void SetAnimations(const AnimationArray& aAnimations); - /** * CONSTRUCTION PHASE ONLY * If a layer is "fixed position", this determines which point on the layer @@ -764,15 +735,11 @@ public: Layer* GetPrevSibling() { return mPrevSibling; } virtual Layer* GetFirstChild() { return nullptr; } virtual Layer* GetLastChild() { return nullptr; } - const gfx3DMatrix GetTransform(); - const gfx3DMatrix& GetBaseTransform() { return mTransform; } - float GetXScale() { return mXScale; } - float GetYScale() { return mYScale; } + const gfx3DMatrix& GetTransform() { return mTransform; } bool GetIsFixedPosition() { return mIsFixedPosition; } gfxPoint GetFixedPositionAnchor() { return mAnchor; } Layer* GetMaskLayer() { return mMaskLayer; } - AnimationArray& GetAnimations() { return mAnimations; } - InfallibleTArray& GetAnimationData() { return mAnimationData; } + /** * DRAWING PHASE ONLY * @@ -973,7 +940,20 @@ public: #endif protected: - Layer(LayerManager* aManager, void* aImplData); + Layer(LayerManager* aManager, void* aImplData) : + mManager(aManager), + mParent(nullptr), + mNextSibling(nullptr), + mPrevSibling(nullptr), + mImplData(aImplData), + mMaskLayer(nullptr), + mOpacity(1.0), + mContentFlags(0), + mUseClipRect(false), + mUseTileSourceRect(false), + mIsFixedPosition(false), + mDebugColorIndex(0) + {} void Mutated() { mManager->Mutated(this); } @@ -988,13 +968,7 @@ protected: * Returns the local transform for this layer: either mTransform or, * for shadow layers, GetShadowTransform() */ - const gfx3DMatrix GetLocalTransform(); - - /** - * Returns the local opacity for this layer: either mOpacity or, - * for shadow layers, GetShadowOpacity() - */ - const float GetLocalOpacity(); + const gfx3DMatrix& GetLocalTransform(); /** * Computes a tweaked version of aTransform that snaps a point or a rectangle @@ -1020,11 +994,7 @@ protected: gfx::UserData mUserData; nsIntRegion mVisibleRegion; gfx3DMatrix mTransform; - float mXScale; - float mYScale; gfx3DMatrix mEffectiveTransform; - AnimationArray mAnimations; - InfallibleTArray mAnimationData; float mOpacity; nsIntRect mClipRect; nsIntRect mTileSourceRect; diff --git a/gfx/layers/Makefile.in b/gfx/layers/Makefile.in index 06ce847476a..42906f6cef0 100644 --- a/gfx/layers/Makefile.in +++ b/gfx/layers/Makefile.in @@ -31,18 +31,16 @@ EXPORTS = \ BasicLayers.h \ BasicTiledThebesLayer.h \ BasicImplData.h \ - CompositorParent.h \ ImageLayers.h \ Layers.h \ LayersBackend.h \ LayerManagerOGLShaders.h \ LayerManagerOGL.h \ LayerManagerOGLProgram.h \ - LayerSorter.h \ ReadbackLayer.h \ - ShadowLayersManager.h \ - SharedTextureImage.h \ + LayerSorter.h \ TexturePoolOGL.h \ + SharedTextureImage.h \ $(NULL) CPPSRCS = \ diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 08b8850a9ff..b508f37d228 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -21,15 +21,6 @@ #include "nsIWidget.h" #include "RenderTrace.h" #include "ShadowLayersParent.h" -#include "BasicLayers.h" -#include "LayerManagerOGL.h" -#include "nsIWidget.h" -#include "nsGkAtoms.h" -#include "RenderTrace.h" -#include "nsStyleAnimation.h" -#include "nsDisplayList.h" -#include "AnimationCommon.h" -#include "nsAnimationManager.h" using namespace base; using namespace mozilla::ipc; @@ -440,15 +431,15 @@ CompositorParent::Composite() return; } - Layer* layer = mLayerManager->GetRoot(); - AutoResolveRefLayers resolve(layer); + Layer* aLayer = mLayerManager->GetRoot(); + AutoResolveRefLayers resolve(aLayer); bool requestNextFrame = TransformShadowTree(mLastCompose); if (requestNextFrame) { ScheduleComposition(); } - RenderTraceLayers(layer, "0000"); + RenderTraceLayers(aLayer, "0000"); if (LAYERS_OPENGL == mLayerManager->GetBackendType() && !mTargetConfig.naturalBounds().IsEmpty()) { @@ -545,10 +536,9 @@ SetShadowProperties(Layer* aLayer) { // FIXME: Bug 717688 -- Do these updates in ShadowLayersParent::RecvUpdate. ShadowLayer* shadow = aLayer->AsShadowLayer(); - shadow->SetShadowTransform(aLayer->GetBaseTransform()); + shadow->SetShadowTransform(aLayer->GetTransform()); shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion()); shadow->SetShadowClipRect(aLayer->GetClipRect()); - shadow->SetShadowOpacity(aLayer->GetOpacity()); for (Layer* child = aLayer->GetFirstChild(); child; child = child->GetNextSibling()) { @@ -556,114 +546,6 @@ SetShadowProperties(Layer* aLayer) } } - -// SampleValue should eventually take the CSS property as an argument. This -// will be needed if we ever animate two values with the same type but different -// interpolation rules. -static void -SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aStart, - nsStyleAnimation::Value& aEnd, Animatable* aValue) -{ - nsStyleAnimation::Value interpolatedValue; - NS_ASSERTION(aStart.GetUnit() == aEnd.GetUnit() || - aStart.GetUnit() == nsStyleAnimation::eUnit_None || - aEnd.GetUnit() == nsStyleAnimation::eUnit_None, "Must have same unit"); - if (aStart.GetUnit() == nsStyleAnimation::eUnit_Transform || - aEnd.GetUnit() == nsStyleAnimation::eUnit_Transform) { - nsStyleAnimation::Interpolate(eCSSProperty_transform, aStart, aEnd, - aPortion, interpolatedValue); - nsCSSValueList* interpolatedList = interpolatedValue.GetCSSValueListValue(); - - TransformData& data = aAnimation.data().get_TransformData(); - gfx3DMatrix transform = - nsDisplayTransform::GetResultingTransformMatrix(nullptr, data.origin(), nsDeviceContext::AppUnitsPerCSSPixel(), - &data.bounds(), interpolatedList, &data.mozOrigin(), - &data.perspectiveOrigin(), &data.perspective()); - - InfallibleTArray* functions = new InfallibleTArray(); - functions->AppendElement(TransformMatrix(transform)); - *aValue = *functions; - return; - } - - NS_ASSERTION(aStart.GetUnit() == nsStyleAnimation::eUnit_Float, "Should be opacity"); - nsStyleAnimation::Interpolate(eCSSProperty_opacity, aStart, aEnd, - aPortion, interpolatedValue); - *aValue = interpolatedValue.GetFloatValue(); -} - -static bool -SampleAnimations(Layer* aLayer, TimeStamp aPoint) -{ - AnimationArray& animations = aLayer->GetAnimations(); - InfallibleTArray& animationData = aLayer->GetAnimationData(); - - bool activeAnimations = false; - - for (PRUint32 i = animations.Length(); i-- !=0; ) { - Animation& animation = animations[i]; - AnimData& animData = animationData[i]; - - double numIterations = animation.numIterations() != -1 ? - animation.numIterations() : NS_IEEEPositiveInfinity(); - double positionInIteration = - ElementAnimations::GetPositionInIteration(animation.startTime(), - aPoint, - animation.duration(), - numIterations, - animation.direction()); - - if (positionInIteration == -1) { - animations.RemoveElementAt(i); - animationData.RemoveElementAt(i); - continue; - } - - NS_ABORT_IF_FALSE(0.0 <= positionInIteration && - positionInIteration <= 1.0, - "position should be in [0-1]"); - - int segmentIndex = 0; - AnimationSegment* segment = animation.segments().Elements(); - while (segment->endPortion() < positionInIteration) { - ++segment; - ++segmentIndex; - } - - double positionInSegment = (positionInIteration - segment->startPortion()) / - (segment->endPortion() - segment->startPortion()); - - double portion = animData.mFunctions[segmentIndex].GetValue(positionInSegment); - - activeAnimations = true; - - // interpolate the property - Animatable interpolatedValue; - SampleValue(portion, animation, animData.mStartValues[segmentIndex], - animData.mEndValues[segmentIndex], &interpolatedValue); - ShadowLayer* shadow = aLayer->AsShadowLayer(); - switch (interpolatedValue.type()) { - case Animatable::TOpacity: - shadow->SetShadowOpacity(interpolatedValue.get_Opacity().value()); - break; - case Animatable::TArrayOfTransformFunction: { - gfx3DMatrix matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value(); - shadow->SetShadowTransform(matrix); - break; - } - default: - NS_WARNING("Unhandled animated property"); - } - } - - for (Layer* child = aLayer->GetFirstChild(); child; - child = child->GetNextSibling()) { - activeAnimations |= SampleAnimations(child, aPoint); - } - - return activeAnimations; -} - bool CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame, Layer *aLayer, @@ -709,13 +591,9 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame) ContainerLayer* container = layer->AsContainerLayer(); Layer* root = mLayerManager->GetRoot(); - // NB: we must sample animations *before* sampling pan/zoom - // transforms. - wantNextFrame |= SampleAnimations(layer, mLastCompose); - const FrameMetrics& metrics = container->GetFrameMetrics(); const gfx3DMatrix& rootTransform = root->GetTransform(); - const gfx3DMatrix& currentTransform = layer->GetBaseTransform(); + const gfx3DMatrix& currentTransform = layer->GetTransform(); // FIXME/bug 775437: unify this interface with the ~native-fennec // derived code @@ -808,6 +686,7 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame) shadow->SetShadowTransform(treeTransform * currentTransform); TransformFixedLayers(layer, offset, scaleDiff); } + return wantNextFrame; } diff --git a/gfx/layers/ipc/PLayer.ipdl b/gfx/layers/ipc/PLayer.ipdl index 793c503b3f1..c740c157be6 100644 --- a/gfx/layers/ipc/PLayer.ipdl +++ b/gfx/layers/ipc/PLayer.ipdl @@ -14,7 +14,7 @@ namespace layers { * PLayer represents a layer shared across thread contexts. */ -async protocol PLayer { +sync protocol PLayer { manager PLayers; /** @@ -32,7 +32,7 @@ async protocol PLayer { * being deleted "soon" (usually immediately). */ parent: - async __delete__(); + __delete__(); }; } // layers diff --git a/gfx/layers/ipc/PLayers.ipdl b/gfx/layers/ipc/PLayers.ipdl index 339b83f4c6d..bc9918e6c33 100644 --- a/gfx/layers/ipc/PLayers.ipdl +++ b/gfx/layers/ipc/PLayers.ipdl @@ -14,14 +14,6 @@ include protocol PRenderFrame; include "gfxipc/ShadowLayerUtils.h"; include "mozilla/WidgetUtils.h"; -include "mozilla/TimeStamp.h"; - -using gfxPoint3D; -using nscoord; -using nsRect; -using nsPoint; -using mozilla::TimeDuration; -using mozilla::TimeStamp; /** * The layers protocol is spoken between thread contexts that manage @@ -50,7 +42,7 @@ struct OpCreateRefLayer { PLayer layer; }; struct ThebesBuffer { SurfaceDescriptor buffer; nsIntRect rect; - nsIntPoint rotation; + nsIntPoint rotation; }; union OptionalThebesBuffer { ThebesBuffer; null_t; }; @@ -59,129 +51,24 @@ union CanvasSurface { null_t; }; -struct CubicBezierFunction { - float x1; - float y1; - float x2; - float y2; -}; - -struct StepFunction { - int steps; - // 1 = nsTimingFunction::StepStart, 2 = nsTimingFunction::StepEnd - int type; -}; - -union TimingFunction { - CubicBezierFunction; - StepFunction; -}; - -struct Color { gfxRGBA value; }; -struct Opacity { float value; }; -struct Perspective { float value; }; -struct RotationX { float radians; }; -struct RotationY { float radians; }; -struct RotationZ { float radians; }; -struct Rotation { float radians; }; -struct Rotation3D { - float x; - float y; - float z; - float radians; -}; -struct Scale { - float x; - float y; - float z; -}; -struct SkewX { float x; }; -struct SkewY { float y; }; -struct TransformMatrix { gfx3DMatrix value; }; -struct Translation { - float x; - float y; - float z; -}; - -union TransformFunction { - Perspective; - RotationX; - RotationY; - RotationZ; - Rotation; - Rotation3D; - Scale; - SkewX; - SkewY; - Translation; - TransformMatrix; -}; - -union Animatable { - Color; - Opacity; - TransformFunction[]; -}; - -struct AnimationSegment { - Animatable startState; - Animatable endState; - float startPortion; - float endPortion; - TimingFunction sampleFn; -}; - -// Transforms need extra information to correctly convert the list of transform -// functions to a gfx3DMatrix that can be applied directly to the layer. -struct TransformData { - nsPoint origin; - gfxPoint3D mozOrigin; - gfxPoint3D perspectiveOrigin; - nsRect bounds; - nscoord perspective; -}; - -union AnimationData { - null_t; - TransformData; -}; - -struct Animation { - TimeStamp startTime; - TimeDuration duration; - // For each frame, the interpolation point is computed based on the - // startTime, the direction, the duration, and the current time. - // The segments must uniquely cover the portion from 0.0 to 1.0 - AnimationSegment[] segments; - // How many times to repeat the animation. < 0 means "forever". - float numIterations; - // This uses the NS_STYLE_ANIMATION_DIRECTION_* constants. - int32_t direction; - AnimationData data; -}; - +// Change a layer's attributes struct CommonLayerAttributes { nsIntRegion visibleRegion; - TransformMatrix transform; - float xScale; - float yScale; + gfx3DMatrix transform; PRUint32 contentFlags; - Opacity opacity; + float opacity; bool useClipRect; nsIntRect clipRect; bool isFixedPosition; gfxPoint fixedPositionAnchor; nullable PLayer maskLayer; - // Animated colors will only honored for ColorLayers. - Animation[] animations; }; struct ThebesLayerAttributes { nsIntRegion validRegion; }; struct ContainerLayerAttributes{ FrameMetrics metrics; }; -struct ColorLayerAttributes { Color color; }; +struct ColorLayerAttributes { gfxRGBA color; }; struct CanvasLayerAttributes { GraphicsFilterType filter; }; struct RefLayerAttributes { int64_t id; }; struct ImageLayerAttributes { diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 258ccce6773..8369d2f3e1b 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -299,9 +299,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies) LayerAttributes attrs; CommonLayerAttributes& common = attrs.common(); common.visibleRegion() = mutant->GetVisibleRegion(); - common.transform() = mutant->GetBaseTransform(); - common.xScale() = mutant->GetXScale(); - common.yScale() = mutant->GetYScale(); + common.transform() = mutant->GetTransform(); common.contentFlags() = mutant->GetContentFlags(); common.opacity() = mutant->GetOpacity(); common.useClipRect() = !!mutant->GetClipRect(); @@ -315,7 +313,6 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies) common.maskLayerChild() = NULL; } common.maskLayerParent() = NULL; - common.animations() = mutant->GetAnimations(); attrs.specific() = null_t(); mutant->FillSpecificAttributes(attrs.specific()); diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index d324fbfc632..815322e61b5 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -524,11 +524,6 @@ public: mShadowVisibleRegion = aRegion; } - void SetShadowOpacity(float aOpacity) - { - mShadowOpacity = aOpacity; - } - void SetShadowClipRect(const nsIntRect* aRect) { mUseShadowClipRect = aRect != nullptr; @@ -543,7 +538,6 @@ public: } // These getters can be used anytime. - float GetShadowOpacity() { return mShadowOpacity; } const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nullptr; } const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; } const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; } @@ -553,7 +547,6 @@ public: protected: ShadowLayer() : mAllocator(nullptr) - , mShadowOpacity(1.0) , mUseShadowClipRect(false) {} @@ -561,7 +554,6 @@ protected: nsIntRegion mShadowVisibleRegion; gfx3DMatrix mShadowTransform; nsIntRect mShadowClipRect; - float mShadowOpacity; bool mUseShadowClipRect; }; diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index f3bca517f16..043d8663f0a 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -214,10 +214,9 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, const CommonLayerAttributes& common = attrs.common(); layer->SetVisibleRegion(common.visibleRegion()); layer->SetContentFlags(common.contentFlags()); - layer->SetOpacity(common.opacity().value()); + layer->SetOpacity(common.opacity()); layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL); - layer->SetBaseTransform(common.transform().value()); - layer->SetScale(common.xScale(), common.yScale()); + layer->SetTransform(common.transform()); static bool fixedPositionLayersEnabled = getenv("MOZ_ENABLE_FIXED_POSITION_LAYERS") != 0; if (fixedPositionLayersEnabled) { layer->SetIsFixedPosition(common.isFixedPosition()); @@ -228,7 +227,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, } else { layer->SetMaskLayer(NULL); } - layer->SetAnimations(common.animations()); typedef SpecificLayerAttributes Specific; const SpecificLayerAttributes& specific = attrs.specific(); @@ -259,7 +257,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, MOZ_LAYERS_LOG(("[ParentSide] color layer")); static_cast(layer)->SetColor( - specific.get_ColorLayerAttributes().color().value()); + specific.get_ColorLayerAttributes().color()); break; case Specific::TCanvasLayerAttributes: diff --git a/gfx/layers/opengl/CanvasLayerOGL.cpp b/gfx/layers/opengl/CanvasLayerOGL.cpp index 20af9bba633..7d530e70baf 100644 --- a/gfx/layers/opengl/CanvasLayerOGL.cpp +++ b/gfx/layers/opengl/CanvasLayerOGL.cpp @@ -110,7 +110,7 @@ CanvasLayerOGL::Initialize(const Data& aData) } mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height); - + // Check the maximum texture size supported by GL. glTexImage2D supports // images of up to 2 + GL_MAX_TEXTURE_SIZE GLint texSize = gl()->GetMaxTextureSize(); @@ -119,7 +119,7 @@ CanvasLayerOGL::Initialize(const Data& aData) MakeTextureIfNeeded(gl(), mTexture); // This should only ever occur with 2d canvas, WebGL can't already have a texture // of this size can it? - NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, + NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "Invalid texture size when WebGL surface already exists at that size?"); } } @@ -291,7 +291,7 @@ ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager) { mImplData = static_cast(this); } - + ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL() {} diff --git a/gfx/src/nsRect.h b/gfx/src/nsRect.h index 8825523f590..4a99de8d0a9 100644 --- a/gfx/src/nsRect.h +++ b/gfx/src/nsRect.h @@ -199,12 +199,6 @@ struct NS_GFX nsRect : inline nsIntRect ScaleToInsidePixels(float aXScale, float aYScale, nscoord aAppUnitsPerPixel) const; inline nsIntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const; - - // This is here only to keep IPDL-generated code happy. DO NOT USE. - bool operator==(const nsRect& aRect) const - { - return IsEqualEdges(aRect); - } }; struct NS_GFX nsIntRect : diff --git a/ipc/glue/IPCMessageUtils.h b/ipc/glue/IPCMessageUtils.h index c4bd56c22f7..ea761cde0a3 100644 --- a/ipc/glue/IPCMessageUtils.h +++ b/ipc/glue/IPCMessageUtils.h @@ -9,7 +9,6 @@ #include "chrome/common/ipc_message_utils.h" -#include "mozilla/TimeStamp.h" #include "mozilla/Util.h" #include "mozilla/gfx/2D.h" @@ -440,28 +439,11 @@ struct ParamTraits static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { - return (ReadParam(aMsg, aIter, &aResult->x) && - ReadParam(aMsg, aIter, &aResult->y)); - } -}; + if (ReadParam(aMsg, aIter, &aResult->x) && + ReadParam(aMsg, aIter, &aResult->y)) + return true; -template<> -struct ParamTraits -{ - typedef gfxPoint3D paramType; - - static void Write(Message* aMsg, const paramType& aParam) - { - WriteParam(aMsg, aParam.x); - WriteParam(aMsg, aParam.y); - WriteParam(aMsg, aParam.z); - } - - static bool Read(const Message* aMsg, void** aIter, paramType* aResult) - { - return (ReadParam(aMsg, aIter, &aResult->x) && - ReadParam(aMsg, aIter, &aResult->y) && - ReadParam(aMsg, aIter, &aResult->z)); + return false; } }; @@ -595,29 +577,11 @@ struct ParamTraits } }; -template<> -struct ParamTraits -{ - typedef nsPoint paramType; - - static void Write(Message* msg, const paramType& param) - { - WriteParam(msg, param.x); - WriteParam(msg, param.y); - } - - static bool Read(const Message* msg, void** iter, paramType* result) - { - return (ReadParam(msg, iter, &result->x) && - ReadParam(msg, iter, &result->y)); - } -}; - template<> struct ParamTraits { typedef nsIntPoint paramType; - + static void Write(Message* msg, const paramType& param) { WriteParam(msg, param.x); @@ -635,7 +599,7 @@ template<> struct ParamTraits { typedef nsIntRect paramType; - + static void Write(Message* msg, const paramType& param) { WriteParam(msg, param.x); @@ -684,11 +648,11 @@ template<> struct ParamTraits { typedef nsIntSize paramType; - + static void Write(Message* msg, const paramType& param) { WriteParam(msg, param.width); - WriteParam(msg, param.height); + WriteParam(msg, param.height); } static bool Read(const Message* msg, void** iter, paramType* result) @@ -702,11 +666,11 @@ template<> struct ParamTraits { typedef mozilla::gfx::Size paramType; - + static void Write(Message* msg, const paramType& param) { WriteParam(msg, param.width); - WriteParam(msg, param.height); + WriteParam(msg, param.height); } static bool Read(const Message* msg, void** iter, paramType* result) @@ -742,7 +706,7 @@ template<> struct ParamTraits { typedef nsRect paramType; - + static void Write(Message* msg, const paramType& param) { WriteParam(msg, param.x); @@ -802,34 +766,6 @@ struct ParamTraits } }; -template<> -struct ParamTraits -{ - typedef mozilla::TimeDuration paramType; - static void Write(Message* aMsg, const paramType& aParam) - { - WriteParam(aMsg, aParam.mValue); - } - static bool Read(const Message* aMsg, void** aIter, paramType* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mValue); - }; -}; - -template<> -struct ParamTraits -{ - typedef mozilla::TimeStamp paramType; - static void Write(Message* aMsg, const paramType& aParam) - { - WriteParam(aMsg, aParam.mValue); - } - static bool Read(const Message* aMsg, void** aIter, paramType* aResult) - { - return ReadParam(aMsg, aIter, &aResult->mValue); - }; -}; - } /* namespace IPC */ #endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */ diff --git a/js/xpconnect/src/Makefile.in b/js/xpconnect/src/Makefile.in index 4e597396ce5..0f660b6d0b9 100644 --- a/js/xpconnect/src/Makefile.in +++ b/js/xpconnect/src/Makefile.in @@ -166,24 +166,9 @@ dombindings_gen.cpp: $(srcdir)/dombindings.conf \ --makedepend-output $(MDDEPDIR)/dombindingsgen.pp \ $(srcdir)/dombindings.conf -DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.h \ - DictionaryHelpers.cpp +DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.cpp -DictionaryHelpers.h: $(srcdir)/dictionary_helper_gen.conf \ - event_impl_gen.conf \ - $(srcdir)/dictionary_helper_gen.py \ - $(srcdir)/codegen.py \ - $(LIBXUL_DIST)/sdk/bin/header.py \ - $(LIBXUL_DIST)/sdk/bin/xpidl.py \ - $(DEPTH)/js/src/js-confdefs.h - $(PYTHON) $(topsrcdir)/config/pythonpath.py \ - $(PLY_INCLUDE) \ - -I$(LIBXUL_DIST)/sdk/bin \ - $(srcdir)/dictionary_helper_gen.py \ - -I $(DEPTH)/dist/idl \ - --header-output DictionaryHelpers.h \ - $(srcdir)/dictionary_helper_gen.conf \ - event_impl_gen.conf +DictionaryHelpers.h: DictionaryHelpers.cpp DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \ event_impl_gen.conf \ @@ -197,6 +182,7 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \ -I$(LIBXUL_DIST)/sdk/bin \ $(srcdir)/dictionary_helper_gen.py \ -I $(DEPTH)/dist/idl \ + --header-output DictionaryHelpers.h \ --stub-output DictionaryHelpers.cpp \ --makedepend-output $(MDDEPDIR)/dictionary_helper_gen.pp \ $(srcdir)/dictionary_helper_gen.conf \ diff --git a/js/xpconnect/src/event_impl_gen.py b/js/xpconnect/src/event_impl_gen.py index 21edeca935d..04f42e946cd 100644 --- a/js/xpconnect/src/event_impl_gen.py +++ b/js/xpconnect/src/event_impl_gen.py @@ -357,10 +357,6 @@ if __name__ == '__main__': conf = readConfigFile(filename) - if options.header_output is not None: - outfd = open(options.header_output, 'w') - print_header_file(outfd, conf) - outfd.close() if options.stub_output is not None: make_targets.append(options.stub_output) outfd = open(options.stub_output, 'w') @@ -368,4 +364,8 @@ if __name__ == '__main__': outfd.close() if options.makedepend_output is not None: writeMakeDependOutput(options.makedepend_output) + if options.header_output is not None: + outfd = open(options.header_output, 'w') + print_header_file(outfd, conf) + outfd.close() diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 6c805d1e429..6746b310038 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -21,9 +21,6 @@ #include "mozilla/Preferences.h" #include "sampler.h" -#include "nsAnimationManager.h" -#include "nsTransitionManager.h" - #ifdef DEBUG #include #endif @@ -631,7 +628,7 @@ FrameLayerBuilder::FlashPaint(gfxContext *aContext) if (!sPaintFlashingPrefCached) { sPaintFlashingPrefCached = true; - mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled, + mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled, "nglayout.debug.paint_flashing"); } @@ -947,7 +944,6 @@ ContainerState::CreateOrRecycleColorLayer() // We will reapply any necessary clipping. layer->SetClipRect(nullptr); layer->SetMaskLayer(nullptr); - layer->SetScale(1.0f, 1.0f); } else { // Create a new layer layer = mManager->CreateColorLayer(); @@ -971,7 +967,6 @@ ContainerState::CreateOrRecycleImageLayer() // We will reapply any necessary clipping. layer->SetClipRect(nullptr); layer->SetMaskLayer(nullptr); - layer->SetScale(1.0f, 1.0f); } else { // Create a new layer layer = mManager->CreateImageLayer(); @@ -989,7 +984,6 @@ ContainerState::CreateOrRecycleMaskImageLayerFor(Layer* aLayer) nsRefPtr result = mRecycledMaskImageLayers.Get(aLayer); if (result) { mRecycledMaskImageLayers.Remove(aLayer); - result->SetScale(1.0f, 1.0f); // XXX if we use clip on mask layers, null it out here } else { // Create a new layer @@ -999,7 +993,7 @@ ContainerState::CreateOrRecycleMaskImageLayerFor(Layer* aLayer) result->SetUserData(&gMaskLayerUserData, new MaskLayerUserData()); result->SetForceSingleTile(true); } - + return result.forget(); } @@ -1064,7 +1058,6 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot) // We will reapply any necessary clipping. layer->SetClipRect(nullptr); layer->SetMaskLayer(nullptr); - layer->SetScale(1.0f, 1.0f); data = static_cast (layer->GetUserData(&gThebesDisplayItemLayerUserData)); @@ -1118,8 +1111,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot) RoundToMatchResidual(scaledOffset.y, data->mActiveScrolledRootPosition.y)); gfxMatrix matrix; matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y)); - layer->SetBaseTransform(gfx3DMatrix::From2D(matrix)); - layer->SetScale(1.0f, 1.0f); + layer->SetTransform(gfx3DMatrix::From2D(matrix)); // FIXME: Temporary workaround for bug 681192 and bug 724786. #ifndef MOZ_JAVA_COMPOSITOR @@ -1239,7 +1231,7 @@ ContainerState::ThebesLayerData::UpdateCommonClipCount( } else { // first item in the layer mCommonClipCount = aCurrentClip.mRoundedClipRects.Length(); - } + } } already_AddRefed @@ -1261,7 +1253,7 @@ ContainerState::PopThebesLayerData() ThebesLayerData* data = mThebesLayerDataStack[lastIndex]; nsRefPtr layer; - nsRefPtr imageContainer = data->CanOptimizeImageLayer(); + nsRefPtr imageContainer = data->CanOptimizeImageLayer(); if ((data->mIsSolidColorInVisibleRegion || imageContainer) && data->mLayer->GetValidRegion().IsEmpty()) { @@ -1274,7 +1266,7 @@ ContainerState::PopThebesLayerData() // The layer's current transform is applied first, then the result is scaled. gfx3DMatrix transform = imageLayer->GetTransform()* gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f); - imageLayer->SetBaseTransform(transform); + imageLayer->SetTransform(transform); if (data->mItemClip.mHaveClipRect) { nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect); imageLayer->IntersectClipRect(clip); @@ -1285,10 +1277,9 @@ ContainerState::PopThebesLayerData() colorLayer->SetIsFixedPosition(data->mLayer->GetIsFixedPosition()); colorLayer->SetColor(data->mSolidColor); - // Copy transform and scale - colorLayer->SetBaseTransform(data->mLayer->GetBaseTransform()); - colorLayer->SetScale(data->mLayer->GetXScale(), data->mLayer->GetYScale()); - + // Copy transform + colorLayer->SetTransform(data->mLayer->GetTransform()); + // Clip colorLayer to its visible region, since ColorLayers are // allowed to paint outside the visible region. Here we rely on the // fact that uniform display items fill rectangles; obviously the @@ -1319,7 +1310,7 @@ ContainerState::PopThebesLayerData() if (!layer->GetTransform().Is2D(&transform)) { NS_ERROR("Only 2D transformations currently supported"); } - + // ImageLayers are already configured with a visible region if (!imageContainer) { NS_ASSERTION(!transform.HasNonIntegerTranslation(), @@ -1649,9 +1640,9 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder, nsRefPtr context = aContext; #ifdef MOZ_DUMP_PAINTING - nsRefPtr surf; + nsRefPtr surf; if (gfxUtils::sDumpPainting) { - surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(), + surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(), gfxASurface::CONTENT_COLOR_ALPHA); surf->SetDeviceOffset(-itemVisibleRect.TopLeft()); context = new gfxContext(surf); @@ -1684,7 +1675,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder, #ifdef MOZ_DUMP_PAINTING if (gfxUtils::sDumpPainting) { DumpPaintedImage(aItem, surf); - + surf->SetDeviceOffset(gfxPoint(0, 0)); aContext->SetSource(surf, itemVisibleRect.TopLeft()); aContext->Rectangle(itemVisibleRect); @@ -1786,7 +1777,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList, // The layer's current transform is applied first, then the result is scaled. gfx3DMatrix transform = ownLayer->GetTransform()* gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f); - ownLayer->SetBaseTransform(transform); + ownLayer->SetTransform(transform); } ownLayer->SetIsFixedPosition( @@ -2130,9 +2121,9 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder, scale = gfxSize(1.0, 1.0); } - aLayer->SetBaseTransform(transform); - // Store the inverse of our resolution-scale on the layer - aLayer->SetScale(1.0f/float(scale.width), 1.0f/float(scale.height)); + // Apply the inverse of our resolution-scale before the rest of our transform + transform = gfx3DMatrix::ScalingMatrix(1.0/scale.width, 1.0/scale.height, 1.0)*transform; + aLayer->SetTransform(transform); FrameLayerBuilder::ContainerParameters result(scale.width, scale.height, aIncomingScale); @@ -2561,8 +2552,8 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height); bounds.ScaleInverse(aDest->AppUnitsPerDevPixel()); - nsRefPtr surf = - gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), + nsRefPtr surf = + gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), gfxASurface::CONTENT_COLOR_ALPHA); surf->SetDeviceOffset(-bounds.TopLeft()); nsRefPtr context = new gfxContext(surf); @@ -2572,7 +2563,7 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi aItem->Paint(aBuilder, ctx); DumpPaintedImage(aItem, surf); aItem->SetPainted(); - + surf->SetDeviceOffset(gfxPoint(0, 0)); aDest->ThebesContext()->SetSource(surf, bounds.TopLeft()); aDest->ThebesContext()->Rectangle(bounds); @@ -3034,7 +3025,7 @@ CalculateBounds(nsTArray aRects, PRInt32 A void ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip, - PRUint32 aRoundedRectClipCount) + PRUint32 aRoundedRectClipCount) { // don't build an unnecessary mask nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds(); @@ -3060,7 +3051,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl aLayer->SetMaskLayer(maskLayer); return; } - + // calculate a more precise bounding rect const PRInt32 A2D = mContainerFrame->PresContext()->AppUnitsPerDevPixel(); gfxRect boundingRect = CalculateBounds(newData.mRoundedClipRects, A2D); @@ -3138,7 +3129,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl } maskLayer->SetContainer(container); - maskLayer->SetBaseTransform(gfx3DMatrix::From2D(maskTransform.Invert())); + maskLayer->SetTransform(gfx3DMatrix::From2D(maskTransform.Invert())); // save the details of the clip in user data userData->mScaleX = newData.mScaleX; diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 8ac62f0c589..4d32eb73e2a 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -10,8 +10,6 @@ * used during painting and hit testing */ -#include "mozilla/layers/PLayers.h" - #include "nsDisplayList.h" #include "nsCSSRendering.h" @@ -38,9 +36,6 @@ #include "nsSVGElement.h" #include "nsSVGClipPathFrame.h" #include "sampler.h" -#include "nsAnimationManager.h" -#include "nsTransitionManager.h" -#include "nsIViewManager.h" #include "mozilla/StandardInteger.h" @@ -48,367 +43,6 @@ using namespace mozilla; using namespace mozilla::layers; typedef FrameMetrics::ViewID ViewID; -static void AddTransformFunctions(nsCSSValueList* aList, - nsStyleContext* aContext, - nsPresContext* aPresContext, - nsRect& aBounds, - float aAppUnitsPerPixel, - InfallibleTArray& aFunctions) -{ - if (aList->mValue.GetUnit() == eCSSUnit_None) { - return; - } - - for (const nsCSSValueList* curr = aList; curr; curr = curr->mNext) { - const nsCSSValue& currElem = curr->mValue; - NS_ASSERTION(currElem.GetUnit() == eCSSUnit_Function, - "Stream should consist solely of functions!"); - nsCSSValue::Array* array = currElem.GetArrayValue(); - bool canStoreInRuleTree = true; - switch (nsStyleTransformMatrix::TransformFunctionOf(array)) { - case eCSSKeyword_rotatex: - { - double theta = array->Item(1).GetAngleValueInRadians(); - aFunctions.AppendElement(RotationX(theta)); - break; - } - case eCSSKeyword_rotatey: - { - double theta = array->Item(1).GetAngleValueInRadians(); - aFunctions.AppendElement(RotationY(theta)); - break; - } - case eCSSKeyword_rotatez: - { - double theta = array->Item(1).GetAngleValueInRadians(); - aFunctions.AppendElement(RotationZ(theta)); - break; - } - case eCSSKeyword_rotate: - { - double theta = array->Item(1).GetAngleValueInRadians(); - aFunctions.AppendElement(Rotation(theta)); - break; - } - case eCSSKeyword_rotate3d: - { - double x = array->Item(1).GetFloatValue(); - double y = array->Item(2).GetFloatValue(); - double z = array->Item(3).GetFloatValue(); - double theta = array->Item(4).GetAngleValueInRadians(); - aFunctions.AppendElement(Rotation3D(x, y, z, theta)); - break; - } - case eCSSKeyword_scalex: - { - double x = array->Item(1).GetFloatValue(); - aFunctions.AppendElement(Scale(x, 1, 1)); - break; - } - case eCSSKeyword_scaley: - { - double y = array->Item(1).GetFloatValue(); - aFunctions.AppendElement(Scale(1, y, 1)); - break; - } - case eCSSKeyword_scalez: - { - double z = array->Item(1).GetFloatValue(); - aFunctions.AppendElement(Scale(1, 1, z)); - break; - } - case eCSSKeyword_scale: - { - double x = array->Item(1).GetFloatValue(); - // scale(x) is shorthand for scale(x, x); - double y = array->Count() == 2 ? x : array->Item(2).GetFloatValue(); - aFunctions.AppendElement(Scale(x, y, 1)); - break; - } - case eCSSKeyword_scale3d: - { - double x = array->Item(1).GetFloatValue(); - double y = array->Item(2).GetFloatValue(); - double z = array->Item(3).GetFloatValue(); - aFunctions.AppendElement(Scale(x, y, z)); - break; - } - case eCSSKeyword_translatex: - { - double x = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(1), aContext, aPresContext, canStoreInRuleTree, - aBounds.Width(), aAppUnitsPerPixel); - aFunctions.AppendElement(Translation(x, 0, 0)); - break; - } - case eCSSKeyword_translatey: - { - double y = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(1), aContext, aPresContext, canStoreInRuleTree, - aBounds.Height(), aAppUnitsPerPixel); - aFunctions.AppendElement(Translation(0, y, 0)); - break; - } - case eCSSKeyword_translatez: - { - double z = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(1), aContext, aPresContext, canStoreInRuleTree, - 0, aAppUnitsPerPixel); - aFunctions.AppendElement(Translation(0, 0, z)); - break; - } - case eCSSKeyword_translate: - { - double x = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(1), aContext, aPresContext, canStoreInRuleTree, - aBounds.Width(), aAppUnitsPerPixel); - // translate(x) is shorthand for translate(x, 0) - double y = 0; - if (array->Count() == 3) { - y = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(2), aContext, aPresContext, canStoreInRuleTree, - aBounds.Height(), aAppUnitsPerPixel); - } - aFunctions.AppendElement(Translation(x, y, 0)); - break; - } - case eCSSKeyword_translate3d: - { - double x = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(1), aContext, aPresContext, canStoreInRuleTree, - aBounds.Width(), aAppUnitsPerPixel); - double y = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(2), aContext, aPresContext, canStoreInRuleTree, - aBounds.Height(), aAppUnitsPerPixel); - double z = nsStyleTransformMatrix::ProcessTranslatePart( - array->Item(3), aContext, aPresContext, canStoreInRuleTree, - 0, aAppUnitsPerPixel); - - aFunctions.AppendElement(Translation(x, y, z)); - break; - } - case eCSSKeyword_skewx: - { - double x = array->Item(1).GetFloatValue(); - aFunctions.AppendElement(SkewX(x)); - break; - } - case eCSSKeyword_skewy: - { - double y = array->Item(1).GetFloatValue(); - aFunctions.AppendElement(SkewY(y)); - break; - } - case eCSSKeyword_matrix: - { - gfx3DMatrix matrix; - matrix._11 = array->Item(1).GetFloatValue(); - matrix._12 = array->Item(2).GetFloatValue(); - matrix._13 = 0; - matrix._14 = array->Item(3).GetFloatValue(); - matrix._21 = array->Item(4).GetFloatValue(); - matrix._22 = array->Item(5).GetFloatValue(); - matrix._23 = 0; - matrix._24 = array->Item(6).GetFloatValue(); - matrix._31 = 0; - matrix._32 = 0; - matrix._33 = 1; - matrix._34 = 0; - matrix._41 = 0; - matrix._42 = 0; - matrix._43 = 0; - matrix._44 = 1; - aFunctions.AppendElement(TransformMatrix(matrix)); - break; - } - case eCSSKeyword_matrix3d: - { - gfx3DMatrix matrix; - matrix._11 = array->Item(1).GetFloatValue(); - matrix._12 = array->Item(2).GetFloatValue(); - matrix._13 = array->Item(3).GetFloatValue(); - matrix._14 = array->Item(4).GetFloatValue(); - matrix._21 = array->Item(5).GetFloatValue(); - matrix._22 = array->Item(6).GetFloatValue(); - matrix._23 = array->Item(7).GetFloatValue(); - matrix._24 = array->Item(8).GetFloatValue(); - matrix._31 = array->Item(9).GetFloatValue(); - matrix._32 = array->Item(10).GetFloatValue(); - matrix._33 = array->Item(11).GetFloatValue(); - matrix._34 = array->Item(12).GetFloatValue(); - matrix._41 = array->Item(13).GetFloatValue(); - matrix._42 = array->Item(14).GetFloatValue(); - matrix._43 = array->Item(15).GetFloatValue(); - matrix._44 = array->Item(16).GetFloatValue(); - aFunctions.AppendElement(TransformMatrix(matrix)); - break; - } - case eCSSKeyword_perspective: - { - aFunctions.AppendElement(Perspective(array->Item(1).GetFloatValue())); - break; - } - default: - NS_ERROR("Function not handled yet!"); - } - } -} - -static TimingFunction -ToTimingFunction(css::ComputedTimingFunction& aCTF) -{ - if (aCTF.GetType() == nsTimingFunction::Function) { - const nsSMILKeySpline* spline = aCTF.GetFunction(); - return TimingFunction(CubicBezierFunction(spline->X1(), spline->Y1(), - spline->X2(), spline->Y2())); - } - - PRUint32 type = aCTF.GetType() == nsTimingFunction::StepStart ? 1 : 2; - return TimingFunction(StepFunction(aCTF.GetSteps(), type)); -} - -static void -AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty, - ElementAnimation* ea, Layer* aLayer, - AnimationData& aData) -{ - NS_ASSERTION(aLayer->AsContainerLayer(), "Should only animate ContainerLayer"); - nsStyleContext* styleContext = aFrame->GetStyleContext(); - nsPresContext* presContext = aFrame->PresContext(); - nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(aFrame); - float scale = nsDeviceContext::AppUnitsPerCSSPixel(); - float iterations = ea->mIterationCount != NS_IEEEPositiveInfinity() - ? ea->mIterationCount : -1; - for (PRUint32 propIdx = 0; propIdx < ea->mProperties.Length(); propIdx++) { - AnimationProperty* property = &ea->mProperties[propIdx]; - InfallibleTArray segments; - - if (aProperty != property->mProperty) { - continue; - } - - for (PRUint32 segIdx = 0; segIdx < property->mSegments.Length(); segIdx++) { - AnimationPropertySegment* segment = &property->mSegments[segIdx]; - - if (aProperty == eCSSProperty_transform) { - nsCSSValueList* list = segment->mFromValue.GetCSSValueListValue(); - InfallibleTArray fromFunctions; - AddTransformFunctions(list, styleContext, - presContext, bounds, - scale, fromFunctions); - - list = segment->mToValue.GetCSSValueListValue(); - InfallibleTArray toFunctions; - AddTransformFunctions(list, styleContext, - presContext, bounds, - scale, toFunctions); - - segments.AppendElement(AnimationSegment(fromFunctions, toFunctions, - segment->mFromKey, segment->mToKey, - ToTimingFunction(segment->mTimingFunction))); - } else if (aProperty == eCSSProperty_opacity) { - segments.AppendElement(AnimationSegment(Opacity(segment->mFromValue.GetFloatValue()), - Opacity(segment->mToValue.GetFloatValue()), - segment->mFromKey, - segment->mToKey, - ToTimingFunction(segment->mTimingFunction))); - } - } - - aLayer->AddAnimation(Animation(ea->mStartTime, - ea->mIterationDuration, - segments, - iterations, - ea->mDirection, - aData)); - } -} - -static void -AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayItem* aItem, - nsCSSProperty aProperty) -{ - aLayer->ClearAnimations(); - - nsIFrame* frame = aItem->GetUnderlyingFrame(); - nsIContent* aContent = frame->GetContent(); - ElementTransitions* et = - nsTransitionManager::GetTransitionsForCompositor(aContent, aProperty); - - ElementAnimations* ea = - nsAnimationManager::GetAnimationsForCompositor(aContent, aProperty); - - if (!ea && !et) { - return; - } - - mozilla::TimeStamp currentTime = - frame->PresContext()->RefreshDriver()->MostRecentRefresh(); - AnimationData data; - if (aProperty == eCSSProperty_transform) { - nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(frame); - float scale = nsDeviceContext::AppUnitsPerCSSPixel(); - gfxPoint3D offsetToTransformOrigin = - nsDisplayTransform::GetDeltaToMozTransformOrigin(frame, scale, &bounds); - gfxPoint3D offsetToPerspectiveOrigin = - nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(frame, scale); - nscoord perspective = 0.0; - nsStyleContext* parentStyleContext = frame->GetStyleContext()->GetParent(); - if (parentStyleContext) { - const nsStyleDisplay* disp = parentStyleContext->GetStyleDisplay(); - if (disp && disp->mChildPerspective.GetUnit() == eStyleUnit_Coord) { - perspective = disp->mChildPerspective.GetCoordValue(); - } - } - nsPoint origin = aItem->ToReferenceFrame(); - - data = TransformData(origin, offsetToTransformOrigin, - offsetToPerspectiveOrigin, bounds, perspective); - } else if (aProperty == eCSSProperty_opacity) { - data = null_t(); - } - - if (et) { - for (PRUint32 tranIdx = 0; tranIdx < et->mPropertyTransitions.Length(); tranIdx++) { - ElementPropertyTransition* pt = &et->mPropertyTransitions[tranIdx]; - if (!pt->CanPerformOnCompositor(et->mElement, currentTime)) { - continue; - } - - ElementAnimation anim; - anim.mIterationCount = 1; - anim.mDirection = NS_STYLE_ANIMATION_DIRECTION_NORMAL; - anim.mFillMode = NS_STYLE_ANIMATION_FILL_MODE_NONE; - anim.mStartTime = pt->mStartTime; - anim.mIterationDuration = pt->mDuration; - - AnimationProperty& prop = *anim.mProperties.AppendElement(); - prop.mProperty = pt->mProperty; - - AnimationPropertySegment& segment = *prop.mSegments.AppendElement(); - segment.mFromKey = 0; - segment.mToKey = 1; - segment.mFromValue = pt->mStartValue; - segment.mToValue = pt->mEndValue; - segment.mTimingFunction = pt->mTimingFunction; - - AddAnimationsForProperty(frame, aProperty, &anim, - aLayer, data); - } - } - - if (ea) { - for (PRUint32 animIdx = 0; animIdx < ea->mAnimations.Length(); animIdx++) { - ElementAnimation* anim = &ea->mAnimations[animIdx]; - if (!anim->CanPerformOnCompositor(ea->mElement, currentTime)) { - continue; - } - AddAnimationsForProperty(frame, aProperty, anim, - aLayer, data); - } - } -} - nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret) : mReferenceFrame(aReferenceFrame), @@ -565,11 +199,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame, nsRect contentBounds = scrollableFrame->GetScrollRange(); contentBounds.width += scrollableFrame->GetScrollPortRect().width; contentBounds.height += scrollableFrame->GetScrollPortRect().height; - metrics.mCSSContentRect = - mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x), - nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y), - nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width), - nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height)); + metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x), + nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y), + nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width), + nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height)); metrics.mContentRect = contentBounds.ScaleToNearestPixels( aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel); metrics.mViewportScrollOffset = scrollableFrame->GetScrollPosition().ScaleToNearestPixels( @@ -577,11 +210,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame, } else { nsRect contentBounds = aForFrame->GetRect(); - metrics.mCSSContentRect = - mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x), - nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y), - nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width), - nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height)); + metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x), + nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y), + nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width), + nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height)); metrics.mContentRect = contentBounds.ScaleToNearestPixels( aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel); } @@ -668,7 +300,7 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame, if (mIsPaintingToWindow) { mReferenceFrame->AddPaintedPresShell(state->mPresShell); - + state->mPresShell->IncrementPaintCount(); } @@ -731,7 +363,7 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame, } void -nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect) +nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect) { nsAutoTArray childListArray; aDirtyFrame->GetChildLists(&childListArray); @@ -988,8 +620,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder, return; } // Root is being scaled up by the X/Y resolution. Scale it back down. - root->SetScale(1.0f/containerParameters.mXScale, - 1.0f/containerParameters.mYScale); + gfx3DMatrix rootTransform = root->GetTransform()* + gfx3DMatrix::ScalingMatrix(1.0f/containerParameters.mXScale, + 1.0f/containerParameters.mYScale, 1.0f); + root->SetTransform(rootTransform); ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID : FrameMetrics::NULL_SCROLL_ID; @@ -1132,8 +766,8 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) { nsAutoTArray outFrames; item->HitTest(aBuilder, aRect, aState, &outFrames); - - // For 3d transforms with preserve-3d we add hit frames into the temp list + + // For 3d transforms with preserve-3d we add hit frames into the temp list // so we can sort them later, otherwise we add them directly to the output list. nsTArray *writeFrames = aOutFrames; if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM && @@ -1149,7 +783,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect, writeFrames = &temp[temp.Length() - 1].mFrames; } } else { - // We may have just finished a run of consecutive preserve-3d transforms, + // We may have just finished a run of consecutive preserve-3d transforms, // so flush these into the destination array before processing our frame list. FlushFramesArray(temp, aOutFrames); } @@ -1194,7 +828,7 @@ static void Sort(nsDisplayList* aList, PRInt32 aCount, nsDisplayList::SortLEQ aC aList->AppendToTop(&list2); return; } - + Sort(&list1, half, aCmp, aClosure); Sort(&list2, aCount - half, aCmp, aClosure); @@ -1258,7 +892,7 @@ void nsDisplayList::ExplodeAnonymousChildLists(nsDisplayListBuilder* aBuilder) { i->~nsDisplayItem(); } } - + AppendToTop(&tmp); } @@ -1648,7 +1282,7 @@ nsDisplayBackground::ConfigureLayer(ImageLayer* aLayer) transform.Translate(mDestRect.TopLeft()); transform.Scale(mDestRect.width/imageSize.width, mDestRect.height/imageSize.height); - aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform)); + aLayer->SetTransform(gfx3DMatrix::From2D(transform)); aLayer->SetVisibleRegion(nsIntRect(0, 0, imageSize.width, imageSize.height)); } @@ -2345,16 +1979,14 @@ already_AddRefed nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerParameters& aContainerParameters) { - nsRefPtr container = GetLayerBuilderForManager(aManager)-> + nsRefPtr layer = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList, aContainerParameters, nullptr); - if (!container) + if (!layer) return nullptr; - container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity); - AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_opacity); - - return container.forget(); + layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity); + return layer.forget(); } /** @@ -2379,12 +2011,6 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder, if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateOpacityLayer) && !IsItemTooSmallForActiveLayer(this)) return LAYER_ACTIVE; - if (mFrame->GetContent()) { - if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(), - eCSSProperty_opacity)) { - return LAYER_ACTIVE; - } - } nsIFrame* activeScrolledRoot = nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nullptr); return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot) @@ -2736,7 +2362,7 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder) // Layer metadata for a particular scroll frame needs to be unique. Only // one nsDisplayScrollLayer (with rendered content) or one // nsDisplayScrollInfoLayer (with only the metadata) should survive the - // visibility computation. + // visibility computation. return RemoveScrollLayerCount() == 1; } @@ -3019,7 +2645,7 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame) NS_PRECONDITION(aFrame, "Can't get the bounds of a nonexistent frame!"); nsRect result; - + if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) { // TODO: SVG needs to define what percentage translations resolve against. return result; @@ -3046,13 +2672,12 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame) /* Returns the delta specified by the -moz-transform-origin property. * This is a positive delta, meaning that it indicates the direction to move - * to get from (0, 0) of the frame to the transform origin. This function is - * called off the main thread. + * to get from (0, 0) of the frame to the transform origin. */ -/* static */ gfxPoint3D -nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame, - float aAppUnitsPerPixel, - const nsRect* aBoundsOverride) +static +gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame, + float aAppUnitsPerPixel, + const nsRect* aBoundsOverride) { NS_PRECONDITION(aFrame, "Can't get delta for a null frame!"); NS_PRECONDITION(aFrame->IsTransformed(), @@ -3067,7 +2692,8 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame, nsDisplayTransform::GetFrameBoundsForTransform(aFrame)); /* Allows us to access named variables by index. */ - float coords[3]; + gfxPoint3D result; + gfxFloat* coords[3] = {&result.x, &result.y, &result.z}; const nscoord* dimensions[2] = {&boundingRect.width, &boundingRect.height}; @@ -3078,17 +2704,17 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame, const nsStyleCoord &coord = display->mTransformOrigin[index]; if (coord.GetUnit() == eStyleUnit_Calc) { const nsStyleCoord::Calc *calc = coord.GetCalcValue(); - coords[index] = + *coords[index] = NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) * calc->mPercent + NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerPixel); } else if (coord.GetUnit() == eStyleUnit_Percent) { - coords[index] = + *coords[index] = NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) * coord.GetPercentValue(); } else { NS_ABORT_IF_FALSE(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit"); - coords[index] = + *coords[index] = NSAppUnitsToFloatPixels(coord.GetCoordValue(), aAppUnitsPerPixel); } if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) && @@ -3097,32 +2723,31 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame, // user space, not the top left of its bounds, so we must adjust for that: nscoord offset = (index == 0) ? aFrame->GetPosition().x : aFrame->GetPosition().y; - coords[index] -= NSAppUnitsToFloatPixels(offset, aAppUnitsPerPixel); + *coords[index] -= NSAppUnitsToFloatPixels(offset, aAppUnitsPerPixel); } } - coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(), - aAppUnitsPerPixel); + *coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(), + aAppUnitsPerPixel); /* Adjust based on the origin of the rectangle. */ - coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel); - coords[1] += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel); + result.x += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel); + result.y += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel); - return gfxPoint3D(coords[0], coords[1], coords[2]); + return result; } /* Returns the delta specified by the -moz-perspective-origin property. * This is a positive delta, meaning that it indicates the direction to move - * to get from (0, 0) of the frame to the perspective origin. This function is - * called off the main thread. + * to get from (0, 0) of the frame to the perspective origin. */ -/* static */ gfxPoint3D -nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame, - float aAppUnitsPerPixel) +static +gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame, + float aAppUnitsPerPixel) { NS_PRECONDITION(aFrame, "Can't get delta for a null frame!"); NS_PRECONDITION(aFrame->IsTransformed(), "Shouldn't get a delta for an untransformed frame!"); - NS_PRECONDITION(aFrame->GetParentStyleContextFrame(), + NS_PRECONDITION(aFrame->GetParentStyleContextFrame(), "Can't get delta without a style parent!"); /* For both of the coordinates, if the value of -moz-perspective-origin is a @@ -3180,22 +2805,12 @@ nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame, */ gfx3DMatrix nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame, - const nsPoint& aOrigin, + const nsPoint &aOrigin, float aAppUnitsPerPixel, const nsRect* aBoundsOverride, - const nsCSSValueList* aTransformOverride, - gfxPoint3D* aToMozOrigin, - gfxPoint3D* aToPerspectiveOrigin, - nscoord* aChildPerspective, nsIFrame** aOutAncestor) { - NS_PRECONDITION(aFrame || (aToMozOrigin && aBoundsOverride && aToPerspectiveOrigin && - aTransformOverride && aChildPerspective), - "Should have frame or necessary infromation to construct matrix"); - - NS_PRECONDITION(!(aFrame && (aToMozOrigin || aToPerspectiveOrigin || - aTransformOverride || aChildPerspective)), - "Should not have both frame and necessary infromation to construct matrix"); + NS_PRECONDITION(aFrame, "Cannot get transform matrix for a null frame!"); if (aOutAncestor) { *aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(aFrame); @@ -3205,7 +2820,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame, * coordinate space to the new origin. */ gfxPoint3D toMozOrigin = - aFrame ? GetDeltaToMozTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride) : *aToMozOrigin; + GetDeltaToMozTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride); gfxPoint3D newOrigin = gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel), NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel), @@ -3214,7 +2829,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame, /* Get the underlying transform matrix. This requires us to get the * bounds of the frame. */ - const nsStyleDisplay* disp = aFrame ? aFrame->GetStyleDisplay() : nullptr; + const nsStyleDisplay* disp = aFrame->GetStyleDisplay(); nsRect bounds = (aBoundsOverride ? *aBoundsOverride : nsDisplayTransform::GetFrameBoundsForTransform(aFrame)); @@ -3225,12 +2840,9 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame, // disp->mSpecifiedTransform, since we still need any transformFromSVGParent. gfxMatrix svgTransform, transformFromSVGParent; bool hasSVGTransforms = - aFrame && aFrame->IsSVGTransformed(&svgTransform, &transformFromSVGParent); + aFrame->IsSVGTransformed(&svgTransform, &transformFromSVGParent); /* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */ - if (aTransformOverride) { - result = nsStyleTransformMatrix::ReadTransforms(aTransformOverride, nullptr, nullptr, - dummy, bounds, aAppUnitsPerPixel); - } else if (disp->mSpecifiedTransform) { + if (disp->mSpecifiedTransform) { result = nsStyleTransformMatrix::ReadTransforms(disp->mSpecifiedTransform, aFrame->GetStyleContext(), aFrame->PresContext(), @@ -3242,6 +2854,10 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame, svgTransform.x0 *= pixelsPerCSSPx; svgTransform.y0 *= pixelsPerCSSPx; result = gfx3DMatrix::From2D(svgTransform); + } else { + NS_ASSERTION(aFrame->GetStyleDisplay()->mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D || + aFrame->GetStyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN, + "If we don't have a transform, then we must have another reason to have an nsDisplayTransform created"); } if (hasSVGTransforms && !transformFromSVGParent.IsIdentity()) { @@ -3254,40 +2870,32 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame, } const nsStyleDisplay* parentDisp = nullptr; - nsStyleContext* parentStyleContext = aFrame ? aFrame->GetStyleContext()->GetParent(): nullptr; + nsStyleContext* parentStyleContext = aFrame->GetStyleContext()->GetParent(); if (parentStyleContext) { parentDisp = parentStyleContext->GetStyleDisplay(); } - nscoord perspectiveCoord = 0; - if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) { - perspectiveCoord = parentDisp->mChildPerspective.GetCoordValue(); - } - if (aChildPerspective) { - perspectiveCoord = *aChildPerspective; - } - - if (nsLayoutUtils::Are3DTransformsEnabled() && perspectiveCoord > 0.0) { + if (nsLayoutUtils::Are3DTransformsEnabled() && + parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord && + parentDisp->mChildPerspective.GetCoordValue() > 0.0) { gfx3DMatrix perspective; perspective._34 = - -1.0 / NSAppUnitsToFloatPixels(perspectiveCoord, aAppUnitsPerPixel); + -1.0 / NSAppUnitsToFloatPixels(parentDisp->mChildPerspective.GetCoordValue(), + aAppUnitsPerPixel); /* At the point when perspective is applied, we have been translated to the transform origin. * The translation to the perspective origin is the difference between these values. */ - gfxPoint3D toPerspectiveOrigin = aFrame ? GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel) : *aToPerspectiveOrigin; + gfxPoint3D toPerspectiveOrigin = GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel); result = result * nsLayoutUtils::ChangeMatrixBasis(toPerspectiveOrigin - toMozOrigin, perspective); } - if (aFrame && aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) { + if (aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) { // Include the transform set on our parent NS_ASSERTION(aFrame->GetParent() && aFrame->GetParent()->IsTransformed() && aFrame->GetParent()->Preserves3DChildren(), "Preserve3D mismatch!"); - gfx3DMatrix parent = - GetResultingTransformMatrix(aFrame->GetParent(), - aOrigin - aFrame->GetPosition(), - aAppUnitsPerPixel, nullptr, nullptr, nullptr, - nullptr, nullptr, aOutAncestor); + gfx3DMatrix parent = GetResultingTransformMatrix(aFrame->GetParent(), aOrigin - aFrame->GetPosition(), + aAppUnitsPerPixel, nullptr, aOutAncestor); return nsLayoutUtils::ChangeMatrixBasis(newOrigin + toMozOrigin, result) * parent; } @@ -3318,7 +2926,7 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui } /* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */ -static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix) +static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix) { if (aMatrix.IsSingular()) { return false; @@ -3336,7 +2944,8 @@ nsDisplayTransform::GetTransform(float aAppUnitsPerPixel) if (mTransform.IsIdentity() || mCachedAppUnitsPerPixel != aAppUnitsPerPixel) { mTransform = GetResultingTransformMatrix(mFrame, ToReferenceFrame(), - aAppUnitsPerPixel); + aAppUnitsPerPixel, + nullptr); mCachedAppUnitsPerPixel = aAppUnitsPerPixel; } return mTransform; @@ -3346,7 +2955,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu LayerManager *aManager, const ContainerParameters& aContainerParameters) { - const gfx3DMatrix& newTransformMatrix = + const gfx3DMatrix& newTransformMatrix = GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel()); if (!IsFrameVisible(mFrame, newTransformMatrix)) { @@ -3362,8 +2971,6 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) { container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D); } - - AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_transform); return container.forget(); } @@ -3378,18 +2985,12 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder, return LAYER_ACTIVE; if (!GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel()).Is2D() || mFrame->Preserves3D()) return LAYER_ACTIVE; - if (mFrame->GetContent()) { - if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(), - eCSSProperty_transform)) { - return LAYER_ACTIVE; - } - } nsIFrame* activeScrolledRoot = nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nullptr); - return !mStoredList.ChildrenCanBeInactive(aBuilder, - aManager, + return !mStoredList.ChildrenCanBeInactive(aBuilder, + aManager, aParameters, - *mStoredList.GetList(), + *mStoredList.GetList(), activeScrolledRoot) ? LAYER_ACTIVE : LAYER_INACTIVE; } @@ -3408,9 +3009,9 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder, !UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, - &untransformedVisibleRect)) + &untransformedVisibleRect)) { - untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() + + untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() + aBuilder->ToReferenceFrame(mFrame); } nsRegion untransformedVisible = untransformedVisibleRect; @@ -3475,7 +3076,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder, NSFloatPixelsToAppUnits(float(rect.Width()), factor), NSFloatPixelsToAppUnits(float(rect.Height()), factor)); } - + #ifdef DEBUG_HIT printf("Frame: %p\n", dynamic_cast(mFrame)); @@ -3501,8 +3102,8 @@ nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint) gfx3DMatrix matrix = GetTransform(factor); NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!"); - - gfxPoint point = + + gfxPoint point = matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor), NSAppUnitsToFloatPixels(aPoint.y, factor))); @@ -3551,7 +3152,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder, if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) { return nsRegion(); } - + const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel()); nsRegion result; @@ -3698,7 +3299,7 @@ bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds, * empty rect. */ float factor = nsPresContext::AppUnitsPerCSSPixel(); - gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor); + gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor, nullptr); return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect); } diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index e72d92ad8b2..99ea8219beb 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -108,10 +108,10 @@ public: * display lists that we make. */ enum Mode { - PAINTING, - EVENT_DELIVERY, - PLUGIN_GEOMETRY, - OTHER + PAINTING, + EVENT_DELIVERY, + PLUGIN_GEOMETRY, + OTHER }; nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret); ~nsDisplayListBuilder(); @@ -2353,13 +2353,6 @@ public: float aAppUnitsPerPixel, nsRect* aOutRect); - static gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame, - float aAppUnitsPerPixel, - const nsRect* aBoundsOverride); - - static gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame, - float aAppUnitsPerPixel); - /** * Returns the bounds of a frame as defined for resolving percentage * s in CSS transforms. If @@ -2393,10 +2386,6 @@ public: const nsPoint& aOrigin, float aAppUnitsPerPixel, const nsRect* aBoundsOverride = nullptr, - const nsCSSValueList* aTransformOverride = nullptr, - gfxPoint3D* aToMozOrigin = nullptr, - gfxPoint3D* aToPerspectiveOrigin = nullptr, - nscoord* aChildPerspective = nullptr, nsIFrame** aOutAncestor = nullptr); /** * Return true when we should try to prerender the entire contents of the diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index 157be0eec9d..1f16248386c 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -4,7 +4,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "base/basictypes.h" #include "mozilla/Util.h" #include "nsLayoutUtils.h" @@ -71,7 +70,7 @@ #include "nsTextFrame.h" #include "nsFontFaceList.h" #include "nsFontInflationData.h" -#include "CompositorParent.h" + #include "nsSVGUtils.h" #include "nsSVGIntegrationUtils.h" #include "nsSVGForeignObjectFrame.h" @@ -84,8 +83,6 @@ #endif #include "sampler.h" -#include "nsAnimationManager.h" -#include "nsTransitionManager.h" using namespace mozilla; using namespace mozilla::layers; @@ -116,32 +113,6 @@ static ContentMap& GetContentMap() { return *sContentMap; } -bool -nsLayoutUtils::HasAnimationsForCompositor(nsIContent* aContent, - nsCSSProperty aProperty) -{ - if (!aContent->MayHaveAnimations()) - return false; - ElementAnimations* animations = - static_cast(aContent->GetProperty(nsGkAtoms::animationsProperty)); - if (animations) { - bool propertyMatches = animations->HasAnimationOfProperty(aProperty); - if (propertyMatches && animations->CanPerformOnCompositorThread()) { - return true; - } - } - - ElementTransitions* transitions = - static_cast(aContent->GetProperty(nsGkAtoms::transitionsProperty)); - if (transitions) { - bool propertyMatches = transitions->HasTransitionOfProperty(aProperty); - if (propertyMatches && transitions->CanPerformOnCompositorThread()) { - return true; - } - } - - return false; -} bool nsLayoutUtils::Are3DTransformsEnabled() @@ -151,43 +122,13 @@ nsLayoutUtils::Are3DTransformsEnabled() if (!s3DTransformPrefCached) { s3DTransformPrefCached = true; - mozilla::Preferences::AddBoolVarCache(&s3DTransformsEnabled, + mozilla::Preferences::AddBoolVarCache(&s3DTransformsEnabled, "layout.3d-transforms.enabled"); } return s3DTransformsEnabled; } -bool -nsLayoutUtils::AreOpacityAnimationsEnabled() -{ - static bool sAreOpacityAnimationsEnabled; - static bool sOpacityPrefCached = false; - - if (!sOpacityPrefCached) { - sOpacityPrefCached = true; - Preferences::AddBoolVarCache(&sAreOpacityAnimationsEnabled, - "layers.offmainthreadcomposition.animate-opacity"); - } - - return sAreOpacityAnimationsEnabled && CompositorParent::CompositorLoop(); -} - -bool -nsLayoutUtils::AreTransformAnimationsEnabled() -{ - static bool sAreTransformAnimationsEnabled; - static bool sTransformPrefCached = false; - - if (!sTransformPrefCached) { - sTransformPrefCached = true; - Preferences::AddBoolVarCache(&sAreTransformAnimationsEnabled, - "layers.offmainthreadcomposition.animate-transform"); - } - - return sAreTransformAnimationsEnabled && CompositorParent::CompositorLoop(); -} - bool nsLayoutUtils::UseBackgroundNearestFiltering() { diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index c41ceb0452c..c1f6db20d18 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1497,24 +1497,11 @@ public: nsMallocSizeOfFun aMallocSizeOf, bool clear); - /** - * Returns true if the content node has animations or transitions that can be - * performed on the compositor. - */ - static bool HasAnimationsForCompositor(nsIContent* aContent, - nsCSSProperty aProperty); - /** * Checks if CSS 3D transforms are currently enabled. */ static bool Are3DTransformsEnabled(); - /** - * Checks if off-main-thread transform and opacity animations are enabled. - */ - static bool AreOpacityAnimationsEnabled(); - static bool AreTransformAnimationsEnabled(); - /** * Checks if we should forcibly use nearest pixel filtering for the * background. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 8b9c630c63c..d17ce7b9210 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -92,8 +92,6 @@ #include "CSSCalc.h" #include "nsAbsoluteContainingBlock.h" #include "nsFontInflationData.h" -#include "nsAnimationManager.h" -#include "nsTransitionManager.h" #include "mozilla/Preferences.h" #include "mozilla/LookAndFeel.h" @@ -937,20 +935,9 @@ nsIFrame::GetPaddingRect() const bool nsIFrame::IsTransformed() const { - return ((mState & NS_FRAME_MAY_BE_TRANSFORMED) && + return (mState & NS_FRAME_MAY_BE_TRANSFORMED) && (GetStyleDisplay()->HasTransform() || - IsSVGTransformed() || - (mContent && - nsLayoutUtils::HasAnimationsForCompositor(mContent, - eCSSProperty_transform)))); -} - -bool -nsIFrame::HasOpacity() const -{ - return GetStyleDisplay()->mOpacity < 1.0f || (mContent && - nsLayoutUtils::HasAnimationsForCompositor(mContent, - eCSSProperty_opacity)); + IsSVGTransformed()); } bool @@ -1777,12 +1764,9 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, nsRect clipPropClip; const nsStyleDisplay* disp = GetStyleDisplay(); // We can stop right away if this is a zero-opacity stacking context and - // we're painting, and we're not animating opacity. - if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() && - !nsLayoutUtils::HasAnimationsForCompositor(mContent, - eCSSProperty_opacity)) { + // we're painting. + if (disp->mOpacity == 0.0 && aBuilder->IsForPainting()) return NS_OK; - } bool applyClipPropClipping = ApplyClipPropClipping(aBuilder, disp, this, &clipPropClip); @@ -1797,7 +1781,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, // Trying to back-transform arbitrary rects gives us really weird results. I believe // this is from points that lie beyond the vanishing point. As a workaround we transform t // he overflow rect into screen space and compare in that coordinate system. - + // Transform the overflow rect into screen space nsRect overflow = GetVisualOverflowRectRelativeToSelf(); nsPoint offset = aBuilder->ToReferenceFrame(this); @@ -1927,6 +1911,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, // resultList was emptied resultList.AppendToTop(item); } + /* If there are any SVG effects, wrap the list up in an SVG effects item * (which also handles CSS group opacity). Note that we create an SVG effects * item even if resultList is empty, since a filter can produce graphical @@ -1942,7 +1927,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder, /* Else, if the list is non-empty and there is CSS group opacity without SVG * effects, wrap it up in an opacity item. */ - else if (HasOpacity() && + else if (disp->mOpacity < 1.0f && !nsSVGUtils::CanOptimizeOpacity(this) && !resultList.IsEmpty()) { rv = resultList.AppendNewToTop( @@ -2096,7 +2081,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, // Child is composited if it's transformed, partially transparent, or has // SVG effects. const nsStyleDisplay* disp = child->GetStyleDisplay(); - bool isVisuallyAtomic = child->HasOpacity() + bool isVisuallyAtomic = disp->mOpacity != 1.0f || child->IsTransformed() || nsSVGIntegrationUtils::UsingEffectsForFrame(child); @@ -4764,8 +4749,8 @@ nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor, PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel(); gfx3DMatrix result = - nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0), scaleFactor, nullptr, - nullptr, nullptr, nullptr, nullptr, aOutAncestor); + nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0), + scaleFactor, nullptr, aOutAncestor); // XXXjwatt: seems like this will double count offsets in the face of preserve-3d: nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor); /* Combine the raw transform with a translation to our parent. */ diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index 33990933d86..9d00fbe133e 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -278,7 +278,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder, gfxMatrix transform; transform.Translate(r.TopLeft()); transform.Scale(r.Width()/canvasSize.width, r.Height()/canvasSize.height); - layer->SetBaseTransform(gfx3DMatrix::From2D(transform)); + layer->SetTransform(gfx3DMatrix::From2D(transform)); layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this)); layer->SetVisibleRegion(nsIntRect(0, 0, canvasSize.width, canvasSize.height)); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index e180c0f0d70..63b7c16fe52 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -1227,8 +1227,6 @@ public: * an SVG viewBox attribute). */ bool IsTransformed() const; - - bool HasOpacity() const; /** * Returns true if this frame is an SVG frame that has SVG transforms applied diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index e9137298dd7..89827eaa9f3 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -1289,7 +1289,7 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer) transform.Translate(destRect.TopLeft()); transform.Scale(destRect.Width()/imageWidth, destRect.Height()/imageHeight); - aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform)); + aLayer->SetTransform(gfx3DMatrix::From2D(transform)); aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight)); } diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 92661637869..d599b777e19 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -1723,7 +1723,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder, gfxMatrix transform; transform.Translate(r.TopLeft()); - layer->SetBaseTransform(gfx3DMatrix::From2D(transform)); + layer->SetTransform(gfx3DMatrix::From2D(transform)); layer->SetVisibleRegion(nsIntRect(0, 0, size.width, size.height)); return layer.forget(); } diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index 4a92c26cb81..6ee970a497b 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -206,7 +206,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder, gfxMatrix transform; transform.Translate(r.TopLeft()); transform.Scale(r.Width()/frameSize.width, r.Height()/frameSize.height); - layer->SetBaseTransform(gfx3DMatrix::From2D(transform)); + layer->SetTransform(gfx3DMatrix::From2D(transform)); layer->SetVisibleRegion(nsIntRect(0, 0, frameSize.width, frameSize.height)); nsRefPtr result = layer.forget(); return result.forget(); diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 0b2a26a37d0..a6ea514d236 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -246,11 +246,10 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader, ShadowLayer* shadow = aLayer->AsShadowLayer(); shadow->SetShadowClipRect(aLayer->GetClipRect()); shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion()); - shadow->SetShadowOpacity(aLayer->GetOpacity()); const FrameMetrics* metrics = GetFrameMetrics(aLayer); - gfx3DMatrix shadowTransform = aLayer->GetBaseTransform(); + gfx3DMatrix shadowTransform = aLayer->GetTransform(); ViewTransform layerTransform = aTransform; if (metrics && metrics->IsScrollable()) { @@ -605,7 +604,7 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder, layer->SetReferentId(id); layer->SetVisibleRegion(aVisibleRect); nsIntPoint rootFrameOffset = GetRootFrameOffset(aFrame, aBuilder); - layer->SetBaseTransform( + layer->SetTransform( gfx3DMatrix::Translation(rootFrameOffset.x, rootFrameOffset.y, 0.0)); return layer.forget(); diff --git a/layout/style/AnimationCommon.cpp b/layout/style/AnimationCommon.cpp index c10ea5126ab..a3adeea0286 100644 --- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -7,9 +7,6 @@ #include "nsRuleData.h" #include "nsCSSValue.h" #include "nsStyleContext.h" -#include "nsIFrame.h" -#include "nsAnimationManager.h" -#include "nsLayoutUtils.h" namespace mozilla { namespace css { @@ -216,26 +213,5 @@ ComputedTimingFunction::GetValue(double aPortion) const } } -bool -CommonElementAnimationData::CanAnimatePropertyOnCompositor(const dom::Element *aElement, - nsCSSProperty aProperty) -{ - nsIFrame* frame = aElement->GetPrimaryFrame(); - if (aProperty == eCSSProperty_opacity) { - return nsLayoutUtils::AreOpacityAnimationsEnabled(); - } - if (aProperty == eCSSProperty_transform && !(frame && - frame->Preserves3D() && - frame->Preserves3DChildren())) { - if (frame && frame->IsSVGTransformed()) { - return false; - } - return nsLayoutUtils::AreTransformAnimationsEnabled(); - } - return false; -} - - - } } diff --git a/layout/style/AnimationCommon.h b/layout/style/AnimationCommon.h index d7d489de7a3..04ddb6afc23 100644 --- a/layout/style/AnimationCommon.h +++ b/layout/style/AnimationCommon.h @@ -107,12 +107,6 @@ public: typedef nsTimingFunction::Type Type; void Init(const nsTimingFunction &aFunction); double GetValue(double aPortion) const; - const nsSMILKeySpline* GetFunction() const { - NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch"); - return &mTimingFunction; - } - Type GetType() const { return mType; } - PRUint32 GetSteps() const { return mSteps; } private: Type mType; nsSMILKeySpline mTimingFunction; @@ -148,10 +142,6 @@ struct CommonElementAnimationData : public PRCList mElement->DeleteProperty(mElementProperty); } - static bool - CanAnimatePropertyOnCompositor(const dom::Element *aElement, - nsCSSProperty aProperty); - dom::Element *mElement; // the atom we use in mElement's prop table (must be a static atom, diff --git a/layout/style/Makefile.in b/layout/style/Makefile.in index 1851556ae1c..b9ac75cb689 100644 --- a/layout/style/Makefile.in +++ b/layout/style/Makefile.in @@ -22,8 +22,6 @@ LIBXUL_LIBRARY = 1 EXPORTS_NAMESPACES = mozilla/css EXPORTS = \ - AnimationCommon.h \ - nsAnimationManager.h \ nsCSSAnonBoxList.h \ nsCSSAnonBoxes.h \ nsCSSFontDescList.h \ @@ -57,7 +55,6 @@ EXPORTS = \ nsRuleNode.h \ nsRuleProcessorData.h \ nsRuleWalker.h \ - nsStyleAnimation.h \ nsStyleContext.h \ nsStyleCoord.h \ nsStyleSet.h \ @@ -127,9 +124,7 @@ FORCE_STATIC_LIB = 1 include $(topsrcdir)/config/rules.mk -include $(topsrcdir)/ipc/chromium/chromium-config.mk - -LOCAL_INCLUDES += \ +LOCAL_INCLUDES = \ -I$(srcdir)/../base \ -I$(srcdir)/../generic \ -I$(srcdir)/../xul/base/src \ diff --git a/layout/style/nsAnimationManager.cpp b/layout/style/nsAnimationManager.cpp index 5049595cdc0..6d39fd0b797 100644 --- a/layout/style/nsAnimationManager.cpp +++ b/layout/style/nsAnimationManager.cpp @@ -11,18 +11,113 @@ #include "nsStyleAnimation.h" #include "nsSMILKeySpline.h" #include "nsEventDispatcher.h" -#include "nsDisplayList.h" -#include "nsCSSFrameConstructor.h" using namespace mozilla; -ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, - nsAnimationManager *aAnimationManager) - : CommonElementAnimationData(aElement, aElementProperty, - aAnimationManager), - mNeedsRefreshes(true) +struct AnimationPropertySegment { -} + float mFromKey, mToKey; + nsStyleAnimation::Value mFromValue, mToValue; + css::ComputedTimingFunction mTimingFunction; +}; + +struct AnimationProperty +{ + nsCSSProperty mProperty; + InfallibleTArray mSegments; +}; + +/** + * Data about one animation (i.e., one of the values of + * 'animation-name') running on an element. + */ +struct ElementAnimation +{ + ElementAnimation() + : mLastNotification(LAST_NOTIFICATION_NONE) + { + } + + nsString mName; // empty string for 'none' + float mIterationCount; // NS_IEEEPositiveInfinity() means infinite + PRUint8 mDirection; + PRUint8 mFillMode; + PRUint8 mPlayState; + + bool FillsForwards() const { + return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH || + mFillMode == NS_STYLE_ANIMATION_FILL_MODE_FORWARDS; + } + bool FillsBackwards() const { + return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH || + mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS; + } + + bool IsPaused() const { + return mPlayState == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED; + } + + TimeStamp mStartTime; // with delay taken into account + TimeStamp mPauseStart; + TimeDuration mIterationDuration; + + enum { + LAST_NOTIFICATION_NONE = PRUint32(-1), + LAST_NOTIFICATION_END = PRUint32(-2) + }; + // One of the above constants, or an integer for the iteration + // whose start we last notified on. + PRUint32 mLastNotification; + + InfallibleTArray mProperties; +}; + +typedef nsAnimationManager::EventArray EventArray; +typedef nsAnimationManager::AnimationEventInfo AnimationEventInfo; + +/** + * Data about all of the animations running on an element. + */ +struct ElementAnimations : public mozilla::css::CommonElementAnimationData +{ + ElementAnimations(dom::Element *aElement, nsIAtom *aElementProperty, + nsAnimationManager *aAnimationManager) + : CommonElementAnimationData(aElement, aElementProperty, + aAnimationManager), + mNeedsRefreshes(true) + { + } + + void EnsureStyleRuleFor(TimeStamp aRefreshTime, + EventArray &aEventsToDispatch); + + bool IsForElement() const { // rather than for a pseudo-element + return mElementProperty == nsGkAtoms::animationsProperty; + } + + void PostRestyleForAnimation(nsPresContext *aPresContext) { + nsRestyleHint hint = IsForElement() ? eRestyle_Self : eRestyle_Subtree; + aPresContext->PresShell()->RestyleForAnimation(mElement, hint); + } + + // This style rule contains the style data for currently animating + // values. It only matches when styling with animation. When we + // style without animation, we need to not use it so that we can + // detect any new changes; if necessary we restyle immediately + // afterwards with animation. + // NOTE: If we don't need to apply any styles, mStyleRule will be + // null, but mStyleRuleRefreshTime will still be valid. + nsRefPtr mStyleRule; + // The refresh time associated with mStyleRule. + TimeStamp mStyleRuleRefreshTime; + + // False when we know that our current style rule is valid + // indefinitely into the future (because all of our animations are + // either completed or paused). May be invalidated by a style change. + bool mNeedsRefreshes; + + InfallibleTArray mAnimations; +}; static void ElementAnimationsPropertyDtor(void *aObject, @@ -38,114 +133,6 @@ ElementAnimationsPropertyDtor(void *aObject, delete ea; } -double -ElementAnimations::GetPositionInIteration(TimeStamp aStartTime, TimeStamp aCurrentTime, - TimeDuration aDuration, double aIterationCount, - PRUint32 aDirection, bool aIsForElement, - ElementAnimation* aAnimation, - ElementAnimations* aEa, - EventArray* aEventsToDispatch) -{ - // Set |currentIterationCount| to the (fractional) number of - // iterations we've completed up to the current position. - TimeDuration currentTimeDuration = aCurrentTime - aStartTime; - double currentIterationCount = - currentTimeDuration / aDuration; - bool dispatchStartOrIteration = false; - if (currentIterationCount >= aIterationCount) { - if (!aAnimation) { - // We are on the compositor, so send a signal that the animation is over. - // The main thread will fire the animationend event. - return -1; - } - // Dispatch 'animationend' when needed. - if (aIsForElement && - aAnimation->mLastNotification != - ElementAnimation::LAST_NOTIFICATION_END) { - aAnimation->mLastNotification = ElementAnimation::LAST_NOTIFICATION_END; - // XXXdz: if this animation was done on the compositor, we should - // invalidate the frame and update style once we start throttling style - // updates. - AnimationEventInfo ei(aEa->mElement, aAnimation->mName, NS_ANIMATION_END, - currentTimeDuration); - aEventsToDispatch->AppendElement(ei); - } - - if (!aAnimation->FillsForwards()) { - // No animation data. - return -1; - } - currentIterationCount = double(aAnimation->mIterationCount); - } else { - if (aAnimation && !aAnimation->IsPaused()) { - aEa->mNeedsRefreshes = true; - } - if (currentIterationCount < 0.0) { - NS_ASSERTION(aAnimation, "Should not run animation that hasn't started yet on the compositor"); - if (!aAnimation->FillsBackwards()) { - // No animation data. - return -1; - } - currentIterationCount = 0.0; - } else { - dispatchStartOrIteration = aAnimation && !aAnimation->IsPaused(); - } - } - - // Set |positionInIteration| to the position from 0% to 100% along - // the keyframes. - NS_ABORT_IF_FALSE(currentIterationCount >= 0.0, "must be positive"); - PRUint32 whichIteration = int(currentIterationCount); - if (whichIteration == aIterationCount && whichIteration != 0) { - // When the animation's iteration count is an integer (as it - // normally is), we need to end at 100% of its last iteration - // rather than 0% of the next one (unless it's zero). - --whichIteration; - } - double positionInIteration = - currentIterationCount - double(whichIteration); - - bool thisIterationReverse = false; - switch (aDirection) { - case NS_STYLE_ANIMATION_DIRECTION_NORMAL: - thisIterationReverse = false; - break; - case NS_STYLE_ANIMATION_DIRECTION_REVERSE: - thisIterationReverse = true; - break; - case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE: - thisIterationReverse = (whichIteration & 1) == 1; - break; - case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE: - thisIterationReverse = (whichIteration & 1) == 0; - break; - } - if (thisIterationReverse) { - positionInIteration = 1.0 - positionInIteration; - } - - // Dispatch 'animationstart' or 'animationiteration' when needed. - if (aAnimation && aIsForElement && dispatchStartOrIteration && - whichIteration != aAnimation->mLastNotification) { - // Notify 'animationstart' even if a negative delay puts us - // past the first iteration. - // Note that when somebody changes the animation-duration - // dynamically, this will fire an extra iteration event - // immediately in many cases. It's not clear to me if that's the - // right thing to do. - PRUint32 message = - aAnimation->mLastNotification == ElementAnimation::LAST_NOTIFICATION_NONE - ? NS_ANIMATION_START : NS_ANIMATION_ITERATION; - // XXXdz: If this is a start, invalidate the frame here once we throttle animations. - aAnimation->mLastNotification = whichIteration; - AnimationEventInfo ei(aEa->mElement, aAnimation->mName, message, - currentTimeDuration); - aEventsToDispatch->AppendElement(ei); - } - - return positionInIteration; -} - void ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime, EventArray& aEventsToDispatch) @@ -178,24 +165,98 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime, continue; } - TimeStamp currentTime; + TimeDuration currentTimeDuration; if (anim.IsPaused()) { // FIXME: avoid recalculating every time - currentTime = anim.mPauseStart; + currentTimeDuration = anim.mPauseStart - anim.mStartTime; } else { - currentTime = aRefreshTime; + currentTimeDuration = aRefreshTime - anim.mStartTime; } - double positionInIteration = - GetPositionInIteration(anim.mStartTime, currentTime, - anim.mIterationDuration, anim.mIterationCount, - anim.mDirection, IsForElement(), - &anim, this, &aEventsToDispatch); + // Set |currentIterationCount| to the (fractional) number of + // iterations we've completed up to the current position. + double currentIterationCount = + currentTimeDuration / anim.mIterationDuration; + bool dispatchStartOrIteration = false; + if (currentIterationCount >= double(anim.mIterationCount)) { + // Dispatch 'animationend' when needed. + if (IsForElement() && + anim.mLastNotification != + ElementAnimation::LAST_NOTIFICATION_END) { + anim.mLastNotification = ElementAnimation::LAST_NOTIFICATION_END; + AnimationEventInfo ei(mElement, anim.mName, NS_ANIMATION_END, + currentTimeDuration); + aEventsToDispatch.AppendElement(ei); + } - // The position is -1 when we don't have fill data for the current time, - // so we shouldn't animate. - if (positionInIteration == -1) - continue; + if (!anim.FillsForwards()) { + // No animation data. + continue; + } + currentIterationCount = double(anim.mIterationCount); + } else { + if (!anim.IsPaused()) { + mNeedsRefreshes = true; + } + if (currentIterationCount < 0.0) { + if (!anim.FillsBackwards()) { + // No animation data. + continue; + } + currentIterationCount = 0.0; + } else { + dispatchStartOrIteration = !anim.IsPaused(); + } + } + + // Set |positionInIteration| to the position from 0% to 100% along + // the keyframes. + NS_ABORT_IF_FALSE(currentIterationCount >= 0.0, "must be positive"); + PRUint32 whichIteration = int(currentIterationCount); + if (whichIteration == anim.mIterationCount && whichIteration != 0) { + // When the animation's iteration count is an integer (as it + // normally is), we need to end at 100% of its last iteration + // rather than 0% of the next one (unless it's zero). + --whichIteration; + } + double positionInIteration = + currentIterationCount - double(whichIteration); + bool thisIterationReverse = false; + switch (anim.mDirection) { + case NS_STYLE_ANIMATION_DIRECTION_NORMAL: + thisIterationReverse = false; + break; + case NS_STYLE_ANIMATION_DIRECTION_REVERSE: + thisIterationReverse = true; + break; + case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE: + thisIterationReverse = (whichIteration & 1) == 1; + break; + case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE: + thisIterationReverse = (whichIteration & 1) == 0; + break; + } + if (thisIterationReverse) { + positionInIteration = 1.0 - positionInIteration; + } + + // Dispatch 'animationstart' or 'animationiteration' when needed. + if (IsForElement() && dispatchStartOrIteration && + whichIteration != anim.mLastNotification) { + // Notify 'animationstart' even if a negative delay puts us + // past the first iteration. + // Note that when somebody changes the animation-duration + // dynamically, this will fire an extra iteration event + // immediately in many cases. It's not clear to me if that's the + // right thing to do. + PRUint32 message = + anim.mLastNotification == ElementAnimation::LAST_NOTIFICATION_NONE + ? NS_ANIMATION_START : NS_ANIMATION_ITERATION; + anim.mLastNotification = whichIteration; + AnimationEventInfo ei(mElement, anim.mName, message, + currentTimeDuration); + aEventsToDispatch.AppendElement(ei); + } NS_ABORT_IF_FALSE(0.0 <= positionInIteration && positionInIteration <= 1.0, @@ -262,66 +323,6 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime, } } -static bool -CanPerformAnimationOnCompositor(const ElementAnimation* aAnim, - mozilla::dom::Element* aElement) -{ - for (PRUint32 propIdx = 0, propEnd = aAnim->mProperties.Length(); - propIdx != propEnd; ++propIdx) { - const AnimationProperty &prop = aAnim->mProperties[propIdx]; - if (!mozilla::css::CommonElementAnimationData:: - CanAnimatePropertyOnCompositor(aElement, - prop.mProperty)) { - return false; - } - } - return true; -} - -bool -ElementAnimation::CanPerformOnCompositor(mozilla::dom::Element* aElement, - TimeStamp aTime) const -{ - return CanPerformAnimationOnCompositor(this, aElement) && - !IsPaused() && aTime > mStartTime && - (aTime - mStartTime) / mIterationDuration < mIterationCount; -} - -bool -ElementAnimations::HasAnimationOfProperty(nsCSSProperty aProperty) const -{ - for (PRUint32 animIdx = mAnimations.Length(); animIdx-- != 0; ) { - const ElementAnimation &anim = mAnimations[animIdx]; - for (PRUint32 propIdx = 0, propEnd = anim.mProperties.Length(); - propIdx != propEnd; ++propIdx) { - const AnimationProperty &prop = anim.mProperties[propIdx]; - if (aProperty == prop.mProperty) { - return true; - } - } - } - return false; -} - -bool -ElementAnimations::CanPerformOnCompositorThread() const -{ - if (mElementProperty != nsGkAtoms::animationsProperty) - return false; - for (PRUint32 animIdx = mAnimations.Length(); animIdx-- != 0; ) { - const ElementAnimation &anim = mAnimations[animIdx]; - if (anim.mIterationDuration.ToMilliseconds() <= 0.0) { - // No animation data - continue; - } - - if (!CanPerformAnimationOnCompositor(&anim, mElement)) - return false; - } - - return true; -} - ElementAnimations* nsAnimationManager::GetElementAnimations(dom::Element *aElement, nsCSSPseudoElements::Type aPseudoType, @@ -350,6 +351,10 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement, if (!ea && aCreateIfNeeded) { // FIXME: Consider arena-allocating? ea = new ElementAnimations(aElement, propName, this); + if (!ea) { + NS_WARNING("out of memory"); + return nullptr; + } nsresult rv = aElement->SetProperty(propName, ea, ElementAnimationsPropertyDtor, nullptr); if (NS_FAILED(rv)) { @@ -357,9 +362,6 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement, delete ea; return nullptr; } - if (propName == nsGkAtoms::animationsProperty) { - aElement->SetMayHaveAnimations(); - } AddElementData(ea); } @@ -461,8 +463,6 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext, TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh(); if (ea) { - - // XXXdz: Invalidate the frame since the animation changed. // The cached style rule is invalid. ea->mStyleRule = nullptr; ea->mStyleRuleRefreshTime = TimeStamp(); diff --git a/layout/style/nsAnimationManager.h b/layout/style/nsAnimationManager.h index 92a824d086c..fb7733c98e5 100644 --- a/layout/style/nsAnimationManager.h +++ b/layout/style/nsAnimationManager.h @@ -11,10 +11,12 @@ #include "nsDataHashtable.h" #include "nsGUIEvent.h" #include "mozilla/TimeStamp.h" -#include "mozilla/Preferences.h" #include "nsThreadUtils.h" class nsCSSKeyframesRule; +struct AnimationPropertySegment; +struct ElementAnimation; +struct ElementAnimations; namespace mozilla { namespace css { @@ -22,179 +24,37 @@ class Declaration; } } -struct AnimationEventInfo { - nsRefPtr mElement; - nsAnimationEvent mEvent; - - AnimationEventInfo(mozilla::dom::Element *aElement, - const nsString& aAnimationName, - PRUint32 aMessage, mozilla::TimeDuration aElapsedTime) - : mElement(aElement), - mEvent(true, aMessage, aAnimationName, aElapsedTime.ToSeconds()) - { - } - - // nsAnimationEvent doesn't support copy-construction, so we need - // to ourselves in order to work with nsTArray - AnimationEventInfo(const AnimationEventInfo &aOther) - : mElement(aOther.mElement), - mEvent(true, aOther.mEvent.message, - aOther.mEvent.animationName, aOther.mEvent.elapsedTime) - { - } -}; - -typedef InfallibleTArray EventArray; - -struct AnimationPropertySegment -{ - float mFromKey, mToKey; - nsStyleAnimation::Value mFromValue, mToValue; - mozilla::css::ComputedTimingFunction mTimingFunction; -}; - -struct AnimationProperty -{ - nsCSSProperty mProperty; - InfallibleTArray mSegments; -}; - -/** - * Data about one animation (i.e., one of the values of - * 'animation-name') running on an element. - */ -struct ElementAnimation -{ - ElementAnimation() - : mLastNotification(LAST_NOTIFICATION_NONE) - { - } - - nsString mName; // empty string for 'none' - float mIterationCount; // NS_IEEEPositiveInfinity() means infinite - PRUint8 mDirection; - PRUint8 mFillMode; - PRUint8 mPlayState; - - bool FillsForwards() const { - return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH || - mFillMode == NS_STYLE_ANIMATION_FILL_MODE_FORWARDS; - } - bool FillsBackwards() const { - return mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BOTH || - mFillMode == NS_STYLE_ANIMATION_FILL_MODE_BACKWARDS; - } - - bool IsPaused() const { - return mPlayState == NS_STYLE_ANIMATION_PLAY_STATE_PAUSED; - } - - bool CanPerformOnCompositor(mozilla::dom::Element* aElement, - mozilla::TimeStamp aTime) const; - - mozilla::TimeStamp mStartTime; // with delay taken into account - mozilla::TimeStamp mPauseStart; - mozilla::TimeDuration mIterationDuration; - - enum { - LAST_NOTIFICATION_NONE = PRUint32(-1), - LAST_NOTIFICATION_END = PRUint32(-2) - }; - // One of the above constants, or an integer for the iteration - // whose start we last notified on. - PRUint32 mLastNotification; - - InfallibleTArray mProperties; -}; - -/** - * Data about all of the animations running on an element. - */ -struct ElementAnimations : public mozilla::css::CommonElementAnimationData -{ - typedef mozilla::TimeStamp TimeStamp; - typedef mozilla::TimeDuration TimeDuration; - - ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, - nsAnimationManager *aAnimationManager); - - // This function takes as input the start time, duration, and direction of an - // animation and returns the position in the current iteration. Note that - // this only works when we know that the animation is currently running. - // This way of calling the function can be used from the compositor. Note - // that if the animation has not started yet, has already ended, or is paused, - // it should not be run from the compositor. When this function is called - // from the main thread, we need the actual ElementAnimation* in order to - // get correct animation-fill behavior and to fire animation events. - // This function returns -1 for the position if the animation should not be - // run (because it is not currently active and has no fill behavior.) - static double GetPositionInIteration(TimeStamp aStartTime, - TimeStamp aCurrentTime, - TimeDuration aDuration, - double aIterationCount, - PRUint32 aDirection, - bool IsForElement = true, - ElementAnimation* aAnimation = nullptr, - ElementAnimations* aEa = nullptr, - EventArray* aEventsToDispatch = nullptr); - - void EnsureStyleRuleFor(TimeStamp aRefreshTime, - EventArray &aEventsToDispatch); - - bool IsForElement() const { // rather than for a pseudo-element - return mElementProperty == nsGkAtoms::animationsProperty; - } - - void PostRestyleForAnimation(nsPresContext *aPresContext) { - nsRestyleHint styleHint = IsForElement() ? eRestyle_Self : eRestyle_Subtree; - aPresContext->PresShell()->RestyleForAnimation(mElement, styleHint); - } - - // True if this animation can be performed on the compositor thread. - bool CanPerformOnCompositorThread() const; - bool HasAnimationOfProperty(nsCSSProperty aProperty) const; - // This style rule contains the style data for currently animating - // values. It only matches when styling with animation. When we - // style without animation, we need to not use it so that we can - // detect any new changes; if necessary we restyle immediately - // afterwards with animation. - // NOTE: If we don't need to apply any styles, mStyleRule will be - // null, but mStyleRuleRefreshTime will still be valid. - nsRefPtr mStyleRule; - // The refresh time associated with mStyleRule. - TimeStamp mStyleRuleRefreshTime; - - // False when we know that our current style rule is valid - // indefinitely into the future (because all of our animations are - // either completed or paused). May be invalidated by a style change. - bool mNeedsRefreshes; - - InfallibleTArray mAnimations; -}; - class nsAnimationManager : public mozilla::css::CommonAnimationManager { public: nsAnimationManager(nsPresContext *aPresContext) - : mozilla::css::CommonAnimationManager(aPresContext) - , mKeyframesListIsDirty(true) + : mozilla::css::CommonAnimationManager(aPresContext), + mKeyframesListIsDirty(true) { mKeyframesRules.Init(16); // FIXME: make infallible! } - static ElementAnimations* GetAnimationsForCompositor(nsIContent* aContent, - nsCSSProperty aProperty) - { - if (!aContent->MayHaveAnimations()) - return nullptr; - ElementAnimations* animations = static_cast( - aContent->GetProperty(nsGkAtoms::animationsProperty)); - if (!animations) - return nullptr; - bool propertyMatches = animations->HasAnimationOfProperty(aProperty); - return (propertyMatches && animations->CanPerformOnCompositorThread()) ? - animations : nullptr; - } + struct AnimationEventInfo { + nsRefPtr mElement; + nsAnimationEvent mEvent; + + AnimationEventInfo(mozilla::dom::Element *aElement, + const nsString& aAnimationName, + PRUint32 aMessage, mozilla::TimeDuration aElapsedTime) + : mElement(aElement), + mEvent(true, aMessage, aAnimationName, aElapsedTime.ToSeconds()) + { + } + + // nsAnimationEvent doesn't support copy-construction, so we need + // to ourselves in order to work with nsTArray + AnimationEventInfo(const AnimationEventInfo &aOther) + : mElement(aOther.mElement), + mEvent(true, aOther.mEvent.message, + aOther.mEvent.animationName, aOther.mEvent.elapsedTime) + { + } + }; // nsIStyleRuleProcessor (parts) virtual void RulesMatching(ElementRuleProcessorData* aData); @@ -229,6 +89,8 @@ public: mKeyframesListIsDirty = true; } + typedef InfallibleTArray EventArray; + /** * Dispatch any pending events. We accumulate animationend and * animationiteration events only during refresh driver notifications diff --git a/layout/style/nsStyleAnimation.cpp b/layout/style/nsStyleAnimation.cpp index 50a28709e06..a05742d8ede 100644 --- a/layout/style/nsStyleAnimation.cpp +++ b/layout/style/nsStyleAnimation.cpp @@ -1122,9 +1122,9 @@ AddTransformScale(const nsCSSValue &aValue1, double aCoeff1, aResult.SetFloatValue(result + 1.0f, eCSSUnit_Number); } -/* static */ already_AddRefed -nsStyleAnimation::AppendTransformFunction(nsCSSKeyword aTransformFunction, - nsCSSValueList**& aListTail) +static already_AddRefed +AppendTransformFunction(nsCSSKeyword aTransformFunction, + nsCSSValueList**& aListTail) { nsRefPtr arr = AppendFunction(aTransformFunction); nsCSSValueList *item = new nsCSSValueList; @@ -1284,7 +1284,7 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale, /* Normalize the matrix */ local.Normalize(); - /** + /** * perspective is used to solve for perspective, but it also provides * an easy way to test for singularity of the upper 3x3 component. */ @@ -1302,13 +1302,13 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale, /* aPerspective is the right hand side of the equation. */ aPerspective = local.TransposedVector(3); - /** + /** * Solve the equation by inverting perspective and multiplying * aPerspective by the inverse. */ perspective.Invert(); aPerspective = perspective.TransposeTransform4D(aPerspective); - + /* Clear the perspective partition */ local.SetTransposedVector(3, empty); } else { @@ -1326,11 +1326,11 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale, /* Compute X scale factor and normalize first row. */ aScale.x = local[0].Length(); local[0] /= aScale.x; - + /* Compute XY shear factor and make 2nd local orthogonal to 1st. */ aShear[XYSHEAR] = local[0].DotProduct(local[1]); local[1] -= local[0] * aShear[XYSHEAR]; - + /* Now, compute Y scale and normalize 2nd local. */ aScale.y = local[1].Length(); local[1] /= aScale.y; @@ -1407,11 +1407,11 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1, // Interpolate each of the pieces gfx3DMatrix result; - gfxPointH3D perspective = + gfxPointH3D perspective = InterpolateNumerically(perspective1, perspective2, aProgress); result.SetTransposedVector(3, perspective); - - gfxPoint3D translate = + + gfxPoint3D translate = InterpolateNumerically(translate1, translate2, aProgress); result.Translate(translate); @@ -1440,7 +1440,7 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1, result.SkewXY(xyshear); } - gfxPoint3D scale = + gfxPoint3D scale = InterpolateNumerically(scale1, scale2, aProgress); if (scale != gfxPoint3D(1.0, 1.0, 1.0)) { result.Scale(scale.x, scale.y, scale.z); @@ -1457,8 +1457,8 @@ AddDifferentTransformLists(const nsCSSValueList* aList1, double aCoeff1, nsCSSValueList **resultTail = getter_Transfers(result); nsRefPtr arr; - arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_interpolatematrix, resultTail); - + arr = AppendTransformFunction(eCSSKeyword_interpolatematrix, resultTail); + // FIXME: We should change the other transform code to also only // take a single progress value, as having values that don't // sum to 1 doesn't make sense for these. @@ -1503,7 +1503,7 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1, tfunc != eCSSKeyword_interpolatematrix && tfunc != eCSSKeyword_rotate3d && tfunc != eCSSKeyword_perspective) { - arr = nsStyleAnimation::AppendTransformFunction(tfunc, resultTail); + arr = AppendTransformFunction(tfunc, resultTail); } switch (tfunc) { diff --git a/layout/style/nsStyleAnimation.h b/layout/style/nsStyleAnimation.h index 80e02e8d67d..6009f9b078a 100644 --- a/layout/style/nsStyleAnimation.h +++ b/layout/style/nsStyleAnimation.h @@ -15,10 +15,14 @@ #include "nsCSSProperty.h" #include "nsCoord.h" #include "nsColor.h" -#include "nsCSSValue.h" class nsPresContext; class nsStyleContext; +class nsCSSValue; +struct nsCSSValueList; +struct nsCSSValuePair; +struct nsCSSValueTriplet; +struct nsCSSValuePairList; struct nsCSSRect; class gfx3DMatrix; @@ -128,7 +132,7 @@ public: * (property ID + string). A style context is needed in case the * specified value depends on inherited style or on the values of other * properties. - * + * * @param aProperty The property whose value we're computing. * @param aTargetElement The content node to which our computed value is * applicable. @@ -199,13 +203,9 @@ public: * @param aProgress Interpolation value in the range [0.0, 1.0] */ static gfx3DMatrix InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1, - const gfx3DMatrix &aMatrix2, + const gfx3DMatrix &aMatrix2, double aProgress); - static already_AddRefed - AppendTransformFunction(nsCSSKeyword aTransformFunction, - nsCSSValueList**& aListTail); - /** * The types and values for the values that we extract and animate. */ diff --git a/layout/style/nsStyleTransformMatrix.cpp b/layout/style/nsStyleTransformMatrix.cpp index 701d6884b40..cf141b112cd 100644 --- a/layout/style/nsStyleTransformMatrix.cpp +++ b/layout/style/nsStyleTransformMatrix.cpp @@ -39,13 +39,12 @@ static double FlushToZero(double aVal) return aVal; } -float +static float ProcessTranslatePart(const nsCSSValue& aValue, nsStyleContext* aContext, nsPresContext* aPresContext, bool& aCanStoreInRuleTree, - nscoord aSize, - float aAppUnitsPerMatrixUnit) + nscoord aSize, float aAppUnitsPerMatrixUnit) { nscoord offset = 0; float percent = 0.0f; diff --git a/layout/style/nsStyleTransformMatrix.h b/layout/style/nsStyleTransformMatrix.h index c18fccadb18..da612c77ddd 100644 --- a/layout/style/nsStyleTransformMatrix.h +++ b/layout/style/nsStyleTransformMatrix.h @@ -30,13 +30,6 @@ namespace nsStyleTransformMatrix { */ nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData); - float ProcessTranslatePart(const nsCSSValue& aValue, - nsStyleContext* aContext, - nsPresContext* aPresContext, - bool& aCanStoreInRuleTree, - nscoord aSize, - float aAppUnitsPerMatrixUnit); - /** * Given an nsCSSValueList containing -moz-transform functions, * returns a matrix containing the value of those functions. diff --git a/layout/style/nsTransitionManager.cpp b/layout/style/nsTransitionManager.cpp index 91f758f4b18..d1ff34e7661 100644 --- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -22,8 +22,6 @@ #include "nsEventDispatcher.h" #include "nsGUIEvent.h" #include "mozilla/dom/Element.h" -#include "nsIFrame.h" -#include "nsCSSFrameConstructor.h" using mozilla::TimeStamp; using mozilla::TimeDuration; @@ -31,12 +29,53 @@ using mozilla::TimeDuration; namespace dom = mozilla::dom; namespace css = mozilla::css; -ElementTransitions::ElementTransitions(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, - nsTransitionManager *aTransitionManager) - : CommonElementAnimationData(aElement, aElementProperty, - aTransitionManager) +/***************************************************************************** + * Per-Element data * + *****************************************************************************/ + +struct ElementPropertyTransition { -} + nsCSSProperty mProperty; + nsStyleAnimation::Value mStartValue, mEndValue; + TimeStamp mStartTime; // actual start plus transition delay + + // data from the relevant nsTransition + TimeDuration mDuration; + css::ComputedTimingFunction mTimingFunction; + + // This is the start value to be used for a check for whether a + // transition is being reversed. Normally the same as mStartValue, + // except when this transition started as the reversal of another + // in-progress transition. Needed so we can handle two reverses in a + // row. + nsStyleAnimation::Value mStartForReversingTest; + // Likewise, the portion (in value space) of the "full" reversed + // transition that we're actually covering. For example, if a :hover + // effect has a transition that moves the element 10px to the right + // (by changing 'left' from 0px to 10px), and the mouse moves in to + // the element (starting the transition) but then moves out after the + // transition has advanced 4px, the second transition (from 10px/4px + // to 0px) will have mReversePortion of 0.4. (If the mouse then moves + // in again when the transition is back to 2px, the mReversePortion + // for the third transition (from 0px/2px to 10px) will be 0.8. + double mReversePortion; + + // Compute the portion of the *value* space that we should be through + // at the given time. (The input to the transition timing function + // has time units, the output has value units.) + double ValuePortionFor(TimeStamp aRefreshTime) const; + + bool IsRemovedSentinel() const + { + return mStartTime.IsNull(); + } + + void SetRemovedSentinel() + { + // assign the null time stamp + mStartTime = TimeStamp(); + } +}; double ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const @@ -66,6 +105,32 @@ ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const return mTimingFunction.GetValue(timePortion); } +struct ElementTransitions : public mozilla::css::CommonElementAnimationData +{ + ElementTransitions(dom::Element *aElement, nsIAtom *aElementProperty, + nsTransitionManager *aTransitionManager) + : CommonElementAnimationData(aElement, aElementProperty, + aTransitionManager) + { + } + + void EnsureStyleRuleFor(TimeStamp aRefreshTime); + + + // Either zero or one for each CSS property: + nsTArray mPropertyTransitions; + + // This style rule overrides style data with the currently + // transitioning value for an element that is executing a transition. + // It only matches when styling with animation. When we style without + // animation, we need to not use it so that we can detect any new + // changes; if necessary we restyle immediately afterwards with + // animation. + nsRefPtr mStyleRule; + // The refresh time associated with mStyleRule. + TimeStamp mStyleRuleRefreshTime; +}; + static void ElementTransitionsPropertyDtor(void *aObject, nsIAtom *aPropertyName, @@ -108,41 +173,6 @@ ElementTransitions::EnsureStyleRuleFor(TimeStamp aRefreshTime) } } -bool -ElementPropertyTransition::CanPerformOnCompositor(mozilla::dom::Element* aElement, - TimeStamp aTime) const { - return css::CommonElementAnimationData:: - CanAnimatePropertyOnCompositor(aElement, mProperty) && !IsRemovedSentinel() && - mStartTime < aTime && aTime < mStartTime + mDuration; -} - -bool -ElementTransitions::HasTransitionOfProperty(nsCSSProperty aProperty) const -{ - for (PRUint32 tranIdx = mPropertyTransitions.Length(); tranIdx-- != 0; ) { - if (aProperty == mPropertyTransitions[tranIdx].mProperty) { - return true; - } - } - return false; -} - -bool -ElementTransitions::CanPerformOnCompositorThread() const -{ - for (PRUint32 i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) { - const ElementPropertyTransition &pt = mPropertyTransitions[i]; - if (pt.IsRemovedSentinel()) { - continue; - } - if (!css::CommonElementAnimationData::CanAnimatePropertyOnCompositor(mElement, - pt.mProperty)) { - return false; - } - } - return true; -} - /***************************************************************************** * nsTransitionManager * *****************************************************************************/ @@ -195,12 +225,13 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, disp->mTransitions[0].GetDelay() == 0.0f && disp->mTransitions[0].GetDuration() == 0.0f) { return nullptr; - } + } + if (aNewStyleContext->PresContext()->IsProcessingAnimationStyleChange()) { return nullptr; } - + if (aNewStyleContext->GetParent() && aNewStyleContext->GetParent()->HasPseudoElementData()) { // Ignore transitions on things that inherit properties from @@ -229,7 +260,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, property == eCSSProperty_UNKNOWN) { // Nothing to do, but need to exclude this from cases below. } else if (property == eCSSPropertyExtra_all_properties) { - for (nsCSSProperty p = nsCSSProperty(0); + for (nsCSSProperty p = nsCSSProperty(0); p < eCSSProperty_COUNT_no_shorthands; p = nsCSSProperty(p + 1)) { ConsiderStartingTransition(p, t, aElement, et, @@ -269,7 +300,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, property == eCSSProperty_UNKNOWN) { // Nothing to do, but need to exclude this from cases below. } else if (property == eCSSPropertyExtra_all_properties) { - for (nsCSSProperty p = nsCSSProperty(0); + for (nsCSSProperty p = nsCSSProperty(0); p < eCSSProperty_COUNT_no_shorthands; p = nsCSSProperty(p + 1)) { allTransitionProperties.AddProperty(p); @@ -333,7 +364,11 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement, // rule. nsRefPtr coverRule = new css::AnimValuesStyleRule; - + if (!coverRule) { + NS_WARNING("out of memory"); + return nullptr; + } + nsTArray &pts = et->mPropertyTransitions; for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) { ElementPropertyTransition &pt = pts[i]; @@ -378,19 +413,9 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty, pt.mStartValue) && ExtractComputedValueForTransition(aProperty, aNewStyleContext, pt.mEndValue); - - bool haveChange = pt.mStartValue != pt.mEndValue; - bool haveOMTA = false; - if (!aNewStyleContext->GetPseudoType()) { - ElementTransitions* et = nsTransitionManager::GetTransitions(aElement); - if (et) { - haveOMTA = et->CanPerformOnCompositorThread(); - } - } - bool shouldAnimate = haveValues && - (haveChange || haveOMTA) && + pt.mStartValue != pt.mEndValue && // Check that we can interpolate between these values // (If this is ever a performance problem, we could add a // CanInterpolate method, but it seems fine for now.) @@ -471,7 +496,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty, // now we'd end up at the current position. double valuePortion = oldPT.ValuePortionFor(mostRecentRefresh) * oldPT.mReversePortion + - (1.0 - oldPT.mReversePortion); + (1.0 - oldPT.mReversePortion); // A timing function with negative y1 (or y2!) might make // valuePortion negative. In this case, we still want to apply our // reversing logic based on relative distances, not make duration @@ -491,7 +516,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty, // reduce positive delays. if (delay < 0.0f) delay *= valuePortion; - duration *= valuePortion; pt.mStartForReversingTest = oldPT.mEndValue; @@ -503,6 +527,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty, pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay); pt.mDuration = TimeDuration::FromMilliseconds(duration); pt.mTimingFunction.Init(tf); + if (!aElementTransitions) { aElementTransitions = GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(), @@ -512,7 +537,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty, return; } } - + nsTArray &pts = aElementTransitions->mPropertyTransitions; #ifdef DEBUG @@ -536,7 +561,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty, nsCSSPseudoElements::ePseudo_NotPseudoElement ? eRestyle_Self : eRestyle_Subtree; presContext->PresShell()->RestyleForAnimation(aElement, hint); - // XXXdz: invalidate the frame here, once animations are throttled. *aStartedAny = true; aWhichStarted->AddProperty(aProperty); @@ -570,6 +594,10 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement, if (!et && aCreateIfNeeded) { // FIXME: Consider arena-allocating? et = new ElementTransitions(aElement, propName, this); + if (!et) { + NS_WARNING("out of memory"); + return nullptr; + } nsresult rv = aElement->SetProperty(propName, et, ElementTransitionsPropertyDtor, nullptr); if (NS_FAILED(rv)) { @@ -577,9 +605,6 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement, delete et; return nullptr; } - if (propName == nsGkAtoms::transitionsProperty) { - aElement->SetMayHaveAnimations(); - } AddElementData(et); } @@ -733,6 +758,8 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime) // completion. See comment below. et->mPropertyTransitions.RemoveElementAt(i); } else if (pt.mStartTime + pt.mDuration <= aTime) { + // This transition has completed. + // Fire transitionend events only for transitions on elements // and not those on pseudo-elements, since we can't target an // event at pseudo-elements. @@ -766,9 +793,6 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime) nsRestyleHint hint = et->mElementProperty == nsGkAtoms::transitionsProperty ? eRestyle_Self : eRestyle_Subtree; mPresContext->PresShell()->RestyleForAnimation(et->mElement, hint); - // XXXdz: if we have started a transition since the last tick and are - // performing the transition off the main thread, we need to invalidate - // the frame once we start throttling animation ticks. if (et->mPropertyTransitions.IsEmpty()) { et->Destroy(); diff --git a/layout/style/nsTransitionManager.h b/layout/style/nsTransitionManager.h index 180e2842603..33b45f292c0 100644 --- a/layout/style/nsTransitionManager.h +++ b/layout/style/nsTransitionManager.h @@ -15,86 +15,7 @@ class nsStyleContext; class nsPresContext; class nsCSSPropertySet; struct nsTransition; - -/***************************************************************************** - * Per-Element data * - *****************************************************************************/ - -struct ElementPropertyTransition -{ - ElementPropertyTransition() {} - - nsCSSProperty mProperty; - nsStyleAnimation::Value mStartValue, mEndValue; - mozilla::TimeStamp mStartTime; // actual start plus transition delay - - // data from the relevant nsTransition - mozilla::TimeDuration mDuration; - mozilla::css::ComputedTimingFunction mTimingFunction; - - // This is the start value to be used for a check for whether a - // transition is being reversed. Normally the same as mStartValue, - // except when this transition started as the reversal of another - // in-progress transition. Needed so we can handle two reverses in a - // row. - nsStyleAnimation::Value mStartForReversingTest; - // Likewise, the portion (in value space) of the "full" reversed - // transition that we're actually covering. For example, if a :hover - // effect has a transition that moves the element 10px to the right - // (by changing 'left' from 0px to 10px), and the mouse moves in to - // the element (starting the transition) but then moves out after the - // transition has advanced 4px, the second transition (from 10px/4px - // to 0px) will have mReversePortion of 0.4. (If the mouse then moves - // in again when the transition is back to 2px, the mReversePortion - // for the third transition (from 0px/2px to 10px) will be 0.8. - double mReversePortion; - - // Compute the portion of the *value* space that we should be through - // at the given time. (The input to the transition timing function - // has time units, the output has value units.) - double ValuePortionFor(mozilla::TimeStamp aRefreshTime) const; - - bool IsRemovedSentinel() const - { - return mStartTime.IsNull(); - } - - void SetRemovedSentinel() - { - // assign the null time stamp - mStartTime = mozilla::TimeStamp(); - } - - bool CanPerformOnCompositor(mozilla::dom::Element* aElement, - mozilla::TimeStamp aTime) const; -}; - -struct ElementTransitions : public mozilla::css::CommonElementAnimationData -{ - ElementTransitions(mozilla::dom::Element *aElement, nsIAtom *aElementProperty, - nsTransitionManager *aTransitionManager); - - void EnsureStyleRuleFor(mozilla::TimeStamp aRefreshTime); - - - bool HasTransitionOfProperty(nsCSSProperty aProperty) const; - // True if this animation can be performed on the compositor thread. - bool CanPerformOnCompositorThread() const; - // Either zero or one for each CSS property: - nsTArray mPropertyTransitions; - - // This style rule overrides style data with the currently - // transitioning value for an element that is executing a transition. - // It only matches when styling with animation. When we style without - // animation, we need to not use it so that we can detect any new - // changes; if necessary we restyle immediately afterwards with - // animation. - nsRefPtr mStyleRule; - // The refresh time associated with mStyleRule. - mozilla::TimeStamp mStyleRuleRefreshTime; -}; - - +struct ElementTransitions; class nsTransitionManager : public mozilla::css::CommonAnimationManager { @@ -104,28 +25,8 @@ public: { } - static ElementTransitions* GetTransitions(nsIContent* aContent) { - return static_cast - (aContent->GetProperty(nsGkAtoms::transitionsProperty)); - } - - static ElementTransitions* - GetTransitionsForCompositor(nsIContent* aContent, - nsCSSProperty aProperty) - { - if (!aContent->MayHaveAnimations()) - return nullptr; - ElementTransitions* transitions = GetTransitions(aContent); - if (!transitions || - !transitions->HasTransitionOfProperty(aProperty) || - !transitions->CanPerformOnCompositorThread()) { - return nullptr; - } - return transitions; - } - /** - * StyleContextChanged + * StyleContextChanged * * To be called from nsFrameManager::ReResolveStyleContext when the * style of an element has changed, to initiate transitions from diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 86a27b29085..3f349ced999 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3512,10 +3512,6 @@ pref("layers.acceleration.force-enabled", false); pref("layers.acceleration.draw-fps", false); -// Whether to animate simple opacity and transforms on the compositor -pref("layers.offmainthreadcomposition.animate-opacity", false); -pref("layers.offmainthreadcomposition.animate-transform", false); - #ifdef MOZ_X11 #ifdef MOZ_WIDGET_GTK2 pref("gfx.xrender.enabled",true); diff --git a/testing/xpcshell/b2g_xpcshell_venv.sh b/testing/xpcshell/b2g_xpcshell_venv.sh new file mode 100644 index 00000000000..da8cde448b0 --- /dev/null +++ b/testing/xpcshell/b2g_xpcshell_venv.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +PYTHON=$1 + +if [ -z "${PYTHON}" ] +then + echo "No python found" + exit 1 +fi + +if [ -z "${MARIONETTE_HOME}" ] +then + echo "No MARIONETTE_HOME found" + exit 1 +fi + +if [ -z "${XPCSHELLTEST_HOME}" ] +then + echo "No XPCSHELLTEST_HOME found" + exit 1 +fi + +echo "Detected Marionette home in $MARIONETTE_HOME" + +# If a GECKO_OBJDIR environemnt variable exists, we will create the Python +# virtual envirnoment there. Otherwise we create it in the PWD. +VENV_DIR="marionette_venv" +if [ -z $GECKO_OBJDIR ] +then + VENV_DIR="$MARIONETTE_HOME/$VENV_DIR" +else + VENV_DIR="$GECKO_OBJDIR/$VENV_DIR" +fi + +# Check if environment exists, if not, create a virtualenv: +if [ -d $VENV_DIR ] +then + echo "Using virtual environment in $VENV_DIR" + cd $VENV_DIR + . bin/activate +else + echo "Creating a virtual environment in $VENV_DIR" + curl https://raw.github.com/pypa/virtualenv/develop/virtualenv.py | ${PYTHON} - $VENV_DIR + cd $VENV_DIR + . bin/activate + # set up mozbase + git clone git://github.com/mozilla/mozbase.git + cd mozbase + python setup_development.py +fi + +# update the marionette_client +cd $MARIONETTE_HOME +python setup.py develop + +cd $XPCSHELLTEST_HOME + +# pop off the python parameter +shift +python runtestsb2g.py $@ diff --git a/testing/xpcshell/remotexpcshelltests.py b/testing/xpcshell/remotexpcshelltests.py index 6d26df6bca8..beb46dd591d 100644 --- a/testing/xpcshell/remotexpcshelltests.py +++ b/testing/xpcshell/remotexpcshelltests.py @@ -101,6 +101,11 @@ class XPCShellRemote(xpcshell.XPCShellTests, object): self.device.pushFile(self.options.localAPK, self.remoteBinDir) + self.pushLibs() + + self.device.chmodDir(self.remoteBinDir) + + def pushLibs(self): if self.options.localAPK: localLib = os.path.join(self.options.objdir, "dist/fennec") if not os.path.exists(localLib): @@ -126,7 +131,6 @@ class XPCShellRemote(xpcshell.XPCShellTests, object): if (file.endswith(".so")): self.device.pushFile(os.path.join(root, file), self.remoteBinDir) - self.device.chmodDir(self.remoteBinDir) def setupTestDir(self): xpcDir = os.path.join(self.options.objdir, "_tests/xpcshell") @@ -197,10 +201,13 @@ class XPCShellRemote(xpcshell.XPCShellTests, object): self.log.info("TEST-INFO | profile dir is %s" % self.profileDir) return self.profileDir + def setLD_LIBRARY_PATH(self, env): + env["LD_LIBRARY_PATH"]=self.remoteBinDir + def launchProcess(self, cmd, stdout, stderr, env, cwd): cmd[0] = self.remoteJoin(self.remoteBinDir, "xpcshell") - env = dict() - env["LD_LIBRARY_PATH"]=self.remoteBinDir + env = {} + self.setLD_LIBRARY_PATH(env) env["MOZ_LINKER_CACHE"]=self.remoteBinDir if self.options.localAPK and self.appRoot: env["GRE_HOME"]=self.appRoot diff --git a/testing/xpcshell/runtestsb2g.py b/testing/xpcshell/runtestsb2g.py index e6790fcbac6..32a60a078b0 100644 --- a/testing/xpcshell/runtestsb2g.py +++ b/testing/xpcshell/runtestsb2g.py @@ -29,8 +29,21 @@ class B2GXPCShellRemote(XPCShellRemote): XPCShellRemote.setupUtilities(self) def clean(self): + print >>sys.stderr, "\nCleaning files from previous run.." self.device.removeDir(DEVICE_TEST_ROOT) + # Overridden + def pushLibs(self): + if not self.options.use_device_libs: + XPCShellRemote.pushLibs(self) + + # Overridden + def setLD_LIBRARY_PATH(self, env): + if self.options.use_device_libs: + env['LD_LIBRARY_PATH'] = '/system/b2g' + else: + XPCShellRemote.setLD_LIBRARY_PATH(self, env) + # Overridden # This returns 1 even when tests pass - this is why it's switched to 0 # https://bugzilla.mozilla.org/show_bug.cgi?id=773703 @@ -52,10 +65,11 @@ class B2GOptions(RemoteXPCShellOptions): help="Path to B2G repo or qemu dir") defaults['b2g_path'] = None - self.add_option('--marionette', action='store', - type='string', dest='marionette', - help="host:port to use when connecting to Marionette") - defaults['marionette'] = None + self.add_option('--emupath', action='store', + type='string', dest='emu_path', + help="Path to emulator folder (if different " + "from b2gpath") + defaults['emu_path'] = None self.add_option('--emulator', action='store', type='string', dest='emulator', @@ -72,6 +86,16 @@ class B2GOptions(RemoteXPCShellOptions): help="Path to adb") defaults['adb_path'] = 'adb' + self.add_option('--address', action='store', + type='string', dest='address', + help="host:port of running Gecko instance to connect to") + defaults['address'] = None + + self.add_option('--use-device-libs', action='store_true', + dest='use_device_libs', + help="Don't push .so's") + defaults['use_device_libs'] = False + defaults['dm_trans'] = 'adb' defaults['debugger'] = None defaults['debuggerArgs'] = None @@ -97,11 +121,14 @@ def main(): if options.no_window: kwargs['noWindow'] = True if options.b2g_path: - kwargs['homedir'] = options.b2g_path - if options.marionette: - host, port = options.marionette.split(':') + kwargs['homedir'] = options.emu_path or options.b2g_path + if options.address: + host, port = options.address.split(':') kwargs['host'] = host kwargs['port'] = int(port) + kwargs['baseurl'] = 'http://%s:%d/' % (host, int(port)) + if options.emulator: + kwargs['connectToRunningEmulator'] = True marionette = Marionette(**kwargs) # Create the DeviceManager instance diff --git a/xpcom/ds/TimeStamp.h b/xpcom/ds/TimeStamp.h index 90b767629f6..960b1b63589 100644 --- a/xpcom/ds/TimeStamp.h +++ b/xpcom/ds/TimeStamp.h @@ -13,10 +13,6 @@ #include "nsDebug.h" #include "prlong.h" -namespace IPC { -template struct ParamTraits; -} - namespace mozilla { class TimeStamp; @@ -99,9 +95,6 @@ public: bool operator>(const TimeDuration& aOther) const { return mValue > aOther.mValue; } - bool operator==(const TimeDuration& aOther) const { - return mValue == aOther.mValue; - } // Return a best guess at the system's current timing resolution, // which might be variable. TimeDurations below this order of @@ -118,7 +111,6 @@ public: private: friend class TimeStamp; - friend struct IPC::ParamTraits; static TimeDuration FromTicks(PRInt64 aTicks) { TimeDuration t; @@ -273,8 +265,6 @@ public: static NS_HIDDEN_(void) Shutdown(); private: - friend struct IPC::ParamTraits; - TimeStamp(PRUint64 aValue) : mValue(aValue) {} /**