зеркало из https://github.com/mozilla/gecko-dev.git
Backout 1244b8a8e57a (bug 755084), 32d16d0f87c9 (bug 706179), 8548e016d4a9 (bug 768440), 697f5b87eae9 (bug 768440), 808fc2bd4e8c (bug 755084), 54b1484cd125 (bug 755084), 876726b632c0 (bug 706179) for xul android R3 failures
This commit is contained in:
Родитель
04ab528588
Коммит
3ed23376d4
|
@ -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,245 +220,6 @@ LayerManager::CreateAsynchronousImageContainer()
|
|||
//--------------------------------------------------
|
||||
// Layer
|
||||
|
||||
Layer::Layer(LayerManager* aManager, void* aImplData) :
|
||||
mManager(aManager),
|
||||
mParent(nsnull),
|
||||
mNextSibling(nsnull),
|
||||
mPrevSibling(nsnull),
|
||||
mImplData(aImplData),
|
||||
mMaskLayer(nsnull),
|
||||
mXScale(1.0f),
|
||||
mYScale(1.0f),
|
||||
mOpacity(1.0),
|
||||
mContentFlags(0),
|
||||
mUseClipRect(false),
|
||||
mUseTileSourceRect(false),
|
||||
mIsFixedPosition(false),
|
||||
mDebugColorIndex(0)
|
||||
{}
|
||||
|
||||
Layer::~Layer()
|
||||
{}
|
||||
|
||||
void
|
||||
Layer::AddAnimation(const Animation& aAnimation)
|
||||
{
|
||||
if (!AsShadowableLayer() || !AsShadowableLayer()->HasShadow())
|
||||
return;
|
||||
|
||||
MOZ_ASSERT(aAnimation.segments().Length() >= 1);
|
||||
|
||||
mAnimations.AppendElement(aAnimation);
|
||||
Mutated();
|
||||
}
|
||||
|
||||
void
|
||||
Layer::ClearAnimations()
|
||||
{
|
||||
mAnimations.Clear();
|
||||
mAnimationData.Clear();
|
||||
Mutated();
|
||||
}
|
||||
|
||||
static nsCSSValueList*
|
||||
CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
|
||||
{
|
||||
nsAutoPtr<nsCSSValueList> result;
|
||||
nsCSSValueList** resultTail = getter_Transfers(result);
|
||||
for (PRUint32 i = 0; i < aFunctions.Length(); i++) {
|
||||
nsRefPtr<nsCSSValue::Array> arr;
|
||||
switch (aFunctions[i].type()) {
|
||||
case TransformFunction::TRotationX:
|
||||
{
|
||||
float theta = aFunctions[i].get_RotationX().radians();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatex, resultTail);
|
||||
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TRotationY:
|
||||
{
|
||||
float theta = aFunctions[i].get_RotationY().radians();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatey, resultTail);
|
||||
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TRotationZ:
|
||||
{
|
||||
float theta = aFunctions[i].get_RotationZ().radians();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatez, resultTail);
|
||||
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TRotation:
|
||||
{
|
||||
float theta = aFunctions[i].get_Rotation().radians();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotate, resultTail);
|
||||
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TRotation3D:
|
||||
{
|
||||
float x = aFunctions[i].get_Rotation3D().x();
|
||||
float y = aFunctions[i].get_Rotation3D().y();
|
||||
float z = aFunctions[i].get_Rotation3D().z();
|
||||
float theta = aFunctions[i].get_Rotation3D().radians();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotate3d, resultTail);
|
||||
arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
|
||||
arr->Item(2).SetFloatValue(y, eCSSUnit_Number);
|
||||
arr->Item(3).SetFloatValue(z, eCSSUnit_Number);
|
||||
arr->Item(4).SetFloatValue(theta, eCSSUnit_Radian);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TScale:
|
||||
{
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_scale3d, resultTail);
|
||||
arr->Item(1).SetFloatValue(aFunctions[i].get_Scale().x(), eCSSUnit_Number);
|
||||
arr->Item(2).SetFloatValue(aFunctions[i].get_Scale().y(), eCSSUnit_Number);
|
||||
arr->Item(3).SetFloatValue(aFunctions[i].get_Scale().z(), eCSSUnit_Number);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TTranslation:
|
||||
{
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_translate3d, resultTail);
|
||||
arr->Item(1).SetFloatValue(aFunctions[i].get_Translation().x(), eCSSUnit_Pixel);
|
||||
arr->Item(2).SetFloatValue(aFunctions[i].get_Translation().y(), eCSSUnit_Pixel);
|
||||
arr->Item(3).SetFloatValue(aFunctions[i].get_Translation().z(), eCSSUnit_Pixel);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TSkewX:
|
||||
{
|
||||
float x = aFunctions[i].get_SkewX().x();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_skewx, resultTail);
|
||||
arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TSkewY:
|
||||
{
|
||||
float y = aFunctions[i].get_SkewY().y();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_skewy, resultTail);
|
||||
arr->Item(1).SetFloatValue(y, eCSSUnit_Number);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TTransformMatrix:
|
||||
{
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_matrix3d, resultTail);
|
||||
const gfx3DMatrix& matrix = aFunctions[i].get_TransformMatrix().value();
|
||||
arr->Item(1).SetFloatValue(matrix._11, eCSSUnit_Number);
|
||||
arr->Item(2).SetFloatValue(matrix._12, eCSSUnit_Number);
|
||||
arr->Item(3).SetFloatValue(matrix._13, eCSSUnit_Number);
|
||||
arr->Item(4).SetFloatValue(matrix._14, eCSSUnit_Number);
|
||||
arr->Item(5).SetFloatValue(matrix._21, eCSSUnit_Number);
|
||||
arr->Item(6).SetFloatValue(matrix._22, eCSSUnit_Number);
|
||||
arr->Item(7).SetFloatValue(matrix._23, eCSSUnit_Number);
|
||||
arr->Item(8).SetFloatValue(matrix._24, eCSSUnit_Number);
|
||||
arr->Item(9).SetFloatValue(matrix._31, eCSSUnit_Number);
|
||||
arr->Item(10).SetFloatValue(matrix._32, eCSSUnit_Number);
|
||||
arr->Item(11).SetFloatValue(matrix._33, eCSSUnit_Number);
|
||||
arr->Item(12).SetFloatValue(matrix._34, eCSSUnit_Number);
|
||||
arr->Item(13).SetFloatValue(matrix._41, eCSSUnit_Number);
|
||||
arr->Item(14).SetFloatValue(matrix._42, eCSSUnit_Number);
|
||||
arr->Item(15).SetFloatValue(matrix._43, eCSSUnit_Number);
|
||||
arr->Item(16).SetFloatValue(matrix._44, eCSSUnit_Number);
|
||||
break;
|
||||
}
|
||||
case TransformFunction::TPerspective:
|
||||
{
|
||||
float perspective = aFunctions[i].get_Perspective().value();
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_perspective, resultTail);
|
||||
arr->Item(1).SetFloatValue(perspective, eCSSUnit_Pixel);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_ASSERTION(false, "All functions should be implemented?");
|
||||
}
|
||||
}
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
void
|
||||
Layer::SetAnimations(const AnimationArray& aAnimations)
|
||||
{
|
||||
mAnimations = aAnimations;
|
||||
mAnimationData.Clear();
|
||||
for (PRUint32 i = 0; i < mAnimations.Length(); i++) {
|
||||
AnimData data;
|
||||
InfallibleTArray<css::ComputedTimingFunction*>* functions =
|
||||
&data.mFunctions;
|
||||
nsTArray<AnimationSegment> segments = mAnimations.ElementAt(i).segments();
|
||||
for (PRUint32 j = 0; j < segments.Length(); j++) {
|
||||
TimingFunction tf = segments.ElementAt(j).sampleFn();
|
||||
css::ComputedTimingFunction* ctf = new css::ComputedTimingFunction();
|
||||
switch (tf.type()) {
|
||||
case TimingFunction::TCubicBezierFunction: {
|
||||
CubicBezierFunction cbf = tf.get_CubicBezierFunction();
|
||||
ctf->Init(nsTimingFunction(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2()));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
NS_ASSERTION(tf.type() == TimingFunction::TStepFunction,
|
||||
"Function must be bezier or step");
|
||||
StepFunction sf = tf.get_StepFunction();
|
||||
nsTimingFunction::Type type = sf.type() == 1 ? nsTimingFunction::StepStart
|
||||
: nsTimingFunction::StepEnd;
|
||||
ctf->Init(nsTimingFunction(type, sf.steps()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
functions->AppendElement(ctf);
|
||||
}
|
||||
|
||||
// Precompute the nsStyleAnimation::Values that we need if this is a transform
|
||||
// animation.
|
||||
InfallibleTArray<nsStyleAnimation::Value>* startValues =
|
||||
&data.mStartValues;
|
||||
InfallibleTArray<nsStyleAnimation::Value>* endValues =
|
||||
&data.mEndValues;
|
||||
for (PRUint32 j = 0; j < mAnimations[i].segments().Length(); j++) {
|
||||
const AnimationSegment& segment = mAnimations[i].segments()[j];
|
||||
if (segment.endState().type() == Animatable::TArrayOfTransformFunction) {
|
||||
const InfallibleTArray<TransformFunction>& startFunctions =
|
||||
segment.startState().get_ArrayOfTransformFunction();
|
||||
nsStyleAnimation::Value startValue;
|
||||
nsCSSValueList* startList;
|
||||
if (startFunctions.Length() > 0) {
|
||||
startList = CreateCSSValueList(startFunctions);
|
||||
} else {
|
||||
startList = new nsCSSValueList();
|
||||
startList->mValue.SetNoneValue();
|
||||
}
|
||||
startValue.SetAndAdoptCSSValueListValue(startList, nsStyleAnimation::eUnit_Transform);
|
||||
startValues->AppendElement(startValue);
|
||||
|
||||
const InfallibleTArray<TransformFunction>& endFunctions =
|
||||
segment.endState().get_ArrayOfTransformFunction();
|
||||
nsStyleAnimation::Value endValue;
|
||||
nsCSSValueList* endList;
|
||||
if (endFunctions.Length() > 0) {
|
||||
endList = CreateCSSValueList(endFunctions);
|
||||
} else {
|
||||
endList = new nsCSSValueList();
|
||||
endList->mValue.SetNoneValue();
|
||||
}
|
||||
endValue.SetAndAdoptCSSValueListValue(endList, nsStyleAnimation::eUnit_Transform);
|
||||
endValues->AppendElement(endValue);
|
||||
} else {
|
||||
NS_ASSERTION(segment.endState().type() == Animatable::TOpacity,
|
||||
"Unknown Animatable type");
|
||||
nsStyleAnimation::Value startValue;
|
||||
startValue.SetFloatValue(segment.startState().get_Opacity().value());
|
||||
startValues->AppendElement(startValue);
|
||||
|
||||
nsStyleAnimation::Value endValue;
|
||||
endValue.SetFloatValue(segment.endState().get_Opacity().value());
|
||||
endValues->AppendElement(endValue);
|
||||
}
|
||||
}
|
||||
mAnimationData.AppendElement(data);
|
||||
}
|
||||
|
||||
Mutated();
|
||||
}
|
||||
|
||||
bool
|
||||
Layer::CanUseOpaqueSurface()
|
||||
{
|
||||
|
@ -544,7 +304,7 @@ Layer::SnapTransform(const gfx3DMatrix& aTransform,
|
|||
return result;
|
||||
}
|
||||
|
||||
nsIntRect
|
||||
nsIntRect
|
||||
Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
||||
const gfxMatrix* aWorldTransform)
|
||||
{
|
||||
|
@ -601,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;
|
||||
}
|
||||
|
@ -648,7 +387,6 @@ Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurf
|
|||
mMaskLayer->mEffectiveTransform = aTransformToSurface;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
gfxMatrix maskTranslation;
|
||||
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
|
||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||
|
@ -1052,7 +790,7 @@ void
|
|||
LayerManager::Dump(FILE* aFile, const char* aPrefix)
|
||||
{
|
||||
FILE* file = FILEOrDefault(aFile);
|
||||
|
||||
|
||||
fprintf(file, "<ul><li><a ");
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
WriteSnapshotLinkToDumpFile(this, file);
|
||||
|
@ -1069,7 +807,7 @@ LayerManager::Dump(FILE* aFile, const char* aPrefix)
|
|||
fprintf(file, "%s(null)</li></ul>", pfx.get());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
fprintf(file, "<ul>");
|
||||
GetRoot()->Dump(file, pfx.get());
|
||||
fprintf(file, "</ul></li></ul>");
|
||||
|
@ -1203,5 +941,5 @@ LayerManager::PrintInfo(nsACString& aTo, const char* aPrefix)
|
|||
|
||||
PRLogModuleInfo* LayerManager::sLog;
|
||||
|
||||
} // namespace layers
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -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 nsnull; }
|
||||
virtual Layer* GetLastChild() { return nsnull; }
|
||||
const gfx3DMatrix GetTransform();
|
||||
const gfx3DMatrix& GetBaseTransform() { return mTransform; }
|
||||
float GetXScale() { return mXScale; }
|
||||
float GetYScale() { return mYScale; }
|
||||
const gfx3DMatrix& GetTransform() { return mTransform; }
|
||||
bool GetIsFixedPosition() { return mIsFixedPosition; }
|
||||
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
|
||||
Layer* GetMaskLayer() { return mMaskLayer; }
|
||||
AnimationArray& GetAnimations() { return mAnimations; }
|
||||
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
||||
|
||||
/**
|
||||
* DRAWING PHASE ONLY
|
||||
*
|
||||
|
@ -973,7 +940,20 @@ public:
|
|||
#endif
|
||||
|
||||
protected:
|
||||
Layer(LayerManager* aManager, void* aImplData);
|
||||
Layer(LayerManager* aManager, void* aImplData) :
|
||||
mManager(aManager),
|
||||
mParent(nsnull),
|
||||
mNextSibling(nsnull),
|
||||
mPrevSibling(nsnull),
|
||||
mImplData(aImplData),
|
||||
mMaskLayer(nsnull),
|
||||
mOpacity(1.0),
|
||||
mContentFlags(0),
|
||||
mUseClipRect(false),
|
||||
mUseTileSourceRect(false),
|
||||
mIsFixedPosition(false),
|
||||
mDebugColorIndex(0)
|
||||
{}
|
||||
|
||||
void Mutated() { mManager->Mutated(this); }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -421,15 +412,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()) {
|
||||
|
@ -526,10 +517,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()) {
|
||||
|
@ -537,114 +527,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(nsnull, data.origin(), nsDeviceContext::AppUnitsPerCSSPixel(),
|
||||
&data.bounds(), interpolatedList, &data.mozOrigin(),
|
||||
&data.perspectiveOrigin(), &data.perspective());
|
||||
|
||||
InfallibleTArray<TransformFunction>* functions = new InfallibleTArray<TransformFunction>();
|
||||
functions->AppendElement(TransformMatrix(transform));
|
||||
*aValue = *functions;
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aStart.GetUnit() == nsStyleAnimation::eUnit_Float, "Should be opacity");
|
||||
nsStyleAnimation::Interpolate(eCSSProperty_opacity, aStart, aEnd,
|
||||
aPortion, interpolatedValue);
|
||||
*aValue = interpolatedValue.GetFloatValue();
|
||||
}
|
||||
|
||||
static bool
|
||||
SampleAnimations(Layer* aLayer, TimeStamp aPoint)
|
||||
{
|
||||
AnimationArray& animations = aLayer->GetAnimations();
|
||||
InfallibleTArray<AnimData>& animationData = aLayer->GetAnimationData();
|
||||
|
||||
bool activeAnimations = false;
|
||||
|
||||
for (PRUint32 i = animations.Length(); i-- !=0; ) {
|
||||
Animation& animation = animations[i];
|
||||
AnimData& animData = animationData[i];
|
||||
|
||||
double numIterations = animation.numIterations() != -1 ?
|
||||
animation.numIterations() : NS_IEEEPositiveInfinity();
|
||||
double positionInIteration =
|
||||
ElementAnimations::GetPositionInIteration(animation.startTime(),
|
||||
aPoint,
|
||||
animation.duration(),
|
||||
numIterations,
|
||||
animation.direction());
|
||||
|
||||
if (positionInIteration == -1) {
|
||||
animations.RemoveElementAt(i);
|
||||
animationData.RemoveElementAt(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE(0.0 <= positionInIteration &&
|
||||
positionInIteration <= 1.0,
|
||||
"position should be in [0-1]");
|
||||
|
||||
int segmentIndex = 0;
|
||||
AnimationSegment* segment = animation.segments().Elements();
|
||||
while (segment->endPortion() < positionInIteration) {
|
||||
++segment;
|
||||
++segmentIndex;
|
||||
}
|
||||
|
||||
double positionInSegment = (positionInIteration - segment->startPortion()) /
|
||||
(segment->endPortion() - segment->startPortion());
|
||||
|
||||
double portion = animData.mFunctions[segmentIndex]->GetValue(positionInSegment);
|
||||
|
||||
activeAnimations = true;
|
||||
|
||||
// interpolate the property
|
||||
Animatable interpolatedValue;
|
||||
SampleValue(portion, animation, animData.mStartValues[segmentIndex],
|
||||
animData.mEndValues[segmentIndex], &interpolatedValue);
|
||||
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||
switch (interpolatedValue.type()) {
|
||||
case Animatable::TOpacity:
|
||||
shadow->SetShadowOpacity(interpolatedValue.get_Opacity().value());
|
||||
break;
|
||||
case Animatable::TArrayOfTransformFunction: {
|
||||
gfx3DMatrix matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value();
|
||||
shadow->SetShadowTransform(matrix);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
NS_WARNING("Unhandled animated property");
|
||||
}
|
||||
}
|
||||
|
||||
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||
child = child->GetNextSibling()) {
|
||||
activeAnimations |= SampleAnimations(child, aPoint);
|
||||
}
|
||||
|
||||
return activeAnimations;
|
||||
}
|
||||
|
||||
bool
|
||||
CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
||||
Layer *aLayer,
|
||||
|
@ -690,13 +572,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
|
||||
|
@ -789,6 +667,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
|
||||
|
@ -50,7 +42,7 @@ struct OpCreateRefLayer { PLayer layer; };
|
|||
struct ThebesBuffer {
|
||||
SurfaceDescriptor buffer;
|
||||
nsIntRect rect;
|
||||
nsIntPoint rotation;
|
||||
nsIntPoint rotation;
|
||||
};
|
||||
union OptionalThebesBuffer { ThebesBuffer; null_t; };
|
||||
|
||||
|
@ -59,129 +51,24 @@ union CanvasSurface {
|
|||
null_t;
|
||||
};
|
||||
|
||||
struct CubicBezierFunction {
|
||||
float x1;
|
||||
float y1;
|
||||
float x2;
|
||||
float y2;
|
||||
};
|
||||
|
||||
struct StepFunction {
|
||||
int steps;
|
||||
// 1 = nsTimingFunction::StepStart, 2 = nsTimingFunction::StepEnd
|
||||
int type;
|
||||
};
|
||||
|
||||
union TimingFunction {
|
||||
CubicBezierFunction;
|
||||
StepFunction;
|
||||
};
|
||||
|
||||
struct Color { gfxRGBA value; };
|
||||
struct Opacity { float value; };
|
||||
struct Perspective { float value; };
|
||||
struct RotationX { float radians; };
|
||||
struct RotationY { float radians; };
|
||||
struct RotationZ { float radians; };
|
||||
struct Rotation { float radians; };
|
||||
struct Rotation3D {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float radians;
|
||||
};
|
||||
struct Scale {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
struct SkewX { float x; };
|
||||
struct SkewY { float y; };
|
||||
struct TransformMatrix { gfx3DMatrix value; };
|
||||
struct Translation {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
union TransformFunction {
|
||||
Perspective;
|
||||
RotationX;
|
||||
RotationY;
|
||||
RotationZ;
|
||||
Rotation;
|
||||
Rotation3D;
|
||||
Scale;
|
||||
SkewX;
|
||||
SkewY;
|
||||
Translation;
|
||||
TransformMatrix;
|
||||
};
|
||||
|
||||
union Animatable {
|
||||
Color;
|
||||
Opacity;
|
||||
TransformFunction[];
|
||||
};
|
||||
|
||||
struct AnimationSegment {
|
||||
Animatable startState;
|
||||
Animatable endState;
|
||||
float startPortion;
|
||||
float endPortion;
|
||||
TimingFunction sampleFn;
|
||||
};
|
||||
|
||||
// Transforms need extra information to correctly convert the list of transform
|
||||
// functions to a gfx3DMatrix that can be applied directly to the layer.
|
||||
struct TransformData {
|
||||
nsPoint origin;
|
||||
gfxPoint3D mozOrigin;
|
||||
gfxPoint3D perspectiveOrigin;
|
||||
nsRect bounds;
|
||||
nscoord perspective;
|
||||
};
|
||||
|
||||
union AnimationData {
|
||||
null_t;
|
||||
TransformData;
|
||||
};
|
||||
|
||||
struct Animation {
|
||||
TimeStamp startTime;
|
||||
TimeDuration duration;
|
||||
// For each frame, the interpolation point is computed based on the
|
||||
// startTime, the direction, the duration, and the current time.
|
||||
// The segments must uniquely cover the portion from 0.0 to 1.0
|
||||
AnimationSegment[] segments;
|
||||
// How many times to repeat the animation. < 0 means "forever".
|
||||
float numIterations;
|
||||
// This uses the NS_STYLE_ANIMATION_DIRECTION_* constants.
|
||||
int32_t direction;
|
||||
AnimationData data;
|
||||
};
|
||||
|
||||
// Change a layer's attributes
|
||||
struct CommonLayerAttributes {
|
||||
nsIntRegion visibleRegion;
|
||||
TransformMatrix transform;
|
||||
float xScale;
|
||||
float yScale;
|
||||
gfx3DMatrix transform;
|
||||
PRUint32 contentFlags;
|
||||
Opacity opacity;
|
||||
float opacity;
|
||||
bool useClipRect;
|
||||
nsIntRect clipRect;
|
||||
bool isFixedPosition;
|
||||
gfxPoint fixedPositionAnchor;
|
||||
nullable PLayer maskLayer;
|
||||
// Animated colors will only honored for ColorLayers.
|
||||
Animation[] animations;
|
||||
};
|
||||
|
||||
struct ThebesLayerAttributes {
|
||||
nsIntRegion validRegion;
|
||||
};
|
||||
struct ContainerLayerAttributes{ FrameMetrics metrics; };
|
||||
struct ColorLayerAttributes { Color color; };
|
||||
struct ColorLayerAttributes { gfxRGBA color; };
|
||||
struct CanvasLayerAttributes { GraphicsFilterType filter; };
|
||||
struct RefLayerAttributes { int64_t id; };
|
||||
struct ImageLayerAttributes {
|
||||
|
|
|
@ -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 != nsnull;
|
||||
|
@ -543,7 +538,6 @@ public:
|
|||
}
|
||||
|
||||
// These getters can be used anytime.
|
||||
float GetShadowOpacity() { return mShadowOpacity; }
|
||||
const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nsnull; }
|
||||
const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
|
||||
const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
|
||||
|
@ -553,7 +547,6 @@ public:
|
|||
protected:
|
||||
ShadowLayer()
|
||||
: mAllocator(nsnull)
|
||||
, 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:
|
||||
|
|
|
@ -109,7 +109,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||
}
|
||||
|
||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||
|
||||
|
||||
// Check the maximum texture size supported by GL. glTexImage2D supports
|
||||
// images of up to 2 + GL_MAX_TEXTURE_SIZE
|
||||
GLint texSize = gl()->GetMaxTextureSize();
|
||||
|
@ -118,7 +118,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||
MakeTextureIfNeeded(gl(), mTexture);
|
||||
// This should only ever occur with 2d canvas, WebGL can't already have a texture
|
||||
// of this size can it?
|
||||
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
|
||||
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
|
||||
"Invalid texture size when WebGL surface already exists at that size?");
|
||||
}
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ CanvasLayerOGL::RenderLayer(int aPreviousDestination,
|
|||
GetMaskLayer() ? Mask2d : MaskNone);
|
||||
} else if (mDelayedUpdates) {
|
||||
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
|
||||
|
||||
|
||||
drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
|
||||
|
||||
nsRefPtr<gfxASurface> surf = mCanvasSurface;
|
||||
|
@ -299,7 +299,7 @@ ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
|
|||
{
|
||||
mImplData = static_cast<LayerOGL*>(this);
|
||||
}
|
||||
|
||||
|
||||
ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL()
|
||||
{}
|
||||
|
||||
|
|
|
@ -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,29 +577,11 @@ 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>
|
||||
{
|
||||
typedef nsIntPoint paramType;
|
||||
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.x);
|
||||
|
@ -635,7 +599,7 @@ template<>
|
|||
struct ParamTraits<nsIntRect>
|
||||
{
|
||||
typedef nsIntRect paramType;
|
||||
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.x);
|
||||
|
@ -684,11 +648,11 @@ template<>
|
|||
struct ParamTraits<nsIntSize>
|
||||
{
|
||||
typedef nsIntSize paramType;
|
||||
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.width);
|
||||
WriteParam(msg, param.height);
|
||||
WriteParam(msg, param.height);
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
|
@ -702,11 +666,11 @@ template<>
|
|||
struct ParamTraits<mozilla::gfx::Size>
|
||||
{
|
||||
typedef mozilla::gfx::Size paramType;
|
||||
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.width);
|
||||
WriteParam(msg, param.height);
|
||||
WriteParam(msg, param.height);
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||
|
@ -742,7 +706,7 @@ template<>
|
|||
struct ParamTraits<nsRect>
|
||||
{
|
||||
typedef nsRect paramType;
|
||||
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
WriteParam(msg, param.x);
|
||||
|
@ -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__ */
|
||||
|
|
|
@ -21,9 +21,6 @@
|
|||
#include "mozilla/Preferences.h"
|
||||
#include "sampler.h"
|
||||
|
||||
#include "nsAnimationManager.h"
|
||||
#include "nsTransitionManager.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
@ -631,7 +628,7 @@ FrameLayerBuilder::FlashPaint(gfxContext *aContext)
|
|||
|
||||
if (!sPaintFlashingPrefCached) {
|
||||
sPaintFlashingPrefCached = true;
|
||||
mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled,
|
||||
mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled,
|
||||
"nglayout.debug.paint_flashing");
|
||||
}
|
||||
|
||||
|
@ -996,7 +993,7 @@ ContainerState::CreateOrRecycleMaskImageLayerFor(Layer* aLayer)
|
|||
result->SetUserData(&gMaskLayerUserData, new MaskLayerUserData());
|
||||
result->SetForceSingleTile(true);
|
||||
}
|
||||
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
|
@ -1114,7 +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->SetTransform(gfx3DMatrix::From2D(matrix));
|
||||
|
||||
// FIXME: Temporary workaround for bug 681192 and bug 724786.
|
||||
#ifndef MOZ_JAVA_COMPOSITOR
|
||||
|
@ -1234,7 +1231,7 @@ ContainerState::ThebesLayerData::UpdateCommonClipCount(
|
|||
} else {
|
||||
// first item in the layer
|
||||
mCommonClipCount = aCurrentClip.mRoundedClipRects.Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<ImageContainer>
|
||||
|
@ -1256,7 +1253,7 @@ ContainerState::PopThebesLayerData()
|
|||
ThebesLayerData* data = mThebesLayerDataStack[lastIndex];
|
||||
|
||||
nsRefPtr<Layer> layer;
|
||||
nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer();
|
||||
nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer();
|
||||
|
||||
if ((data->mIsSolidColorInVisibleRegion || imageContainer) &&
|
||||
data->mLayer->GetValidRegion().IsEmpty()) {
|
||||
|
@ -1267,7 +1264,9 @@ ContainerState::PopThebesLayerData()
|
|||
imageLayer->SetContainer(imageContainer);
|
||||
data->mImage->ConfigureLayer(imageLayer);
|
||||
// The layer's current transform is applied first, then the result is scaled.
|
||||
imageLayer->SetScale(mParameters.mXScale, mParameters.mYScale);
|
||||
gfx3DMatrix transform = imageLayer->GetTransform()*
|
||||
gfx3DMatrix::ScalingMatrix(mParameters.mXScale, mParameters.mYScale, 1.0f);
|
||||
imageLayer->SetTransform(transform);
|
||||
if (data->mItemClip.mHaveClipRect) {
|
||||
nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect);
|
||||
imageLayer->IntersectClipRect(clip);
|
||||
|
@ -1279,9 +1278,8 @@ ContainerState::PopThebesLayerData()
|
|||
colorLayer->SetColor(data->mSolidColor);
|
||||
|
||||
// Copy transform
|
||||
colorLayer->SetBaseTransform(data->mLayer->GetTransform());
|
||||
colorLayer->SetScale(data->mLayer->GetXScale(), data->mLayer->GetYScale());
|
||||
|
||||
colorLayer->SetTransform(data->mLayer->GetTransform());
|
||||
|
||||
// Clip colorLayer to its visible region, since ColorLayers are
|
||||
// allowed to paint outside the visible region. Here we rely on the
|
||||
// fact that uniform display items fill rectangles; obviously the
|
||||
|
@ -1312,7 +1310,7 @@ ContainerState::PopThebesLayerData()
|
|||
if (!layer->GetTransform().Is2D(&transform)) {
|
||||
NS_ERROR("Only 2D transformations currently supported");
|
||||
}
|
||||
|
||||
|
||||
// ImageLayers are already configured with a visible region
|
||||
if (!imageContainer) {
|
||||
NS_ASSERTION(!transform.HasNonIntegerTranslation(),
|
||||
|
@ -1642,9 +1640,9 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
nsRefPtr<gfxContext> context = aContext;
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
if (gfxUtils::sDumpPainting) {
|
||||
surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(),
|
||||
surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
surf->SetDeviceOffset(-itemVisibleRect.TopLeft());
|
||||
context = new gfxContext(surf);
|
||||
|
@ -1677,7 +1675,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
|||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (gfxUtils::sDumpPainting) {
|
||||
DumpPaintedImage(aItem, surf);
|
||||
|
||||
|
||||
surf->SetDeviceOffset(gfxPoint(0, 0));
|
||||
aContext->SetSource(surf, itemVisibleRect.TopLeft());
|
||||
aContext->Rectangle(itemVisibleRect);
|
||||
|
@ -1779,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(
|
||||
|
@ -2123,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);
|
||||
|
@ -2554,8 +2552,8 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi
|
|||
gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height);
|
||||
bounds.ScaleInverse(aDest->AppUnitsPerDevPixel());
|
||||
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
|
||||
nsRefPtr<gfxASurface> surf =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
|
||||
gfxASurface::CONTENT_COLOR_ALPHA);
|
||||
surf->SetDeviceOffset(-bounds.TopLeft());
|
||||
nsRefPtr<gfxContext> context = new gfxContext(surf);
|
||||
|
@ -2565,7 +2563,7 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi
|
|||
aItem->Paint(aBuilder, ctx);
|
||||
DumpPaintedImage(aItem, surf);
|
||||
aItem->SetPainted();
|
||||
|
||||
|
||||
surf->SetDeviceOffset(gfxPoint(0, 0));
|
||||
aDest->ThebesContext()->SetSource(surf, bounds.TopLeft());
|
||||
aDest->ThebesContext()->Rectangle(bounds);
|
||||
|
@ -3027,7 +3025,7 @@ CalculateBounds(nsTArray<FrameLayerBuilder::Clip::RoundedRect> aRects, PRInt32 A
|
|||
|
||||
void
|
||||
ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
|
||||
PRUint32 aRoundedRectClipCount)
|
||||
PRUint32 aRoundedRectClipCount)
|
||||
{
|
||||
// don't build an unnecessary mask
|
||||
nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds();
|
||||
|
@ -3053,7 +3051,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
|||
aLayer->SetMaskLayer(maskLayer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// calculate a more precise bounding rect
|
||||
const PRInt32 A2D = mContainerFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
gfxRect boundingRect = CalculateBounds(newData.mRoundedClipRects, A2D);
|
||||
|
@ -3131,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);
|
||||
}
|
||||
|
@ -668,7 +300,7 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
|
|||
|
||||
if (mIsPaintingToWindow) {
|
||||
mReferenceFrame->AddPaintedPresShell(state->mPresShell);
|
||||
|
||||
|
||||
state->mPresShell->IncrementPaintCount();
|
||||
}
|
||||
|
||||
|
@ -731,7 +363,7 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
|
|||
}
|
||||
|
||||
void
|
||||
nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect)
|
||||
nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect)
|
||||
{
|
||||
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||
aDirtyFrame->GetChildLists(&childListArray);
|
||||
|
@ -988,10 +620,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
|
|||
return;
|
||||
}
|
||||
// Root is being scaled up by the X/Y resolution. Scale it back down.
|
||||
gfx3DMatrix rootTransform = root->GetBaseTransform()*
|
||||
gfx3DMatrix rootTransform = root->GetTransform()*
|
||||
gfx3DMatrix::ScalingMatrix(1.0f/containerParameters.mXScale,
|
||||
1.0f/containerParameters.mYScale, 1.0f);
|
||||
root->SetBaseTransform(rootTransform);
|
||||
root->SetTransform(rootTransform);
|
||||
|
||||
ViewID id = presContext->IsRootContentDocument() ? FrameMetrics::ROOT_SCROLL_ID
|
||||
: FrameMetrics::NULL_SCROLL_ID;
|
||||
|
@ -1134,8 +766,8 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|||
if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) {
|
||||
nsAutoTArray<nsIFrame*, 16> outFrames;
|
||||
item->HitTest(aBuilder, aRect, aState, &outFrames);
|
||||
|
||||
// For 3d transforms with preserve-3d we add hit frames into the temp list
|
||||
|
||||
// For 3d transforms with preserve-3d we add hit frames into the temp list
|
||||
// so we can sort them later, otherwise we add them directly to the output list.
|
||||
nsTArray<nsIFrame*> *writeFrames = aOutFrames;
|
||||
if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
|
||||
|
@ -1151,7 +783,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|||
writeFrames = &temp[temp.Length() - 1].mFrames;
|
||||
}
|
||||
} else {
|
||||
// We may have just finished a run of consecutive preserve-3d transforms,
|
||||
// We may have just finished a run of consecutive preserve-3d transforms,
|
||||
// so flush these into the destination array before processing our frame list.
|
||||
FlushFramesArray(temp, aOutFrames);
|
||||
}
|
||||
|
@ -1196,7 +828,7 @@ static void Sort(nsDisplayList* aList, PRInt32 aCount, nsDisplayList::SortLEQ aC
|
|||
aList->AppendToTop(&list2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Sort(&list1, half, aCmp, aClosure);
|
||||
Sort(&list2, aCount - half, aCmp, aClosure);
|
||||
|
||||
|
@ -1260,7 +892,7 @@ void nsDisplayList::ExplodeAnonymousChildLists(nsDisplayListBuilder* aBuilder) {
|
|||
i->~nsDisplayItem();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AppendToTop(&tmp);
|
||||
}
|
||||
|
||||
|
@ -1650,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));
|
||||
}
|
||||
|
@ -2347,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, nsnull);
|
||||
if (!container)
|
||||
if (!layer)
|
||||
return nsnull;
|
||||
|
||||
container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
||||
AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_opacity);
|
||||
|
||||
return container.forget();
|
||||
layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2381,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, nsnull);
|
||||
return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot)
|
||||
|
@ -2738,7 +2362,7 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
|
|||
// Layer metadata for a particular scroll frame needs to be unique. Only
|
||||
// one nsDisplayScrollLayer (with rendered content) or one
|
||||
// nsDisplayScrollInfoLayer (with only the metadata) should survive the
|
||||
// visibility computation.
|
||||
// visibility computation.
|
||||
return RemoveScrollLayerCount() == 1;
|
||||
}
|
||||
|
||||
|
@ -3021,7 +2645,7 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
|
|||
NS_PRECONDITION(aFrame, "Can't get the bounds of a nonexistent frame!");
|
||||
|
||||
nsRect result;
|
||||
|
||||
|
||||
if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
|
||||
// TODO: SVG needs to define what percentage translations resolve against.
|
||||
return result;
|
||||
|
@ -3048,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(),
|
||||
|
@ -3069,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};
|
||||
|
||||
|
@ -3080,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) &&
|
||||
|
@ -3099,32 +2723,31 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
|||
// user space, not the top left of its bounds, so we must adjust for that:
|
||||
nscoord offset =
|
||||
(index == 0) ? aFrame->GetPosition().x : aFrame->GetPosition().y;
|
||||
coords[index] -= NSAppUnitsToFloatPixels(offset, aAppUnitsPerPixel);
|
||||
*coords[index] -= NSAppUnitsToFloatPixels(offset, aAppUnitsPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
|
||||
aAppUnitsPerPixel);
|
||||
*coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
|
||||
aAppUnitsPerPixel);
|
||||
/* Adjust based on the origin of the rectangle. */
|
||||
coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
|
||||
coords[1] += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel);
|
||||
result.x += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
|
||||
result.y += NSAppUnitsToFloatPixels(boundingRect.y, aAppUnitsPerPixel);
|
||||
|
||||
return gfxPoint3D(coords[0], coords[1], coords[2]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Returns the delta specified by the -moz-perspective-origin property.
|
||||
* This is a positive delta, meaning that it indicates the direction to move
|
||||
* to get from (0, 0) of the frame to the perspective origin. This function is
|
||||
* called off the main thread.
|
||||
* to get from (0, 0) of the frame to the perspective origin.
|
||||
*/
|
||||
/* static */ gfxPoint3D
|
||||
nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel)
|
||||
static
|
||||
gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||
float aAppUnitsPerPixel)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
||||
NS_PRECONDITION(aFrame->IsTransformed(),
|
||||
"Shouldn't get a delta for an untransformed frame!");
|
||||
NS_PRECONDITION(aFrame->GetParentStyleContextFrame(),
|
||||
NS_PRECONDITION(aFrame->GetParentStyleContextFrame(),
|
||||
"Can't get delta without a style parent!");
|
||||
|
||||
/* For both of the coordinates, if the value of -moz-perspective-origin is a
|
||||
|
@ -3182,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);
|
||||
|
@ -3207,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),
|
||||
|
@ -3216,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() : nsnull;
|
||||
const nsStyleDisplay* disp = aFrame->GetStyleDisplay();
|
||||
nsRect bounds = (aBoundsOverride ? *aBoundsOverride :
|
||||
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
||||
|
||||
|
@ -3227,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, nsnull, nsnull,
|
||||
dummy, bounds, aAppUnitsPerPixel);
|
||||
} else if (disp->mSpecifiedTransform) {
|
||||
if (disp->mSpecifiedTransform) {
|
||||
result = nsStyleTransformMatrix::ReadTransforms(disp->mSpecifiedTransform,
|
||||
aFrame->GetStyleContext(),
|
||||
aFrame->PresContext(),
|
||||
|
@ -3244,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()) {
|
||||
|
@ -3256,40 +2870,32 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||
}
|
||||
|
||||
const nsStyleDisplay* parentDisp = nsnull;
|
||||
nsStyleContext* parentStyleContext = aFrame ? aFrame->GetStyleContext()->GetParent(): nsnull;
|
||||
nsStyleContext* parentStyleContext = aFrame->GetStyleContext()->GetParent();
|
||||
if (parentStyleContext) {
|
||||
parentDisp = parentStyleContext->GetStyleDisplay();
|
||||
}
|
||||
nscoord perspectiveCoord = 0;
|
||||
if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
|
||||
perspectiveCoord = parentDisp->mChildPerspective.GetCoordValue();
|
||||
}
|
||||
if (aChildPerspective) {
|
||||
perspectiveCoord = *aChildPerspective;
|
||||
}
|
||||
|
||||
if (nsLayoutUtils::Are3DTransformsEnabled() && perspectiveCoord > 0.0) {
|
||||
if (nsLayoutUtils::Are3DTransformsEnabled() &&
|
||||
parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord &&
|
||||
parentDisp->mChildPerspective.GetCoordValue() > 0.0) {
|
||||
gfx3DMatrix perspective;
|
||||
perspective._34 =
|
||||
-1.0 / NSAppUnitsToFloatPixels(perspectiveCoord, aAppUnitsPerPixel);
|
||||
-1.0 / NSAppUnitsToFloatPixels(parentDisp->mChildPerspective.GetCoordValue(),
|
||||
aAppUnitsPerPixel);
|
||||
/* At the point when perspective is applied, we have been translated to the transform origin.
|
||||
* The translation to the perspective origin is the difference between these values.
|
||||
*/
|
||||
gfxPoint3D toPerspectiveOrigin = aFrame ? GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel) : *aToPerspectiveOrigin;
|
||||
gfxPoint3D toPerspectiveOrigin = GetDeltaToMozPerspectiveOrigin(aFrame, aAppUnitsPerPixel);
|
||||
result = result * nsLayoutUtils::ChangeMatrixBasis(toPerspectiveOrigin - toMozOrigin, perspective);
|
||||
}
|
||||
|
||||
if (aFrame && aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) {
|
||||
if (aFrame->Preserves3D() && nsLayoutUtils::Are3DTransformsEnabled()) {
|
||||
// Include the transform set on our parent
|
||||
NS_ASSERTION(aFrame->GetParent() &&
|
||||
aFrame->GetParent()->IsTransformed() &&
|
||||
aFrame->GetParent()->Preserves3DChildren(),
|
||||
"Preserve3D mismatch!");
|
||||
gfx3DMatrix parent =
|
||||
GetResultingTransformMatrix(aFrame->GetParent(),
|
||||
aOrigin - aFrame->GetPosition(),
|
||||
aAppUnitsPerPixel, nsnull, nsnull, nsnull,
|
||||
nsnull, nsnull, aOutAncestor);
|
||||
gfx3DMatrix parent = GetResultingTransformMatrix(aFrame->GetParent(), aOrigin - aFrame->GetPosition(),
|
||||
aAppUnitsPerPixel, nsnull, aOutAncestor);
|
||||
return nsLayoutUtils::ChangeMatrixBasis(newOrigin + toMozOrigin, result) * parent;
|
||||
}
|
||||
|
||||
|
@ -3320,7 +2926,7 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui
|
|||
}
|
||||
|
||||
/* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */
|
||||
static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix)
|
||||
static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
if (aMatrix.IsSingular()) {
|
||||
return false;
|
||||
|
@ -3338,7 +2944,8 @@ nsDisplayTransform::GetTransform(float aAppUnitsPerPixel)
|
|||
if (mTransform.IsIdentity() || mCachedAppUnitsPerPixel != aAppUnitsPerPixel) {
|
||||
mTransform =
|
||||
GetResultingTransformMatrix(mFrame, ToReferenceFrame(),
|
||||
aAppUnitsPerPixel);
|
||||
aAppUnitsPerPixel,
|
||||
nsnull);
|
||||
mCachedAppUnitsPerPixel = aAppUnitsPerPixel;
|
||||
}
|
||||
return mTransform;
|
||||
|
@ -3348,7 +2955,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
|||
LayerManager *aManager,
|
||||
const ContainerParameters& aContainerParameters)
|
||||
{
|
||||
const gfx3DMatrix& newTransformMatrix =
|
||||
const gfx3DMatrix& newTransformMatrix =
|
||||
GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
|
||||
if (!IsFrameVisible(mFrame, newTransformMatrix)) {
|
||||
|
@ -3364,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();
|
||||
}
|
||||
|
||||
|
@ -3380,18 +2985,12 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
|
|||
return LAYER_ACTIVE;
|
||||
if (!GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel()).Is2D() || mFrame->Preserves3D())
|
||||
return LAYER_ACTIVE;
|
||||
if (mFrame->GetContent()) {
|
||||
if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(),
|
||||
eCSSProperty_transform)) {
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
}
|
||||
nsIFrame* activeScrolledRoot =
|
||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
||||
return !mStoredList.ChildrenCanBeInactive(aBuilder,
|
||||
aManager,
|
||||
return !mStoredList.ChildrenCanBeInactive(aBuilder,
|
||||
aManager,
|
||||
aParameters,
|
||||
*mStoredList.GetList(),
|
||||
*mStoredList.GetList(),
|
||||
activeScrolledRoot)
|
||||
? LAYER_ACTIVE : LAYER_INACTIVE;
|
||||
}
|
||||
|
@ -3410,9 +3009,9 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
|
|||
!UntransformRectMatrix(mVisibleRect,
|
||||
GetTransform(factor),
|
||||
factor,
|
||||
&untransformedVisibleRect))
|
||||
&untransformedVisibleRect))
|
||||
{
|
||||
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() +
|
||||
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() +
|
||||
aBuilder->ToReferenceFrame(mFrame);
|
||||
}
|
||||
nsRegion untransformedVisible = untransformedVisibleRect;
|
||||
|
@ -3477,7 +3076,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
|||
NSFloatPixelsToAppUnits(float(rect.Width()), factor),
|
||||
NSFloatPixelsToAppUnits(float(rect.Height()), factor));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_HIT
|
||||
printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
|
||||
|
@ -3503,8 +3102,8 @@ nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint)
|
|||
gfx3DMatrix matrix = GetTransform(factor);
|
||||
|
||||
NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!");
|
||||
|
||||
gfxPoint point =
|
||||
|
||||
gfxPoint point =
|
||||
matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
|
||||
NSAppUnitsToFloatPixels(aPoint.y, factor)));
|
||||
|
||||
|
@ -3553,7 +3152,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
|
|||
if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) {
|
||||
return nsRegion();
|
||||
}
|
||||
|
||||
|
||||
const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel());
|
||||
|
||||
nsRegion result;
|
||||
|
@ -3700,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, nsnull);
|
||||
|
||||
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();
|
||||
|
@ -2341,13 +2341,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
|
||||
|
@ -2381,10 +2374,6 @@ public:
|
|||
const nsPoint& aOrigin,
|
||||
float aAppUnitsPerPixel,
|
||||
const nsRect* aBoundsOverride = nsnull,
|
||||
const nsCSSValueList* aTransformOverride = nsnull,
|
||||
gfxPoint3D* aToMozOrigin = nsnull,
|
||||
gfxPoint3D* aToPerspectiveOrigin = nsnull,
|
||||
nscoord* aChildPerspective = nsnull,
|
||||
nsIFrame** aOutAncestor = nsnull);
|
||||
/**
|
||||
* Return true when we should try to prerender the entire contents of the
|
||||
|
|
|
@ -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()
|
||||
|
@ -151,43 +122,13 @@ nsLayoutUtils::Are3DTransformsEnabled()
|
|||
|
||||
if (!s3DTransformPrefCached) {
|
||||
s3DTransformPrefCached = true;
|
||||
mozilla::Preferences::AddBoolVarCache(&s3DTransformsEnabled,
|
||||
mozilla::Preferences::AddBoolVarCache(&s3DTransformsEnabled,
|
||||
"layout.3d-transforms.enabled");
|
||||
}
|
||||
|
||||
return s3DTransformsEnabled;
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::AreOpacityAnimationsEnabled()
|
||||
{
|
||||
static bool sAreOpacityAnimationsEnabled;
|
||||
static bool sOpacityPrefCached = false;
|
||||
|
||||
if (!sOpacityPrefCached) {
|
||||
sOpacityPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sAreOpacityAnimationsEnabled,
|
||||
"layers.offmainthreadcomposition.animate-opacity");
|
||||
}
|
||||
|
||||
return sAreOpacityAnimationsEnabled && CompositorParent::CompositorLoop();
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::AreTransformAnimationsEnabled()
|
||||
{
|
||||
static bool sAreTransformAnimationsEnabled;
|
||||
static bool sTransformPrefCached = false;
|
||||
|
||||
if (!sTransformPrefCached) {
|
||||
sTransformPrefCached = true;
|
||||
Preferences::AddBoolVarCache(&sAreTransformAnimationsEnabled,
|
||||
"layers.offmainthreadcomposition.animate-transform");
|
||||
}
|
||||
|
||||
return sAreTransformAnimationsEnabled && CompositorParent::CompositorLoop();
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::UseBackgroundNearestFiltering()
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
@ -1768,6 +1755,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplayList* aList) {
|
||||
if (GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
|
||||
return NS_OK;
|
||||
|
||||
// Replaced elements have their visibility handled here, because
|
||||
// they're visually atomic
|
||||
if (IsFrameOfType(eReplaced) && !IsVisibleForPainting(aBuilder))
|
||||
|
@ -1775,13 +1763,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
|
||||
nsRect clipPropClip;
|
||||
const nsStyleDisplay* disp = GetStyleDisplay();
|
||||
// We can stop right away if this is a zero-opacity stacking context,
|
||||
// we're painting, and we're not animating opacity.
|
||||
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() &&
|
||||
!nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
||||
eCSSProperty_opacity)) {
|
||||
// We can stop right away if this is a zero-opacity stacking context and
|
||||
// we're painting.
|
||||
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting())
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool applyClipPropClipping =
|
||||
ApplyClipPropClipping(aBuilder, disp, this, &clipPropClip);
|
||||
|
@ -1798,7 +1783,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||
// gives us really weird results. I believe this is from points that lie beyond the
|
||||
// vanishing point. As a workaround we transform the overflow rect into screen space
|
||||
// and compare in that coordinate system.
|
||||
|
||||
|
||||
// Transform the overflow rect into screen space
|
||||
nsRect overflow = GetVisualOverflowRectRelativeToSelf();
|
||||
nsPoint offset = aBuilder->ToReferenceFrame(this);
|
||||
|
@ -1935,6 +1920,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
|
||||
|
@ -1950,7 +1936,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(
|
||||
|
@ -2104,7 +2090,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);
|
||||
|
||||
|
@ -4772,8 +4758,8 @@ nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
|||
PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
gfx3DMatrix result =
|
||||
nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0), scaleFactor, nsnull,
|
||||
nsnull, nsnull, nsnull, nsnull, aOutAncestor);
|
||||
nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0),
|
||||
scaleFactor, nsnull, aOutAncestor);
|
||||
// XXXjwatt: seems like this will double count offsets in the face of preserve-3d:
|
||||
nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor);
|
||||
/* Combine the raw transform with a translation to our parent. */
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -1227,8 +1227,6 @@ public:
|
|||
* an SVG viewBox attribute).
|
||||
*/
|
||||
bool IsTransformed() const;
|
||||
|
||||
bool HasOpacity() const;
|
||||
|
||||
/**
|
||||
* Returns true if this frame is an SVG frame that has SVG transforms applied
|
||||
|
|
|
@ -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,7 +246,6 @@ 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);
|
||||
|
||||
|
@ -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 nsnull;
|
||||
}
|
||||
nsresult rv = aElement->SetProperty(propName, ea,
|
||||
ElementAnimationsPropertyDtor, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -357,9 +362,6 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
|||
delete ea;
|
||||
return nsnull;
|
||||
}
|
||||
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 = nsnull;
|
||||
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 = nsnull,
|
||||
ElementAnimations* aEa = nsnull,
|
||||
EventArray* aEventsToDispatch = nsnull);
|
||||
|
||||
void EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||
EventArray &aEventsToDispatch);
|
||||
|
||||
bool IsForElement() const { // rather than for a pseudo-element
|
||||
return mElementProperty == nsGkAtoms::animationsProperty;
|
||||
}
|
||||
|
||||
void PostRestyleForAnimation(nsPresContext *aPresContext) {
|
||||
nsRestyleHint styleHint = IsForElement() ? eRestyle_Self : eRestyle_Subtree;
|
||||
aPresContext->PresShell()->RestyleForAnimation(mElement, styleHint);
|
||||
}
|
||||
|
||||
// True if this animation can be performed on the compositor thread.
|
||||
bool CanPerformOnCompositorThread() const;
|
||||
bool HasAnimationOfProperty(nsCSSProperty aProperty) const;
|
||||
// This style rule contains the style data for currently animating
|
||||
// values. It only matches when styling with animation. When we
|
||||
// style without animation, we need to not use it so that we can
|
||||
// detect any new changes; if necessary we restyle immediately
|
||||
// afterwards with animation.
|
||||
// NOTE: If we don't need to apply any styles, mStyleRule will be
|
||||
// null, but mStyleRuleRefreshTime will still be valid.
|
||||
nsRefPtr<mozilla::css::AnimValuesStyleRule> mStyleRule;
|
||||
// The refresh time associated with mStyleRule.
|
||||
TimeStamp mStyleRuleRefreshTime;
|
||||
|
||||
// False when we know that our current style rule is valid
|
||||
// indefinitely into the future (because all of our animations are
|
||||
// either completed or paused). May be invalidated by a style change.
|
||||
bool mNeedsRefreshes;
|
||||
|
||||
InfallibleTArray<ElementAnimation> mAnimations;
|
||||
};
|
||||
|
||||
class nsAnimationManager : public mozilla::css::CommonAnimationManager
|
||||
{
|
||||
public:
|
||||
nsAnimationManager(nsPresContext *aPresContext)
|
||||
: mozilla::css::CommonAnimationManager(aPresContext)
|
||||
, mKeyframesListIsDirty(true)
|
||||
: mozilla::css::CommonAnimationManager(aPresContext),
|
||||
mKeyframesListIsDirty(true)
|
||||
{
|
||||
mKeyframesRules.Init(16); // FIXME: make infallible!
|
||||
}
|
||||
|
||||
static ElementAnimations* GetAnimationsForCompositor(nsIContent* aContent,
|
||||
nsCSSProperty aProperty)
|
||||
{
|
||||
if (!aContent->MayHaveAnimations())
|
||||
return nsnull;
|
||||
ElementAnimations* animations = static_cast<ElementAnimations*>(
|
||||
aContent->GetProperty(nsGkAtoms::animationsProperty));
|
||||
if (!animations)
|
||||
return nsnull;
|
||||
bool propertyMatches = animations->HasAnimationOfProperty(aProperty);
|
||||
return (propertyMatches && animations->CanPerformOnCompositorThread()) ?
|
||||
animations : nsnull;
|
||||
}
|
||||
struct AnimationEventInfo {
|
||||
nsRefPtr<mozilla::dom::Element> mElement;
|
||||
nsAnimationEvent mEvent;
|
||||
|
||||
AnimationEventInfo(mozilla::dom::Element *aElement,
|
||||
const nsString& aAnimationName,
|
||||
PRUint32 aMessage, mozilla::TimeDuration aElapsedTime)
|
||||
: mElement(aElement),
|
||||
mEvent(true, aMessage, aAnimationName, aElapsedTime.ToSeconds())
|
||||
{
|
||||
}
|
||||
|
||||
// nsAnimationEvent doesn't support copy-construction, so we need
|
||||
// to ourselves in order to work with nsTArray
|
||||
AnimationEventInfo(const AnimationEventInfo &aOther)
|
||||
: mElement(aOther.mElement),
|
||||
mEvent(true, aOther.mEvent.message,
|
||||
aOther.mEvent.animationName, aOther.mEvent.elapsedTime)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
// nsIStyleRuleProcessor (parts)
|
||||
virtual void RulesMatching(ElementRuleProcessorData* aData);
|
||||
|
@ -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;
|
||||
|
@ -1284,7 +1284,7 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale,
|
|||
/* Normalize the matrix */
|
||||
local.Normalize();
|
||||
|
||||
/**
|
||||
/**
|
||||
* perspective is used to solve for perspective, but it also provides
|
||||
* an easy way to test for singularity of the upper 3x3 component.
|
||||
*/
|
||||
|
@ -1302,13 +1302,13 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale,
|
|||
/* aPerspective is the right hand side of the equation. */
|
||||
aPerspective = local.TransposedVector(3);
|
||||
|
||||
/**
|
||||
/**
|
||||
* Solve the equation by inverting perspective and multiplying
|
||||
* aPerspective by the inverse.
|
||||
*/
|
||||
perspective.Invert();
|
||||
aPerspective = perspective.TransposeTransform4D(aPerspective);
|
||||
|
||||
|
||||
/* Clear the perspective partition */
|
||||
local.SetTransposedVector(3, empty);
|
||||
} else {
|
||||
|
@ -1326,11 +1326,11 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale,
|
|||
/* Compute X scale factor and normalize first row. */
|
||||
aScale.x = local[0].Length();
|
||||
local[0] /= aScale.x;
|
||||
|
||||
|
||||
/* Compute XY shear factor and make 2nd local orthogonal to 1st. */
|
||||
aShear[XYSHEAR] = local[0].DotProduct(local[1]);
|
||||
local[1] -= local[0] * aShear[XYSHEAR];
|
||||
|
||||
|
||||
/* Now, compute Y scale and normalize 2nd local. */
|
||||
aScale.y = local[1].Length();
|
||||
local[1] /= aScale.y;
|
||||
|
@ -1407,11 +1407,11 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
|||
// Interpolate each of the pieces
|
||||
gfx3DMatrix result;
|
||||
|
||||
gfxPointH3D perspective =
|
||||
gfxPointH3D perspective =
|
||||
InterpolateNumerically(perspective1, perspective2, aProgress);
|
||||
result.SetTransposedVector(3, perspective);
|
||||
|
||||
gfxPoint3D translate =
|
||||
|
||||
gfxPoint3D translate =
|
||||
InterpolateNumerically(translate1, translate2, aProgress);
|
||||
result.Translate(translate);
|
||||
|
||||
|
@ -1440,7 +1440,7 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
|||
result.SkewXY(xyshear);
|
||||
}
|
||||
|
||||
gfxPoint3D scale =
|
||||
gfxPoint3D scale =
|
||||
InterpolateNumerically(scale1, scale2, aProgress);
|
||||
if (scale != gfxPoint3D(1.0, 1.0, 1.0)) {
|
||||
result.Scale(scale.x, scale.y, scale.z);
|
||||
|
@ -1457,8 +1457,8 @@ AddDifferentTransformLists(const nsCSSValueList* aList1, double aCoeff1,
|
|||
nsCSSValueList **resultTail = getter_Transfers(result);
|
||||
|
||||
nsRefPtr<nsCSSValue::Array> arr;
|
||||
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_interpolatematrix, resultTail);
|
||||
|
||||
arr = AppendTransformFunction(eCSSKeyword_interpolatematrix, resultTail);
|
||||
|
||||
// FIXME: We should change the other transform code to also only
|
||||
// take a single progress value, as having values that don't
|
||||
// sum to 1 doesn't make sense for these.
|
||||
|
@ -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;
|
||||
|
||||
|
@ -128,7 +132,7 @@ public:
|
|||
* (property ID + string). A style context is needed in case the
|
||||
* specified value depends on inherited style or on the values of other
|
||||
* properties.
|
||||
*
|
||||
*
|
||||
* @param aProperty The property whose value we're computing.
|
||||
* @param aTargetElement The content node to which our computed value is
|
||||
* applicable.
|
||||
|
@ -199,13 +203,9 @@ public:
|
|||
* @param aProgress Interpolation value in the range [0.0, 1.0]
|
||||
*/
|
||||
static gfx3DMatrix InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
||||
const gfx3DMatrix &aMatrix2,
|
||||
const gfx3DMatrix &aMatrix2,
|
||||
double aProgress);
|
||||
|
||||
static already_AddRefed<nsCSSValue::Array>
|
||||
AppendTransformFunction(nsCSSKeyword aTransformFunction,
|
||||
nsCSSValueList**& aListTail);
|
||||
|
||||
/**
|
||||
* The types and values for the values that we extract and animate.
|
||||
*/
|
||||
|
|
|
@ -60,13 +60,12 @@ static nscoord CalcLength(const nsCSSValue &aValue,
|
|||
aCanStoreInRuleTree);
|
||||
}
|
||||
|
||||
float
|
||||
static float
|
||||
ProcessTranslatePart(const nsCSSValue& aValue,
|
||||
nsStyleContext* aContext,
|
||||
nsPresContext* aPresContext,
|
||||
bool& aCanStoreInRuleTree,
|
||||
nscoord aSize,
|
||||
float aAppUnitsPerMatrixUnit)
|
||||
nscoord aSize, float aAppUnitsPerMatrixUnit)
|
||||
{
|
||||
nscoord offset = 0;
|
||||
float percent = 0.0f;
|
||||
|
|
|
@ -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 *
|
||||
*****************************************************************************/
|
||||
|
@ -195,12 +225,13 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||
disp->mTransitions[0].GetDelay() == 0.0f &&
|
||||
disp->mTransitions[0].GetDuration() == 0.0f) {
|
||||
return nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (aNewStyleContext->PresContext()->IsProcessingAnimationStyleChange()) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
if (aNewStyleContext->GetParent() &&
|
||||
aNewStyleContext->GetParent()->HasPseudoElementData()) {
|
||||
// Ignore transitions on things that inherit properties from
|
||||
|
@ -229,7 +260,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||
property == eCSSProperty_UNKNOWN) {
|
||||
// Nothing to do, but need to exclude this from cases below.
|
||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
p < eCSSProperty_COUNT_no_shorthands;
|
||||
p = nsCSSProperty(p + 1)) {
|
||||
ConsiderStartingTransition(p, t, aElement, et,
|
||||
|
@ -269,7 +300,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||
property == eCSSProperty_UNKNOWN) {
|
||||
// Nothing to do, but need to exclude this from cases below.
|
||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
for (nsCSSProperty p = nsCSSProperty(0);
|
||||
p < eCSSProperty_COUNT_no_shorthands;
|
||||
p = nsCSSProperty(p + 1)) {
|
||||
allTransitionProperties.AddProperty(p);
|
||||
|
@ -333,7 +364,11 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||
// rule.
|
||||
|
||||
nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
|
||||
|
||||
if (!coverRule) {
|
||||
NS_WARNING("out of memory");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
|
||||
for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
||||
ElementPropertyTransition &pt = pts[i];
|
||||
|
@ -378,19 +413,9 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
pt.mStartValue) &&
|
||||
ExtractComputedValueForTransition(aProperty, aNewStyleContext,
|
||||
pt.mEndValue);
|
||||
|
||||
bool haveChange = pt.mStartValue != pt.mEndValue;
|
||||
bool haveOMTA = false;
|
||||
if (!aNewStyleContext->GetPseudoType()) {
|
||||
ElementTransitions* et = nsTransitionManager::GetTransitions(aElement);
|
||||
if (et) {
|
||||
haveOMTA = et->CanPerformOnCompositorThread();
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldAnimate =
|
||||
haveValues &&
|
||||
(haveChange || haveOMTA) &&
|
||||
pt.mStartValue != pt.mEndValue &&
|
||||
// Check that we can interpolate between these values
|
||||
// (If this is ever a performance problem, we could add a
|
||||
// CanInterpolate method, but it seems fine for now.)
|
||||
|
@ -471,7 +496,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
// now we'd end up at the current position.
|
||||
double valuePortion =
|
||||
oldPT.ValuePortionFor(mostRecentRefresh) * oldPT.mReversePortion +
|
||||
(1.0 - oldPT.mReversePortion);
|
||||
(1.0 - oldPT.mReversePortion);
|
||||
// A timing function with negative y1 (or y2!) might make
|
||||
// valuePortion negative. In this case, we still want to apply our
|
||||
// reversing logic based on relative distances, not make duration
|
||||
|
@ -491,7 +516,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
// reduce positive delays.
|
||||
if (delay < 0.0f)
|
||||
delay *= valuePortion;
|
||||
|
||||
duration *= valuePortion;
|
||||
|
||||
pt.mStartForReversingTest = oldPT.mEndValue;
|
||||
|
@ -503,6 +527,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
|
||||
pt.mDuration = TimeDuration::FromMilliseconds(duration);
|
||||
pt.mTimingFunction.Init(tf);
|
||||
|
||||
if (!aElementTransitions) {
|
||||
aElementTransitions =
|
||||
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
|
||||
|
@ -512,7 +537,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsTArray<ElementPropertyTransition> &pts =
|
||||
aElementTransitions->mPropertyTransitions;
|
||||
#ifdef DEBUG
|
||||
|
@ -536,7 +561,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||
nsCSSPseudoElements::ePseudo_NotPseudoElement ?
|
||||
eRestyle_Self : eRestyle_Subtree;
|
||||
presContext->PresShell()->RestyleForAnimation(aElement, hint);
|
||||
// XXXdz: invalidate the frame here, once animations are throttled.
|
||||
|
||||
*aStartedAny = true;
|
||||
aWhichStarted->AddProperty(aProperty);
|
||||
|
@ -570,6 +594,10 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement,
|
|||
if (!et && aCreateIfNeeded) {
|
||||
// FIXME: Consider arena-allocating?
|
||||
et = new ElementTransitions(aElement, propName, this);
|
||||
if (!et) {
|
||||
NS_WARNING("out of memory");
|
||||
return nsnull;
|
||||
}
|
||||
nsresult rv = aElement->SetProperty(propName, et,
|
||||
ElementTransitionsPropertyDtor, nsnull);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -577,9 +605,6 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement,
|
|||
delete et;
|
||||
return nsnull;
|
||||
}
|
||||
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,28 +25,8 @@ 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 nsnull;
|
||||
ElementTransitions* transitions = GetTransitions(aContent);
|
||||
if (!transitions ||
|
||||
!transitions->HasTransitionOfProperty(aProperty) ||
|
||||
!transitions->CanPerformOnCompositorThread()) {
|
||||
return nsnull;
|
||||
}
|
||||
return transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* StyleContextChanged
|
||||
* StyleContextChanged
|
||||
*
|
||||
* To be called from nsFrameManager::ReResolveStyleContext when the
|
||||
* style of an element has changed, to initiate transitions from
|
||||
|
|
|
@ -3503,10 +3503,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);
|
||||
|
|
|
@ -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) {}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче