Backout 1244b8a8e57a (bug 755084), 32d16d0f87c9 (bug 706179), 8548e016d4a9 (bug 768440), 697f5b87eae9 (bug 768440), 808fc2bd4e8c (bug 755084), 54b1484cd125 (bug 755084), 876726b632c0 (bug 706179) for xul android R3 failures
authorEd Morley <emorley@mozilla.com>
Wed, 25 Jul 2012 16:37:04 +0100
changeset 106439 7ad3878167c106e3bc3806c8f405e97fd140a993
parent 106438 94e2e8ea1d11317b1f78309507eb4cbaa88179c4
child 106440 e5e8d176ac96e7e79f3385f7ad6712c62d917ff9
push id214
push userakeybl@mozilla.com
push dateWed, 14 Nov 2012 20:38:59 +0000
treeherdermozilla-release@c8b08ec8e1aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs755084, 706179, 768440
milestone17.0a1
backs out1244b8a8e57afe99e1069b25c84293708b8e41f2
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backout 1244b8a8e57a (bug 755084), 32d16d0f87c9 (bug 706179), 8548e016d4a9 (bug 768440), 697f5b87eae9 (bug 768440), 808fc2bd4e8c (bug 755084), 54b1484cd125 (bug 755084), 876726b632c0 (bug 706179) for xul android R3 failures
content/base/public/nsIContent.h
content/base/public/nsINode.h
content/smil/nsSMILKeySpline.h
gfx/layers/Layers.cpp
gfx/layers/Layers.h
gfx/layers/Makefile.in
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/PLayer.ipdl
gfx/layers/ipc/PLayers.ipdl
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
gfx/layers/ipc/ShadowLayersParent.cpp
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/src/nsRect.h
ipc/glue/IPCMessageUtils.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/generic/nsIFrame.h
layout/generic/nsImageFrame.cpp
layout/generic/nsObjectFrame.cpp
layout/generic/nsVideoFrame.cpp
layout/ipc/RenderFrameParent.cpp
layout/style/AnimationCommon.cpp
layout/style/AnimationCommon.h
layout/style/Makefile.in
layout/style/nsAnimationManager.cpp
layout/style/nsAnimationManager.h
layout/style/nsStyleAnimation.cpp
layout/style/nsStyleAnimation.h
layout/style/nsStyleTransformMatrix.cpp
layout/style/nsStyleTransformMatrix.h
layout/style/nsTransitionManager.cpp
layout/style/nsTransitionManager.h
modules/libpref/src/init/all.js
xpcom/ds/TimeStamp.h
--- a/content/base/public/nsIContent.h
+++ b/content/base/public/nsIContent.h
@@ -6,17 +6,16 @@
 #define nsIContent_h___
 
 #include "nsCOMPtr.h" // for already_AddRefed
 #include "nsStringGlue.h"
 #include "nsCaseTreatment.h"
 #include "nsChangeHint.h"
 #include "nsINode.h"
 #include "nsIDocument.h" // for IsInHTMLDocument
-#include "nsCSSProperty.h"
 
 // Forward declarations
 class nsIAtom;
 class nsIDOMEvent;
 class nsIContent;
 class nsEventListenerManager;
 class nsIURI;
 class nsRuleWalker;
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1286,18 +1286,16 @@ private:
     // Set if the element has some style states locked
     ElementHasLockedStyleStates,
     // Set if element has pointer locked
     ElementHasPointerLock,
     // Set if the node may have DOMMutationObserver attached to it.
     NodeMayHaveDOMMutationObserver,
     // Set if node is Content
     NodeIsContent,
-    // Set if the node has animations or transitions
-    ElementHasAnimations,
     // Guard value
     BooleanFlagCount
   };
 
   void SetBoolFlag(BooleanFlag name, bool value) {
     PR_STATIC_ASSERT(BooleanFlagCount <= 8*sizeof(mBoolFlags));
     mBoolFlags = (mBoolFlags & ~(1 << name)) | (value << name);
   }
@@ -1353,18 +1351,16 @@ public:
   bool MayHaveDOMMutationObserver()
     { return GetBoolFlag(NodeMayHaveDOMMutationObserver); }
   void SetMayHaveDOMMutationObserver()
     { SetBoolFlag(NodeMayHaveDOMMutationObserver, true); }
   bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); }
   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); }
   void SetNodeIsContent() { SetBoolFlag(NodeIsContent); }
   void ClearInDocument() { ClearBoolFlag(IsInDocument); }
   void SetIsElement() { SetBoolFlag(NodeIsElement); }
   void ClearIsElement() { ClearBoolFlag(NodeIsElement); }
   void SetHasID() { SetBoolFlag(ElementHasID); }
--- a/content/smil/nsSMILKeySpline.h
+++ b/content/smil/nsSMILKeySpline.h
@@ -21,21 +21,16 @@ public:
    * SMILANIM 3.2.3. They must each be in the range 0.0 <= x <= 1.0
    */
   nsSMILKeySpline(double aX1, double aY1,
                   double aX2, double aY2)
   {
     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);
 
   /**
    * Gets the output (y) value for an input (x).
    *
    * @param aX  The input x value. A floating-point number between 0 and
    *            1 (inclusive).
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -12,17 +12,16 @@
 #include "ImageLayers.h"
 #include "Layers.h"
 #include "gfxPlatform.h"
 #include "ReadbackLayer.h"
 #include "gfxUtils.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Util.h"
 #include "LayerSorter.h"
-#include "AnimationCommon.h"
 
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 typedef FrameMetrics::ViewID ViewID;
 const ViewID FrameMetrics::NULL_SCROLL_ID = 0;
 const ViewID FrameMetrics::ROOT_SCROLL_ID = 1;
 const ViewID FrameMetrics::START_SCROLL_ID = 2;
@@ -216,255 +215,16 @@ LayerManager::CreateAsynchronousImageCon
 {
   nsRefPtr<ImageContainer> container = new ImageContainer(ImageContainer::ENABLE_ASYNC);
   return container.forget();
 }
 
 //--------------------------------------------------
 // Layer
 
-Layer::Layer(LayerManager* aManager, void* aImplData) :
-  mManager(aManager),
-  mParent(nsnull),
-  mNextSibling(nsnull),
-  mPrevSibling(nsnull),
-  mImplData(aImplData),
-  mMaskLayer(nsnull),
-  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<TransformFunction>& aFunctions)
-{
-  nsAutoPtr<nsCSSValueList> result;
-  nsCSSValueList** resultTail = getter_Transfers(result);
-  for (PRUint32 i = 0; i < aFunctions.Length(); i++) {
-    nsRefPtr<nsCSSValue::Array> 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<css::ComputedTimingFunction*>* functions =
-      &data.mFunctions;
-    nsTArray<AnimationSegment> segments = mAnimations.ElementAt(i).segments();
-    for (PRUint32 j = 0; j < segments.Length(); j++) {
-      TimingFunction tf = segments.ElementAt(j).sampleFn();
-      css::ComputedTimingFunction* ctf = new css::ComputedTimingFunction();
-      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;
-        }
-      }
-      functions->AppendElement(ctf);
-    }
-
-    // Precompute the nsStyleAnimation::Values that we need if this is a transform
-    // animation.
-    InfallibleTArray<nsStyleAnimation::Value>* startValues =
-      &data.mStartValues;
-    InfallibleTArray<nsStyleAnimation::Value>* 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<TransformFunction>& 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<TransformFunction>& 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()
 {
   // If the visible content in the layer is opaque, there is no need
   // for an alpha channel.
   if (GetContentFlags() & CONTENT_OPAQUE)
     return true;
   // Also, if this layer is the bottommost layer in a container which
@@ -539,17 +299,17 @@ Layer::SnapTransform(const gfx3DMatrix& 
       *aResidualTransform = matrix2D * snappedMatrixInverse;
     }
   } else {
     result = aTransform;
   }
   return result;
 }
 
-nsIntRect
+nsIntRect 
 Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
                             const gfxMatrix* aWorldTransform)
 {
   ContainerLayer* container = GetParent();
   NS_ASSERTION(container, "This can't be called on the root!");
 
   // Establish initial clip rect: it's either the one passed in, or
   // if the parent has an intermediate surface, it's the extents of that surface.
@@ -596,64 +356,42 @@ Layer::CalculateScissorRect(const nsIntR
     gfxRect trScissor = aWorldTransform->TransformBounds(r);
     trScissor.Round();
     if (!gfxUtils::GfxRectToIntRect(trScissor, &scissor))
       return nsIntRect(currentClip.TopLeft(), nsIntSize(0, 0));
   }
   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;
 }
 
 void
 Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurface)
 {
   if (mMaskLayer) {
     mMaskLayer->mEffectiveTransform = aTransformToSurface;
 
 #ifdef DEBUG
-
     gfxMatrix maskTranslation;
     bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
     NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
 #endif
     mMaskLayer->mEffectiveTransform.PreMultiply(mMaskLayer->GetTransform());
   }
 }
 
@@ -1047,34 +785,34 @@ ReadbackLayer::PrintInfo(nsACString& aTo
 
 //--------------------------------------------------
 // LayerManager
 
 void
 LayerManager::Dump(FILE* aFile, const char* aPrefix)
 {
   FILE* file = FILEOrDefault(aFile);
-
+ 
   fprintf(file, "<ul><li><a ");
 #ifdef MOZ_DUMP_PAINTING
   WriteSnapshotLinkToDumpFile(this, file);
 #endif
   fprintf(file, ">");
   DumpSelf(file, aPrefix);
 #ifdef MOZ_DUMP_PAINTING
   fprintf(file, "</a>");
 #endif
 
   nsCAutoString pfx(aPrefix);
   pfx += "  ";
   if (!GetRoot()) {
     fprintf(file, "%s(null)</li></ul>", pfx.get());
     return;
   }
-
+ 
   fprintf(file, "<ul>");
   GetRoot()->Dump(file, pfx.get());
   fprintf(file, "</ul></li></ul>");
 }
 
 void
 LayerManager::DumpSelf(FILE* aFile, const char* aPrefix)
 {
@@ -1198,10 +936,10 @@ LayerManager::PrintInfo(nsACString& aTo,
 
 /*static*/ void LayerManager::InitLog() {}
 /*static*/ bool LayerManager::IsLogEnabled() { return false; }
 
 #endif // MOZ_LAYERS_HAVE_LOG
 
 PRLogModuleInfo* LayerManager::sLog;
 
-} // namespace layers
+} // namespace layers 
 } // namespace mozilla
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -13,17 +13,16 @@
 #include "nsRect.h"
 #include "nsISupportsImpl.h"
 #include "nsAutoPtr.h"
 #include "gfx3DMatrix.h"
 #include "gfxColor.h"
 #include "gfxPattern.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
-#include "nsStyleAnimation.h"
 #include "LayersBackend.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/TimeStamp.h"
 
 #if defined(DEBUG) || defined(PR_LOGGING)
 #  include <stdio.h>            // FILE
 #  include "prlog.h"
 #  ifndef MOZ_LAYERS_HAVE_LOG
@@ -39,24 +38,18 @@ struct PRLogModuleInfo;
 class gfxContext;
 class nsPaintEvent;
 
 namespace mozilla {
 namespace gl {
 class GLContext;
 }
 
-namespace css {
-class ComputedTimingFunction;
-}
-
 namespace layers {
 
-class Animation;
-class CommonLayerAttributes;
 class Layer;
 class ThebesLayer;
 class ContainerLayer;
 class ImageLayer;
 class ColorLayer;
 class ImageContainer;
 class CanvasLayer;
 class ReadbackLayer;
@@ -532,23 +525,16 @@ protected:
   static PRLogModuleInfo* sLog;
   uint64_t mId;
 private:
   TimeStamp mLastFrameTime;
   nsTArray<float> mFrameTimes;
 };
 
 class ThebesLayer;
-typedef InfallibleTArray<Animation> AnimationArray;
-
-struct AnimData {
-  InfallibleTArray<nsStyleAnimation::Value> mStartValues;
-  InfallibleTArray<nsStyleAnimation::Value> mEndValues;
-  InfallibleTArray<mozilla::css::ComputedTimingFunction*> mFunctions;
-};
 
 /**
  * A Layer represents anything that can be rendered onto a destination
  * surface.
  */
 class THEBES_API Layer {
   NS_INLINE_DECL_REFCOUNTING(Layer)  
 
@@ -560,17 +546,17 @@ public:
     TYPE_CONTAINER,
     TYPE_IMAGE,
     TYPE_READBACK,
     TYPE_REF,
     TYPE_SHADOW,
     TYPE_THEBES
   };
 
-  virtual ~Layer();
+  virtual ~Layer() {}
 
   /**
    * Returns the LayerManager this Layer belongs to. Note that the layer
    * manager might be in a destroyed state, at which point it's only
    * valid to set/get user data from it.
    */
   LayerManager* Manager() { return mManager; }
 
@@ -711,45 +697,30 @@ public:
 
   /**
    * CONSTRUCTION PHASE ONLY
    * Tell this layer what its transform should be. The transformation
    * is applied when compositing the layer into its parent container.
    * 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
    * (not chrome) document, the topmost content document has a root scrollframe
    * with a displayport, but the layer does not move when that displayport scrolls.
    */
   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
    * is considered the "anchor" point, that is, the point which remains in the
    * same position when compositing the layer tree with a transformation
    * (such as when asynchronously scrolling and zooming).
    */
   void SetFixedPositionAnchor(const gfxPoint& aAnchor) { mAnchor = aAnchor; }
@@ -759,25 +730,21 @@ public:
   const nsIntRect* GetClipRect() { return mUseClipRect ? &mClipRect : nsnull; }
   PRUint32 GetContentFlags() { return mContentFlags; }
   const nsIntRegion& GetVisibleRegion() { return mVisibleRegion; }
   ContainerLayer* GetParent() { return mParent; }
   Layer* GetNextSibling() { return mNextSibling; }
   Layer* GetPrevSibling() { return mPrevSibling; }
   virtual Layer* GetFirstChild() { return nsnull; }
   virtual Layer* GetLastChild() { return nsnull; }
-  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<AnimData>& GetAnimationData() { return mAnimationData; }
+
   /**
    * DRAWING PHASE ONLY
    *
    * Write layer-subtype-specific attributes into aAttrs.  Used to
    * synchronize layer attributes to their shadows'.
    */
   virtual void FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { }
 
@@ -968,38 +935,45 @@ public:
   static bool IsLogEnabled() { return LayerManager::IsLogEnabled(); }
 
 #ifdef DEBUG
   void SetDebugColorIndex(PRUint32 aIndex) { mDebugColorIndex = aIndex; }
   PRUint32 GetDebugColorIndex() { return mDebugColorIndex; }
 #endif
 
 protected:
-  Layer(LayerManager* aManager, void* aImplData);
+  Layer(LayerManager* aManager, void* aImplData) :
+    mManager(aManager),
+    mParent(nsnull),
+    mNextSibling(nsnull),
+    mPrevSibling(nsnull),
+    mImplData(aImplData),
+    mMaskLayer(nsnull),
+    mOpacity(1.0),
+    mContentFlags(0),
+    mUseClipRect(false),
+    mUseTileSourceRect(false),
+    mIsFixedPosition(false),
+    mDebugColorIndex(0)
+    {}
 
   void Mutated() { mManager->Mutated(this); }
 
   // Print interesting information about this into aTo.  Internally
   // used to implement Dump*() and Log*().  If subclasses have
   // additional interesting properties, they should override this with
   // an implementation that first calls the base implementation then
   // appends additional info to aTo.
   virtual nsACString& PrintInfo(nsACString& aTo, const char* aPrefix);
 
   /**
    * 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
    * to pixel boundaries. Snapping is only performed if this layer's
    * layer manager has enabled snapping (which is the default).
    * @param aSnapRect a rectangle whose edges should be snapped to pixel
    * boundaries in the destination surface. If the rectangle is empty,
    * then the snapping process should preserve the scale factors of the
@@ -1015,21 +989,17 @@ protected:
   ContainerLayer* mParent;
   Layer* mNextSibling;
   Layer* mPrevSibling;
   void* mImplData;
   nsRefPtr<Layer> mMaskLayer;
   gfx::UserData mUserData;
   nsIntRegion mVisibleRegion;
   gfx3DMatrix mTransform;
-  float mXScale;
-  float mYScale;
   gfx3DMatrix mEffectiveTransform;
-  AnimationArray mAnimations;
-  InfallibleTArray<AnimData> mAnimationData;
   float mOpacity;
   nsIntRect mClipRect;
   nsIntRect mTileSourceRect;
   PRUint32 mContentFlags;
   bool mUseClipRect;
   bool mUseTileSourceRect;
   bool mIsFixedPosition;
   gfxPoint mAnchor;
--- a/gfx/layers/Makefile.in
+++ b/gfx/layers/Makefile.in
@@ -26,28 +26,26 @@ DEFINES += -DIMPL_THEBES
 ifdef MOZ_DEBUG
 DEFINES += -DD3D_DEBUG_INFO
 endif
 
 EXPORTS = \
         BasicLayers.h \
         BasicTiledThebesLayer.h \
         BasicImplData.h \
-        CompositorParent.h \
         ImageLayers.h \
         Layers.h \
         LayersBackend.h \
         LayerManagerOGLShaders.h \
         LayerManagerOGL.h \
         LayerManagerOGLProgram.h \
+        ReadbackLayer.h \
         LayerSorter.h \
-        ReadbackLayer.h \
-        ShadowLayersManager.h \
+        TexturePoolOGL.h \
         SharedTextureImage.h \
-        TexturePoolOGL.h \
         $(NULL)
 
 CPPSRCS = \
         BasicImages.cpp \
         BasicLayerManager.cpp \
         BasicCanvasLayer.cpp \
         BasicColorLayer.cpp \
         BasicContainerLayer.cpp \
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -16,25 +16,16 @@
 #include "AsyncPanZoomController.h"
 #include "BasicLayers.h"
 #include "CompositorParent.h"
 #include "LayerManagerOGL.h"
 #include "nsGkAtoms.h"
 #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;
 using namespace std;
 
 namespace mozilla {
 namespace layers {
 
@@ -416,25 +407,25 @@ CompositorParent::Composite()
   mCurrentCompositeTask = NULL;
 
   mLastCompose = TimeStamp::Now();
 
   if (mPaused || !mLayerManager || !mLayerManager->GetRoot()) {
     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()) {
     LayerManagerOGL* lm = static_cast<LayerManagerOGL*>(mLayerManager.get());
     lm->SetWorldTransform(
       ComputeGLTransformForRotation(mTargetConfig.naturalBounds(),
                                     mTargetConfig.rotation()));
   }
@@ -521,135 +512,26 @@ CompositorParent::TransformFixedLayers(L
 
 // Go down shadow layer tree, setting properties to match their non-shadow
 // counterparts.
 static void
 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()) {
     SetShadowProperties(child);
   }
 }
 
-
-// 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(nsnull, data.origin(), nsDeviceContext::AppUnitsPerCSSPixel(),
-                                                      &data.bounds(), interpolatedList, &data.mozOrigin(),
-                                                      &data.perspectiveOrigin(), &data.perspective());
-
-    InfallibleTArray<TransformFunction>* functions = new InfallibleTArray<TransformFunction>();
-    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<AnimData>& 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,
                                                    bool* aWantNextFrame)
 {
   bool appliedTransform = false;
   for (Layer* child = aLayer->GetFirstChild();
       child; child = child->GetNextSibling()) {
@@ -685,23 +567,19 @@ bool
 CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
 {
   bool wantNextFrame = false;
   Layer* layer = GetPrimaryScrollableLayer();
   ShadowLayer* shadow = layer->AsShadowLayer();
   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
   // 
   // Attempt to apply an async content transform to any layer that has
   // an async pan zoom controller (which means that it is rendered
   // async using Gecko). If this fails, fall back to transforming the
   // primary scrollable layer.  "Failing" here means that we don't
@@ -784,16 +662,17 @@ CompositorParent::TransformShadowTree(Ti
                          mContentRect.YMost() - mWidgetSize.height / tempScaleDiffY) -
                  metricsScrollOffset.y;
       scaleDiff.y = tempScaleDiffY;
     }
 
     shadow->SetShadowTransform(treeTransform * currentTransform);
     TransformFixedLayers(layer, offset, scaleDiff);
   }
+
   return wantNextFrame;
 }
 
 void
 CompositorParent::SetFirstPaintViewport(const nsIntPoint& aOffset, float aZoom,
                                         const nsIntRect& aPageRect, const gfx::Rect& aCssPageRect)
 {
 #ifdef MOZ_WIDGET_ANDROID
--- a/gfx/layers/ipc/PLayer.ipdl
+++ b/gfx/layers/ipc/PLayer.ipdl
@@ -9,17 +9,17 @@ include protocol PLayers;
 
 namespace mozilla {
 namespace layers {
 
 /**
  * PLayer represents a layer shared across thread contexts.
  */
 
-async protocol PLayer {
+sync protocol PLayer {
     manager PLayers;
 
     /**
      * OWNERSHIP MODEL
      *
      * Roughly speaking, the child side "actually owns" a Layer.  This
      * is because the parent side is the "shadow"; when the child
      * releases a Layer, the parent's shadow is no longer meaningful.
@@ -27,13 +27,13 @@ async protocol PLayer {
      * To implement this model, the concrete PLayerParent keeps a
      * strong ref to its Layer, so the Layer's lifetime is bound to
      * the PLayerParent's.  Then, when the Layer's refcount hits 0 on
      * the child side, we send __delete__() from the child to parent.
      * The parent then releases its Layer, which results in the Layer
      * being deleted "soon" (usually immediately).
      */
 parent:
-    async __delete__();
+    __delete__();
 };
 
 } // layers
 } // mozilla
--- a/gfx/layers/ipc/PLayers.ipdl
+++ b/gfx/layers/ipc/PLayers.ipdl
@@ -9,24 +9,16 @@ include LayersSurfaces;
 using mozilla::ScreenRotation;
 include protocol PCompositor;
 include protocol PGrallocBuffer;
 include protocol PLayer;
 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
  * layer (sub)trees.  The protocol comprises atomically publishing
  * layer subtrees to a "shadow" thread context (which grafts the
  * subtree into its own tree), and atomically updating a published
  * subtree.  ("Atomic" in this sense is wrt painting.)
  */
@@ -45,148 +37,43 @@ struct OpCreateContainerLayer  { PLayer 
 struct OpCreateImageLayer      { PLayer layer; };
 struct OpCreateColorLayer      { PLayer layer; };
 struct OpCreateCanvasLayer     { PLayer layer; };
 struct OpCreateRefLayer        { PLayer layer; };
 
 struct ThebesBuffer {
   SurfaceDescriptor buffer;
   nsIntRect rect;
-  nsIntPoint rotation;
+  nsIntPoint rotation; 
 };
 union OptionalThebesBuffer { ThebesBuffer; null_t; };
 
 union CanvasSurface {
   SurfaceDescriptor;
   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    {
   GraphicsFilterType filter;
   bool forceSingleTile;
 };
 
 union SpecificLayerAttributes {
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -294,33 +294,30 @@ ShadowLayerForwarder::EndTransaction(Inf
        it != mTxn->mMutants.end(); ++it) {
     ShadowableLayer* shadow = *it;
     Layer* mutant = shadow->AsLayer();
     NS_ABORT_IF_FALSE(!!mutant, "unshadowable layer?");
 
     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();
     common.clipRect() = (common.useClipRect() ?
                          *mutant->GetClipRect() : nsIntRect());
     common.isFixedPosition() = mutant->GetIsFixedPosition();
     common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor();
     if (Layer* maskLayer = mutant->GetMaskLayer()) {
       common.maskLayerChild() = Shadow(maskLayer->AsShadowableLayer());
     } else {
       common.maskLayerChild() = NULL;
     }
     common.maskLayerParent() = NULL;
-    common.animations() = mutant->GetAnimations();
     attrs.specific() = null_t();
     mutant->FillSpecificAttributes(attrs.specific());
 
     mTxn->AddEdit(OpSetLayerAttributes(NULL, Shadow(shadow), attrs));
   }
 
   AutoInfallibleTArray<Edit, 10> cset;
   size_t nCsets = mTxn->mCset.size() + mTxn->mPaints.size();
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -519,54 +519,46 @@ public:
    *
    * They are analogous to the Layer interface.
    */
   void SetShadowVisibleRegion(const nsIntRegion& aRegion)
   {
     mShadowVisibleRegion = aRegion;
   }
 
-  void SetShadowOpacity(float aOpacity)
-  {
-    mShadowOpacity = aOpacity;
-  }
-
   void SetShadowClipRect(const nsIntRect* aRect)
   {
     mUseShadowClipRect = aRect != nsnull;
     if (aRect) {
       mShadowClipRect = *aRect;
     }
   }
 
   void SetShadowTransform(const gfx3DMatrix& aMatrix)
   {
     mShadowTransform = aMatrix;
   }
 
   // These getters can be used anytime.
-  float GetShadowOpacity() { return mShadowOpacity; }
   const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nsnull; }
   const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
   const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
 
   virtual TiledLayerComposer* AsTiledLayerComposer() { return NULL; }
 
 protected:
   ShadowLayer()
     : mAllocator(nsnull)
-    , mShadowOpacity(1.0)
     , mUseShadowClipRect(false)
   {}
 
   ISurfaceDeAllocator* mAllocator;
   nsIntRegion mShadowVisibleRegion;
   gfx3DMatrix mShadowTransform;
   nsIntRect mShadowClipRect;
-  float mShadowOpacity;
   bool mUseShadowClipRect;
 };
 
 
 class ShadowThebesLayer : public ShadowLayer,
                           public ThebesLayer
 {
 public:
--- a/gfx/layers/ipc/ShadowLayersParent.cpp
+++ b/gfx/layers/ipc/ShadowLayersParent.cpp
@@ -209,31 +209,29 @@ ShadowLayersParent::RecvUpdate(const Inf
 
       const OpSetLayerAttributes& osla = edit.get_OpSetLayerAttributes();
       Layer* layer = AsShadowLayer(osla)->AsLayer();
       const LayerAttributes& attrs = osla.attrs();
 
       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());
         layer->SetFixedPositionAnchor(common.fixedPositionAnchor());
       }
       if (PLayerParent* maskLayer = common.maskLayerParent()) {
         layer->SetMaskLayer(cast(maskLayer)->AsLayer());
       } else {
         layer->SetMaskLayer(NULL);
       }
-      layer->SetAnimations(common.animations());
 
       typedef SpecificLayerAttributes Specific;
       const SpecificLayerAttributes& specific = attrs.specific();
       switch (specific.type()) {
       case Specific::Tnull_t:
         break;
 
       case Specific::TThebesLayerAttributes: {
@@ -254,17 +252,17 @@ ShadowLayersParent::RecvUpdate(const Inf
         static_cast<ContainerLayer*>(layer)->SetFrameMetrics(
           specific.get_ContainerLayerAttributes().metrics());
         break;
 
       case Specific::TColorLayerAttributes:
         MOZ_LAYERS_LOG(("[ParentSide]   color layer"));
 
         static_cast<ColorLayer*>(layer)->SetColor(
-          specific.get_ColorLayerAttributes().color().value());
+          specific.get_ColorLayerAttributes().color());
         break;
 
       case Specific::TCanvasLayerAttributes:
         MOZ_LAYERS_LOG(("[ParentSide]   canvas layer"));
 
         static_cast<CanvasLayer*>(layer)->SetFilter(
           specific.get_CanvasLayerAttributes().filter());
         break;
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -104,26 +104,26 @@ CanvasLayerOGL::Initialize(const Data& a
 
     mNeedsYFlip = mCanvasGLContext->GetOffscreenTexture() != 0;
   } else {
     NS_WARNING("CanvasLayerOGL::Initialize called without surface or GL context!");
     return;
   }
 
   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();
   if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
     mDelayedUpdates = true;
     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?");
   }
 }
 
 /**
  * Following UpdateSurface(), mTexture on context this->gl() should contain the data we want,
  * unless mDelayedUpdates is true because of a too-large surface.
  */
@@ -218,17 +218,17 @@ CanvasLayerOGL::RenderLayer(int aPreviou
 
   if (useGLContext) {
     gl()->BindTex2DOffscreen(mCanvasGLContext);
     program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(),
                                                 true,
                                                 GetMaskLayer() ? Mask2d : MaskNone);
   } else if (mDelayedUpdates) {
     NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
-
+    
     drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
 
     nsRefPtr<gfxASurface> surf = mCanvasSurface;
     if (mDrawTarget) {
       surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
     }
 
     mLayerProgram =
@@ -294,17 +294,17 @@ IsValidSharedTexDescriptor(const Surface
 ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
   : ShadowCanvasLayer(aManager, nsnull)
   , LayerOGL(aManager)
   , mNeedsYFlip(false)
   , mTexture(0)
 {
   mImplData = static_cast<LayerOGL*>(this);
 }
-
+ 
 ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL()
 {}
 
 void
 ShadowCanvasLayerOGL::Initialize(const Data& aData)
 {
   NS_RUNTIMEABORT("Incompatibe surface type");
 }
--- a/gfx/src/nsRect.h
+++ b/gfx/src/nsRect.h
@@ -194,22 +194,16 @@ struct NS_GFX nsRect :
   // Note: this can turn an empty rectangle into a non-empty rectangle
   inline nsIntRect ScaleToOutsidePixels(float aXScale, float aYScale,
                                         nscoord aAppUnitsPerPixel) const;
   // Note: this can turn an empty rectangle into a non-empty rectangle
   inline nsIntRect ToOutsidePixels(nscoord aAppUnitsPerPixel) const;
   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 :
   public mozilla::gfx::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> {
   typedef mozilla::gfx::BaseRect<PRInt32, nsIntRect, nsIntPoint, nsIntSize, nsIntMargin> Super;
 
   // Constructors
   nsIntRect() : Super()
--- a/ipc/glue/IPCMessageUtils.h
+++ b/ipc/glue/IPCMessageUtils.h
@@ -4,17 +4,16 @@
  * 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/. */
 
 #ifndef __IPC_GLUE_IPCMESSAGEUTILS_H__
 #define __IPC_GLUE_IPCMESSAGEUTILS_H__
 
 #include "chrome/common/ipc_message_utils.h"
 
-#include "mozilla/TimeStamp.h"
 #include "mozilla/Util.h"
 #include "mozilla/gfx/2D.h"
 
 #include "prtypes.h"
 #include "nsID.h"
 #include "nsMemory.h"
 #include "nsStringGlue.h"
 #include "nsTArray.h"
@@ -435,38 +434,21 @@ struct ParamTraits<gfxPoint>
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, aParam.x);
     WriteParam(aMsg, aParam.y);
   }
 
   static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
-    return (ReadParam(aMsg, aIter, &aResult->x) &&
-            ReadParam(aMsg, aIter, &aResult->y));
- }
-};
-
-template<>
-struct ParamTraits<gfxPoint3D>
-{
-  typedef gfxPoint3D paramType;
+    if (ReadParam(aMsg, aIter, &aResult->x) &&
+        ReadParam(aMsg, aIter, &aResult->y))
+      return true;
 
-  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;
   }
 };
 
 template<>
 struct ParamTraits<gfxSize>
 {
   typedef gfxSize paramType;
 
@@ -591,38 +573,20 @@ struct ParamTraits<mozilla::null_t>
   Read(const Message* aMsg, void** aIter, paramType* aResult)
   {
     *aResult = paramType();
     return true;
   }
 };
 
 template<>
-struct ParamTraits<nsPoint>
-{
-  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<nsIntPoint>
 {
   typedef nsIntPoint 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)
   {
@@ -630,17 +594,17 @@ struct ParamTraits<nsIntPoint>
             ReadParam(msg, iter, &result->y));
   }
 };
 
 template<>
 struct ParamTraits<nsIntRect>
 {
   typedef nsIntRect paramType;
-
+  
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
@@ -679,39 +643,39 @@ struct ParamTraits<nsIntRegion>
     return false;
   }
 };
 
 template<>
 struct ParamTraits<nsIntSize>
 {
   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)
   {
     return (ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
 
 template<>
 struct ParamTraits<mozilla::gfx::Size>
 {
   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)
   {
     return (ReadParam(msg, iter, &result->width) &&
             ReadParam(msg, iter, &result->height));
   }
 };
@@ -737,17 +701,17 @@ struct ParamTraits<mozilla::gfx::Rect>
             ReadParam(msg, iter, &result->height));
   }
 };
 
 template<>
 struct ParamTraits<nsRect>
 {
   typedef nsRect paramType;
-
+  
   static void Write(Message* msg, const paramType& param)
   {
     WriteParam(msg, param.x);
     WriteParam(msg, param.y);
     WriteParam(msg, param.width);
     WriteParam(msg, param.height);
   }
 
@@ -797,39 +761,11 @@ struct ParamTraits<nsID>
                               aParam.m1,
                               aParam.m2));
     for (unsigned int i = 0; i < mozilla::ArrayLength(aParam.m3); i++)
       aLog->append(StringPrintf(L"%2.2X", aParam.m3[i]));
     aLog->append(L"}");
   }
 };
 
-template<>
-struct ParamTraits<mozilla::TimeDuration>
-{
-  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<mozilla::TimeStamp>
-{
-  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__ */
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -16,19 +16,16 @@
 #include "gfxUtils.h"
 #include "nsImageFrame.h"
 #include "nsRenderingContext.h"
 #include "MaskLayerImageCache.h"
 
 #include "mozilla/Preferences.h"
 #include "sampler.h"
 
-#include "nsAnimationManager.h"
-#include "nsTransitionManager.h"
-
 #ifdef DEBUG
 #include <stdio.h>
 #endif
 
 using namespace mozilla::layers;
 
 namespace mozilla {
 
@@ -626,17 +623,17 @@ FrameLayerBuilder::DisplayItemDataEntry:
 void
 FrameLayerBuilder::FlashPaint(gfxContext *aContext)
 {
   static bool sPaintFlashingEnabled;
   static bool sPaintFlashingPrefCached = false;
 
   if (!sPaintFlashingPrefCached) {
     sPaintFlashingPrefCached = true;
-    mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled,
+    mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled, 
                                           "nglayout.debug.paint_flashing");
   }
 
   if (sPaintFlashingEnabled) {
     float r = float(rand()) / RAND_MAX;
     float g = float(rand()) / RAND_MAX;
     float b = float(rand()) / RAND_MAX;
     aContext->SetColor(gfxRGBA(r, g, b, 0.2));
@@ -991,17 +988,17 @@ ContainerState::CreateOrRecycleMaskImage
   } else {
     // Create a new layer
     result = mManager->CreateImageLayer();
     if (!result)
       return nsnull;
     result->SetUserData(&gMaskLayerUserData, new MaskLayerUserData());
     result->SetForceSingleTile(true);
   }
-
+  
   return result.forget();
 }
 
 static nsIntPoint
 GetTranslationForThebesLayer(ThebesLayer* aLayer)
 {
   gfxMatrix transform;
   if (!aLayer->GetTransform().Is2D(&transform) ||
@@ -1109,17 +1106,17 @@ ContainerState::CreateOrRecycleThebesLay
       NSAppUnitsToDoublePixels(offset.x, appUnitsPerDevPixel)*mParameters.mXScale,
       NSAppUnitsToDoublePixels(offset.y, appUnitsPerDevPixel)*mParameters.mYScale);
   // We call RoundToMatchResidual here so that the residual after rounding
   // is close to data->mActiveScrolledRootPosition if possible.
   nsIntPoint pixOffset(RoundToMatchResidual(scaledOffset.x, data->mActiveScrolledRootPosition.x),
                        RoundToMatchResidual(scaledOffset.y, data->mActiveScrolledRootPosition.y));
   gfxMatrix matrix;
   matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y));
-  layer->SetBaseTransform(gfx3DMatrix::From2D(matrix));
+  layer->SetTransform(gfx3DMatrix::From2D(matrix));
 
   // FIXME: Temporary workaround for bug 681192 and bug 724786.
 #ifndef MOZ_JAVA_COMPOSITOR
   // Calculate exact position of the top-left of the active scrolled root.
   // This might not be 0,0 due to the snapping in ScaleToNearestPixels.
   gfxPoint activeScrolledRootTopLeft = scaledOffset - matrix.GetTranslation();
   // If it has changed, then we need to invalidate the entire layer since the
   // pixels in the layer buffer have the content at a (subpixel) offset
@@ -1229,17 +1226,17 @@ ContainerState::ThebesLayerData::UpdateC
       }
     }
     mCommonClipCount = clipCount;
     NS_ASSERTION(mItemClip.mRoundedClipRects.Length() >= PRUint32(mCommonClipCount),
                  "Inconsistent common clip count.");
   } else {
     // first item in the layer
     mCommonClipCount = aCurrentClip.mRoundedClipRects.Length();
-  }
+  } 
 }
 
 already_AddRefed<ImageContainer>
 ContainerState::ThebesLayerData::CanOptimizeImageLayer()
 {
   if (!mImage) {
     return nsnull;
   }
@@ -1251,42 +1248,43 @@ void
 ContainerState::PopThebesLayerData()
 {
   NS_ASSERTION(!mThebesLayerDataStack.IsEmpty(), "Can't pop");
 
   PRInt32 lastIndex = mThebesLayerDataStack.Length() - 1;
   ThebesLayerData* data = mThebesLayerDataStack[lastIndex];
 
   nsRefPtr<Layer> layer;
-  nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer();
+  nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer(); 
 
   if ((data->mIsSolidColorInVisibleRegion || imageContainer) &&
       data->mLayer->GetValidRegion().IsEmpty()) {
     NS_ASSERTION(!(data->mIsSolidColorInVisibleRegion && imageContainer),
                  "Can't be a solid color as well as an image!");
     if (imageContainer) {
       nsRefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer();
       imageLayer->SetContainer(imageContainer);
       data->mImage->ConfigureLayer(imageLayer);
       // The layer's current transform is applied first, then the result is scaled.
-      imageLayer->SetScale(mParameters.mXScale, mParameters.mYScale);
+      gfx3DMatrix transform = imageLayer->GetTransform()*
+        gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
+      imageLayer->SetTransform(transform);
       if (data->mItemClip.mHaveClipRect) {
         nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect);
         imageLayer->IntersectClipRect(clip);
       }
       layer = imageLayer;
     } else {
       nsRefPtr<ColorLayer> colorLayer = CreateOrRecycleColorLayer();
       colorLayer->SetIsFixedPosition(data->mLayer->GetIsFixedPosition());
       colorLayer->SetColor(data->mSolidColor);
 
       // Copy transform
-      colorLayer->SetBaseTransform(data->mLayer->GetTransform());
-      colorLayer->SetScale(data->mLayer->GetXScale(), data->mLayer->GetYScale());
-
+      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
       // area to fill must contain the visible region, and because it's
       // a rectangle, it must therefore contain the visible region's GetBounds.
       // Note that the visible region is already clipped appropriately.
       nsIntRect visibleRect = data->mVisibleRegion.GetBounds();
       colorLayer->SetClipRect(&visibleRect);
@@ -1307,17 +1305,17 @@ ContainerState::PopThebesLayerData()
     layer = data->mLayer;
     imageContainer = nsnull;
   }
 
   gfxMatrix transform;
   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(),
                  "Matrix not just an integer translation?");
     // Convert from relative to the container to relative to the
     // ThebesLayer itself.
     nsIntRegion rgn = data->mVisibleRegion;
     rgn.MoveBy(-nsIntPoint(PRInt32(transform.x0), PRInt32(transform.y0)));
@@ -1637,19 +1635,19 @@ PaintInactiveLayer(nsDisplayListBuilder*
   // This item has an inactive layer. Render it to a ThebesLayer
   // using a temporary BasicLayerManager.
   PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
   nsIntRect itemVisibleRect =
     aItem->GetVisibleRect().ToOutsidePixels(appUnitsPerDevPixel);
 
   nsRefPtr<gfxContext> context = aContext;
 #ifdef MOZ_DUMP_PAINTING
-  nsRefPtr<gfxASurface> surf;
+  nsRefPtr<gfxASurface> 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);
   }
 #endif
 
   nsRefPtr<BasicLayerManager> tempManager = new BasicLayerManager();
   tempManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(aLayerBuilder, false));
@@ -1672,17 +1670,17 @@ PaintInactiveLayer(nsDisplayListBuilder*
   } else {
     tempManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer, aBuilder);
   }
   aLayerBuilder->DidEndTransaction(tempManager);
  
 #ifdef MOZ_DUMP_PAINTING
   if (gfxUtils::sDumpPainting) {
     DumpPaintedImage(aItem, surf);
-
+  
     surf->SetDeviceOffset(gfxPoint(0, 0));
     aContext->SetSource(surf, itemVisibleRect.TopLeft());
     aContext->Rectangle(itemVisibleRect);
     aContext->Fill();
     aItem->SetPainted();
   }
 #endif
 }
@@ -1774,17 +1772,17 @@ ContainerState::ProcessDisplayItems(cons
       }
 
       // If it's not a ContainerLayer, we need to apply the scale transform
       // ourselves.
       if (!ownLayer->AsContainerLayer()) {
         // 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(
         !nsLayoutUtils::IsScrolledByRootContentDocumentDisplayportScrolling(
                                       activeScrolledRoot, mBuilder));
 
       // Update that layer's clip and visible rects.
       NS_ASSERTION(ownLayer->Manager() == mManager, "Wrong manager");
