mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to inbound.
This commit is contained in:
commit
ed3645f4ca
@ -11,7 +11,6 @@
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIDocument.h" // for IsInHTMLDocument
|
||||
#include "nsCSSProperty.h"
|
||||
|
||||
// Forward declarations
|
||||
class nsIAtom;
|
||||
|
@ -1291,8 +1291,6 @@ private:
|
||||
NodeMayHaveDOMMutationObserver,
|
||||
// Set if node is Content
|
||||
NodeIsContent,
|
||||
// Set if the node has animations or transitions
|
||||
ElementHasAnimations,
|
||||
// Guard value
|
||||
BooleanFlagCount
|
||||
};
|
||||
@ -1358,8 +1356,6 @@ public:
|
||||
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
|
||||
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
|
||||
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
||||
bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
|
||||
void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
|
||||
protected:
|
||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
||||
|
@ -26,11 +26,6 @@ public:
|
||||
Init(aX1, aY1, aX2, aY2);
|
||||
}
|
||||
|
||||
double X1() const { return mX1; }
|
||||
double Y1() const { return mY1; }
|
||||
double X2() const { return mX2; }
|
||||
double Y2() const { return mY2; }
|
||||
|
||||
void Init(double aX1, double aY1,
|
||||
double aX2, double aY2);
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "nsPrintfCString.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "LayerSorter.h"
|
||||
#include "AnimationCommon.h"
|
||||
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::gfx;
|
||||
@ -221,244 +220,6 @@ LayerManager::CreateAsynchronousImageContainer()
|
||||
//--------------------------------------------------
|
||||
// Layer
|
||||
|
||||
Layer::Layer(LayerManager* aManager, void* aImplData) :
|
||||
mManager(aManager),
|
||||
mParent(nullptr),
|
||||
mNextSibling(nullptr),
|
||||
mPrevSibling(nullptr),
|
||||
mImplData(aImplData),
|
||||
mMaskLayer(nullptr),
|
||||
mXScale(1.0f),
|
||||
mYScale(1.0f),
|
||||
mOpacity(1.0),
|
||||
mContentFlags(0),
|
||||
mUseClipRect(false),
|
||||
mUseTileSourceRect(false),
|
||||
mIsFixedPosition(false),
|
||||
mDebugColorIndex(0)
|
||||
{}
|
||||
|
||||
Layer::~Layer()
|
||||
{}
|
||||
|
||||
void
|
||||
Layer::AddAnimation(const Animation& aAnimation)
|
||||
{
|
||||
if (!AsShadowableLayer() || !AsShadowableLayer()->HasShadow())
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(aAnimation.segments().Length() >= 1);
|
||||
|
||||
mAnimations.AppendElement(aAnimation);
|
||||
Mutated();
|
||||
}
|
||||
|
||||
void
|
||||
Layer::ClearAnimations()
|
||||
{
|
||||
mAnimations.Clear();
|
||||
mAnimationData.Clear();
|
||||
Mutated();
|
||||
}
|
||||
|
||||
static nsCSSValueList*
|
||||
CreateCSSValueList(const InfallibleTArray<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 = functions->AppendElement();
|
||||
switch (tf.type()) {
|
||||
case TimingFunction::TCubicBezierFunction: {
|
||||
CubicBezierFunction cbf = tf.get_CubicBezierFunction();
|
||||
ctf->Init(nsTimingFunction(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2()));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NS_ASSERTION(tf.type() == TimingFunction::TStepFunction,
|
||||
"Function must be bezier or step");
|
||||
StepFunction sf = tf.get_StepFunction();
|
||||
nsTimingFunction::Type type = sf.type() == 1 ? nsTimingFunction::StepStart
|
||||
: nsTimingFunction::StepEnd;
|
||||
ctf->Init(nsTimingFunction(type, sf.steps()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Precompute the nsStyleAnimation::Values that we need if this is a transform
|
||||
// animation.
|
||||
InfallibleTArray<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()
|
||||
{
|
||||
@ -600,42 +361,21 @@ Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
||||
return currentClip.Intersect(scissor);
|
||||
}
|
||||
|
||||
const gfx3DMatrix
|
||||
Layer::GetTransform()
|
||||
{
|
||||
gfx3DMatrix transform = mTransform;
|
||||
transform.Scale(mXScale, mYScale, 1);
|
||||
return transform;
|
||||
}
|
||||
|
||||
const gfx3DMatrix
|
||||
const gfx3DMatrix&
|
||||
Layer::GetLocalTransform()
|
||||
{
|
||||
gfx3DMatrix transform;
|
||||
if (ShadowLayer* shadow = AsShadowLayer()) {
|
||||
transform = shadow->GetShadowTransform();
|
||||
} else {
|
||||
transform = mTransform;
|
||||
}
|
||||
transform.Scale(mXScale, mYScale, 1);
|
||||
return transform;
|
||||
}
|
||||
|
||||
const float
|
||||
Layer::GetLocalOpacity()
|
||||
{
|
||||
if (ShadowLayer* shadow = AsShadowLayer())
|
||||
return shadow->GetShadowOpacity();
|
||||
return mOpacity;
|
||||
return shadow->GetShadowTransform();
|
||||
return mTransform;
|
||||
}
|
||||
|
||||
float
|
||||
Layer::GetEffectiveOpacity()
|
||||
{
|
||||
float opacity = GetLocalOpacity();
|
||||
float opacity = GetOpacity();
|
||||
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
||||
c = c->GetParent()) {
|
||||
opacity *= c->GetLocalOpacity();
|
||||
opacity *= c->GetOpacity();
|
||||
}
|
||||
return opacity;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "gfxPattern.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsStyleAnimation.h"
|
||||
#include "LayersBackend.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
@ -44,14 +43,8 @@ namespace gl {
|
||||
class GLContext;
|
||||
}
|
||||
|
||||
namespace css {
|
||||
class ComputedTimingFunction;
|
||||
}
|
||||
|
||||
namespace layers {
|
||||
|
||||
class Animation;
|
||||
class CommonLayerAttributes;
|
||||
class Layer;
|
||||
class ThebesLayer;
|
||||
class ContainerLayer;
|
||||
@ -537,13 +530,6 @@ private:
|
||||
};
|
||||
|
||||
class ThebesLayer;
|
||||
typedef InfallibleTArray<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
|
||||
@ -565,7 +551,7 @@ public:
|
||||
TYPE_THEBES
|
||||
};
|
||||
|
||||
virtual ~Layer();
|
||||
virtual ~Layer() {}
|
||||
|
||||
/**
|
||||
* Returns the LayerManager this Layer belongs to. Note that the layer
|
||||
@ -716,19 +702,12 @@ public:
|
||||
* XXX Currently only transformations corresponding to 2D affine transforms
|
||||
* are supported.
|
||||
*/
|
||||
void SetBaseTransform(const gfx3DMatrix& aMatrix)
|
||||
void SetTransform(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
mTransform = aMatrix;
|
||||
Mutated();
|
||||
}
|
||||
|
||||
void SetScale(float aXScale, float aYScale)
|
||||
{
|
||||
mXScale = aXScale;
|
||||
mYScale = aYScale;
|
||||
Mutated();
|
||||
}
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* A layer is "fixed position" when it draws content from a content
|
||||
@ -737,14 +716,6 @@ public:
|
||||
*/
|
||||
void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; }
|
||||
|
||||
// Call AddAnimation to add an animation to this layer from layout code.
|
||||
void AddAnimation(const Animation& aAnimation);
|
||||
// ClearAnimations clears animations on this layer.
|
||||
void ClearAnimations();
|
||||
// This is only called when the layer tree is updated. Do not call this from
|
||||
// layout code. To add an animation to this layer, use AddAnimation.
|
||||
void SetAnimations(const AnimationArray& aAnimations);
|
||||
|
||||
/**
|
||||
* CONSTRUCTION PHASE ONLY
|
||||
* If a layer is "fixed position", this determines which point on the layer
|
||||
@ -764,15 +735,11 @@ public:
|
||||
Layer* GetPrevSibling() { return mPrevSibling; }
|
||||
virtual Layer* GetFirstChild() { return nullptr; }
|
||||
virtual Layer* GetLastChild() { return nullptr; }
|
||||
const gfx3DMatrix GetTransform();
|
||||
const gfx3DMatrix& GetBaseTransform() { return mTransform; }
|
||||
float GetXScale() { return mXScale; }
|
||||
float GetYScale() { return mYScale; }
|
||||
const gfx3DMatrix& GetTransform() { return mTransform; }
|
||||
bool GetIsFixedPosition() { return mIsFixedPosition; }
|
||||
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
|
||||
Layer* GetMaskLayer() { return mMaskLayer; }
|
||||
AnimationArray& GetAnimations() { return mAnimations; }
|
||||
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
*
|
||||
@ -973,7 +940,20 @@ public:
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Layer(LayerManager* aManager, void* aImplData);
|
||||
Layer(LayerManager* aManager, void* aImplData) :
|
||||
mManager(aManager),
|
||||
mParent(nullptr),
|
||||
mNextSibling(nullptr),
|
||||
mPrevSibling(nullptr),
|
||||
mImplData(aImplData),
|
||||
mMaskLayer(nullptr),
|
||||
mOpacity(1.0),
|
||||
mContentFlags(0),
|
||||
mUseClipRect(false),
|
||||
mUseTileSourceRect(false),
|
||||
mIsFixedPosition(false),
|
||||
mDebugColorIndex(0)
|
||||
{}
|
||||
|
||||
void Mutated() { mManager->Mutated(this); }
|
||||
|
||||
@ -988,13 +968,7 @@ protected:
|
||||
* Returns the local transform for this layer: either mTransform or,
|
||||
* for shadow layers, GetShadowTransform()
|
||||
*/
|
||||
const gfx3DMatrix GetLocalTransform();
|
||||
|
||||
/**
|
||||
* Returns the local opacity for this layer: either mOpacity or,
|
||||
* for shadow layers, GetShadowOpacity()
|
||||
*/
|
||||
const float GetLocalOpacity();
|
||||
const gfx3DMatrix& GetLocalTransform();
|
||||
|
||||
/**
|
||||
* Computes a tweaked version of aTransform that snaps a point or a rectangle
|
||||
@ -1020,11 +994,7 @@ protected:
|
||||
gfx::UserData mUserData;
|
||||
nsIntRegion mVisibleRegion;
|
||||
gfx3DMatrix mTransform;
|
||||
float mXScale;
|
||||
float mYScale;
|
||||
gfx3DMatrix mEffectiveTransform;
|
||||
AnimationArray mAnimations;
|
||||
InfallibleTArray<AnimData> mAnimationData;
|
||||
float mOpacity;
|
||||
nsIntRect mClipRect;
|
||||
nsIntRect mTileSourceRect;
|
||||
|
@ -31,18 +31,16 @@ EXPORTS = \
|
||||
BasicLayers.h \
|
||||
BasicTiledThebesLayer.h \
|
||||
BasicImplData.h \
|
||||
CompositorParent.h \
|
||||
ImageLayers.h \
|
||||
Layers.h \
|
||||
LayersBackend.h \
|
||||
LayerManagerOGLShaders.h \
|
||||
LayerManagerOGL.h \
|
||||
LayerManagerOGLProgram.h \
|
||||
LayerSorter.h \
|
||||
ReadbackLayer.h \
|
||||
ShadowLayersManager.h \
|
||||
SharedTextureImage.h \
|
||||
LayerSorter.h \
|
||||
TexturePoolOGL.h \
|
||||
SharedTextureImage.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
|
@ -21,15 +21,6 @@
|
||||
#include "nsIWidget.h"
|
||||
#include "RenderTrace.h"
|
||||
#include "ShadowLayersParent.h"
|
||||
#include "BasicLayers.h"
|
||||
#include "LayerManagerOGL.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "RenderTrace.h"
|
||||
#include "nsStyleAnimation.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "AnimationCommon.h"
|
||||
#include "nsAnimationManager.h"
|
||||
|
||||
using namespace base;
|
||||
using namespace mozilla::ipc;
|
||||
@ -440,15 +431,15 @@ CompositorParent::Composite()
|
||||
return;
|
||||
}
|
||||
|
||||
Layer* layer = mLayerManager->GetRoot();
|
||||
AutoResolveRefLayers resolve(layer);
|
||||
Layer* aLayer = mLayerManager->GetRoot();
|
||||
AutoResolveRefLayers resolve(aLayer);
|
||||
|
||||
bool requestNextFrame = TransformShadowTree(mLastCompose);
|
||||
if (requestNextFrame) {
|
||||
ScheduleComposition();
|
||||
}
|
||||
|
||||
RenderTraceLayers(layer, "0000");
|
||||
RenderTraceLayers(aLayer, "0000");
|
||||
|
||||
if (LAYERS_OPENGL == mLayerManager->GetBackendType() &&
|
||||
!mTargetConfig.naturalBounds().IsEmpty()) {
|
||||
@ -545,10 +536,9 @@ SetShadowProperties(Layer* aLayer)
|
||||
{
|
||||
// FIXME: Bug 717688 -- Do these updates in ShadowLayersParent::RecvUpdate.
|
||||
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||
shadow->SetShadowTransform(aLayer->GetBaseTransform());
|
||||
shadow->SetShadowTransform(aLayer->GetTransform());
|
||||
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
||||
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
||||
shadow->SetShadowOpacity(aLayer->GetOpacity());
|
||||
|
||||
for (Layer* child = aLayer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
@ -556,114 +546,6 @@ SetShadowProperties(Layer* aLayer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// SampleValue should eventually take the CSS property as an argument. This
|
||||
// will be needed if we ever animate two values with the same type but different
|
||||
// interpolation rules.
|
||||
static void
|
||||
SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aStart,
|
||||
nsStyleAnimation::Value& aEnd, Animatable* aValue)
|
||||
{
|
||||
nsStyleAnimation::Value interpolatedValue;
|
||||
NS_ASSERTION(aStart.GetUnit() == aEnd.GetUnit() ||
|
||||
aStart.GetUnit() == nsStyleAnimation::eUnit_None ||
|
||||
aEnd.GetUnit() == nsStyleAnimation::eUnit_None, "Must have same unit");
|
||||
if (aStart.GetUnit() == nsStyleAnimation::eUnit_Transform ||
|
||||
aEnd.GetUnit() == nsStyleAnimation::eUnit_Transform) {
|
||||
nsStyleAnimation::Interpolate(eCSSProperty_transform, aStart, aEnd,
|
||||
aPortion, interpolatedValue);
|
||||
nsCSSValueList* interpolatedList = interpolatedValue.GetCSSValueListValue();
|
||||
|
||||
TransformData& data = aAnimation.data().get_TransformData();
|
||||
gfx3DMatrix transform =
|
||||
nsDisplayTransform::GetResultingTransformMatrix(nullptr, data.origin(), nsDeviceContext::AppUnitsPerCSSPixel(),
|
||||
&data.bounds(), interpolatedList, &data.mozOrigin(),
|
||||
&data.perspectiveOrigin(), &data.perspective());
|
||||
|
||||
InfallibleTArray<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,
|
||||
@ -709,13 +591,9 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
ContainerLayer* container = layer->AsContainerLayer();
|
||||
Layer* root = mLayerManager->GetRoot();
|
||||
|
||||
// NB: we must sample animations *before* sampling pan/zoom
|
||||
// transforms.
|
||||
wantNextFrame |= SampleAnimations(layer, mLastCompose);
|
||||
|
||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||
const gfx3DMatrix& rootTransform = root->GetTransform();
|
||||
const gfx3DMatrix& currentTransform = layer->GetBaseTransform();
|
||||
const gfx3DMatrix& currentTransform = layer->GetTransform();
|
||||
|
||||
// FIXME/bug 775437: unify this interface with the ~native-fennec
|
||||
// derived code
|
||||
@ -808,6 +686,7 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
||||
shadow->SetShadowTransform(treeTransform * currentTransform);
|
||||
TransformFixedLayers(layer, offset, scaleDiff);
|
||||
}
|
||||
|
||||
return wantNextFrame;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace layers {
|
||||
* PLayer represents a layer shared across thread contexts.
|
||||
*/
|
||||
|
||||
async protocol PLayer {
|
||||
sync protocol PLayer {
|
||||
manager PLayers;
|
||||
|
||||
/**
|
||||
@ -32,7 +32,7 @@ async protocol PLayer {
|
||||
* being deleted "soon" (usually immediately).
|
||||
*/
|
||||
parent:
|
||||
async __delete__();
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // layers
|
||||
|
@ -14,14 +14,6 @@ include protocol PRenderFrame;
|
||||
|
||||
include "gfxipc/ShadowLayerUtils.h";
|
||||
include "mozilla/WidgetUtils.h";
|
||||
include "mozilla/TimeStamp.h";
|
||||
|
||||
using gfxPoint3D;
|
||||
using nscoord;
|
||||
using nsRect;
|
||||
using nsPoint;
|
||||
using mozilla::TimeDuration;
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
/**
|
||||
* The layers protocol is spoken between thread contexts that manage
|
||||
@ -59,129 +51,24 @@ union CanvasSurface {
|
||||
null_t;
|
||||
};
|
||||
|
||||
struct CubicBezierFunction {
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
};
|
||||
|
||||
struct StepFunction {
|
||||
int steps;
|
||||
// 1 = nsTimingFunction::StepStart, 2 = nsTimingFunction::StepEnd
|
||||
int type;
|
||||
};
|
||||
|
||||
union TimingFunction {
|
||||
CubicBezierFunction;
|
||||
StepFunction;
|
||||
};
|
||||
|
||||
struct Color { gfxRGBA value; };
|
||||
struct Opacity { float value; };
|
||||
struct Perspective { float value; };
|
||||
struct RotationX { float radians; };
|
||||
struct RotationY { float radians; };
|
||||
struct RotationZ { float radians; };
|
||||
struct Rotation { float radians; };
|
||||
struct Rotation3D {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float radians;
|
||||
};
|
||||
struct Scale {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
struct SkewX { float x; };
|
||||
struct SkewY { float y; };
|
||||
struct TransformMatrix { gfx3DMatrix value; };
|
||||
struct Translation {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
union TransformFunction {
|
||||
Perspective;
|
||||
RotationX;
|
||||
RotationY;
|
||||
RotationZ;
|
||||
Rotation;
|
||||
Rotation3D;
|
||||
Scale;
|
||||
SkewX;
|
||||
SkewY;
|
||||
Translation;
|
||||
TransformMatrix;
|
||||
};
|
||||
|
||||
union Animatable {
|
||||
Color;
|
||||
Opacity;
|
||||
TransformFunction[];
|
||||
};
|
||||
|
||||
struct AnimationSegment {
|
||||
Animatable startState;
|
||||
Animatable endState;
|
||||
float startPortion;
|
||||
float endPortion;
|
||||
TimingFunction sampleFn;
|
||||
};
|
||||
|
||||
// Transforms need extra information to correctly convert the list of transform
|
||||
// functions to a gfx3DMatrix that can be applied directly to the layer.
|
||||
struct TransformData {
|
||||
nsPoint origin;
|
||||
gfxPoint3D mozOrigin;
|
||||
gfxPoint3D perspectiveOrigin;
|
||||
nsRect bounds;
|
||||
nscoord perspective;
|
||||
};
|
||||
|
||||
union AnimationData {
|
||||
null_t;
|
||||
TransformData;
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
TimeStamp startTime;
|
||||
TimeDuration duration;
|
||||
// For each frame, the interpolation point is computed based on the
|
||||
// startTime, the direction, the duration, and the current time.
|
||||
// The segments must uniquely cover the portion from 0.0 to 1.0
|
||||
AnimationSegment[] segments;
|
||||
// How many times to repeat the animation. < 0 means "forever".
|
||||
float numIterations;
|
||||
// This uses the NS_STYLE_ANIMATION_DIRECTION_* constants.
|
||||
int32_t direction;
|
||||
AnimationData data;
|
||||
};
|
||||
|
||||
// Change a layer's attributes
|
||||
struct CommonLayerAttributes {
|
||||
nsIntRegion visibleRegion;
|
||||
TransformMatrix transform;
|
||||
float xScale;
|
||||
float yScale;
|
||||
gfx3DMatrix transform;
|
||||
PRUint32 contentFlags;
|
||||
Opacity opacity;
|
||||
float opacity;
|
||||
bool useClipRect;
|
||||
nsIntRect clipRect;
|
||||
bool isFixedPosition;
|
||||
gfxPoint fixedPositionAnchor;
|
||||
nullable PLayer maskLayer;
|
||||
// Animated colors will only honored for ColorLayers.
|
||||
Animation[] animations;
|
||||
};
|
||||
|
||||
struct ThebesLayerAttributes {
|
||||
nsIntRegion validRegion;
|
||||
};
|
||||
struct ContainerLayerAttributes{ FrameMetrics metrics; };
|
||||
struct ColorLayerAttributes { Color color; };
|
||||
struct ColorLayerAttributes { gfxRGBA color; };
|
||||
struct CanvasLayerAttributes { GraphicsFilterType filter; };
|
||||
struct RefLayerAttributes { int64_t id; };
|
||||
struct ImageLayerAttributes {
|
||||
|
@ -299,9 +299,7 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
|
||||
LayerAttributes attrs;
|
||||
CommonLayerAttributes& common = attrs.common();
|
||||
common.visibleRegion() = mutant->GetVisibleRegion();
|
||||
common.transform() = mutant->GetBaseTransform();
|
||||
common.xScale() = mutant->GetXScale();
|
||||
common.yScale() = mutant->GetYScale();
|
||||
common.transform() = mutant->GetTransform();
|
||||
common.contentFlags() = mutant->GetContentFlags();
|
||||
common.opacity() = mutant->GetOpacity();
|
||||
common.useClipRect() = !!mutant->GetClipRect();
|
||||
@ -315,7 +313,6 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
|
||||
common.maskLayerChild() = NULL;
|
||||
}
|
||||
common.maskLayerParent() = NULL;
|
||||
common.animations() = mutant->GetAnimations();
|
||||
attrs.specific() = null_t();
|
||||
mutant->FillSpecificAttributes(attrs.specific());
|
||||
|
||||
|
@ -524,11 +524,6 @@ public:
|
||||
mShadowVisibleRegion = aRegion;
|
||||
}
|
||||
|
||||
void SetShadowOpacity(float aOpacity)
|
||||
{
|
||||
mShadowOpacity = aOpacity;
|
||||
}
|
||||
|
||||
void SetShadowClipRect(const nsIntRect* aRect)
|
||||
{
|
||||
mUseShadowClipRect = aRect != nullptr;
|
||||
@ -543,7 +538,6 @@ public:
|
||||
}
|
||||
|
||||
// These getters can be used anytime.
|
||||
float GetShadowOpacity() { return mShadowOpacity; }
|
||||
const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nullptr; }
|
||||
const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
|
||||
const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
|
||||
@ -553,7 +547,6 @@ public:
|
||||
protected:
|
||||
ShadowLayer()
|
||||
: mAllocator(nullptr)
|
||||
, mShadowOpacity(1.0)
|
||||
, mUseShadowClipRect(false)
|
||||
{}
|
||||
|
||||
@ -561,7 +554,6 @@ protected:
|
||||
nsIntRegion mShadowVisibleRegion;
|
||||
gfx3DMatrix mShadowTransform;
|
||||
nsIntRect mShadowClipRect;
|
||||
float mShadowOpacity;
|
||||
bool mUseShadowClipRect;
|
||||
};
|
||||
|
||||
|
@ -214,10 +214,9 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
const CommonLayerAttributes& common = attrs.common();
|
||||
layer->SetVisibleRegion(common.visibleRegion());
|
||||
layer->SetContentFlags(common.contentFlags());
|
||||
layer->SetOpacity(common.opacity().value());
|
||||
layer->SetOpacity(common.opacity());
|
||||
layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
|
||||
layer->SetBaseTransform(common.transform().value());
|
||||
layer->SetScale(common.xScale(), common.yScale());
|
||||
layer->SetTransform(common.transform());
|
||||
static bool fixedPositionLayersEnabled = getenv("MOZ_ENABLE_FIXED_POSITION_LAYERS") != 0;
|
||||
if (fixedPositionLayersEnabled) {
|
||||
layer->SetIsFixedPosition(common.isFixedPosition());
|
||||
@ -228,7 +227,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
} else {
|
||||
layer->SetMaskLayer(NULL);
|
||||
}
|
||||
layer->SetAnimations(common.animations());
|
||||
|
||||
typedef SpecificLayerAttributes Specific;
|
||||
const SpecificLayerAttributes& specific = attrs.specific();
|
||||
@ -259,7 +257,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
||||
MOZ_LAYERS_LOG(("[ParentSide] color layer"));
|
||||
|
||||
static_cast<ColorLayer*>(layer)->SetColor(
|
||||
specific.get_ColorLayerAttributes().color().value());
|
||||
specific.get_ColorLayerAttributes().color());
|
||||
break;
|
||||
|
||||
case Specific::TCanvasLayerAttributes:
|
||||
|
@ -199,12 +199,6 @@ struct NS_GFX nsRect :
|
||||
inline nsIntRect ScaleToInsidePixels(float aXScale, float aYScale,
|
||||
nscoord aAppUnitsPerPixel) const;
|
||||
inline nsIntRect ToInsidePixels(nscoord aAppUnitsPerPixel) const;
|
||||
|
||||
// This is here only to keep IPDL-generated code happy. DO NOT USE.
|
||||
bool operator==(const nsRect& aRect) const
|
||||
{
|
||||
return IsEqualEdges(aRect);
|
||||
}
|
||||
};
|
||||
|
||||
struct NS_GFX nsIntRect :
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "chrome/common/ipc_message_utils.h"
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
@ -440,28 +439,11 @@ struct ParamTraits<gfxPoint>
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return (ReadParam(aMsg, aIter, &aResult->x) &&
|
||||
ReadParam(aMsg, aIter, &aResult->y));
|
||||
}
|
||||
};
|
||||
if (ReadParam(aMsg, aIter, &aResult->x) &&
|
||||
ReadParam(aMsg, aIter, &aResult->y))
|
||||
return true;
|
||||
|
||||
template<>
|
||||
struct ParamTraits<gfxPoint3D>
|
||||
{
|
||||
typedef gfxPoint3D paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.x);
|
||||
WriteParam(aMsg, aParam.y);
|
||||
WriteParam(aMsg, aParam.z);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return (ReadParam(aMsg, aIter, &aResult->x) &&
|
||||
ReadParam(aMsg, aIter, &aResult->y) &&
|
||||
ReadParam(aMsg, aIter, &aResult->z));
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@ -595,24 +577,6 @@ struct ParamTraits<mozilla::null_t>
|
||||
}
|
||||
};
|
||||
|
||||
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>
|
||||
{
|
||||
@ -802,34 +766,6 @@ struct ParamTraits<nsID>
|
||||
}
|
||||
};
|
||||
|
||||
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__ */
|
||||
|
@ -166,24 +166,9 @@ dombindings_gen.cpp: $(srcdir)/dombindings.conf \
|
||||
--makedepend-output $(MDDEPDIR)/dombindingsgen.pp \
|
||||
$(srcdir)/dombindings.conf
|
||||
|
||||
DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.h \
|
||||
DictionaryHelpers.cpp
|
||||
DictionaryHelpers.$(OBJ_SUFFIX): DictionaryHelpers.cpp
|
||||
|
||||
DictionaryHelpers.h: $(srcdir)/dictionary_helper_gen.conf \
|
||||
event_impl_gen.conf \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
$(srcdir)/codegen.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/header.py \
|
||||
$(LIBXUL_DIST)/sdk/bin/xpidl.py \
|
||||
$(DEPTH)/js/src/js-confdefs.h
|
||||
$(PYTHON) $(topsrcdir)/config/pythonpath.py \
|
||||
$(PLY_INCLUDE) \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
-I $(DEPTH)/dist/idl \
|
||||
--header-output DictionaryHelpers.h \
|
||||
$(srcdir)/dictionary_helper_gen.conf \
|
||||
event_impl_gen.conf
|
||||
DictionaryHelpers.h: DictionaryHelpers.cpp
|
||||
|
||||
DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
|
||||
event_impl_gen.conf \
|
||||
@ -197,6 +182,7 @@ DictionaryHelpers.cpp: $(srcdir)/dictionary_helper_gen.conf \
|
||||
-I$(LIBXUL_DIST)/sdk/bin \
|
||||
$(srcdir)/dictionary_helper_gen.py \
|
||||
-I $(DEPTH)/dist/idl \
|
||||
--header-output DictionaryHelpers.h \
|
||||
--stub-output DictionaryHelpers.cpp \
|
||||
--makedepend-output $(MDDEPDIR)/dictionary_helper_gen.pp \
|
||||
$(srcdir)/dictionary_helper_gen.conf \
|
||||
|
@ -357,10 +357,6 @@ if __name__ == '__main__':
|
||||
|
||||
conf = readConfigFile(filename)
|
||||
|
||||
if options.header_output is not None:
|
||||
outfd = open(options.header_output, 'w')
|
||||
print_header_file(outfd, conf)
|
||||
outfd.close()
|
||||
if options.stub_output is not None:
|
||||
make_targets.append(options.stub_output)
|
||||
outfd = open(options.stub_output, 'w')
|
||||
@ -368,4 +364,8 @@ if __name__ == '__main__':
|
||||
outfd.close()
|
||||
if options.makedepend_output is not None:
|
||||
writeMakeDependOutput(options.makedepend_output)
|
||||
if options.header_output is not None:
|
||||
outfd = open(options.header_output, 'w')
|
||||
print_header_file(outfd, conf)
|
||||
outfd.close()
|
||||
|
||||
|
@ -21,9 +21,6 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "sampler.h"
|
||||
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsTransitionManager.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
@ -947,7 +944,6 @@ ContainerState::CreateOrRecycleColorLayer()
|
||||
// We will reapply any necessary clipping.
|
||||
layer->SetClipRect(nullptr);
|
||||
layer->SetMaskLayer(nullptr);
|
||||
layer->SetScale(1.0f, 1.0f);
|
||||
} else {
|
||||
// Create a new layer
|
||||
layer = mManager->CreateColorLayer();
|
||||
@ -971,7 +967,6 @@ ContainerState::CreateOrRecycleImageLayer()
|
||||
// We will reapply any necessary clipping.
|
||||
layer->SetClipRect(nullptr);
|
||||
layer->SetMaskLayer(nullptr);
|
||||
layer->SetScale(1.0f, 1.0f);
|
||||
} else {
|
||||
// Create a new layer
|
||||
layer = mManager->CreateImageLayer();
|
||||
@ -989,7 +984,6 @@ ContainerState::CreateOrRecycleMaskImageLayerFor(Layer* aLayer)
|
||||
nsRefPtr<ImageLayer> result = mRecycledMaskImageLayers.Get(aLayer);
|
||||
if (result) {
|
||||
mRecycledMaskImageLayers.Remove(aLayer);
|
||||
result->SetScale(1.0f, 1.0f);
|
||||
// XXX if we use clip on mask layers, null it out here
|
||||
} else {
|
||||
// Create a new layer
|
||||
@ -1064,7 +1058,6 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
|
||||
// We will reapply any necessary clipping.
|
||||
layer->SetClipRect(nullptr);
|
||||
layer->SetMaskLayer(nullptr);
|
||||
layer->SetScale(1.0f, 1.0f);
|
||||
|
||||
data = static_cast<ThebesDisplayItemLayerUserData*>
|
||||
(layer->GetUserData(&gThebesDisplayItemLayerUserData));
|
||||
@ -1118,8 +1111,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
|
||||
RoundToMatchResidual(scaledOffset.y, data->mActiveScrolledRootPosition.y));
|
||||
gfxMatrix matrix;
|
||||
matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y));
|
||||
layer->SetBaseTransform(gfx3DMatrix::From2D(matrix));
|
||||
layer->SetScale(1.0f, 1.0f);
|
||||
layer->SetTransform(gfx3DMatrix::From2D(matrix));
|
||||
|
||||
// FIXME: Temporary workaround for bug 681192 and bug 724786.
|
||||
#ifndef MOZ_JAVA_COMPOSITOR
|
||||
@ -1274,7 +1266,7 @@ ContainerState::PopThebesLayerData()
|
||||
// The layer's current transform is applied first, then the result is scaled.
|
||||
gfx3DMatrix transform = imageLayer->GetTransform()*
|
||||
gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
|
||||
imageLayer->SetBaseTransform(transform);
|
||||
imageLayer->SetTransform(transform);
|
||||
if (data->mItemClip.mHaveClipRect) {
|
||||
nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect);
|
||||
imageLayer->IntersectClipRect(clip);
|
||||
@ -1285,9 +1277,8 @@ ContainerState::PopThebesLayerData()
|
||||
colorLayer->SetIsFixedPosition(data->mLayer->GetIsFixedPosition());
|
||||
colorLayer->SetColor(data->mSolidColor);
|
||||
|
||||
// Copy transform and scale
|
||||
colorLayer->SetBaseTransform(data->mLayer->GetBaseTransform());
|
||||
colorLayer->SetScale(data->mLayer->GetXScale(), data->mLayer->GetYScale());
|
||||
// Copy transform
|
||||
colorLayer->SetTransform(data->mLayer->GetTransform());
|
||||
|
||||
// Clip colorLayer to its visible region, since ColorLayers are
|
||||
// allowed to paint outside the visible region. Here we rely on the
|
||||
@ -1786,7 +1777,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||
// The layer's current transform is applied first, then the result is scaled.
|
||||
gfx3DMatrix transform = ownLayer->GetTransform()*
|
||||
gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
|
||||
ownLayer->SetBaseTransform(transform);
|
||||
ownLayer->SetTransform(transform);
|
||||
}
|
||||
|
||||
ownLayer->SetIsFixedPosition(
|
||||
@ -2130,9 +2121,9 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
||||
scale = gfxSize(1.0, 1.0);
|
||||
}
|
||||
|
||||
aLayer->SetBaseTransform(transform);
|
||||
// Store the inverse of our resolution-scale on the layer
|
||||
aLayer->SetScale(1.0f/float(scale.width), 1.0f/float(scale.height));
|
||||
// Apply the inverse of our resolution-scale before the rest of our transform
|
||||
transform = gfx3DMatrix::ScalingMatrix(1.0/scale.width, 1.0/scale.height, 1.0)*transform;
|
||||
aLayer->SetTransform(transform);
|
||||
|
||||
FrameLayerBuilder::ContainerParameters
|
||||
result(scale.width, scale.height, aIncomingScale);
|
||||
@ -3138,7 +3129,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
||||
}
|
||||
|
||||
maskLayer->SetContainer(container);
|
||||
maskLayer->SetBaseTransform(gfx3DMatrix::From2D(maskTransform.Invert()));
|
||||
maskLayer->SetTransform(gfx3DMatrix::From2D(maskTransform.Invert()));
|
||||
|
||||
// save the details of the clip in user data
|
||||
userData->mScaleX = newData.mScaleX;
|
||||
|
@ -10,8 +10,6 @@
|
||||
* used during painting and hit testing
|
||||
*/
|
||||
|
||||
#include "mozilla/layers/PLayers.h"
|
||||
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
#include "nsCSSRendering.h"
|
||||
@ -38,9 +36,6 @@
|
||||
#include "nsSVGElement.h"
|
||||
#include "nsSVGClipPathFrame.h"
|
||||
#include "sampler.h"
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsTransitionManager.h"
|
||||
#include "nsIViewManager.h"
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
|
||||
@ -48,367 +43,6 @@ using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
typedef FrameMetrics::ViewID ViewID;
|
||||
|
||||
static void AddTransformFunctions(nsCSSValueList* aList,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
nsRect& aBounds,
|
||||
float aAppUnitsPerPixel,
|
||||
InfallibleTArray<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),
|
||||
@ -565,11 +199,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
nsRect contentBounds = scrollableFrame->GetScrollRange();
|
||||
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
|
||||
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
|
||||
metrics.mCSSContentRect =
|
||||
mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
||||
metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
||||
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||
metrics.mViewportScrollOffset = scrollableFrame->GetScrollPosition().ScaleToNearestPixels(
|
||||
@ -577,11 +210,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
||||
}
|
||||
else {
|
||||
nsRect contentBounds = aForFrame->GetRect();
|
||||
metrics.mCSSContentRect =
|
||||
mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
||||
metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
||||
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||
}
|
||||
@ -988,8 +620,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
||||
return;
|
||||
}
|
||||
// Root is being scaled up by the X/Y resolution. Scale it back down.
|
||||
root->SetScale(1.0f/containerParameters.mXScale,
|
||||
1.0f/containerParameters.mYScale);
|
||||
gfx3DMatrix rootTransform = root->GetTransform()*
|
||||
gfx3DMatrix::ScalingMatrix(1.0f/containerParameters.mXScale,
|
||||
1.0f/containerParameters.mYScale, 1.0f);
|
||||
root->SetTransform(rootTransform);
|
||||
|
||||
ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
|
||||
: FrameMetrics::NULL_SCROLL_ID;
|
||||
@ -1648,7 +1282,7 @@ nsDisplayBackground::ConfigureLayer(ImageLayer* aLayer)
|
||||
transform.Translate(mDestRect.TopLeft());
|
||||
transform.Scale(mDestRect.width/imageSize.width,
|
||||
mDestRect.height/imageSize.height);
|
||||
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
|
||||
aLayer->SetTransform(gfx3DMatrix::From2D(transform));
|
||||
|
||||
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageSize.width, imageSize.height));
|
||||
}
|
||||
@ -2345,16 +1979,14 @@ already_AddRefed<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, nullptr);
|
||||
if (!container)
|
||||
if (!layer)
|
||||
return nullptr;
|
||||
|
||||
container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
||||
AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_opacity);
|
||||
|
||||
return container.forget();
|
||||
layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2379,12 +2011,6 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateOpacityLayer) &&
|
||||
!IsItemTooSmallForActiveLayer(this))
|
||||
return LAYER_ACTIVE;
|
||||
if (mFrame->GetContent()) {
|
||||
if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(),
|
||||
eCSSProperty_opacity)) {
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
}
|
||||
nsIFrame* activeScrolledRoot =
|
||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nullptr);
|
||||
return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot)
|
||||
@ -3046,13 +2672,12 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
|
||||
|
||||
/* Returns the delta specified by the -moz-transform-origin property.
|
||||
* This is a positive delta, meaning that it indicates the direction to move
|
||||
* to get from (0, 0) of the frame to the transform origin. This function is
|
||||
* called off the main thread.
|
||||
* to get from (0, 0) of the frame to the transform origin.
|
||||
*/
|
||||
/* static */ gfxPoint3D
|
||||
nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel,
|
||||
const nsRect* aBoundsOverride)
|
||||
static
|
||||
gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel,
|
||||
const nsRect* aBoundsOverride)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
||||
NS_PRECONDITION(aFrame->IsTransformed(),
|
||||
@ -3067,7 +2692,8 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
||||
|
||||
/* Allows us to access named variables by index. */
|
||||
float coords[3];
|
||||
gfxPoint3D result;
|
||||
gfxFloat* coords[3] = {&result.x, &result.y, &result.z};
|
||||
const nscoord* dimensions[2] =
|
||||
{&boundingRect.width, &boundingRect.height};
|
||||
|
||||
@ -3078,17 +2704,17 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||
const nsStyleCoord &coord = display->mTransformOrigin[index];
|
||||
if (coord.GetUnit() == eStyleUnit_Calc) {
|
||||
const nsStyleCoord::Calc *calc = coord.GetCalcValue();
|
||||
coords[index] =
|
||||
*coords[index] =
|
||||
NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) *
|
||||
calc->mPercent +
|
||||
NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerPixel);
|
||||
} else if (coord.GetUnit() == eStyleUnit_Percent) {
|
||||
coords[index] =
|
||||
*coords[index] =
|
||||
NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) *
|
||||
coord.GetPercentValue();
|
||||
} else {
|
||||
NS_ABORT_IF_FALSE(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
|
||||
coords[index] =
|
||||
*coords[index] =
|
||||
NSAppUnitsToFloatPixels(coord.GetCoordValue(), aAppUnitsPerPixel);
|
||||
}
|
||||
if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) &&
|
||||
@ -3097,27 +2723,26 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||
// user space, not the top left of its bounds, so we must adjust for that:
|
||||
nscoord offset =
|
||||
(index == 0) ? aFrame->GetPosition().x : aFrame->GetPosition().y;
|
||||
coords[index] -= NSAppUnitsToFloatPixels(offset, aAppUnitsPerPixel);
|
||||
*coords[index] -= NSAppUnitsToFloatPixels(offset, aAppUnitsPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
|
||||
aAppUnitsPerPixel);
|
||||
*coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
|
||||
aAppUnitsPerPixel);
|
||||
/* Adjust based on the origin of the rectangle. */
|
||||
coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
|
||||
coords[1] += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel);
|
||||
result.x += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
|
||||
result.y += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel);
|
||||
|
||||
return gfxPoint3D(coords[0], coords[1], coords[2]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns the delta specified by the -moz-perspective-origin property.
|
||||
* This is a positive delta, meaning that it indicates the direction to move
|
||||
* to get from (0, 0) of the frame to the perspective origin. This function is
|
||||
* called off the main thread.
|
||||
* to get from (0, 0) of the frame to the perspective origin.
|
||||
*/
|
||||
/* static */ gfxPoint3D
|
||||
nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel)
|
||||
static
|
||||
gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
||||
NS_PRECONDITION(aFrame->IsTransformed(),
|
||||
@ -3180,22 +2805,12 @@ nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||
*/
|
||||
gfx3DMatrix
|
||||
nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
const nsPoint& aOrigin,
|
||||
const nsPoint &aOrigin,
|
||||
float aAppUnitsPerPixel,
|
||||
const nsRect* aBoundsOverride,
|
||||
const nsCSSValueList* aTransformOverride,
|
||||
gfxPoint3D* aToMozOrigin,
|
||||
gfxPoint3D* aToPerspectiveOrigin,
|
||||
nscoord* aChildPerspective,
|
||||
nsIFrame** aOutAncestor)
|
||||
{
|
||||
NS_PRECONDITION(aFrame || (aToMozOrigin && aBoundsOverride && aToPerspectiveOrigin &&
|
||||
aTransformOverride && aChildPerspective),
|
||||
"Should have frame or necessary infromation to construct matrix");
|
||||
|
||||
NS_PRECONDITION(!(aFrame && (aToMozOrigin || aToPerspectiveOrigin ||
|
||||
aTransformOverride || aChildPerspective)),
|
||||
"Should not have both frame and necessary infromation to construct matrix");
|
||||
NS_PRECONDITION(aFrame, "Cannot get transform matrix for a null frame!");
|
||||
|
||||
if (aOutAncestor) {
|
||||
*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||
@ -3205,7 +2820,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
* coordinate space to the new origin.
|
||||
*/
|
||||
gfxPoint3D toMozOrigin =
|
||||
aFrame ? GetDeltaToMozTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride) : *aToMozOrigin;
|
||||
GetDeltaToMozTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride);
|
||||
gfxPoint3D newOrigin =
|
||||
gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
|
||||
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
|
||||
@ -3214,7 +2829,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
/* Get the underlying transform matrix. This requires us to get the
|
||||
* bounds of the frame.
|
||||
*/
|
||||
const nsStyleDisplay* disp = aFrame ? aFrame->GetStyleDisplay() : nullptr;
|
||||
const nsStyleDisplay* disp = aFrame->GetStyleDisplay();
|
||||
nsRect bounds = (aBoundsOverride ? *aBoundsOverride :
|
||||
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
||||
|
||||
@ -3225,12 +2840,9 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
// disp->mSpecifiedTransform, since we still need any transformFromSVGParent.
|
||||
gfxMatrix svgTransform, transformFromSVGParent;
|
||||
bool hasSVGTransforms =
|
||||
aFrame && aFrame->IsSVGTransformed(&svgTransform, &transformFromSVGParent);
|
||||
aFrame->IsSVGTransformed(&svgTransform, &transformFromSVGParent);
|
||||
/* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */
|
||||
if (aTransformOverride) {
|
||||
result = nsStyleTransformMatrix::ReadTransforms(aTransformOverride, nullptr, nullptr,
|
||||
dummy, bounds, aAppUnitsPerPixel);
|
||||
} else if (disp->mSpecifiedTransform) {
|
||||
if (disp->mSpecifiedTransform) {
|
||||
result = nsStyleTransformMatrix::ReadTransforms(disp->mSpecifiedTransform,
|
||||
aFrame->GetStyleContext(),
|
||||
aFrame->PresContext(),
|
||||
@ -3242,6 +2854,10 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
svgTransform.x0 *= pixelsPerCSSPx;
|
||||
svgTransform.y0 *= pixelsPerCSSPx;
|
||||
result = gfx3DMatrix::From2D(svgTransform);
|
||||
} else {
|
||||
NS_ASSERTION(aFrame->GetStyleDisplay()->mTransformStyle == NS_STYLE_TRANSFORM_STYLE_PRESERVE_3D ||
|
||||
aFrame->GetStyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN,
|
||||
"If we don't have a transform, then we must have another reason to have an nsDisplayTransform created");
|
||||
}
|
||||
|
||||
if (hasSVGTransforms && !transformFromSVGParent.IsIdentity()) {
|
||||
@ -3254,40 +2870,32 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
const nsStyleDisplay* parentDisp = nullptr;
|
||||
nsStyleContext* parentStyleContext = aFrame ? aFrame->GetStyleContext()->GetParent(): nullptr;
|
||||
nsStyleContext* parentStyleContext = aFrame->GetStyleContext()->GetParent();
|
||||
if (parentStyleContext) {
|
||||
parentDisp = parentStyleContext->GetStyleDisplay();
|
||||
}
|
||||
nscoord perspectiveCoord = 0;
|
||||
if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
|
||||
perspectiveCoord = parentDisp->mChildPerspective.GetCoordValue();
|
||||
}
|
||||
if (aChildPerspective) {
|
||||
perspectiveCoord = *aChildPerspective;
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::Are3DTransformsEnabled() && perspectiveCoord > 0.0) {
|
||||
if (nsLayoutUtils::Are3DTransformsEnabled() &&
|
||||
parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord &&
|
||||
parentDisp->mChildPerspective.GetCoordValue() > 0.0) {
|
||||
gfx3DMatrix perspective;
|
||||
perspective._34 =
|
||||
-1.0 / NSAppUnitsToFloatPixels(perspectiveCoord, aAppUnitsPerPixel);
|
||||
-1.0 / NSAppUnitsToFloatPixels(parentDisp->mChildPerspective.GetCoordValue(),
|
||||
aAppUnitsPerPixel);
|
||||
/* At the point when perspective is applied, we have been translated to the transform origin.
|
||||
* The translation to the perspective origin is the difference between these values.
|
||||
*/
|
||||
gfxPoint3D toPerspectiveOrigin = aFrame ? GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel) : *aToPerspectiveOrigin;
|
||||
gfxPoint3D toPerspectiveOrigin = GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel);
|
||||
result = result * nsLayoutUtils::ChangeMatrixBasis(toPerspectiveOrigin - toMozOrigin, perspective);
|
||||
}
|
||||
|
||||
if (aFrame && aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) {
|
||||
if (aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) {
|
||||
// Include the transform set on our parent
|
||||
NS_ASSERTION(aFrame->GetParent() &&
|
||||
aFrame->GetParent()->IsTransformed() &&
|
||||
aFrame->GetParent()->Preserves3DChildren(),
|
||||
"Preserve3D mismatch!");
|
||||
gfx3DMatrix parent =
|
||||
GetResultingTransformMatrix(aFrame->GetParent(),
|
||||
aOrigin - aFrame->GetPosition(),
|
||||
aAppUnitsPerPixel, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr, aOutAncestor);
|
||||
gfx3DMatrix parent = GetResultingTransformMatrix(aFrame->GetParent(), aOrigin - aFrame->GetPosition(),
|
||||
aAppUnitsPerPixel, nullptr, aOutAncestor);
|
||||
return nsLayoutUtils::ChangeMatrixBasis(newOrigin + toMozOrigin, result) * parent;
|
||||
}
|
||||
|
||||
@ -3336,7 +2944,8 @@ nsDisplayTransform::GetTransform(float aAppUnitsPerPixel)
|
||||
if (mTransform.IsIdentity() || mCachedAppUnitsPerPixel != aAppUnitsPerPixel) {
|
||||
mTransform =
|
||||
GetResultingTransformMatrix(mFrame, ToReferenceFrame(),
|
||||
aAppUnitsPerPixel);
|
||||
aAppUnitsPerPixel,
|
||||
nullptr);
|
||||
mCachedAppUnitsPerPixel = aAppUnitsPerPixel;
|
||||
}
|
||||
return mTransform;
|
||||
@ -3362,8 +2971,6 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
||||
if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) {
|
||||
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D);
|
||||
}
|
||||
|
||||
AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_transform);
|
||||
return container.forget();
|
||||
}
|
||||
|
||||
@ -3378,12 +2985,6 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
return LAYER_ACTIVE;
|
||||
if (!GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel()).Is2D() || mFrame->Preserves3D())
|
||||
return LAYER_ACTIVE;
|
||||
if (mFrame->GetContent()) {
|
||||
if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(),
|
||||
eCSSProperty_transform)) {
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
}
|
||||
nsIFrame* activeScrolledRoot =
|
||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nullptr);
|
||||
return !mStoredList.ChildrenCanBeInactive(aBuilder,
|
||||
@ -3698,7 +3299,7 @@ bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
|
||||
* empty rect.
|
||||
*/
|
||||
float factor = nsPresContext::AppUnitsPerCSSPixel();
|
||||
gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor);
|
||||
gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor, nullptr);
|
||||
|
||||
return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect);
|
||||
}
|
||||
|
@ -108,10 +108,10 @@ public:
|
||||
* display lists that we make.
|
||||
*/
|
||||
enum Mode {
|
||||
PAINTING,
|
||||
EVENT_DELIVERY,
|
||||
PLUGIN_GEOMETRY,
|
||||
OTHER
|
||||
PAINTING,
|
||||
EVENT_DELIVERY,
|
||||
PLUGIN_GEOMETRY,
|
||||
OTHER
|
||||
};
|
||||
nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
|
||||
~nsDisplayListBuilder();
|
||||
@ -2353,13 +2353,6 @@ public:
|
||||
float aAppUnitsPerPixel,
|
||||
nsRect* aOutRect);
|
||||
|
||||
static gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel,
|
||||
const nsRect* aBoundsOverride);
|
||||
|
||||
static gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel);
|
||||
|
||||
/**
|
||||
* Returns the bounds of a frame as defined for resolving percentage
|
||||
* <translation-value>s in CSS transforms. If
|
||||
@ -2393,10 +2386,6 @@ public:
|
||||
const nsPoint& aOrigin,
|
||||
float aAppUnitsPerPixel,
|
||||
const nsRect* aBoundsOverride = nullptr,
|
||||
const nsCSSValueList* aTransformOverride = nullptr,
|
||||
gfxPoint3D* aToMozOrigin = nullptr,
|
||||
gfxPoint3D* aToPerspectiveOrigin = nullptr,
|
||||
nscoord* aChildPerspective = nullptr,
|
||||
nsIFrame** aOutAncestor = nullptr);
|
||||
/**
|
||||
* Return true when we should try to prerender the entire contents of the
|
||||
|
@ -4,7 +4,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "nsLayoutUtils.h"
|
||||
@ -71,7 +70,7 @@
|
||||
#include "nsTextFrame.h"
|
||||
#include "nsFontFaceList.h"
|
||||
#include "nsFontInflationData.h"
|
||||
#include "CompositorParent.h"
|
||||
|
||||
#include "nsSVGUtils.h"
|
||||
#include "nsSVGIntegrationUtils.h"
|
||||
#include "nsSVGForeignObjectFrame.h"
|
||||
@ -84,8 +83,6 @@
|
||||
#endif
|
||||
|
||||
#include "sampler.h"
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsTransitionManager.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::layers;
|
||||
@ -116,32 +113,6 @@ static ContentMap& GetContentMap() {
|
||||
return *sContentMap;
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::HasAnimationsForCompositor(nsIContent* aContent,
|
||||
nsCSSProperty aProperty)
|
||||
{
|
||||
if (!aContent->MayHaveAnimations())
|
||||
return false;
|
||||
ElementAnimations* animations =
|
||||
static_cast<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()
|
||||
@ -158,36 +129,6 @@ nsLayoutUtils::Are3DTransformsEnabled()
|
||||
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()
|
||||
{
|
||||
|
@ -1497,24 +1497,11 @@ public:
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
bool clear);
|
||||
|
||||
/**
|
||||
* Returns true if the content node has animations or transitions that can be
|
||||
* performed on the compositor.
|
||||
*/
|
||||
static bool HasAnimationsForCompositor(nsIContent* aContent,
|
||||
nsCSSProperty aProperty);
|
||||
|
||||
/**
|
||||
* Checks if CSS 3D transforms are currently enabled.
|
||||
*/
|
||||
static bool Are3DTransformsEnabled();
|
||||
|
||||
/**
|
||||
* Checks if off-main-thread transform and opacity animations are enabled.
|
||||
*/
|
||||
static bool AreOpacityAnimationsEnabled();
|
||||
static bool AreTransformAnimationsEnabled();
|
||||
|
||||
/**
|
||||
* Checks if we should forcibly use nearest pixel filtering for the
|
||||
* background.
|
||||
|
@ -92,8 +92,6 @@
|
||||
#include "CSSCalc.h"
|
||||
#include "nsAbsoluteContainingBlock.h"
|
||||
#include "nsFontInflationData.h"
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsTransitionManager.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
@ -937,20 +935,9 @@ nsIFrame::GetPaddingRect() const
|
||||
bool
|
||||
nsIFrame::IsTransformed() const
|
||||
{
|
||||
return ((mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
|
||||
return (mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
|
||||
(GetStyleDisplay()->HasTransform() ||
|
||||
IsSVGTransformed() ||
|
||||
(mContent &&
|
||||
nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
||||
eCSSProperty_transform))));
|
||||
}
|
||||
|
||||
bool
|
||||
nsIFrame::HasOpacity() const
|
||||
{
|
||||
return GetStyleDisplay()->mOpacity < 1.0f || (mContent &&
|
||||
nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
||||
eCSSProperty_opacity));
|
||||
IsSVGTransformed());
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1777,12 +1764,9 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
nsRect clipPropClip;
|
||||
const nsStyleDisplay* disp = GetStyleDisplay();
|
||||
// We can stop right away if this is a zero-opacity stacking context and
|
||||
// we're painting, and we're not animating opacity.
|
||||
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() &&
|
||||
!nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
||||
eCSSProperty_opacity)) {
|
||||
// we're painting.
|
||||
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting())
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool applyClipPropClipping =
|
||||
ApplyClipPropClipping(aBuilder, disp, this, &clipPropClip);
|
||||
@ -1927,6 +1911,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
// resultList was emptied
|
||||
resultList.AppendToTop(item);
|
||||
}
|
||||
|
||||
/* If there are any SVG effects, wrap the list up in an SVG effects item
|
||||
* (which also handles CSS group opacity). Note that we create an SVG effects
|
||||
* item even if resultList is empty, since a filter can produce graphical
|
||||
@ -1942,7 +1927,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
||||
/* Else, if the list is non-empty and there is CSS group opacity without SVG
|
||||
* effects, wrap it up in an opacity item.
|
||||
*/
|
||||
else if (HasOpacity() &&
|
||||
else if (disp->mOpacity < 1.0f &&
|
||||
!nsSVGUtils::CanOptimizeOpacity(this) &&
|
||||
!resultList.IsEmpty()) {
|
||||
rv = resultList.AppendNewToTop(
|
||||
@ -2096,7 +2081,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
||||
// Child is composited if it's transformed, partially transparent, or has
|
||||
// SVG effects.
|
||||
const nsStyleDisplay* disp = child->GetStyleDisplay();
|
||||
bool isVisuallyAtomic = child->HasOpacity()
|
||||
bool isVisuallyAtomic = disp->mOpacity != 1.0f
|
||||
|| child->IsTransformed()
|
||||
|| nsSVGIntegrationUtils::UsingEffectsForFrame(child);
|
||||
|
||||
@ -4764,8 +4749,8 @@ nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
||||
PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
gfx3DMatrix result =
|
||||
nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0), scaleFactor, nullptr,
|
||||
nullptr, nullptr, nullptr, nullptr, aOutAncestor);
|
||||
nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0),
|
||||
scaleFactor, nullptr, aOutAncestor);
|
||||
// XXXjwatt: seems like this will double count offsets in the face of preserve-3d:
|
||||
nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor);
|
||||
/* Combine the raw transform with a translation to our parent. */
|
||||
|
@ -278,7 +278,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
gfxMatrix transform;
|
||||
transform.Translate(r.TopLeft());
|
||||
transform.Scale(r.Width()/canvasSize.width, r.Height()/canvasSize.height);
|
||||
layer->SetBaseTransform(gfx3DMatrix::From2D(transform));
|
||||
layer->SetTransform(gfx3DMatrix::From2D(transform));
|
||||
layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
|
||||
layer->SetVisibleRegion(nsIntRect(0, 0, canvasSize.width, canvasSize.height));
|
||||
|
||||
|
@ -1228,8 +1228,6 @@ public:
|
||||
*/
|
||||
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
|
||||
|
@ -1289,7 +1289,7 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer)
|
||||
transform.Translate(destRect.TopLeft());
|
||||
transform.Scale(destRect.Width()/imageWidth,
|
||||
destRect.Height()/imageHeight);
|
||||
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
|
||||
aLayer->SetTransform(gfx3DMatrix::From2D(transform));
|
||||
|
||||
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
|
||||
}
|
||||
|
@ -1723,7 +1723,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
gfxMatrix transform;
|
||||
transform.Translate(r.TopLeft());
|
||||
|
||||
layer->SetBaseTransform(gfx3DMatrix::From2D(transform));
|
||||
layer->SetTransform(gfx3DMatrix::From2D(transform));
|
||||
layer->SetVisibleRegion(nsIntRect(0, 0, size.width, size.height));
|
||||
return layer.forget();
|
||||
}
|
||||
|
@ -206,7 +206,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
gfxMatrix transform;
|
||||
transform.Translate(r.TopLeft());
|
||||
transform.Scale(r.Width()/frameSize.width, r.Height()/frameSize.height);
|
||||
layer->SetBaseTransform(gfx3DMatrix::From2D(transform));
|
||||
layer->SetTransform(gfx3DMatrix::From2D(transform));
|
||||
layer->SetVisibleRegion(nsIntRect(0, 0, frameSize.width, frameSize.height));
|
||||
nsRefPtr<Layer> result = layer.forget();
|
||||
return result.forget();
|
||||
|
@ -246,11 +246,10 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
|
||||
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
||||
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
||||
shadow->SetShadowOpacity(aLayer->GetOpacity());
|
||||
|
||||
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
|
||||
|
||||
gfx3DMatrix shadowTransform = aLayer->GetBaseTransform();
|
||||
gfx3DMatrix shadowTransform = aLayer->GetTransform();
|
||||
ViewTransform layerTransform = aTransform;
|
||||
|
||||
if (metrics && metrics->IsScrollable()) {
|
||||
@ -605,7 +604,7 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||
layer->SetReferentId(id);
|
||||
layer->SetVisibleRegion(aVisibleRect);
|
||||
nsIntPoint rootFrameOffset = GetRootFrameOffset(aFrame, aBuilder);
|
||||
layer->SetBaseTransform(
|
||||
layer->SetTransform(
|
||||
gfx3DMatrix::Translation(rootFrameOffset.x, rootFrameOffset.y, 0.0));
|
||||
|
||||
return layer.forget();
|
||||
|
@ -7,9 +7,6 @@
|
||||
#include "nsRuleData.h"
|
||||
#include "nsCSSValue.h"
|
||||
#include "nsStyleContext.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
@ -216,26 +213,5 @@ ComputedTimingFunction::GetValue(double aPortion) const
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CommonElementAnimationData::CanAnimatePropertyOnCompositor(const dom::Element *aElement,
|
||||
nsCSSProperty aProperty)
|
||||
{
|
||||
nsIFrame* frame = aElement->GetPrimaryFrame();
|
||||
if (aProperty == eCSSProperty_opacity) {
|
||||
return nsLayoutUtils::AreOpacityAnimationsEnabled();
|
||||
}
|
||||
if (aProperty == eCSSProperty_transform && !(frame &&
|
||||
frame->Preserves3D() &&
|
||||
frame->Preserves3DChildren())) {
|
||||
if (frame && frame->IsSVGTransformed()) {
|
||||
return false;
|
||||
}
|
||||
return nsLayoutUtils::AreTransformAnimationsEnabled();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -107,12 +107,6 @@ public:
|
||||
typedef nsTimingFunction::Type Type;
|
||||
void Init(const nsTimingFunction &aFunction);
|
||||
double GetValue(double aPortion) const;
|
||||
const nsSMILKeySpline* GetFunction() const {
|
||||
NS_ASSERTION(mType == nsTimingFunction::Function, "Type mismatch");
|
||||
return &mTimingFunction;
|
||||
}
|
||||
Type GetType() const { return mType; }
|
||||
PRUint32 GetSteps() const { return mSteps; }
|
||||
private:
|
||||
Type mType;
|
||||
nsSMILKeySpline mTimingFunction;
|
||||
@ -148,10 +142,6 @@ struct CommonElementAnimationData : public PRCList
|
||||
mElement->DeleteProperty(mElementProperty);
|
||||
}
|
||||
|
||||
static bool
|
||||
CanAnimatePropertyOnCompositor(const dom::Element *aElement,
|
||||
nsCSSProperty aProperty);
|
||||
|
||||
dom::Element *mElement;
|
||||
|
||||
// the atom we use in mElement's prop table (must be a static atom,
|
||||
|
@ -22,8 +22,6 @@ LIBXUL_LIBRARY = 1
|
||||
EXPORTS_NAMESPACES = mozilla/css
|
||||
|
||||
EXPORTS = \
|
||||
AnimationCommon.h \
|
||||
nsAnimationManager.h \
|
||||
nsCSSAnonBoxList.h \
|
||||
nsCSSAnonBoxes.h \
|
||||
nsCSSFontDescList.h \
|
||||
@ -57,7 +55,6 @@ EXPORTS = \
|
||||
nsRuleNode.h \
|
||||
nsRuleProcessorData.h \
|
||||
nsRuleWalker.h \
|
||||
nsStyleAnimation.h \
|
||||
nsStyleContext.h \
|
||||
nsStyleCoord.h \
|
||||
nsStyleSet.h \
|
||||
@ -127,9 +124,7 @@ FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
||||
|
||||
LOCAL_INCLUDES += \
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../base \
|
||||
-I$(srcdir)/../generic \
|
||||
-I$(srcdir)/../xul/base/src \
|
||||
|
@ -11,18 +11,113 @@
|
||||
#include "nsStyleAnimation.h"
|
||||
#include "nsSMILKeySpline.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsDisplayList.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
||||
nsAnimationManager *aAnimationManager)
|
||||
: CommonElementAnimationData(aElement, aElementProperty,
|
||||
aAnimationManager),
|
||||
mNeedsRefreshes(true)
|
||||
struct AnimationPropertySegment
|
||||
{
|
||||
}
|
||||
float mFromKey, mToKey;
|
||||
nsStyleAnimation::Value mFromValue, mToValue;
|
||||
css::ComputedTimingFunction mTimingFunction;
|
||||
};
|
||||
|
||||
struct AnimationProperty
|
||||
{
|
||||
nsCSSProperty mProperty;
|
||||
InfallibleTArray<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,
|
||||
@ -38,114 +133,6 @@ ElementAnimationsPropertyDtor(void *aObject,
|
||||
delete ea;
|
||||
}
|
||||
|
||||
double
|
||||
ElementAnimations::GetPositionInIteration(TimeStamp aStartTime, TimeStamp aCurrentTime,
|
||||
TimeDuration aDuration, double aIterationCount,
|
||||
PRUint32 aDirection, bool aIsForElement,
|
||||
ElementAnimation* aAnimation,
|
||||
ElementAnimations* aEa,
|
||||
EventArray* aEventsToDispatch)
|
||||
{
|
||||
// Set |currentIterationCount| to the (fractional) number of
|
||||
// iterations we've completed up to the current position.
|
||||
TimeDuration currentTimeDuration = aCurrentTime - aStartTime;
|
||||
double currentIterationCount =
|
||||
currentTimeDuration / aDuration;
|
||||
bool dispatchStartOrIteration = false;
|
||||
if (currentIterationCount >= aIterationCount) {
|
||||
if (!aAnimation) {
|
||||
// We are on the compositor, so send a signal that the animation is over.
|
||||
// The main thread will fire the animationend event.
|
||||
return -1;
|
||||
}
|
||||
// Dispatch 'animationend' when needed.
|
||||
if (aIsForElement &&
|
||||
aAnimation->mLastNotification !=
|
||||
ElementAnimation::LAST_NOTIFICATION_END) {
|
||||
aAnimation->mLastNotification = ElementAnimation::LAST_NOTIFICATION_END;
|
||||
// XXXdz: if this animation was done on the compositor, we should
|
||||
// invalidate the frame and update style once we start throttling style
|
||||
// updates.
|
||||
AnimationEventInfo ei(aEa->mElement, aAnimation->mName, NS_ANIMATION_END,
|
||||
currentTimeDuration);
|
||||
aEventsToDispatch->AppendElement(ei);
|
||||
}
|
||||
|
||||
if (!aAnimation->FillsForwards()) {
|
||||
// No animation data.
|
||||
return -1;
|
||||
}
|
||||
currentIterationCount = double(aAnimation->mIterationCount);
|
||||
} else {
|
||||
if (aAnimation && !aAnimation->IsPaused()) {
|
||||
aEa->mNeedsRefreshes = true;
|
||||
}
|
||||
if (currentIterationCount < 0.0) {
|
||||
NS_ASSERTION(aAnimation, "Should not run animation that hasn't started yet on the compositor");
|
||||
if (!aAnimation->FillsBackwards()) {
|
||||
// No animation data.
|
||||
return -1;
|
||||
}
|
||||
currentIterationCount = 0.0;
|
||||
} else {
|
||||
dispatchStartOrIteration = aAnimation && !aAnimation->IsPaused();
|
||||
}
|
||||
}
|
||||
|
||||
// Set |positionInIteration| to the position from 0% to 100% along
|
||||
// the keyframes.
|
||||
NS_ABORT_IF_FALSE(currentIterationCount >= 0.0, "must be positive");
|
||||
PRUint32 whichIteration = int(currentIterationCount);
|
||||
if (whichIteration == aIterationCount && whichIteration != 0) {
|
||||
// When the animation's iteration count is an integer (as it
|
||||
// normally is), we need to end at 100% of its last iteration
|
||||
// rather than 0% of the next one (unless it's zero).
|
||||
--whichIteration;
|
||||
}
|
||||
double positionInIteration =
|
||||
currentIterationCount - double(whichIteration);
|
||||
|
||||
bool thisIterationReverse = false;
|
||||
switch (aDirection) {
|
||||
case NS_STYLE_ANIMATION_DIRECTION_NORMAL:
|
||||
thisIterationReverse = false;
|
||||
break;
|
||||
case NS_STYLE_ANIMATION_DIRECTION_REVERSE:
|
||||
thisIterationReverse = true;
|
||||
break;
|
||||
case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE:
|
||||
thisIterationReverse = (whichIteration & 1) == 1;
|
||||
break;
|
||||
case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE:
|
||||
thisIterationReverse = (whichIteration & 1) == 0;
|
||||
break;
|
||||
}
|
||||
if (thisIterationReverse) {
|
||||
positionInIteration = 1.0 - positionInIteration;
|
||||
}
|
||||
|
||||
// Dispatch 'animationstart' or 'animationiteration' when needed.
|
||||
if (aAnimation && aIsForElement && dispatchStartOrIteration &&
|
||||
whichIteration != aAnimation->mLastNotification) {
|
||||
// Notify 'animationstart' even if a negative delay puts us
|
||||
// past the first iteration.
|
||||
// Note that when somebody changes the animation-duration
|
||||
// dynamically, this will fire an extra iteration event
|
||||
// immediately in many cases. It's not clear to me if that's the
|
||||
// right thing to do.
|
||||
PRUint32 message =
|
||||
aAnimation->mLastNotification == ElementAnimation::LAST_NOTIFICATION_NONE
|
||||
? NS_ANIMATION_START : NS_ANIMATION_ITERATION;
|
||||
// XXXdz: If this is a start, invalidate the frame here once we throttle animations.
|
||||
aAnimation->mLastNotification = whichIteration;
|
||||
AnimationEventInfo ei(aEa->mElement, aAnimation->mName, message,
|
||||
currentTimeDuration);
|
||||
aEventsToDispatch->AppendElement(ei);
|
||||
}
|
||||
|
||||
return positionInIteration;
|
||||
}
|
||||
|
||||
void
|
||||
ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||
EventArray& aEventsToDispatch)
|
||||
@ -178,24 +165,98 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||
continue;
|
||||
}
|
||||
|
||||
TimeStamp currentTime;
|
||||
TimeDuration currentTimeDuration;
|
||||
if (anim.IsPaused()) {
|
||||
// FIXME: avoid recalculating every time
|
||||
currentTime = anim.mPauseStart;
|
||||
currentTimeDuration = anim.mPauseStart - anim.mStartTime;
|
||||
} else {
|
||||
currentTime = aRefreshTime;
|
||||
currentTimeDuration = aRefreshTime - anim.mStartTime;
|
||||
}
|
||||
|
||||
double positionInIteration =
|
||||
GetPositionInIteration(anim.mStartTime, currentTime,
|
||||
anim.mIterationDuration, anim.mIterationCount,
|
||||
anim.mDirection, IsForElement(),
|
||||
&anim, this, &aEventsToDispatch);
|
||||
// Set |currentIterationCount| to the (fractional) number of
|
||||
// iterations we've completed up to the current position.
|
||||
double currentIterationCount =
|
||||
currentTimeDuration / anim.mIterationDuration;
|
||||
bool dispatchStartOrIteration = false;
|
||||
if (currentIterationCount >= double(anim.mIterationCount)) {
|
||||
// Dispatch 'animationend' when needed.
|
||||
if (IsForElement() &&
|
||||
anim.mLastNotification !=
|
||||
ElementAnimation::LAST_NOTIFICATION_END) {
|
||||
anim.mLastNotification = ElementAnimation::LAST_NOTIFICATION_END;
|
||||
AnimationEventInfo ei(mElement, anim.mName, NS_ANIMATION_END,
|
||||
currentTimeDuration);
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
|
||||
// The position is -1 when we don't have fill data for the current time,
|
||||
// so we shouldn't animate.
|
||||
if (positionInIteration == -1)
|
||||
continue;
|
||||
if (!anim.FillsForwards()) {
|
||||
// No animation data.
|
||||
continue;
|
||||
}
|
||||
currentIterationCount = double(anim.mIterationCount);
|
||||
} else {
|
||||
if (!anim.IsPaused()) {
|
||||
mNeedsRefreshes = true;
|
||||
}
|
||||
if (currentIterationCount < 0.0) {
|
||||
if (!anim.FillsBackwards()) {
|
||||
// No animation data.
|
||||
continue;
|
||||
}
|
||||
currentIterationCount = 0.0;
|
||||
} else {
|
||||
dispatchStartOrIteration = !anim.IsPaused();
|
||||
}
|
||||
}
|
||||
|
||||
// Set |positionInIteration| to the position from 0% to 100% along
|
||||
// the keyframes.
|
||||
NS_ABORT_IF_FALSE(currentIterationCount >= 0.0, "must be positive");
|
||||
PRUint32 whichIteration = int(currentIterationCount);
|
||||
if (whichIteration == anim.mIterationCount && whichIteration != 0) {
|
||||
// When the animation's iteration count is an integer (as it
|
||||
// normally is), we need to end at 100% of its last iteration
|
||||
// rather than 0% of the next one (unless it's zero).
|
||||
--whichIteration;
|
||||
}
|
||||
double positionInIteration =
|
||||
currentIterationCount - double(whichIteration);
|
||||
bool thisIterationReverse = false;
|
||||
switch (anim.mDirection) {
|
||||
case NS_STYLE_ANIMATION_DIRECTION_NORMAL:
|
||||
thisIterationReverse = false;
|
||||
break;
|
||||
case NS_STYLE_ANIMATION_DIRECTION_REVERSE:
|
||||
thisIterationReverse = true;
|
||||
break;
|
||||
case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE:
|
||||
thisIterationReverse = (whichIteration & 1) == 1;
|
||||
break;
|
||||
case NS_STYLE_ANIMATION_DIRECTION_ALTERNATE_REVERSE:
|
||||
thisIterationReverse = (whichIteration & 1) == 0;
|
||||
break;
|
||||
}
|
||||
if (thisIterationReverse) {
|
||||
positionInIteration = 1.0 - positionInIteration;
|
||||
}
|
||||
|
||||
// Dispatch 'animationstart' or 'animationiteration' when needed.
|
||||
if (IsForElement() && dispatchStartOrIteration &&
|
||||
whichIteration != anim.mLastNotification) {
|
||||
// Notify 'animationstart' even if a negative delay puts us
|
||||
// past the first iteration.
|
||||
// Note that when somebody changes the animation-duration
|
||||
// dynamically, this will fire an extra iteration event
|
||||
// immediately in many cases. It's not clear to me if that's the
|
||||
// right thing to do.
|
||||
PRUint32 message =
|
||||
anim.mLastNotification == ElementAnimation::LAST_NOTIFICATION_NONE
|
||||
? NS_ANIMATION_START : NS_ANIMATION_ITERATION;
|
||||
anim.mLastNotification = whichIteration;
|
||||
AnimationEventInfo ei(mElement, anim.mName, message,
|
||||
currentTimeDuration);
|
||||
aEventsToDispatch.AppendElement(ei);
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(0.0 <= positionInIteration &&
|
||||
positionInIteration <= 1.0,
|
||||
@ -262,66 +323,6 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
CanPerformAnimationOnCompositor(const ElementAnimation* aAnim,
|
||||
mozilla::dom::Element* aElement)
|
||||
{
|
||||
for (PRUint32 propIdx = 0, propEnd = aAnim->mProperties.Length();
|
||||
propIdx != propEnd; ++propIdx) {
|
||||
const AnimationProperty &prop = aAnim->mProperties[propIdx];
|
||||
if (!mozilla::css::CommonElementAnimationData::
|
||||
CanAnimatePropertyOnCompositor(aElement,
|
||||
prop.mProperty)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ElementAnimation::CanPerformOnCompositor(mozilla::dom::Element* aElement,
|
||||
TimeStamp aTime) const
|
||||
{
|
||||
return CanPerformAnimationOnCompositor(this, aElement) &&
|
||||
!IsPaused() && aTime > mStartTime &&
|
||||
(aTime - mStartTime) / mIterationDuration < mIterationCount;
|
||||
}
|
||||
|
||||
bool
|
||||
ElementAnimations::HasAnimationOfProperty(nsCSSProperty aProperty) const
|
||||
{
|
||||
for (PRUint32 animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
const ElementAnimation &anim = mAnimations[animIdx];
|
||||
for (PRUint32 propIdx = 0, propEnd = anim.mProperties.Length();
|
||||
propIdx != propEnd; ++propIdx) {
|
||||
const AnimationProperty &prop = anim.mProperties[propIdx];
|
||||
if (aProperty == prop.mProperty) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ElementAnimations::CanPerformOnCompositorThread() const
|
||||
{
|
||||
if (mElementProperty != nsGkAtoms::animationsProperty)
|
||||
return false;
|
||||
for (PRUint32 animIdx = mAnimations.Length(); animIdx-- != 0; ) {
|
||||
const ElementAnimation &anim = mAnimations[animIdx];
|
||||
if (anim.mIterationDuration.ToMilliseconds() <= 0.0) {
|
||||
// No animation data
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!CanPerformAnimationOnCompositor(&anim, mElement))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ElementAnimations*
|
||||
nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
||||
nsCSSPseudoElements::Type aPseudoType,
|
||||
@ -350,6 +351,10 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
||||
if (!ea && aCreateIfNeeded) {
|
||||
// FIXME: Consider arena-allocating?
|
||||
ea = new ElementAnimations(aElement, propName, this);
|
||||
if (!ea) {
|
||||
NS_WARNING("out of memory");
|
||||
return nullptr;
|
||||
}
|
||||
nsresult rv = aElement->SetProperty(propName, ea,
|
||||
ElementAnimationsPropertyDtor, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -357,9 +362,6 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
||||
delete ea;
|
||||
return nullptr;
|
||||
}
|
||||
if (propName == nsGkAtoms::animationsProperty) {
|
||||
aElement->SetMayHaveAnimations();
|
||||
}
|
||||
|
||||
AddElementData(ea);
|
||||
}
|
||||
@ -461,8 +463,6 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
||||
TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
|
||||
|
||||
if (ea) {
|
||||
|
||||
// XXXdz: Invalidate the frame since the animation changed.
|
||||
// The cached style rule is invalid.
|
||||
ea->mStyleRule = nullptr;
|
||||
ea->mStyleRuleRefreshTime = TimeStamp();
|
||||
|
@ -11,10 +11,12 @@
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsCSSKeyframesRule;
|
||||
struct AnimationPropertySegment;
|
||||
struct ElementAnimation;
|
||||
struct ElementAnimations;
|
||||
|
||||
namespace mozilla {
|
||||
namespace css {
|
||||
@ -22,179 +24,37 @@ class Declaration;
|
||||
}
|
||||
}
|
||||
|
||||
struct AnimationEventInfo {
|
||||
nsRefPtr<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 = nullptr,
|
||||
ElementAnimations* aEa = nullptr,
|
||||
EventArray* aEventsToDispatch = nullptr);
|
||||
|
||||
void EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||
EventArray &aEventsToDispatch);
|
||||
|
||||
bool IsForElement() const { // rather than for a pseudo-element
|
||||
return mElementProperty == nsGkAtoms::animationsProperty;
|
||||
}
|
||||
|
||||
void PostRestyleForAnimation(nsPresContext *aPresContext) {
|
||||
nsRestyleHint styleHint = IsForElement() ? eRestyle_Self : eRestyle_Subtree;
|
||||
aPresContext->PresShell()->RestyleForAnimation(mElement, styleHint);
|
||||
}
|
||||
|
||||
// True if this animation can be performed on the compositor thread.
|
||||
bool CanPerformOnCompositorThread() const;
|
||||
bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
|
||||
// This style rule contains the style data for currently animating
|
||||
// values. It only matches when styling with animation. When we
|
||||
// style without animation, we need to not use it so that we can
|
||||
// detect any new changes; if necessary we restyle immediately
|
||||
// afterwards with animation.
|
||||
// NOTE: If we don't need to apply any styles, mStyleRule will be
|
||||
// null, but mStyleRuleRefreshTime will still be valid.
|
||||
nsRefPtr<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 nullptr;
|
||||
ElementAnimations* animations = static_cast<ElementAnimations*>(
|
||||
aContent->GetProperty(nsGkAtoms::animationsProperty));
|
||||
if (!animations)
|
||||
return nullptr;
|
||||
bool propertyMatches = animations->HasAnimationOfProperty(aProperty);
|
||||
return (propertyMatches && animations->CanPerformOnCompositorThread()) ?
|
||||
animations : nullptr;
|
||||
}
|
||||
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);
|
||||
@ -229,6 +89,8 @@ public:
|
||||
mKeyframesListIsDirty = true;
|
||||
}
|
||||
|
||||
typedef InfallibleTArray<AnimationEventInfo> EventArray;
|
||||
|
||||
/**
|
||||
* Dispatch any pending events. We accumulate animationend and
|
||||
* animationiteration events only during refresh driver notifications
|
||||
|
@ -1122,9 +1122,9 @@ AddTransformScale(const nsCSSValue &aValue1, double aCoeff1,
|
||||
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;
|
||||
@ -1457,7 +1457,7 @@ AddDifferentTransformLists(const nsCSSValueList* aList1, double aCoeff1,
|
||||
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
|
||||
@ -1503,7 +1503,7 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
|
||||
tfunc != eCSSKeyword_interpolatematrix &&
|
||||
tfunc != eCSSKeyword_rotate3d &&
|
||||
tfunc != eCSSKeyword_perspective) {
|
||||
arr = nsStyleAnimation::AppendTransformFunction(tfunc, resultTail);
|
||||
arr = AppendTransformFunction(tfunc, resultTail);
|
||||
}
|
||||
|
||||
switch (tfunc) {
|
||||
|
@ -15,10 +15,14 @@
|
||||
#include "nsCSSProperty.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsCSSValue.h"
|
||||
|
||||
class nsPresContext;
|
||||
class nsStyleContext;
|
||||
class nsCSSValue;
|
||||
struct nsCSSValueList;
|
||||
struct nsCSSValuePair;
|
||||
struct nsCSSValueTriplet;
|
||||
struct nsCSSValuePairList;
|
||||
struct nsCSSRect;
|
||||
class gfx3DMatrix;
|
||||
|
||||
@ -202,10 +206,6 @@ public:
|
||||
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.
|
||||
*/
|
||||
|
@ -39,13 +39,12 @@ static double FlushToZero(double aVal)
|
||||
return aVal;
|
||||
}
|
||||
|
||||
float
|
||||
static float
|
||||
ProcessTranslatePart(const nsCSSValue& aValue,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
bool& aCanStoreInRuleTree,
|
||||
nscoord aSize,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
nscoord aSize, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
nscoord offset = 0;
|
||||
float percent = 0.0f;
|
||||
|
@ -30,13 +30,6 @@ namespace nsStyleTransformMatrix {
|
||||
*/
|
||||
nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
|
||||
|
||||
float ProcessTranslatePart(const nsCSSValue& aValue,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
bool& aCanStoreInRuleTree,
|
||||
nscoord aSize,
|
||||
float aAppUnitsPerMatrixUnit);
|
||||
|
||||
/**
|
||||
* Given an nsCSSValueList containing -moz-transform functions,
|
||||
* returns a matrix containing the value of those functions.
|
||||
|
@ -22,8 +22,6 @@
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
|
||||
using mozilla::TimeStamp;
|
||||
using mozilla::TimeDuration;
|
||||
@ -31,12 +29,53 @@ using mozilla::TimeDuration;
|
||||
namespace dom = mozilla::dom;
|
||||
namespace css = mozilla::css;
|
||||
|
||||
ElementTransitions::ElementTransitions(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
||||
nsTransitionManager *aTransitionManager)
|
||||
: CommonElementAnimationData(aElement, aElementProperty,
|
||||
aTransitionManager)
|
||||
/*****************************************************************************
|
||||
* Per-Element data *
|
||||
*****************************************************************************/
|
||||
|
||||
struct ElementPropertyTransition
|
||||
{
|
||||
}
|
||||
nsCSSProperty mProperty;
|
||||
nsStyleAnimation::Value mStartValue, mEndValue;
|
||||
TimeStamp mStartTime; // actual start plus transition delay
|
||||
|
||||
// data from the relevant nsTransition
|
||||
TimeDuration mDuration;
|
||||
css::ComputedTimingFunction mTimingFunction;
|
||||
|
||||
// This is the start value to be used for a check for whether a
|
||||
// transition is being reversed. Normally the same as mStartValue,
|
||||
// except when this transition started as the reversal of another
|
||||
// in-progress transition. Needed so we can handle two reverses in a
|
||||
// row.
|
||||
nsStyleAnimation::Value mStartForReversingTest;
|
||||
// Likewise, the portion (in value space) of the "full" reversed
|
||||
// transition that we're actually covering. For example, if a :hover
|
||||
// effect has a transition that moves the element 10px to the right
|
||||
// (by changing 'left' from 0px to 10px), and the mouse moves in to
|
||||
// the element (starting the transition) but then moves out after the
|
||||
// transition has advanced 4px, the second transition (from 10px/4px
|
||||
// to 0px) will have mReversePortion of 0.4. (If the mouse then moves
|
||||
// in again when the transition is back to 2px, the mReversePortion
|
||||
// for the third transition (from 0px/2px to 10px) will be 0.8.
|
||||
double mReversePortion;
|
||||
|
||||
// Compute the portion of the *value* space that we should be through
|
||||
// at the given time. (The input to the transition timing function
|
||||
// has time units, the output has value units.)
|
||||
double ValuePortionFor(TimeStamp aRefreshTime) const;
|
||||
|
||||
bool IsRemovedSentinel() const
|
||||
{
|
||||
return mStartTime.IsNull();
|
||||
}
|
||||
|
||||
void SetRemovedSentinel()
|
||||
{
|
||||
// assign the null time stamp
|
||||
mStartTime = TimeStamp();
|
||||
}
|
||||
};
|
||||
|
||||
double
|
||||
ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const
|
||||
@ -66,6 +105,32 @@ ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const
|
||||
return mTimingFunction.GetValue(timePortion);
|
||||
}
|
||||
|
||||
struct ElementTransitions : public mozilla::css::CommonElementAnimationData
|
||||
{
|
||||
ElementTransitions(dom::Element *aElement, nsIAtom *aElementProperty,
|
||||
nsTransitionManager *aTransitionManager)
|
||||
: CommonElementAnimationData(aElement, aElementProperty,
|
||||
aTransitionManager)
|
||||
{
|
||||
}
|
||||
|
||||
void EnsureStyleRuleFor(TimeStamp aRefreshTime);
|
||||
|
||||
|
||||
// Either zero or one for each CSS property:
|
||||
nsTArray<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,
|
||||
@ -108,41 +173,6 @@ ElementTransitions::EnsureStyleRuleFor(TimeStamp aRefreshTime)
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ElementPropertyTransition::CanPerformOnCompositor(mozilla::dom::Element* aElement,
|
||||
TimeStamp aTime) const {
|
||||
return css::CommonElementAnimationData::
|
||||
CanAnimatePropertyOnCompositor(aElement, mProperty) && !IsRemovedSentinel() &&
|
||||
mStartTime < aTime && aTime < mStartTime + mDuration;
|
||||
}
|
||||
|
||||
bool
|
||||
ElementTransitions::HasTransitionOfProperty(nsCSSProperty aProperty) const
|
||||
{
|
||||
for (PRUint32 tranIdx = mPropertyTransitions.Length(); tranIdx-- != 0; ) {
|
||||
if (aProperty == mPropertyTransitions[tranIdx].mProperty) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
ElementTransitions::CanPerformOnCompositorThread() const
|
||||
{
|
||||
for (PRUint32 i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
|
||||
const ElementPropertyTransition &pt = mPropertyTransitions[i];
|
||||
if (pt.IsRemovedSentinel()) {
|
||||
continue;
|
||||
}
|
||||
if (!css::CommonElementAnimationData::CanAnimatePropertyOnCompositor(mElement,
|
||||
pt.mProperty)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* nsTransitionManager *
|
||||
*****************************************************************************/
|
||||
@ -197,6 +227,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (aNewStyleContext->PresContext()->IsProcessingAnimationStyleChange()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -333,6 +364,10 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
||||
// rule.
|
||||
|
||||
nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
|
||||
if (!coverRule) {
|
||||
NS_WARNING("out of memory");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
|
||||
for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
||||
@ -378,19 +413,9 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||
pt.mStartValue) &&
|
||||
ExtractComputedValueForTransition(aProperty, aNewStyleContext,
|
||||
pt.mEndValue);
|
||||
|
||||
bool haveChange = pt.mStartValue != pt.mEndValue;
|
||||
bool haveOMTA = false;
|
||||
if (!aNewStyleContext->GetPseudoType()) {
|
||||
ElementTransitions* et = nsTransitionManager::GetTransitions(aElement);
|
||||
if (et) {
|
||||
haveOMTA = et->CanPerformOnCompositorThread();
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldAnimate =
|
||||
haveValues &&
|
||||
(haveChange || haveOMTA) &&
|
||||
pt.mStartValue != pt.mEndValue &&
|
||||
// Check that we can interpolate between these values
|
||||
// (If this is ever a performance problem, we could add a
|
||||
// CanInterpolate method, but it seems fine for now.)
|
||||
@ -491,7 +516,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||
// reduce positive delays.
|
||||
if (delay < 0.0f)
|
||||
delay *= valuePortion;
|
||||
|
||||
duration *= valuePortion;
|
||||
|
||||
pt.mStartForReversingTest = oldPT.mEndValue;
|
||||
@ -503,6 +527,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||
pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
|
||||
pt.mDuration = TimeDuration::FromMilliseconds(duration);
|
||||
pt.mTimingFunction.Init(tf);
|
||||
|
||||
if (!aElementTransitions) {
|
||||
aElementTransitions =
|
||||
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
|
||||
@ -536,7 +561,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
||||
nsCSSPseudoElements::ePseudo_NotPseudoElement ?
|
||||
eRestyle_Self : eRestyle_Subtree;
|
||||
presContext->PresShell()->RestyleForAnimation(aElement, hint);
|
||||
// XXXdz: invalidate the frame here, once animations are throttled.
|
||||
|
||||
*aStartedAny = true;
|
||||
aWhichStarted->AddProperty(aProperty);
|
||||
@ -570,6 +594,10 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement,
|
||||
if (!et && aCreateIfNeeded) {
|
||||
// FIXME: Consider arena-allocating?
|
||||
et = new ElementTransitions(aElement, propName, this);
|
||||
if (!et) {
|
||||
NS_WARNING("out of memory");
|
||||
return nullptr;
|
||||
}
|
||||
nsresult rv = aElement->SetProperty(propName, et,
|
||||
ElementTransitionsPropertyDtor, nullptr);
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -577,9 +605,6 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement,
|
||||
delete et;
|
||||
return nullptr;
|
||||
}
|
||||
if (propName == nsGkAtoms::transitionsProperty) {
|
||||
aElement->SetMayHaveAnimations();
|
||||
}
|
||||
|
||||
AddElementData(et);
|
||||
}
|
||||
@ -733,6 +758,8 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime)
|
||||
// completion. See comment below.
|
||||
et->mPropertyTransitions.RemoveElementAt(i);
|
||||
} else if (pt.mStartTime + pt.mDuration <= aTime) {
|
||||
// This transition has completed.
|
||||
|
||||
// Fire transitionend events only for transitions on elements
|
||||
// and not those on pseudo-elements, since we can't target an
|
||||
// event at pseudo-elements.
|
||||
@ -766,9 +793,6 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime)
|
||||
nsRestyleHint hint = et->mElementProperty == nsGkAtoms::transitionsProperty ?
|
||||
eRestyle_Self : eRestyle_Subtree;
|
||||
mPresContext->PresShell()->RestyleForAnimation(et->mElement, hint);
|
||||
// XXXdz: if we have started a transition since the last tick and are
|
||||
// performing the transition off the main thread, we need to invalidate
|
||||
// the frame once we start throttling animation ticks.
|
||||
|
||||
if (et->mPropertyTransitions.IsEmpty()) {
|
||||
et->Destroy();
|
||||
|
@ -15,86 +15,7 @@ class nsStyleContext;
|
||||
class nsPresContext;
|
||||
class nsCSSPropertySet;
|
||||
struct nsTransition;
|
||||
|
||||
/*****************************************************************************
|
||||
* Per-Element data *
|
||||
*****************************************************************************/
|
||||
|
||||
struct ElementPropertyTransition
|
||||
{
|
||||
ElementPropertyTransition() {}
|
||||
|
||||
nsCSSProperty mProperty;
|
||||
nsStyleAnimation::Value mStartValue, mEndValue;
|
||||
mozilla::TimeStamp mStartTime; // actual start plus transition delay
|
||||
|
||||
// data from the relevant nsTransition
|
||||
mozilla::TimeDuration mDuration;
|
||||
mozilla::css::ComputedTimingFunction mTimingFunction;
|
||||
|
||||
// This is the start value to be used for a check for whether a
|
||||
// transition is being reversed. Normally the same as mStartValue,
|
||||
// except when this transition started as the reversal of another
|
||||
// in-progress transition. Needed so we can handle two reverses in a
|
||||
// row.
|
||||
nsStyleAnimation::Value mStartForReversingTest;
|
||||
// Likewise, the portion (in value space) of the "full" reversed
|
||||
// transition that we're actually covering. For example, if a :hover
|
||||
// effect has a transition that moves the element 10px to the right
|
||||
// (by changing 'left' from 0px to 10px), and the mouse moves in to
|
||||
// the element (starting the transition) but then moves out after the
|
||||
// transition has advanced 4px, the second transition (from 10px/4px
|
||||
// to 0px) will have mReversePortion of 0.4. (If the mouse then moves
|
||||
// in again when the transition is back to 2px, the mReversePortion
|
||||
// for the third transition (from 0px/2px to 10px) will be 0.8.
|
||||
double mReversePortion;
|
||||
|
||||
// Compute the portion of the *value* space that we should be through
|
||||
// at the given time. (The input to the transition timing function
|
||||
// has time units, the output has value units.)
|
||||
double ValuePortionFor(mozilla::TimeStamp aRefreshTime) const;
|
||||
|
||||
bool IsRemovedSentinel() const
|
||||
{
|
||||
return mStartTime.IsNull();
|
||||
}
|
||||
|
||||
void SetRemovedSentinel()
|
||||
{
|
||||
// assign the null time stamp
|
||||
mStartTime = mozilla::TimeStamp();
|
||||
}
|
||||
|
||||
bool CanPerformOnCompositor(mozilla::dom::Element* aElement,
|
||||
mozilla::TimeStamp aTime) const;
|
||||
};
|
||||
|
||||
struct ElementTransitions : public mozilla::css::CommonElementAnimationData
|
||||
{
|
||||
ElementTransitions(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
||||
nsTransitionManager *aTransitionManager);
|
||||
|
||||
void EnsureStyleRuleFor(mozilla::TimeStamp aRefreshTime);
|
||||
|
||||
|
||||
bool HasTransitionOfProperty(nsCSSProperty aProperty) const;
|
||||
// True if this animation can be performed on the compositor thread.
|
||||
bool CanPerformOnCompositorThread() const;
|
||||
// Either zero or one for each CSS property:
|
||||
nsTArray<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
|
||||
{
|
||||
@ -104,26 +25,6 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
static ElementTransitions* GetTransitions(nsIContent* aContent) {
|
||||
return static_cast<ElementTransitions*>
|
||||
(aContent->GetProperty(nsGkAtoms::transitionsProperty));
|
||||
}
|
||||
|
||||
static ElementTransitions*
|
||||
GetTransitionsForCompositor(nsIContent* aContent,
|
||||
nsCSSProperty aProperty)
|
||||
{
|
||||
if (!aContent->MayHaveAnimations())
|
||||
return nullptr;
|
||||
ElementTransitions* transitions = GetTransitions(aContent);
|
||||
if (!transitions ||
|
||||
!transitions->HasTransitionOfProperty(aProperty) ||
|
||||
!transitions->CanPerformOnCompositorThread()) {
|
||||
return nullptr;
|
||||
}
|
||||
return transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* StyleContextChanged
|
||||
*
|
||||
|
@ -3512,10 +3512,6 @@ pref("layers.acceleration.force-enabled", false);
|
||||
|
||||
pref("layers.acceleration.draw-fps", false);
|
||||
|
||||
// Whether to animate simple opacity and transforms on the compositor
|
||||
pref("layers.offmainthreadcomposition.animate-opacity", false);
|
||||
pref("layers.offmainthreadcomposition.animate-transform", false);
|
||||
|
||||
#ifdef MOZ_X11
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
pref("gfx.xrender.enabled",true);
|
||||
|
63
testing/xpcshell/b2g_xpcshell_venv.sh
Normal file
63
testing/xpcshell/b2g_xpcshell_venv.sh
Normal file
@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
PYTHON=$1
|
||||
|
||||
if [ -z "${PYTHON}" ]
|
||||
then
|
||||
echo "No python found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${MARIONETTE_HOME}" ]
|
||||
then
|
||||
echo "No MARIONETTE_HOME found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${XPCSHELLTEST_HOME}" ]
|
||||
then
|
||||
echo "No XPCSHELLTEST_HOME found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Detected Marionette home in $MARIONETTE_HOME"
|
||||
|
||||
# If a GECKO_OBJDIR environemnt variable exists, we will create the Python
|
||||
# virtual envirnoment there. Otherwise we create it in the PWD.
|
||||
VENV_DIR="marionette_venv"
|
||||
if [ -z $GECKO_OBJDIR ]
|
||||
then
|
||||
VENV_DIR="$MARIONETTE_HOME/$VENV_DIR"
|
||||
else
|
||||
VENV_DIR="$GECKO_OBJDIR/$VENV_DIR"
|
||||
fi
|
||||
|
||||
# Check if environment exists, if not, create a virtualenv:
|
||||
if [ -d $VENV_DIR ]
|
||||
then
|
||||
echo "Using virtual environment in $VENV_DIR"
|
||||
cd $VENV_DIR
|
||||
. bin/activate
|
||||
else
|
||||
echo "Creating a virtual environment in $VENV_DIR"
|
||||
curl https://raw.github.com/pypa/virtualenv/develop/virtualenv.py | ${PYTHON} - $VENV_DIR
|
||||
cd $VENV_DIR
|
||||
. bin/activate
|
||||
# set up mozbase
|
||||
git clone git://github.com/mozilla/mozbase.git
|
||||
cd mozbase
|
||||
python setup_development.py
|
||||
fi
|
||||
|
||||
# update the marionette_client
|
||||
cd $MARIONETTE_HOME
|
||||
python setup.py develop
|
||||
|
||||
cd $XPCSHELLTEST_HOME
|
||||
|
||||
# pop off the python parameter
|
||||
shift
|
||||
python runtestsb2g.py $@
|
@ -101,6 +101,11 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
||||
|
||||
self.device.pushFile(self.options.localAPK, self.remoteBinDir)
|
||||
|
||||
self.pushLibs()
|
||||
|
||||
self.device.chmodDir(self.remoteBinDir)
|
||||
|
||||
def pushLibs(self):
|
||||
if self.options.localAPK:
|
||||
localLib = os.path.join(self.options.objdir, "dist/fennec")
|
||||
if not os.path.exists(localLib):
|
||||
@ -126,7 +131,6 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
||||
if (file.endswith(".so")):
|
||||
self.device.pushFile(os.path.join(root, file), self.remoteBinDir)
|
||||
|
||||
self.device.chmodDir(self.remoteBinDir)
|
||||
|
||||
def setupTestDir(self):
|
||||
xpcDir = os.path.join(self.options.objdir, "_tests/xpcshell")
|
||||
@ -197,10 +201,13 @@ class XPCShellRemote(xpcshell.XPCShellTests, object):
|
||||
self.log.info("TEST-INFO | profile dir is %s" % self.profileDir)
|
||||
return self.profileDir
|
||||
|
||||
def setLD_LIBRARY_PATH(self, env):
|
||||
env["LD_LIBRARY_PATH"]=self.remoteBinDir
|
||||
|
||||
def launchProcess(self, cmd, stdout, stderr, env, cwd):
|
||||
cmd[0] = self.remoteJoin(self.remoteBinDir, "xpcshell")
|
||||
env = dict()
|
||||
env["LD_LIBRARY_PATH"]=self.remoteBinDir
|
||||
env = {}
|
||||
self.setLD_LIBRARY_PATH(env)
|
||||
env["MOZ_LINKER_CACHE"]=self.remoteBinDir
|
||||
if self.options.localAPK and self.appRoot:
|
||||
env["GRE_HOME"]=self.appRoot
|
||||
|
@ -29,8 +29,21 @@ class B2GXPCShellRemote(XPCShellRemote):
|
||||
XPCShellRemote.setupUtilities(self)
|
||||
|
||||
def clean(self):
|
||||
print >>sys.stderr, "\nCleaning files from previous run.."
|
||||
self.device.removeDir(DEVICE_TEST_ROOT)
|
||||
|
||||
# Overridden
|
||||
def pushLibs(self):
|
||||
if not self.options.use_device_libs:
|
||||
XPCShellRemote.pushLibs(self)
|
||||
|
||||
# Overridden
|
||||
def setLD_LIBRARY_PATH(self, env):
|
||||
if self.options.use_device_libs:
|
||||
env['LD_LIBRARY_PATH'] = '/system/b2g'
|
||||
else:
|
||||
XPCShellRemote.setLD_LIBRARY_PATH(self, env)
|
||||
|
||||
# Overridden
|
||||
# This returns 1 even when tests pass - this is why it's switched to 0
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=773703
|
||||
@ -52,10 +65,11 @@ class B2GOptions(RemoteXPCShellOptions):
|
||||
help="Path to B2G repo or qemu dir")
|
||||
defaults['b2g_path'] = None
|
||||
|
||||
self.add_option('--marionette', action='store',
|
||||
type='string', dest='marionette',
|
||||
help="host:port to use when connecting to Marionette")
|
||||
defaults['marionette'] = None
|
||||
self.add_option('--emupath', action='store',
|
||||
type='string', dest='emu_path',
|
||||
help="Path to emulator folder (if different "
|
||||
"from b2gpath")
|
||||
defaults['emu_path'] = None
|
||||
|
||||
self.add_option('--emulator', action='store',
|
||||
type='string', dest='emulator',
|
||||
@ -72,6 +86,16 @@ class B2GOptions(RemoteXPCShellOptions):
|
||||
help="Path to adb")
|
||||
defaults['adb_path'] = 'adb'
|
||||
|
||||
self.add_option('--address', action='store',
|
||||
type='string', dest='address',
|
||||
help="host:port of running Gecko instance to connect to")
|
||||
defaults['address'] = None
|
||||
|
||||
self.add_option('--use-device-libs', action='store_true',
|
||||
dest='use_device_libs',
|
||||
help="Don't push .so's")
|
||||
defaults['use_device_libs'] = False
|
||||
|
||||
defaults['dm_trans'] = 'adb'
|
||||
defaults['debugger'] = None
|
||||
defaults['debuggerArgs'] = None
|
||||
@ -97,11 +121,14 @@ def main():
|
||||
if options.no_window:
|
||||
kwargs['noWindow'] = True
|
||||
if options.b2g_path:
|
||||
kwargs['homedir'] = options.b2g_path
|
||||
if options.marionette:
|
||||
host, port = options.marionette.split(':')
|
||||
kwargs['homedir'] = options.emu_path or options.b2g_path
|
||||
if options.address:
|
||||
host, port = options.address.split(':')
|
||||
kwargs['host'] = host
|
||||
kwargs['port'] = int(port)
|
||||
kwargs['baseurl'] = 'http://%s:%d/' % (host, int(port))
|
||||
if options.emulator:
|
||||
kwargs['connectToRunningEmulator'] = True
|
||||
marionette = Marionette(**kwargs)
|
||||
|
||||
# Create the DeviceManager instance
|
||||
|
@ -13,10 +13,6 @@
|
||||
#include "nsDebug.h"
|
||||
#include "prlong.h"
|
||||
|
||||
namespace IPC {
|
||||
template <typename T> struct ParamTraits;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class TimeStamp;
|
||||
@ -99,9 +95,6 @@ public:
|
||||
bool operator>(const TimeDuration& aOther) const {
|
||||
return mValue > aOther.mValue;
|
||||
}
|
||||
bool operator==(const TimeDuration& aOther) const {
|
||||
return mValue == aOther.mValue;
|
||||
}
|
||||
|
||||
// Return a best guess at the system's current timing resolution,
|
||||
// which might be variable. TimeDurations below this order of
|
||||
@ -118,7 +111,6 @@ public:
|
||||
|
||||
private:
|
||||
friend class TimeStamp;
|
||||
friend struct IPC::ParamTraits<mozilla::TimeDuration>;
|
||||
|
||||
static TimeDuration FromTicks(PRInt64 aTicks) {
|
||||
TimeDuration t;
|
||||
@ -273,8 +265,6 @@ public:
|
||||
static NS_HIDDEN_(void) Shutdown();
|
||||
|
||||
private:
|
||||
friend struct IPC::ParamTraits<mozilla::TimeStamp>;
|
||||
|
||||
TimeStamp(PRUint64 aValue) : mValue(aValue) {}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user