@@ -2118,19 +2116,19 @@ ChooseScaleAndSetTransform(FrameLayerBui
     // scaled out of sight anyway.
     if (fabs(scale.width) < 1e-8 || fabs(scale.height) < 1e-8) {
       scale = gfxSize(1.0, 1.0);
     }
   } else {
     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);
   if (aTransform) {
     result.mInTransformedSubtree = true;
     if (aContainerFrame->AreLayersMarkedActive(nsChangeHint_UpdateTransformLayer)) {
       result.mInActiveTransformedSubtree = true;
     }
@@ -2549,28 +2547,28 @@ FrameLayerBuilder::GetThebesLayerResolut
 #ifdef MOZ_DUMP_PAINTING
 static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDisplayListBuilder* aBuilder)
 {
   bool snap;
   nsRect appUnitBounds = aItem->GetBounds(aBuilder, &snap);
   gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height);
   bounds.ScaleInverse(aDest->AppUnitsPerDevPixel());
 
-  nsRefPtr<gfxASurface> surf =
-    gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
+  nsRefPtr<gfxASurface> surf = 
+    gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height), 
                                                        gfxASurface::CONTENT_COLOR_ALPHA);
   surf->SetDeviceOffset(-bounds.TopLeft());
   nsRefPtr<gfxContext> context = new gfxContext(surf);
   nsRefPtr<nsRenderingContext> ctx = new nsRenderingContext();
   ctx->Init(aDest->DeviceContext(), context);
 
   aItem->Paint(aBuilder, ctx);
   DumpPaintedImage(aItem, surf);
   aItem->SetPainted();
-
+    
   surf->SetDeviceOffset(gfxPoint(0, 0));
   aDest->ThebesContext()->SetSource(surf, bounds.TopLeft());
   aDest->ThebesContext()->Rectangle(bounds);
   aDest->ThebesContext()->Fill();
 }
 #endif
 
 /*
@@ -3022,17 +3020,17 @@ CalculateBounds(nsTArray<FrameLayerBuild
     bounds.UnionRect(bounds, aRects[i].mRect);
    }
  
   return nsLayoutUtils::RectToGfxRect(bounds, A2D);
 }
  
 void
 ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
-                               PRUint32 aRoundedRectClipCount)
+                               PRUint32 aRoundedRectClipCount) 
 {
   // don't build an unnecessary mask
   nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds();
   if (aClip.mRoundedClipRects.IsEmpty() ||
       aRoundedRectClipCount <= 0 ||
       layerBounds.IsEmpty()) {
     return;
   }
@@ -3048,17 +3046,17 @@ ContainerState::SetupMaskLayer(Layer *aL
   }
   newData.mScaleX = mParameters.mXScale;
   newData.mScaleY = mParameters.mYScale;
 
   if (*userData == newData) {
     aLayer->SetMaskLayer(maskLayer);
     return;
   }
-
+ 
   // calculate a more precise bounding rect
   const PRInt32 A2D = mContainerFrame->PresContext()->AppUnitsPerDevPixel();
   gfxRect boundingRect = CalculateBounds(newData.mRoundedClipRects, A2D);
   boundingRect.Scale(mParameters.mXScale, mParameters.mYScale);
 
   PRUint32 maxSize = mManager->GetMaxTextureSize();
   NS_ASSERTION(maxSize > 0, "Invalid max texture size");
   nsIntSize surfaceSize(NS_MIN<PRInt32>(boundingRect.Width(), maxSize),
@@ -3126,17 +3124,17 @@ ContainerState::SetupMaskLayer(Layer *aL
     data.mSize = surfaceSize;
     static_cast<CairoImage*>(image.get())->SetData(data);
     container->SetCurrentImage(image);
 
     GetMaskLayerImageCache()->PutImage(key, container);
   }
 
   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;
   userData->mScaleY = newData.mScaleY;
   userData->mRoundedClipRects.SwapElements(newData.mRoundedClipRects);
   userData->mImageKey = key;
 
   aLayer->SetMaskLayer(maskLayer);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -5,18 +5,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
 /*
  * structures that represent things to be painted (ordered in z-order),
  * used during painting and hit testing
  */
 
-#include "mozilla/layers/PLayers.h"
-
 #include "nsDisplayList.h"
 
 #include "nsCSSRendering.h"
 #include "nsRenderingContext.h"
 #include "nsISelectionController.h"
 #include "nsIPresShell.h"
 #include "nsRegion.h"
 #include "nsFrameManager.h"
@@ -33,387 +31,23 @@
 #include "nsIInterfaceRequestorUtils.h"
 #include "BasicLayers.h"
 #include "nsBoxFrame.h"
 #include "nsViewportFrame.h"
 #include "nsSVGEffects.h"
 #include "nsSVGElement.h"
 #include "nsSVGClipPathFrame.h"
 #include "sampler.h"
-#include "nsAnimationManager.h"
-#include "nsTransitionManager.h"
-#include "nsIViewManager.h"
 
 #include "mozilla/StandardInteger.h"
 
 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<TransformFunction>& 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<AnimationSegment> 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<TransformFunction> fromFunctions;
-        AddTransformFunctions(list, styleContext,
-                              presContext, bounds,
-                              scale, fromFunctions);
-
-        list = segment->mToValue.GetCSSValueListValue();
-        InfallibleTArray<TransformFunction> 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),
       mIgnoreScrollFrame(nsnull),
       mCurrentTableItem(nsnull),
       mFinalTransparentRegion(nsnull),
       mCachedOffsetFrame(aReferenceFrame),
       mCachedOffset(0, 0),
@@ -560,33 +194,31 @@ static void RecordFrameMetrics(nsIFrame*
   nsIScrollableFrame* scrollableFrame = nsnull;
   if (aScrollFrame)
     scrollableFrame = aScrollFrame->GetScrollTargetFrame();
 
   if (scrollableFrame) {
     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(
       aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
   }
   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);
   }
 
   metrics.mScrollId = aScrollId;
 
   nsIPresShell* presShell = presContext->GetPresShell();
   metrics.mResolution = gfxSize(presShell->GetXResolution(), presShell->GetYResolution());
@@ -663,17 +295,17 @@ nsDisplayListBuilder::EnterPresShell(nsI
   state->mPresShell = aReferenceFrame->PresContext()->PresShell();
   state->mCaretFrame = nsnull;
   state->mFirstFrameMarkedForDisplay = mFramesMarkedForDisplay.Length();
 
   state->mPresShell->UpdateCanvasBackground();
 
   if (mIsPaintingToWindow) {
     mReferenceFrame->AddPaintedPresShell(state->mPresShell);
-
+    
     state->mPresShell->IncrementPaintCount();
   }
 
   bool buildCaret = mBuildCaret;
   if (mIgnoreSuppression || !state->mPresShell->IsPaintingSuppressed()) {
     if (state->mPresShell->IsPaintingSuppressed()) {
       mHadToIgnoreSuppression = true;
     }
@@ -726,17 +358,17 @@ nsDisplayListBuilder::MarkFramesForDispl
                                                const nsRect& aDirtyRect) {
   for (nsFrameList::Enumerator e(aFrames); !e.AtEnd(); e.Next()) {
     mFramesMarkedForDisplay.AppendElement(e.get());
     MarkOutOfFlowFrameForDisplay(aDirtyFrame, e.get(), aDirtyRect);
   }
 }
 
 void
-nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect)
+nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect) 
 {
   nsAutoTArray<nsIFrame::ChildList,4> childListArray;
   aDirtyFrame->GetChildLists(&childListArray);
   nsIFrame::ChildListArrayIterator lists(childListArray);
   for (; !lists.IsDone(); lists.Next()) {
     nsFrameList::Enumerator childFrames(lists.CurrentList());
     for (; !childFrames.AtEnd(); childFrames.Next()) {
       nsIFrame *child = childFrames.get();
@@ -983,20 +615,20 @@ void nsDisplayList::PaintForFrame(nsDisp
     BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nsnull, *this,
                            containerParameters, nsnull);
 
   if (!root) {
     layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
     return;
   }
   // Root is being scaled up by the X/Y resolution. Scale it back down.
-  gfx3DMatrix rootTransform = root->GetBaseTransform()*
+  gfx3DMatrix rootTransform = root->GetTransform()*
     gfx3DMatrix::ScalingMatrix(1.0f/containerParameters.mXScale,
                                1.0f/containerParameters.mYScale, 1.0f);
-  root->SetBaseTransform(rootTransform);
+  root->SetTransform(rootTransform);
 
   ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
                                                    : FrameMetrics::NULL_SCROLL_ID;
 
   nsIFrame* rootScrollFrame = presShell->GetRootScrollFrame();
   nsRect displayport;
   bool usingDisplayport = false;
   if (rootScrollFrame) {
@@ -1129,34 +761,34 @@ void nsDisplayList::HitTest(nsDisplayLis
     // so that recursive calls to HitTest have more buffer space.
     item = aState->mItemBuffer[i];
     aState->mItemBuffer.SetLength(i);
 
     bool snap;
     if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) {
       nsAutoTArray<nsIFrame*, 16> 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<nsIFrame*> *writeFrames = aOutFrames;
       if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
           item->GetUnderlyingFrame()->Preserves3D()) {
         if (outFrames.Length()) {
           nsDisplayTransform *transform = static_cast<nsDisplayTransform*>(item);
           nsPoint point = aRect.TopLeft();
           // A 1x1 rect means a point, otherwise use the center of the rect
           if (aRect.width != 1 || aRect.height != 1) {
             point = aRect.Center();
           }
           temp.AppendElement(FramesWithDepth(transform->GetHitDepthAtPoint(point)));
           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);
       }
 
       for (PRUint32 j = 0; j < outFrames.Length(); j++) {
         nsIFrame *f = outFrames.ElementAt(j);
         // Handle the XUL 'mousethrough' feature and 'pointer-events'.
         if (!GetMouseThrough(f) &&
@@ -1191,17 +823,17 @@ static void Sort(nsDisplayList* aList, P
     }
     prev = item;
   }
   if (sorted) {
     aList->AppendToTop(&list1);
     aList->AppendToTop(&list2);
     return;
   }
-
+  
   Sort(&list1, half, aCmp, aClosure);
   Sort(&list2, aCount - half, aCmp, aClosure);
 
   for (i = 0; i < aCount; ++i) {
     if (list1.GetBottom() &&
         (!list2.GetBottom() ||
          aCmp(list1.GetBottom(), list2.GetBottom(), aClosure))) {
       aList->AppendToTop(list1.RemoveBottom());
@@ -1255,17 +887,17 @@ void nsDisplayList::ExplodeAnonymousChil
       nsDisplayItem* j;
       while ((j = list->RemoveBottom()) != nsnull) {
         tmp.AppendToTop(static_cast<nsDisplayWrapList*>(i)->
             WrapWithClone(aBuilder, j));
       }
       i->~nsDisplayItem();
     }
   }
-
+  
   AppendToTop(&tmp);
 }
 
 void nsDisplayList::SortByZOrder(nsDisplayListBuilder* aBuilder,
                                  nsIContent* aCommonAncestor) {
   Sort(aBuilder, IsZOrderLEQ, aCommonAncestor);
 }
 
@@ -1645,17 +1277,17 @@ nsDisplayBackground::ConfigureLayer(Imag
 
   gfxIntSize imageSize = mImageContainer->GetCurrentSize();
   NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!");
 
   gfxMatrix transform;
   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));
 }
 
 void
 nsDisplayBackground::HitTest(nsDisplayListBuilder* aBuilder,
                              const nsRect& aRect,
                              HitTestState* aState,
@@ -2342,26 +1974,24 @@ nsRegion nsDisplayOpacity::GetOpaqueRegi
   return nsRegion();
 }
 
 // nsDisplayOpacity uses layers for rendering
 already_AddRefed<Layer>
 nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
                              LayerManager* aManager,
                              const ContainerParameters& aContainerParameters) {
-  nsRefPtr<Layer> container = GetLayerBuilderForManager(aManager)->
+  nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
                            aContainerParameters, nsnull);
-  if (!container)
+  if (!layer)
     return nsnull;
 
-  container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
-  AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_opacity);
-
-  return container.forget();
+  layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
+  return layer.forget();
 }
 
 /**
  * This doesn't take into account layer scaling --- the layer may be
  * rendered at a higher (or lower) resolution, affecting the retained layer
  * size --- but this should be good enough.
  */
 static bool
@@ -2376,22 +2006,16 @@ IsItemTooSmallForActiveLayer(nsDisplayIt
 
 nsDisplayItem::LayerState
 nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
                                 LayerManager* aManager,
                                 const ContainerParameters& aParameters) {
   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, nsnull);
   return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot)
       ? LAYER_ACTIVE : LAYER_INACTIVE;
 }
 
 bool
 nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
@@ -2733,17 +2357,17 @@ nsDisplayScrollInfoLayer::TryMerge(nsDis
 }
 
 bool
 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;
 }
 
 nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
                              nsIFrame* aFrame, nsDisplayItem* aItem,
                              const nsRect& aRect)
    : nsDisplayWrapList(aBuilder, aFrame, aItem,
        aFrame == aItem->GetUnderlyingFrame() ? aItem->ToReferenceFrame() : aBuilder->ToReferenceFrame(aFrame)),
@@ -3016,17 +2640,17 @@ nsDisplayTransform::GetFrameBoundsForTra
 #else
 
 nsRect
 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;
   }
 
   /* Iterate through the continuation list, unioning together all the
    * bounding rects.
    */
@@ -3043,93 +2667,92 @@ nsDisplayTransform::GetFrameBoundsForTra
 
   return result;
 }
 
 #endif
 
 /* 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(),
                   "Shouldn't get a delta for an untransformed frame!");
 
   /* For both of the coordinates, if the value of -moz-transform is a
    * percentage, it's relative to the size of the frame.  Otherwise, if it's
    * a distance, it's already computed for us!
    */
   const nsStyleDisplay* display = aFrame->GetStyleDisplay();
   nsRect boundingRect = (aBoundsOverride ? *aBoundsOverride :
                          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};
 
   for (PRUint8 index = 0; index < 2; ++index) {
     /* If the -moz-transform-origin specifies a percentage, take the percentage
      * of the size of the box.
      */
     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) &&
         coord.GetUnit() != eStyleUnit_Percent) {
       // <length> values represent offsets from the origin of the SVG element's
       // 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);
-
-  return gfxPoint3D(coords[0], coords[1], coords[2]);
+  result.x += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
+  result.y += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel);
+
+  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
    * percentage, it's relative to the size of the frame.  Otherwise, if it's
    * a distance, it's already computed for us!
    */
 
   //TODO: Should this be using our bounds or the parent's bounds?
@@ -3177,124 +2800,107 @@ nsDisplayTransform::GetDeltaToMozPerspec
 }
 
 /* Wraps up the -moz-transform matrix in a change-of-basis matrix pair that
  * translates from local coordinate space to transform coordinate space, then
  * hands it back.
  */
 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);
   }
 
   /* Account for the -moz-transform-origin property by translating the
    * 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),
                0.0f);
 
   /* Get the underlying transform matrix.  This requires us to get the
    * bounds of the frame.
    */
-  const nsStyleDisplay* disp = aFrame ? aFrame->GetStyleDisplay() : nsnull;
+  const nsStyleDisplay* disp = aFrame->GetStyleDisplay();
   nsRect bounds = (aBoundsOverride ? *aBoundsOverride :
                    nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
 
   /* Get the matrix, then change its basis to factor in the origin. */
   bool dummy;
   gfx3DMatrix result;
   // Call IsSVGTransformed() regardless of the value of
   // 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, nsnull, nsnull,
-                                                    dummy, bounds, aAppUnitsPerPixel);
-  } else if (disp->mSpecifiedTransform) {
+  if (disp->mSpecifiedTransform) {
     result = nsStyleTransformMatrix::ReadTransforms(disp->mSpecifiedTransform,
                                                     aFrame->GetStyleContext(),
                                                     aFrame->PresContext(),
                                                     dummy, bounds, aAppUnitsPerPixel);
   } else if (hasSVGTransforms) {
     // Correct the translation components for zoom:
     float pixelsPerCSSPx = aFrame->PresContext()->AppUnitsPerCSSPixel() /
                              aAppUnitsPerPixel;
     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()) {
     // Correct the translation components for zoom:
     float pixelsPerCSSPx = aFrame->PresContext()->AppUnitsPerCSSPixel() /
                              aAppUnitsPerPixel;
     transformFromSVGParent.x0 *= pixelsPerCSSPx;
     transformFromSVGParent.y0 *= pixelsPerCSSPx;
     result = result * gfx3DMatrix::From2D(transformFromSVGParent);
   }
 
   const nsStyleDisplay* parentDisp = nsnull;
-  nsStyleContext* parentStyleContext = aFrame ? aFrame->GetStyleContext()->GetParent(): nsnull;
+  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, nsnull, nsnull, nsnull,
-                                    nsnull, nsnull, aOutAncestor);
+      gfx3DMatrix parent = GetResultingTransformMatrix(aFrame->GetParent(), aOrigin - aFrame->GetPosition(),
+                                                       aAppUnitsPerPixel, nsnull, aOutAncestor);
       return nsLayoutUtils::ChangeMatrixBasis(newOrigin + toMozOrigin, result) * parent;
   }
 
   return nsLayoutUtils::ChangeMatrixBasis
     (newOrigin + toMozOrigin, result);
 }
 
 bool
@@ -3315,17 +2921,17 @@ nsDisplayTransform::ShouldPrerenderTrans
         return true;
       }
     }
   }
   return false;
 }
 
 /* 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;
   }
   if (aFrame->GetStyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
       aMatrix.IsBackfaceVisible()) {
     return false;
   }
@@ -3333,70 +2939,63 @@ static bool IsFrameVisible(nsIFrame* aFr
 }
 
 const gfx3DMatrix&
 nsDisplayTransform::GetTransform(float aAppUnitsPerPixel)
 {
   if (mTransform.IsIdentity() || mCachedAppUnitsPerPixel != aAppUnitsPerPixel) {
     mTransform =
       GetResultingTransformMatrix(mFrame, ToReferenceFrame(),
-                                  aAppUnitsPerPixel);
+                                  aAppUnitsPerPixel,
+                                  nsnull);
     mCachedAppUnitsPerPixel = aAppUnitsPerPixel;
   }
   return mTransform;
 }
 
 already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBuilder,
                                                        LayerManager *aManager,
                                                        const ContainerParameters& aContainerParameters)
 {
-  const gfx3DMatrix& newTransformMatrix =
+  const gfx3DMatrix& newTransformMatrix = 
     GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel());
 
   if (!IsFrameVisible(mFrame, newTransformMatrix)) {
     return nsnull;
   }
 
   nsRefPtr<ContainerLayer> container = GetLayerBuilderForManager(aManager)->
     BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetList(),
                            aContainerParameters, &newTransformMatrix);
 
   // Add the preserve-3d flag for this layer, BuildContainerLayerFor clears all flags,
   // so we never need to explicitely unset this flag.
   if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) {
     container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D);
   }
-
-  AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_transform);
   return container.forget();
 }
 
 nsDisplayItem::LayerState
 nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
                                   LayerManager* aManager,
                                   const ContainerParameters& aParameters) {
   // Here we check if the *post-transform* bounds of this item are big enough
   // to justify an active layer.
   if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateTransformLayer) &&
       !IsItemTooSmallForActiveLayer(this))
     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, nsnull);
-  return !mStoredList.ChildrenCanBeInactive(aBuilder,
-                                            aManager,
+  return !mStoredList.ChildrenCanBeInactive(aBuilder, 
+                                            aManager, 
                                             aParameters,
-                                            *mStoredList.GetList(),
+                                            *mStoredList.GetList(), 
                                             activeScrolledRoot)
       ? LAYER_ACTIVE : LAYER_INACTIVE;
 }
 
 bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
                                              nsRegion *aVisibleRegion,
                                              const nsRect& aAllowVisibleRegionExpansion)
 {
@@ -3405,19 +3004,19 @@ bool nsDisplayTransform::ComputeVisibili
    * think that it's painting in its original rectangular coordinate space.
    * If we can't untransform, take the entire overflow rect */
   nsRect untransformedVisibleRect;
   float factor = nsPresContext::AppUnitsPerCSSPixel();
   if (ShouldPrerenderTransformedContent(aBuilder, mFrame) ||
       !UntransformRectMatrix(mVisibleRect,
                              GetTransform(factor),
                              factor,
-                             &untransformedVisibleRect))
+                             &untransformedVisibleRect)) 
   {
-    untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() +
+    untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() +  
                                aBuilder->ToReferenceFrame(mFrame);
   }
   nsRegion untransformedVisible = untransformedVisibleRect;
   // Call RecomputeVisiblity instead of ComputeVisibility since
   // nsDisplayItem::ComputeVisibility should only be called from
   // nsDisplayList::ComputeVisibility (which sets mVisibleRect on the item)
   mStoredList.RecomputeVisibility(aBuilder, &untransformedVisible);
   return true;
@@ -3472,17 +3071,17 @@ void nsDisplayTransform::HitTest(nsDispl
 
     gfxRect rect = matrix.Inverse().ProjectRectBounds(originalRect);;
 
     resultingRect = nsRect(NSFloatPixelsToAppUnits(float(rect.X()), factor),
                            NSFloatPixelsToAppUnits(float(rect.Y()), factor),
                            NSFloatPixelsToAppUnits(float(rect.Width()), factor),
                            NSFloatPixelsToAppUnits(float(rect.Height()), factor));
   }
-
+  
 
 #ifdef DEBUG_HIT
   printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
   printf("  Untransformed point: (%f, %f)\n", resultingRect.X(), resultingRect.Y());
   PRUint32 originalFrameCount = aOutFrames.Length();
 #endif
 
   mStoredList.HitTest(aBuilder, resultingRect, aState, aOutFrames);
@@ -3498,18 +3097,18 @@ void nsDisplayTransform::HitTest(nsDispl
 
 float
 nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint)
 {
   float factor = nsPresContext::AppUnitsPerCSSPixel();
   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)));
 
   gfxPoint3D transformed = matrix.Transform3D(gfxPoint3D(point.x, point.y, 0));
   return transformed.z;
 }
 
 /* The bounding rectangle for the object is the overflow rectangle translated
@@ -3548,17 +3147,17 @@ nsRegion nsDisplayTransform::GetOpaqueRe
                                              bool* aSnap)
 {
   *aSnap = false;
   nsRect untransformedVisible;
   float factor = nsPresContext::AppUnitsPerCSSPixel();
   if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) {
       return nsRegion();
   }
-
+  
   const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel());
 
   nsRegion result;
   gfxMatrix matrix2d;
   bool tmpSnap;
   if (matrix.Is2D(&matrix2d) &&
       matrix2d.PreservesAxisAlignedRectangles() &&
       mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap).Contains(untransformedVisible)) {
@@ -3695,17 +3294,17 @@ bool nsDisplayTransform::UntransformRect
                                            nsRect* aOutRect)
 {
   NS_PRECONDITION(aFrame, "Can't take the transform based on a null frame!");
 
   /* Grab the matrix.  If the transform is degenerate, just hand back the
    * empty rect.
    */
   float factor = nsPresContext::AppUnitsPerCSSPixel();
-  gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor);
+  gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor, nsnull);
 
   return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect);
 }
 
 nsDisplaySVGEffects::nsDisplaySVGEffects(nsDisplayListBuilder* aBuilder,
                                          nsIFrame* aFrame, nsDisplayList* aList)
     : nsDisplayWrapList(aBuilder, aFrame, aList),
       mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -103,20 +103,20 @@ public:
    * @param aReferenceFrame the frame at the root of the subtree; its origin
    * is the origin of the reference coordinate system for this display list
    * @param aIsForEvents true if we're creating this list in order to
    * determine which frame is under the mouse position
    * @param aBuildCaret whether or not we should include the caret in any
    * 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();
 
   /**
    * @return true if the display is being built in order to determine which
    * frame is under the mouse position.
    */
@@ -2336,23 +2336,16 @@ public:
                                 const nsPoint &aOrigin,
                                 nsRect* aOutRect);
   
   static bool UntransformRectMatrix(const nsRect &aUntransformedBounds, 
                                     const gfx3DMatrix& aMatrix,
                                     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
    * <translation-value>s in CSS transforms.  If
    * UNIFIED_CONTINUATIONS is not defined, this is simply the frame's bounding
    * rectangle, translated to the origin.  Otherwise, returns the smallest
    * rectangle containing a frame and all of its continuations.  For example,
    * if there is a <span> element with several continuations split over
    * several lines, this function will return the rectangle containing all of
@@ -2376,20 +2369,16 @@ public:
    *        for the frame's bounding rectangle. Otherwise, it will use the
    *        value of aBoundsOverride.  This is mostly for internal use and in
    *        most cases you will not need to specify a value.
    */
   static gfx3DMatrix GetResultingTransformMatrix(const nsIFrame* aFrame,
                                                  const nsPoint& aOrigin,
                                                  float aAppUnitsPerPixel,
                                                  const nsRect* aBoundsOverride = nsnull,
-                                                 const nsCSSValueList* aTransformOverride = nsnull,
-                                                 gfxPoint3D* aToMozOrigin = nsnull,
-                                                 gfxPoint3D* aToPerspectiveOrigin = nsnull,
-                                                 nscoord* aChildPerspective = nsnull, 
                                                  nsIFrame** aOutAncestor = nsnull);
   /**
    * Return true when we should try to prerender the entire contents of the
    * transformed frame even when it's not completely visible (yet).
    */
   static bool ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBuilder,
                                                 nsIFrame* aFrame);
 
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1,15 +1,14 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=2 sw=2 et tw=78: */
 /* 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/. */
 
-#include "base/basictypes.h"
 #include "mozilla/Util.h"
 
 #include "nsLayoutUtils.h"
 #include "nsIFormControlFrame.h"
 #include "nsPresContext.h"
 #include "nsIContent.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
@@ -66,31 +65,29 @@
 #include "mozilla/dom/Element.h"
 #include "nsCanvasFrame.h"
 #include "gfxDrawable.h"
 #include "gfxUtils.h"
 #include "nsDataHashtable.h"
 #include "nsTextFrame.h"
 #include "nsFontFaceList.h"
 #include "nsFontInflationData.h"
-#include "CompositorParent.h"
+
 #include "nsSVGUtils.h"
 #include "nsSVGIntegrationUtils.h"
 #include "nsSVGForeignObjectFrame.h"
 #include "nsSVGOuterSVGFrame.h"
 
 #include "mozilla/Preferences.h"
 
 #ifdef MOZ_XUL
 #include "nsXULPopupManager.h"
 #endif
 
 #include "sampler.h"
-#include "nsAnimationManager.h"
-#include "nsTransitionManager.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 using namespace mozilla::layout;
 
 #ifdef DEBUG
 // TODO: remove, see bug 598468.
@@ -111,89 +108,33 @@ static ContentMap* sContentMap = NULL;
 static ContentMap& GetContentMap() {
   if (!sContentMap) {
     sContentMap = new ContentMap();
     sContentMap->Init();
   }
   return *sContentMap;
 }
 
-bool
-nsLayoutUtils::HasAnimationsForCompositor(nsIContent* aContent,
-                                          nsCSSProperty aProperty)
-{
-  if (!aContent->MayHaveAnimations())
-    return false;
-  ElementAnimations* animations =
-    static_cast<ElementAnimations*>(aContent->GetProperty(nsGkAtoms::animationsProperty));
-  if (animations) {
-    bool propertyMatches = animations->HasAnimationOfProperty(aProperty);
-    if (propertyMatches && animations->CanPerformOnCompositorThread()) {
-      return true;
-    }
-  }
-
-  ElementTransitions* transitions =
-    static_cast<ElementTransitions*>(aContent->GetProperty(nsGkAtoms::transitionsProperty));
-  if (transitions) {
-    bool propertyMatches = transitions->HasTransitionOfProperty(aProperty);
-    if (propertyMatches && transitions->CanPerformOnCompositorThread()) {
-      return true;
-    }
-  }
-
-  return false;
-}
 
 bool
 nsLayoutUtils::Are3DTransformsEnabled()
 {
   static bool s3DTransformsEnabled;
   static bool s3DTransformPrefCached = false;
 
   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()
 {
   static bool sUseBackgroundNearestFilteringEnabled;
   static bool sUseBackgroundNearestFilteringPrefInitialised = false;
 
   if (!sUseBackgroundNearestFilteringPrefInitialised) {
     sUseBackgroundNearestFilteringPrefInitialised = true;
     sUseBackgroundNearestFilteringEnabled = mozilla::Preferences::GetBool("gfx.filter.nearest.force-enabled", false);
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -1493,34 +1493,21 @@ public:
    *    (void)SizeOfTextRunsForFrames(rootFrame, nsnull, true);
    *    total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false);
    */
   static size_t SizeOfTextRunsForFrames(nsIFrame* aFrame,
                                         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.
    */
   static bool UseBackgroundNearestFiltering();
 
   /**
    * Checks whether we want to use the GPU to scale images when
    * possible.
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -87,18 +87,16 @@
 #include "nsDeckFrame.h"
 #include "nsTableFrame.h"
 
 #include "gfxContext.h"
 #include "nsRenderingContext.h"
 #include "CSSCalc.h"
 #include "nsAbsoluteContainingBlock.h"
 #include "nsFontInflationData.h"
-#include "nsAnimationManager.h"
-#include "nsTransitionManager.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/LookAndFeel.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 
@@ -932,30 +930,19 @@ nsRect
 nsIFrame::GetPaddingRect() const
 {
   return GetPaddingRectRelativeToSelf() + GetPosition();
 }
 
 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
 nsIFrame::IsSVGTransformed(gfxMatrix *aOwnTransforms,
                            gfxMatrix *aFromParentTransforms) const
 {
   return false;
 }
@@ -1763,47 +1750,45 @@ WrapPreserve3DList(nsIFrame* aFrame, nsD
 }
 
 nsresult
 nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
                                              const nsRect&         aDirtyRect,
                                              nsDisplayList*        aList) {
   if (GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
     return NS_OK;
+
   // Replaced elements have their visibility handled here, because
   // they're visually atomic
   if (IsFrameOfType(eReplaced) && !IsVisibleForPainting(aBuilder))
     return NS_OK;
 
   nsRect clipPropClip;
   const nsStyleDisplay* disp = GetStyleDisplay();
-  // We can stop right away if this is a zero-opacity stacking context,
-  // we're painting, and we're not animating opacity.
-  if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() &&
-      !nsLayoutUtils::HasAnimationsForCompositor(mContent,
-                                                 eCSSProperty_opacity)) {
+  // We can stop right away if this is a zero-opacity stacking context and
+  // we're painting.
+  if (disp->mOpacity == 0.0 && aBuilder->IsForPainting())
     return NS_OK;
-  }
 
   bool applyClipPropClipping =
       ApplyClipPropClipping(aBuilder, disp, this, &clipPropClip);
   nsRect dirtyRect = aDirtyRect;
 
   bool inTransform = aBuilder->IsInTransform();
   if (IsTransformed()) {
     if (aBuilder->IsForPainting() &&
         nsDisplayTransform::ShouldPrerenderTransformedContent(aBuilder, this)) {
       dirtyRect = GetVisualOverflowRectRelativeToSelf();
     } else {
       if (Preserves3D()) {
         // Preserve3D frames are difficult. 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 the 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);
         overflow += offset;
         overflow = nsDisplayTransform::TransformRect(overflow, this, offset);
 
         dirtyRect += offset;
 
@@ -1930,32 +1915,33 @@ nsIFrame::BuildDisplayListForStackingCon
       (!resultList.IsEmpty() || usingSVGEffects)) {
     nsDisplayClipPropWrapper wrapper(clipPropClip);
     nsDisplayItem* item = wrapper.WrapList(aBuilder, this, &resultList);
     if (!item)
       return NS_ERROR_OUT_OF_MEMORY;
     // 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
    * output even if the element being filtered wouldn't otherwise do so.
    */
   if (usingSVGEffects) {
     /* List now emptied, so add the new list to the top. */
     rv = resultList.AppendNewToTop(
         new (aBuilder) nsDisplaySVGEffects(aBuilder, this, &resultList));
     if (NS_FAILED(rv))
       return rv;
   }
   /* 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(
         new (aBuilder) nsDisplayOpacity(aBuilder, this, &resultList));
     if (NS_FAILED(rv))
       return rv;
   }
 
@@ -2099,17 +2085,17 @@ nsIFrame::BuildDisplayListForChild(nsDis
   // Don't paint our children if the theme object is a leaf.
   if (IsThemed(ourDisp) &&
       !PresContext()->GetTheme()->WidgetIsContainer(ourDisp->mAppearance))
     return NS_OK;
 
   // 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);
 
   bool isPositioned = !isSVG && disp->IsPositioned();
   if (isVisuallyAtomic || isPositioned || (!isSVG && disp->IsFloating()) ||
       ((disp->mClipFlags & NS_STYLE_CLIP_RECT) &&
        IsSVGContentWithCSSClip(this)) ||
       (aFlags & DISPLAY_CHILD_FORCE_STACKING_CONTEXT)) {
@@ -4767,18 +4753,18 @@ nsIFrame::GetTransformMatrix(nsIFrame* a
     /* Compute the delta to the parent, which we need because we are converting
      * coordinates to our parent.
      */
     NS_ASSERTION(nsLayoutUtils::GetCrossDocParentFrame(this),
 	             "Cannot transform the viewport frame!");
     PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
 
     gfx3DMatrix result =
-      nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0), scaleFactor, nsnull, 
-                                                      nsnull, nsnull, nsnull, nsnull, aOutAncestor);
+      nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0),
+                                                      scaleFactor, nsnull, 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. */
     result *= gfx3DMatrix::Translation
       (NSAppUnitsToFloatPixels(delta.x, scaleFactor),
        NSAppUnitsToFloatPixels(delta.y, scaleFactor),
        0.0f);
     return result;
--- a/layout/generic/nsHTMLCanvasFrame.cpp
+++ b/layout/generic/nsHTMLCanvasFrame.cpp
@@ -273,17 +273,17 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayL
                       presContext->AppUnitsToGfxUnits(area.y),
                       presContext->AppUnitsToGfxUnits(area.width),
                       presContext->AppUnitsToGfxUnits(area.height));
 
   // Transform the canvas into the right place
   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));
 
   return layer.forget();
 }
 
 NS_IMETHODIMP
 nsHTMLCanvasFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1222,18 +1222,16 @@ public:
   virtual bool NeedsView() { return false; }
 
   /**
    * Returns true if this frame is transformed (e.g. has CSS or SVG transforms)
    * or if its parent is an SVG frame that has children-only transforms (e.g.
    * an SVG viewBox attribute).
    */
   bool IsTransformed() const;
-  
-  bool HasOpacity() const;
 
   /**
    * Returns true if this frame is an SVG frame that has SVG transforms applied
    * to it, or if its parent frame is an SVG frame that has children-only
    * transforms (e.g. an SVG viewBox attribute).
    * If aOwnTransforms is non-null and the frame has its own SVG transforms,
    * aOwnTransforms will be set to these transforms. If aFromParentTransforms
    * is non-null and the frame has an SVG parent with children-only transforms,
--- a/layout/generic/nsImageFrame.cpp
+++ b/layout/generic/nsImageFrame.cpp
@@ -1284,17 +1284,17 @@ nsDisplayImage::ConfigureLayer(ImageLaye
   NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
 
   const gfxRect destRect = GetDestRect();
 
   gfxMatrix transform;
   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));
 }
 
 void
 nsImageFrame::PaintImage(nsRenderingContext& aRenderingContext, nsPoint aPt,
                          const nsRect& aDirtyRect, imgIContainer* aImage,
                          PRUint32 aFlags)
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -1718,17 +1718,17 @@ nsObjectFrame::BuildLayer(nsDisplayListB
       // or the frame dies, the connection from the surviving object is nulled out.
     }
   }
 
   // Set a transform on the layer to draw the plugin in the right place
   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();
 }
 
 void
 nsObjectFrame::PaintPlugin(nsDisplayListBuilder* aBuilder,
                            nsRenderingContext& aRenderingContext,
                            const nsRect& aDirtyRect, const nsRect& aPluginRect)
--- a/layout/generic/nsVideoFrame.cpp
+++ b/layout/generic/nsVideoFrame.cpp
@@ -201,17 +201,17 @@ nsVideoFrame::BuildLayer(nsDisplayListBu
 
   layer->SetContainer(container);
   layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
   layer->SetContentFlags(Layer::CONTENT_OPAQUE);
   // Set a transform on the layer to draw the video in the right place
   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<Layer> result = layer.forget();
   return result.forget();
 }
 
 NS_IMETHODIMP
 nsVideoFrame::Reflow(nsPresContext*           aPresContext,
                      nsHTMLReflowMetrics&     aMetrics,
--- a/layout/ipc/RenderFrameParent.cpp
+++ b/layout/ipc/RenderFrameParent.cpp
@@ -241,17 +241,16 @@ TransformShadowTree(nsDisplayListBuilder
                     nsIFrame* aFrame, Layer* aLayer,
                     const ViewTransform& aTransform,
                     float aTempScaleDiffX = 1.0,
                     float aTempScaleDiffY = 1.0)
 {
   ShadowLayer* shadow = aLayer->AsShadowLayer();
   shadow->SetShadowClipRect(aLayer->GetClipRect());
   shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
-  shadow->SetShadowOpacity(aLayer->GetOpacity());
 
   const FrameMetrics* metrics = GetFrameMetrics(aLayer);
 
   gfx3DMatrix shadowTransform = aLayer->GetTransform();
   ViewTransform layerTransform = aTransform;
 
   if (metrics && metrics->IsScrollable()) {
     const ViewID scrollId = metrics->mScrollId;
@@ -600,17 +599,17 @@ RenderFrameParent::BuildLayer(nsDisplayL
     if (!layer) {
       // Probably a temporary layer manager that doesn't know how to
       // use ref layers.
       return nsnull;
     }
     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();
   }
 
   if (mContainer) {
     ClearContainer(mContainer);
   }
--- a/layout/style/AnimationCommon.cpp
+++ b/layout/style/AnimationCommon.cpp
@@ -2,19 +2,16 @@
 /* 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/. */
 
 #include "AnimationCommon.h"
 #include "nsRuleData.h"
 #include "nsCSSValue.h"
 #include "nsStyleContext.h"
-#include "nsIFrame.h"
-#include "nsAnimationManager.h"
-#include "nsLayoutUtils.h"
 
 namespace mozilla {
 namespace css {
 
 CommonAnimationManager::CommonAnimationManager(nsPresContext *aPresContext)
   : mPresContext(aPresContext)
 {
   PR_INIT_CLIST(&mElementData);
@@ -211,31 +208,10 @@ ComputedTimingFunction::GetValue(double 
     default:
       NS_ABORT_IF_FALSE(false, "bad type");
       // fall through
     case nsTimingFunction::StepEnd:
       return StepEnd(mSteps, aPortion);
   }
 }
 
-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;
-}
-
-
-
 }
 }
--- a/layout/style/AnimationCommon.h
+++ b/layout/style/AnimationCommon.h
@@ -102,22 +102,16 @@ private:
   InfallibleTArray<PropertyValuePair> mPropertyValuePairs;
 };
 
 class ComputedTimingFunction {
 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;
   PRUint32 mSteps;
 };
 
 struct CommonElementAnimationData : public PRCList
 {
@@ -143,20 +137,16 @@ struct CommonElementAnimationData : publ
   }
 
   void Destroy()
   {
     // This will call our destructor.
     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,
   // i.e., in an atom list)
   nsIAtom *mElementProperty;
 
   CommonAnimationManager *mManager;
 
--- a/layout/style/Makefile.in
+++ b/layout/style/Makefile.in
@@ -17,18 +17,16 @@ endif
 
 MODULE		= layout
 LIBRARY_NAME	= gkstyle_s
 LIBXUL_LIBRARY	= 1
 
 EXPORTS_NAMESPACES = mozilla/css
 
 EXPORTS		= \
-		AnimationCommon.h \
-		nsAnimationManager.h \
 		nsCSSAnonBoxList.h \
 		nsCSSAnonBoxes.h \
 		nsCSSFontDescList.h \
 		nsCSSKeywordList.h \
 		nsCSSKeywords.h \
 		nsCSSParser.h \
 		nsCSSPropAliasList.h \
 		nsCSSPropList.h \
@@ -52,17 +50,16 @@ EXPORTS		= \
 		nsIStyleRule.h \
 		nsIStyleRuleProcessor.h \
 		nsIStyleSheet.h \
 		nsLayoutStylesheetCache.h \
 		nsRuleData.h \
 		nsRuleNode.h \
 		nsRuleProcessorData.h \
 		nsRuleWalker.h \
-		nsStyleAnimation.h \
 		nsStyleContext.h \
 		nsStyleCoord.h \
 		nsStyleSet.h \
 		nsStyleStruct.h \
 		nsStyleStructFwd.h \
 		nsStyleStructInlines.h \
 		nsStyleStructList.h \
 		nsStyleTransformMatrix.h \
@@ -122,19 +119,17 @@ CPPSRCS		= \
 		nsTransitionManager.cpp \
 		StyleRule.cpp \
 		$(NULL)
 
 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 \
 		-I$(srcdir)/../../content/base/src \
 		-I$(srcdir)/../../content/html/content/src \
 		-I$(srcdir)/../../content/xbl/src \
 		-I$(srcdir)/../../content/xul/document/src \
 		$(NULL)
--- a/layout/style/nsAnimationManager.cpp
+++ b/layout/style/nsAnimationManager.cpp
@@ -6,151 +6,138 @@
 #include "nsAnimationManager.h"
 #include "nsPresContext.h"
 #include "nsRuleProcessorData.h"
 #include "nsStyleSet.h"
 #include "nsCSSRules.h"
 #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<AnimationPropertySegment> 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<AnimationProperty> 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<css::AnimValuesStyleRule> 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<ElementAnimation> mAnimations;
+};
 
 static void
 ElementAnimationsPropertyDtor(void           *aObject,
                               nsIAtom        *aPropertyName,
                               void           *aPropertyValue,
                               void           *aData)
 {
   ElementAnimations *ea = static_cast<ElementAnimations*>(aPropertyValue);
 #ifdef DEBUG
   NS_ABORT_IF_FALSE(!ea->mCalledPropertyDtor, "can't call dtor twice");
   ea->mCalledPropertyDtor = true;
 #endif
   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)
 {
   if (!mNeedsRefreshes) {
     // All of our animations are paused or completed.
     mStyleRuleRefreshTime = aRefreshTime;
     return;
@@ -173,34 +160,108 @@ ElementAnimations::EnsureStyleRuleFor(Ti
       ElementAnimation &anim = mAnimations[animIdx];
 
       if (anim.mProperties.Length() == 0 ||
           anim.mIterationDuration.ToMilliseconds() <= 0.0) {
         // No animation data.
         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;
+      }
+
+      // 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);
+        }
+
+        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 =
-        GetPositionInIteration(anim.mStartTime, currentTime,
-                               anim.mIterationDuration, anim.mIterationCount,
-                               anim.mDirection, IsForElement(),
-                               &anim, this, &aEventsToDispatch);
+        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;
+      }
 
-      // The position is -1 when we don't have fill data for the current time,
-      // so we shouldn't animate.
-      if (positionInIteration == -1)
-        continue;
+      // 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,
                         "position should be in [0-1]");
 
       for (PRUint32 propIdx = 0, propEnd = anim.mProperties.Length();
            propIdx != propEnd; ++propIdx)
       {
@@ -257,76 +318,16 @@ ElementAnimations::EnsureStyleRuleFor(Ti
                                         segment->mFromValue, segment->mToValue,
                                         valuePosition, *val);
         NS_ABORT_IF_FALSE(result, "interpolate must succeed now");
       }
     }
   }
 }
 
-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,
                                          bool aCreateIfNeeded)
 {
   if (!aCreateIfNeeded && PR_CLIST_IS_EMPTY(&mElementData)) {
     // Early return for the most common case.
     return nsnull;
@@ -345,26 +346,27 @@ nsAnimationManager::GetElementAnimations
                  "other than :before or :after");
     return nsnull;
   }
   ElementAnimations *ea = static_cast<ElementAnimations*>(
                              aElement->GetProperty(propName));
   if (!ea && aCreateIfNeeded) {
     // FIXME: Consider arena-allocating?
     ea = new ElementAnimations(aElement, propName, this);
+    if (!ea) {
+      NS_WARNING("out of memory");
+      return nsnull;
+    }
     nsresult rv = aElement->SetProperty(propName, ea,
                                         ElementAnimationsPropertyDtor, nsnull);
     if (NS_FAILED(rv)) {
       NS_WARNING("SetProperty failed");
       delete ea;
       return nsnull;
     }
-    if (propName == nsGkAtoms::animationsProperty) {
-      aElement->SetMayHaveAnimations();
-    }
 
     AddElementData(ea);
   }
 
   return ea;
 }
 
 /* virtual */ void
@@ -456,18 +458,16 @@ nsAnimationManager::CheckAnimationRule(n
         ea->Destroy();
       }
       return nsnull;
     }
 
     TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
 
     if (ea) {
-
-      // XXXdz: Invalidate the frame since the animation changed.
       // The cached style rule is invalid.
       ea->mStyleRule = nsnull;
       ea->mStyleRuleRefreshTime = TimeStamp();
 
       // Copy over the start times and (if still paused) pause starts
       // for each animation (matching on name only) that was also in the
       // old list of animations.
       // This means that we honor dynamic changes, which isn't what the
--- a/layout/style/nsAnimationManager.h
+++ b/layout/style/nsAnimationManager.h
@@ -6,200 +6,60 @@
 #define nsAnimationManager_h_
 
 #include "AnimationCommon.h"
 #include "nsCSSPseudoElements.h"
 #include "nsStyleContext.h"
 #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 {
 class Declaration;
 }
 }
 
-struct AnimationEventInfo {
-  nsRefPtr<mozilla::dom::Element> 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<AnimationEventInfo> EventArray;
-
-struct AnimationPropertySegment
-{
-  float mFromKey, mToKey;
-  nsStyleAnimation::Value mFromValue, mToValue;
-  mozilla::css::ComputedTimingFunction mTimingFunction;
-};
-
-struct AnimationProperty
-{
-  nsCSSProperty mProperty;
-  InfallibleTArray<AnimationPropertySegment> 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<AnimationProperty> 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 = nsnull,
-                                       ElementAnimations* aEa = nsnull,
-                                       EventArray* aEventsToDispatch = nsnull);
-
-  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<mozilla::css::AnimValuesStyleRule> 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<ElementAnimation> 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 nsnull;
-    ElementAnimations* animations = static_cast<ElementAnimations*>(
-      aContent->GetProperty(nsGkAtoms::animationsProperty));
-    if (!animations)
-      return nsnull;
-    bool propertyMatches = animations->HasAnimationOfProperty(aProperty);
-    return (propertyMatches && animations->CanPerformOnCompositorThread()) ?
-      animations : nsnull;
-  }
+  struct AnimationEventInfo {
+    nsRefPtr<mozilla::dom::Element> 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);
   virtual void RulesMatching(PseudoElementRuleProcessorData* aData);
   virtual void RulesMatching(AnonBoxRuleProcessorData* aData);
 #ifdef MOZ_XUL
   virtual void RulesMatching(XULTreeRuleProcessorData* aData);
 #endif
@@ -224,16 +84,18 @@ public:
    */
   nsIStyleRule* CheckAnimationRule(nsStyleContext* aStyleContext,
                                    mozilla::dom::Element* aElement);
 
   void KeyframesListIsDirty() {
     mKeyframesListIsDirty = true;
   }
 
+  typedef InfallibleTArray<AnimationEventInfo> EventArray;
+
   /**
    * Dispatch any pending events.  We accumulate animationend and
    * animationiteration events only during refresh driver notifications
    * (and dispatch them at the end of such notifications), but we
    * accumulate animationstart events at other points when style
    * contexts are created.
    */
   void DispatchEvents() {
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -1117,19 +1117,19 @@ AddTransformScale(const nsCSSValue &aVal
   NS_ABORT_IF_FALSE(aValue2.GetUnit() == eCSSUnit_Number, "unexpected unit");
 
   float v1 = aValue1.GetFloatValue() - 1.0f,
         v2 = aValue2.GetFloatValue() - 1.0f;
   float result = v1 * aCoeff1 + v2 * aCoeff2;
   aResult.SetFloatValue(result + 1.0f, eCSSUnit_Number);
 }
 
-/* static */ already_AddRefed<nsCSSValue::Array>
-nsStyleAnimation::AppendTransformFunction(nsCSSKeyword aTransformFunction,
-                                          nsCSSValueList**& aListTail)
+static already_AddRefed<nsCSSValue::Array>
+AppendTransformFunction(nsCSSKeyword aTransformFunction,
+                        nsCSSValueList**& aListTail)
 {
   nsRefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction);
   nsCSSValueList *item = new nsCSSValueList;
   item->mValue.SetArrayValue(arr, eCSSUnit_Function);
 
   *aListTail = item;
   aListTail = &item->mNext;
 
@@ -1279,17 +1279,17 @@ Decompose3DMatrix(const gfx3DMatrix &aMa
   gfx3DMatrix local = aMatrix;
 
   if (local[3][3] == 0) {
     return false;
   }
   /* 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.
    */
   gfx3DMatrix perspective = local;
   gfxPointH3D empty(0, 0, 0, 1);
   perspective.SetTransposedVector(3, empty);
 
   if (perspective.Determinant() == 0.0) {
@@ -1297,23 +1297,23 @@ Decompose3DMatrix(const gfx3DMatrix &aMa
   }
 
   /* First, isolate perspective. */
   if (local[0][3] != 0 || local[1][3] != 0 ||
       local[2][3] != 0) {
     /* 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 {
     aPerspective = gfxPointH3D(0, 0, 0, 1);
   }
 
   /* Next take care of translation */
   for (int i = 0; i < 3; i++) {
@@ -1321,21 +1321,21 @@ Decompose3DMatrix(const gfx3DMatrix &aMa
     local[3][i] = 0;
   }
 
   /* Now get scale and shear. */
 
   /* 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;
   aShear[XYSHEAR] /= aScale.y;
 
   /* Compute XZ and YZ shears, make 3rd local orthogonal */
   aShear[XZSHEAR] = local[0].DotProduct(local[2]);
   local[2] -= local[0] * aShear[XZSHEAR];
@@ -1402,21 +1402,21 @@ nsStyleAnimation::InterpolateTransformMa
                       rotate1, translate1, perspective1);
     Decompose3DMatrix(aMatrix2, scale2, shear2,
                       rotate2, translate2, perspective2);
   }
 
   // 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);
 
   gfxQuaternion q3 = rotate1.Slerp(rotate2, aProgress);
   gfx3DMatrix rotate = q3.ToMatrix();
   if (!rotate.IsIdentity()) {
       result = rotate * result;
   }
@@ -1435,35 +1435,35 @@ nsStyleAnimation::InterpolateTransformMa
   }
 
   float xyshear =
     InterpolateNumerically(shear1[XYSHEAR], shear2[XYSHEAR], aProgress);
   if (xyshear != 0.0) {
     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);
   }
 
   return result;
 }
 
 static nsCSSValueList*
 AddDifferentTransformLists(const nsCSSValueList* aList1, double aCoeff1,
                            const nsCSSValueList* aList2, double aCoeff2)
 {
   nsAutoPtr<nsCSSValueList> result;
   nsCSSValueList **resultTail = getter_Transfers(result);
 
   nsRefPtr<nsCSSValue::Array> 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.
   if (aList1 == aList2) {
     arr->Item(1).Reset();
   } else {
     aList1->CloneInto(arr->Item(1).SetListValue());
   }
@@ -1498,17 +1498,17 @@ AddTransformLists(const nsCSSValueList* 
 
     nsCSSKeyword tfunc = nsStyleTransformMatrix::TransformFunctionOf(a1);
     nsRefPtr<nsCSSValue::Array> arr;
     if (tfunc != eCSSKeyword_matrix &&
         tfunc != eCSSKeyword_matrix3d &&
         tfunc != eCSSKeyword_interpolatematrix &&
         tfunc != eCSSKeyword_rotate3d &&
         tfunc != eCSSKeyword_perspective) {
-      arr = nsStyleAnimation::AppendTransformFunction(tfunc, resultTail);
+      arr = AppendTransformFunction(tfunc, resultTail);
     }
 
     switch (tfunc) {
       case eCSSKeyword_translate3d: {
           NS_ABORT_IF_FALSE(a1->Count() == 4, "unexpected count");
           NS_ABORT_IF_FALSE(a2->Count() == 4, "unexpected count");
           AddTransformTranslate(a1->Item(1), aCoeff1, a2->Item(1), aCoeff2,
                                 arr->Item(1));
--- a/layout/style/nsStyleAnimation.h
+++ b/layout/style/nsStyleAnimation.h
@@ -10,20 +10,24 @@
 
 #include "prtypes.h"
 #include "nsAString.h"
 #include "nsCRTGlue.h"
 #include "nsStringBuffer.h"
 #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;
 
 namespace mozilla {
 namespace dom {
 class Element;
 } // namespace dom
 } // namespace mozilla
@@ -123,17 +127,17 @@ public:
 
   // Type-conversion methods
   // -----------------------
   /**
    * Creates a computed value for the given specified value
    * (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.
    * @param aSpecifiedValue The specified value, from which we'll build our
    *                        computed value.
    * @param aUseSVGMode     A flag to indicate whether we should parse
    *                        |aSpecifiedValue| in SVG mode.
    * @param [out] aComputedValue The resulting computed value.
@@ -194,23 +198,19 @@ public:
    /**
     * Interpolates between 2 matrices by decomposing them.
     *
     * @param aMatrix1   First matrix, using CSS pixel units.
     * @param aMatrix2   Second matrix, using CSS pixel units.
     * @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<nsCSSValue::Array>
-     AppendTransformFunction(nsCSSKeyword aTransformFunction,
-                             nsCSSValueList**& aListTail);
-
   /**
    * The types and values for the values that we extract and animate.
    */
   enum Unit {
     eUnit_Null, // not initialized
     eUnit_Normal,
     eUnit_Auto,
     eUnit_None,
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -55,23 +55,22 @@ static nscoord CalcLength(const nsCSSVal
     //
     // Raw numbers are treated as being pixels.
     return nsPresContext::CSSPixelsToAppUnits(aValue.GetFloatValue());
   }
   return nsRuleNode::CalcLength(aValue, aContext, aPresContext,
                                 aCanStoreInRuleTree);
 }
 
-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;
 
   if (aValue.GetUnit() == eCSSUnit_Percent) {
     percent = aValue.GetPercentValue();
   } else if (aValue.IsCalcUnit()) {
     nsRuleNode::ComputedCalc result =
--- a/layout/style/nsStyleTransformMatrix.h
+++ b/layout/style/nsStyleTransformMatrix.h
@@ -25,23 +25,16 @@ class nsPresContext;
 namespace nsStyleTransformMatrix {
   
   /**
    * Return the transform function, as an nsCSSKeyword, for the given
    * nsCSSValue::Array from a transform list.
    */
   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.
    *
    * @param aData The nsCSSValueList containing the transform functions
    * @param aContext The style context, used for unit conversion.
    * @param aPresContext The presentation context, used for unit conversion.
    * @param aCanStoreInRuleTree Set to false if the result cannot be cached
--- a/layout/style/nsTransitionManager.cpp
+++ b/layout/style/nsTransitionManager.cpp
@@ -17,31 +17,70 @@
 #include "nsRuleWalker.h"
 #include "nsRuleData.h"
 #include "gfxColor.h"
 #include "nsCSSPropertySet.h"
 #include "nsStyleAnimation.h"
 #include "nsEventDispatcher.h"
 #include "nsGUIEvent.h"
 #include "mozilla/dom/Element.h"
-#include "nsIFrame.h"
-#include "nsCSSFrameConstructor.h"
 
 using mozilla::TimeStamp;
 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
 {
   // Set |timePortion| to the portion of the way we are through the time
   // input to the transition's timing function (always within the range
   // 0-1).
   double duration = mDuration.ToSeconds();
@@ -61,16 +100,42 @@ ElementPropertyTransition::ValuePortionF
       timePortion = 0.0; // use start value during transition-delay
     if (timePortion > 1.0)
       timePortion = 1.0; // we might be behind on flushing
   }
 
   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<ElementPropertyTransition> 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<css::AnimValuesStyleRule> mStyleRule;
+  // The refresh time associated with mStyleRule.
+  TimeStamp mStyleRuleRefreshTime;
+};
+
 static void
 ElementTransitionsPropertyDtor(void           *aObject,
                                nsIAtom        *aPropertyName,
                                void           *aPropertyValue,
                                void           *aData)
 {
   ElementTransitions *et = static_cast<ElementTransitions*>(aPropertyValue);
 #ifdef DEBUG
@@ -103,51 +168,16 @@ ElementTransitions::EnsureStyleRuleFor(T
         nsStyleAnimation::Interpolate(pt.mProperty,
                                       pt.mStartValue, pt.mEndValue,
                                       valuePortion, *val);
       NS_ABORT_IF_FALSE(ok, "could not interpolate values");
     }
   }
 }
 
-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                                                       *
  *****************************************************************************/
 
 already_AddRefed<nsIStyleRule>
 nsTransitionManager::StyleContextChanged(dom::Element *aElement,
                                          nsStyleContext *aOldStyleContext,
                                          nsStyleContext *aNewStyleContext)
@@ -190,22 +220,23 @@ nsTransitionManager::StyleContextChanged
 
   ElementTransitions *et =
       GetElementTransitions(aElement, pseudoType, false);
   if (!et &&
       disp->mTransitionPropertyCount == 1 &&
       disp->mTransitions[0].GetDelay() == 0.0f &&
       disp->mTransitions[0].GetDuration() == 0.0f) {
     return nsnull;
-  }
+  }      
+
 
   if (aNewStyleContext->PresContext()->IsProcessingAnimationStyleChange()) {
     return nsnull;
   }
-
+  
   if (aNewStyleContext->GetParent() &&
       aNewStyleContext->GetParent()->HasPseudoElementData()) {
     // Ignore transitions on things that inherit properties from
     // pseudo-elements.
     // FIXME (Bug 522599): Add tests for this.
     return nsnull;
   }
 
@@ -224,17 +255,17 @@ nsTransitionManager::StyleContextChanged
       // properties in question changed and are animatable.
       // FIXME: Would be good to find a way to share code between this
       // interpretation of transition-property and the one below.
       nsCSSProperty property = t.GetProperty();
       if (property == eCSSPropertyExtra_no_properties ||
           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,
                                      aOldStyleContext, aNewStyleContext,
                                      &startedAny, &whichStarted);
         }
       } else if (nsCSSProps::IsShorthand(property)) {
         CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, property) {
@@ -264,17 +295,17 @@ nsTransitionManager::StyleContextChanged
         const nsTransition& t = disp->mTransitions[i];
         // FIXME: Would be good to find a way to share code between this
         // interpretation of transition-property and the one above.
         nsCSSProperty property = t.GetProperty();
         if (property == eCSSPropertyExtra_no_properties ||
             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);
           }
         } else if (nsCSSProps::IsShorthand(property)) {
           CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(subprop, property) {
             allTransitionProperties.AddProperty(*subprop);
           }
@@ -328,17 +359,21 @@ nsTransitionManager::StyleContextChanged
   // covers up any changes on which we started transitions, so that
   // descendants don't start their own transitions.  (In the case of
   // negative transition delay, this covering rule produces different
   // results than applying the transition rule immediately would).
   // Our caller is responsible for restyling again using this covering
   // rule.
 
   nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
-
+  if (!coverRule) {
+    NS_WARNING("out of memory");
+    return nsnull;
+  }
+  
   nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
   for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) {
     ElementPropertyTransition &pt = pts[i];
     if (whichStarted.HasProperty(pt.mProperty)) {
       coverRule->AddValue(pt.mProperty, pt.mStartValue);
     }
   }
 
@@ -373,29 +408,19 @@ nsTransitionManager::ConsiderStartingTra
 
   ElementPropertyTransition pt;
   nsStyleAnimation::Value dummyValue;
   bool haveValues =
     ExtractComputedValueForTransition(aProperty, aOldStyleContext,
                                       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.)
     nsStyleAnimation::Interpolate(aProperty, pt.mStartValue, pt.mEndValue,
                                   0.5, dummyValue);
 
   PRUint32 currentIndex = nsTArray<ElementPropertyTransition>::NoIndex;
   if (aElementTransitions) {
@@ -466,17 +491,17 @@ nsTransitionManager::ConsiderStartingTra
     // If the new transition reverses the old one, we'll need to handle
     // the timing differently.
     if (!oldPT.IsRemovedSentinel() &&
         oldPT.mStartForReversingTest == pt.mEndValue) {
       // Compute the appropriate negative transition-delay such that right
       // 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
       // negative.
       if (valuePortion < 0.0)
         valuePortion = -valuePortion;
       // A timing function with y2 (or y1!) greater than one might
       // advance past its terminal value.  It's probably a good idea to
@@ -486,38 +511,38 @@ nsTransitionManager::ConsiderStartingTra
       if (valuePortion > 1.0)
         valuePortion = 1.0;
 
       // Negative delays are essentially part of the transition
       // function, so reduce them along with the duration, but don't
       // reduce positive delays.
       if (delay < 0.0f)
         delay *= valuePortion;
-
       duration *= valuePortion;
 
       pt.mStartForReversingTest = oldPT.mEndValue;
       pt.mReversePortion = valuePortion;
     }
   }
 
   pt.mProperty = aProperty;
   pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
   pt.mDuration = TimeDuration::FromMilliseconds(duration);
   pt.mTimingFunction.Init(tf);
+
   if (!aElementTransitions) {
     aElementTransitions =
       GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
                             true);
     if (!aElementTransitions) {
       NS_WARNING("allocating ElementTransitions failed");
       return;
     }
   }
-
+  
   nsTArray<ElementPropertyTransition> &pts =
     aElementTransitions->mPropertyTransitions;
 #ifdef DEBUG
   for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) {
     NS_ABORT_IF_FALSE(i == currentIndex ||
                       pts[i].mProperty != aProperty,
                       "duplicate transitions for property");
   }
@@ -531,17 +556,16 @@ nsTransitionManager::ConsiderStartingTra
     }
   }
 
   nsRestyleHint hint =
     aNewStyleContext->GetPseudoType() ==
       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);
 }
 
 ElementTransitions*
 nsTransitionManager::GetElementTransitions(dom::Element *aElement,
                                            nsCSSPseudoElements::Type aPseudoType,
@@ -565,26 +589,27 @@ nsTransitionManager::GetElementTransitio
                  "other than :before or :after");
     return nsnull;
   }
   ElementTransitions *et = static_cast<ElementTransitions*>(
                              aElement->GetProperty(propName));
   if (!et && aCreateIfNeeded) {
     // FIXME: Consider arena-allocating?
     et = new ElementTransitions(aElement, propName, this);
+    if (!et) {
+      NS_WARNING("out of memory");
+      return nsnull;
+    }
     nsresult rv = aElement->SetProperty(propName, et,
                                         ElementTransitionsPropertyDtor, nsnull);
     if (NS_FAILED(rv)) {
       NS_WARNING("SetProperty failed");
       delete et;
       return nsnull;
     }
-    if (propName == nsGkAtoms::transitionsProperty) {
-      aElement->SetMayHaveAnimations();
-    }
 
     AddElementData(et);
   }
 
   return et;
 }
 
 /*
@@ -728,16 +753,18 @@ nsTransitionManager::WillRefresh(mozilla
       do {
         --i;
         ElementPropertyTransition &pt = et->mPropertyTransitions[i];
         if (pt.IsRemovedSentinel()) {
           // Actually remove transitions one cycle after their
           // 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.
           if (et->mElementProperty == nsGkAtoms::transitionsProperty) {
             nsCSSProperty prop = pt.mProperty;
             if (nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_REPORT_OTHER_NAME))
             {
               prop = nsCSSProps::OtherNameFor(prop);
@@ -761,19 +788,16 @@ nsTransitionManager::WillRefresh(mozilla
       // applies (in which case we just made it not apply).
       NS_ASSERTION(et->mElementProperty == nsGkAtoms::transitionsProperty ||
                    et->mElementProperty == nsGkAtoms::transitionsOfBeforeProperty ||
                    et->mElementProperty == nsGkAtoms::transitionsOfAfterProperty,
                    "Unexpected element property; might restyle too much");
       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();
         // |et| is now a dangling pointer!
         et = nsnull;
       }
     }
   }
--- a/layout/style/nsTransitionManager.h
+++ b/layout/style/nsTransitionManager.h
@@ -10,127 +10,28 @@
 
 #include "AnimationCommon.h"
 #include "nsCSSPseudoElements.h"
 
 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<ElementPropertyTransition> 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<mozilla::css::AnimValuesStyleRule> mStyleRule;
-  // The refresh time associated with mStyleRule.
-  mozilla::TimeStamp mStyleRuleRefreshTime;
-};
-
-
+struct ElementTransitions;
 
 class nsTransitionManager : public mozilla::css::CommonAnimationManager
 {
 public:
   nsTransitionManager(nsPresContext *aPresContext)
     : mozilla::css::CommonAnimationManager(aPresContext)
   {
   }
 
-  static ElementTransitions* GetTransitions(nsIContent* aContent) {
-    return static_cast<ElementTransitions*>
-      (aContent->GetProperty(nsGkAtoms::transitionsProperty));
-  }
-
-  static ElementTransitions*
-    GetTransitionsForCompositor(nsIContent* aContent,
-                                nsCSSProperty aProperty)
-  {
-    if (!aContent->MayHaveAnimations())
-      return nsnull;
-    ElementTransitions* transitions = GetTransitions(aContent);
-    if (!transitions ||
-        !transitions->HasTransitionOfProperty(aProperty) ||
-        !transitions->CanPerformOnCompositorThread()) {
-      return nsnull;
-    }
-    return transitions;
-  }
-
   /**
-   * StyleContextChanged
+   * StyleContextChanged 
    *
    * To be called from nsFrameManager::ReResolveStyleContext when the
    * style of an element has changed, to initiate transitions from
    * that style change.  For style contexts with :before and :after
    * pseudos, aElement is expected to be the generated before/after
    * element.
    *
    * It may return a "cover rule" (see CoverTransitionStartStyleRule) to
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3498,20 +3498,16 @@ pref("layers.acceleration.disabled", tru
 pref("layers.acceleration.disabled", false);
 #endif
 
 // Whether to force acceleration on, ignoring blacklists.
 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);
 #endif
 #endif
 
 #ifdef XP_WIN
 // Whether to disable the automatic detection and use of direct2d.
--- a/xpcom/ds/TimeStamp.h
+++ b/xpcom/ds/TimeStamp.h
@@ -8,20 +8,16 @@
 #define mozilla_TimeStamp_h
 
 #include "mozilla/Assertions.h"
 
 #include "prinrval.h"
 #include "nsDebug.h"
 #include "prlong.h"
 
-namespace IPC {
-template <typename T> struct ParamTraits;
-}
-
 namespace mozilla {
 
 class TimeStamp;
 
 /**
  * Instances of this class represent the length of an interval of time.
  * Negative durations are allowed, meaning the end is before the start.
  * 
@@ -94,36 +90,32 @@ public:
     return mValue <= aOther.mValue;
   }
   bool operator>=(const TimeDuration& aOther) const {
     return mValue >= aOther.mValue;
   }
   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
   // magnitude are meaningless, and those at the same order of
   // magnitude or just above are suspect.
   static TimeDuration Resolution();
 
   // We could define additional operators here:
   // -- convert to/from other time units
   // -- scale duration by a float
   // but let's do that on demand.
   // Comparing durations for equality will only lead to bugs on
   // platforms with high-resolution timers.
 
 private:
   friend class TimeStamp;
-  friend struct IPC::ParamTraits<mozilla::TimeDuration>;
 
   static TimeDuration FromTicks(PRInt64 aTicks) {
     TimeDuration t;
     t.mValue = aTicks;
     return t;
   }
 
   static TimeDuration FromTicks(double aTicks) {
@@ -268,18 +260,16 @@ public:
   // Comparing TimeStamps for equality should be discouraged. Adding
   // two TimeStamps, or scaling TimeStamps, is nonsense and must never
   // be allowed.
 
   static NS_HIDDEN_(nsresult) Startup();
   static NS_HIDDEN_(void) Shutdown();
 
 private:
-  friend struct IPC::ParamTraits<mozilla::TimeStamp>;
-
   TimeStamp(PRUint64 aValue) : mValue(aValue) {}
 
   /**
    * When built with PRIntervalTime, a value of 0 means this instance
    * is "null". Otherwise, the low 32 bits represent a PRIntervalTime,
    * and the high 32 bits represent a counter of the number of
    * rollovers of PRIntervalTime that we've seen. This counter starts
    * at 1 to avoid a real time colliding with the "null" value.