Back out f4f5189b1d0c, 3b4f0606c547, b8a5a1ab8a5f, 5078933d6954, 7e0260c45de9 (bug 768440, bug 755084, bug 706179) because of reftest failures
This commit is contained in:
@@ -11,7 +11,6 @@
|
|||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsIDocument.h" // for IsInHTMLDocument
|
#include "nsIDocument.h" // for IsInHTMLDocument
|
||||||
#include "nsCSSProperty.h"
|
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
|||||||
@@ -1291,8 +1291,6 @@ private:
|
|||||||
NodeMayHaveDOMMutationObserver,
|
NodeMayHaveDOMMutationObserver,
|
||||||
// Set if node is Content
|
// Set if node is Content
|
||||||
NodeIsContent,
|
NodeIsContent,
|
||||||
// Set if the node has animations or transitions
|
|
||||||
ElementHasAnimations,
|
|
||||||
// Guard value
|
// Guard value
|
||||||
BooleanFlagCount
|
BooleanFlagCount
|
||||||
};
|
};
|
||||||
@@ -1358,8 +1356,6 @@ public:
|
|||||||
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
|
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
|
||||||
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
|
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
|
||||||
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
||||||
bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
|
|
||||||
void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
|
|
||||||
protected:
|
protected:
|
||||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||||
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
||||||
|
|||||||
@@ -26,11 +26,6 @@ public:
|
|||||||
Init(aX1, aY1, aX2, aY2);
|
Init(aX1, aY1, aX2, aY2);
|
||||||
}
|
}
|
||||||
|
|
||||||
double X1() const { return mX1; }
|
|
||||||
double Y1() const { return mY1; }
|
|
||||||
double X2() const { return mX2; }
|
|
||||||
double Y2() const { return mY2; }
|
|
||||||
|
|
||||||
void Init(double aX1, double aY1,
|
void Init(double aX1, double aY1,
|
||||||
double aX2, double aY2);
|
double aX2, double aY2);
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "mozilla/Util.h"
|
#include "mozilla/Util.h"
|
||||||
#include "LayerSorter.h"
|
#include "LayerSorter.h"
|
||||||
#include "AnimationCommon.h"
|
|
||||||
|
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
@@ -221,245 +220,6 @@ LayerManager::CreateAsynchronousImageContainer()
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// Layer
|
// 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
|
bool
|
||||||
Layer::CanUseOpaqueSurface()
|
Layer::CanUseOpaqueSurface()
|
||||||
{
|
{
|
||||||
@@ -544,7 +304,7 @@ Layer::SnapTransform(const gfx3DMatrix& aTransform,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIntRect
|
nsIntRect
|
||||||
Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
||||||
const gfxMatrix* aWorldTransform)
|
const gfxMatrix* aWorldTransform)
|
||||||
{
|
{
|
||||||
@@ -601,34 +361,21 @@ Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
|||||||
return currentClip.Intersect(scissor);
|
return currentClip.Intersect(scissor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gfx3DMatrix
|
const gfx3DMatrix&
|
||||||
Layer::GetLocalTransform()
|
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())
|
if (ShadowLayer* shadow = AsShadowLayer())
|
||||||
return shadow->GetShadowOpacity();
|
return shadow->GetShadowTransform();
|
||||||
return mOpacity;
|
return mTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
Layer::GetEffectiveOpacity()
|
Layer::GetEffectiveOpacity()
|
||||||
{
|
{
|
||||||
float opacity = GetLocalOpacity();
|
float opacity = GetOpacity();
|
||||||
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
||||||
c = c->GetParent()) {
|
c = c->GetParent()) {
|
||||||
opacity *= c->GetLocalOpacity();
|
opacity *= c->GetOpacity();
|
||||||
}
|
}
|
||||||
return opacity;
|
return opacity;
|
||||||
}
|
}
|
||||||
@@ -637,15 +384,14 @@ void
|
|||||||
Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurface)
|
Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurface)
|
||||||
{
|
{
|
||||||
if (mMaskLayer) {
|
if (mMaskLayer) {
|
||||||
mMaskLayer->mEffectiveTransform = aTransformToSurface;
|
mMaskLayer->mEffectiveTransform = aTransformToSurface;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
gfxMatrix maskTranslation;
|
||||||
gfxMatrix maskTranslation;
|
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
|
||||||
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
|
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
#endif
|
||||||
#endif
|
mMaskLayer->mEffectiveTransform.PreMultiply(mMaskLayer->GetTransform());
|
||||||
mMaskLayer->mEffectiveTransform.PreMultiply(mMaskLayer->GetTransform());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1044,7 +790,7 @@ void
|
|||||||
LayerManager::Dump(FILE* aFile, const char* aPrefix)
|
LayerManager::Dump(FILE* aFile, const char* aPrefix)
|
||||||
{
|
{
|
||||||
FILE* file = FILEOrDefault(aFile);
|
FILE* file = FILEOrDefault(aFile);
|
||||||
|
|
||||||
fprintf(file, "<ul><li><a ");
|
fprintf(file, "<ul><li><a ");
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
WriteSnapshotLinkToDumpFile(this, file);
|
WriteSnapshotLinkToDumpFile(this, file);
|
||||||
@@ -1061,7 +807,7 @@ LayerManager::Dump(FILE* aFile, const char* aPrefix)
|
|||||||
fprintf(file, "%s(null)</li></ul>", pfx.get());
|
fprintf(file, "%s(null)</li></ul>", pfx.get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(file, "<ul>");
|
fprintf(file, "<ul>");
|
||||||
GetRoot()->Dump(file, pfx.get());
|
GetRoot()->Dump(file, pfx.get());
|
||||||
fprintf(file, "</ul></li></ul>");
|
fprintf(file, "</ul></li></ul>");
|
||||||
@@ -1195,5 +941,5 @@ LayerManager::PrintInfo(nsACString& aTo, const char* aPrefix)
|
|||||||
|
|
||||||
PRLogModuleInfo* LayerManager::sLog;
|
PRLogModuleInfo* LayerManager::sLog;
|
||||||
|
|
||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
#include "gfxPattern.h"
|
#include "gfxPattern.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsStyleAnimation.h"
|
|
||||||
#include "LayersBackend.h"
|
#include "LayersBackend.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
@@ -44,14 +43,8 @@ namespace gl {
|
|||||||
class GLContext;
|
class GLContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace css {
|
|
||||||
class ComputedTimingFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
class Animation;
|
|
||||||
class CommonLayerAttributes;
|
|
||||||
class Layer;
|
class Layer;
|
||||||
class ThebesLayer;
|
class ThebesLayer;
|
||||||
class ContainerLayer;
|
class ContainerLayer;
|
||||||
@@ -537,13 +530,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ThebesLayer;
|
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
|
* A Layer represents anything that can be rendered onto a destination
|
||||||
@@ -565,7 +551,7 @@ public:
|
|||||||
TYPE_THEBES
|
TYPE_THEBES
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Layer();
|
virtual ~Layer() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the LayerManager this Layer belongs to. Note that the layer
|
* Returns the LayerManager this Layer belongs to. Note that the layer
|
||||||
@@ -722,13 +708,6 @@ public:
|
|||||||
Mutated();
|
Mutated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetScale(float aXScale, float aYScale)
|
|
||||||
{
|
|
||||||
mXScale = aXScale;
|
|
||||||
mYScale = aYScale;
|
|
||||||
Mutated();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CONSTRUCTION PHASE ONLY
|
* CONSTRUCTION PHASE ONLY
|
||||||
* A layer is "fixed position" when it draws content from a content
|
* A layer is "fixed position" when it draws content from a content
|
||||||
@@ -737,14 +716,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; }
|
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
|
* CONSTRUCTION PHASE ONLY
|
||||||
* If a layer is "fixed position", this determines which point on the layer
|
* If a layer is "fixed position", this determines which point on the layer
|
||||||
@@ -765,13 +736,10 @@ public:
|
|||||||
virtual Layer* GetFirstChild() { return nsnull; }
|
virtual Layer* GetFirstChild() { return nsnull; }
|
||||||
virtual Layer* GetLastChild() { return nsnull; }
|
virtual Layer* GetLastChild() { return nsnull; }
|
||||||
const gfx3DMatrix& GetTransform() { return mTransform; }
|
const gfx3DMatrix& GetTransform() { return mTransform; }
|
||||||
float GetXScale() { return mXScale; }
|
|
||||||
float GetYScale() { return mYScale; }
|
|
||||||
bool GetIsFixedPosition() { return mIsFixedPosition; }
|
bool GetIsFixedPosition() { return mIsFixedPosition; }
|
||||||
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
|
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
|
||||||
Layer* GetMaskLayer() { return mMaskLayer; }
|
Layer* GetMaskLayer() { return mMaskLayer; }
|
||||||
AnimationArray& GetAnimations() { return mAnimations; }
|
|
||||||
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
|
||||||
/**
|
/**
|
||||||
* DRAWING PHASE ONLY
|
* DRAWING PHASE ONLY
|
||||||
*
|
*
|
||||||
@@ -972,7 +940,20 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
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); }
|
void Mutated() { mManager->Mutated(this); }
|
||||||
|
|
||||||
@@ -987,13 +968,7 @@ protected:
|
|||||||
* Returns the local transform for this layer: either mTransform or,
|
* Returns the local transform for this layer: either mTransform or,
|
||||||
* for shadow layers, GetShadowTransform()
|
* for shadow layers, GetShadowTransform()
|
||||||
*/
|
*/
|
||||||
const gfx3DMatrix GetLocalTransform();
|
const gfx3DMatrix& GetLocalTransform();
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the local opacity for this layer: either mOpacity or,
|
|
||||||
* for shadow layers, GetShadowOpacity()
|
|
||||||
*/
|
|
||||||
const float GetLocalOpacity();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes a tweaked version of aTransform that snaps a point or a rectangle
|
* Computes a tweaked version of aTransform that snaps a point or a rectangle
|
||||||
@@ -1019,11 +994,7 @@ protected:
|
|||||||
gfx::UserData mUserData;
|
gfx::UserData mUserData;
|
||||||
nsIntRegion mVisibleRegion;
|
nsIntRegion mVisibleRegion;
|
||||||
gfx3DMatrix mTransform;
|
gfx3DMatrix mTransform;
|
||||||
float mXScale;
|
|
||||||
float mYScale;
|
|
||||||
gfx3DMatrix mEffectiveTransform;
|
gfx3DMatrix mEffectiveTransform;
|
||||||
AnimationArray mAnimations;
|
|
||||||
InfallibleTArray<AnimData> mAnimationData;
|
|
||||||
float mOpacity;
|
float mOpacity;
|
||||||
nsIntRect mClipRect;
|
nsIntRect mClipRect;
|
||||||
nsIntRect mTileSourceRect;
|
nsIntRect mTileSourceRect;
|
||||||
|
|||||||
@@ -21,15 +21,6 @@
|
|||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
#include "RenderTrace.h"
|
#include "RenderTrace.h"
|
||||||
#include "ShadowLayersParent.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 base;
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
@@ -421,15 +412,15 @@ CompositorParent::Composite()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer* layer = mLayerManager->GetRoot();
|
Layer* aLayer = mLayerManager->GetRoot();
|
||||||
AutoResolveRefLayers resolve(layer);
|
AutoResolveRefLayers resolve(aLayer);
|
||||||
|
|
||||||
bool requestNextFrame = TransformShadowTree(mLastCompose);
|
bool requestNextFrame = TransformShadowTree(mLastCompose);
|
||||||
if (requestNextFrame) {
|
if (requestNextFrame) {
|
||||||
ScheduleComposition();
|
ScheduleComposition();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTraceLayers(layer, "0000");
|
RenderTraceLayers(aLayer, "0000");
|
||||||
|
|
||||||
mLayerManager->EndEmptyTransaction();
|
mLayerManager->EndEmptyTransaction();
|
||||||
|
|
||||||
@@ -522,7 +513,6 @@ SetShadowProperties(Layer* aLayer)
|
|||||||
shadow->SetShadowTransform(aLayer->GetTransform());
|
shadow->SetShadowTransform(aLayer->GetTransform());
|
||||||
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
||||||
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
||||||
shadow->SetShadowOpacity(aLayer->GetOpacity());
|
|
||||||
|
|
||||||
for (Layer* child = aLayer->GetFirstChild();
|
for (Layer* child = aLayer->GetFirstChild();
|
||||||
child; child = child->GetNextSibling()) {
|
child; child = child->GetNextSibling()) {
|
||||||
@@ -530,114 +520,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
|
bool
|
||||||
CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
||||||
Layer *aLayer,
|
Layer *aLayer,
|
||||||
@@ -683,10 +565,6 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
|||||||
ContainerLayer* container = layer->AsContainerLayer();
|
ContainerLayer* container = layer->AsContainerLayer();
|
||||||
Layer* root = mLayerManager->GetRoot();
|
Layer* root = mLayerManager->GetRoot();
|
||||||
|
|
||||||
// NB: we must sample animations *before* sampling pan/zoom
|
|
||||||
// transforms.
|
|
||||||
wantNextFrame |= SampleAnimations(layer, mLastCompose);
|
|
||||||
|
|
||||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||||
const gfx3DMatrix& rootTransform = root->GetTransform();
|
const gfx3DMatrix& rootTransform = root->GetTransform();
|
||||||
const gfx3DMatrix& currentTransform = layer->GetTransform();
|
const gfx3DMatrix& currentTransform = layer->GetTransform();
|
||||||
@@ -782,6 +660,7 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
|||||||
shadow->SetShadowTransform(treeTransform * currentTransform);
|
shadow->SetShadowTransform(treeTransform * currentTransform);
|
||||||
TransformFixedLayers(layer, offset, scaleDiff);
|
TransformFixedLayers(layer, offset, scaleDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wantNextFrame;
|
return wantNextFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace layers {
|
|||||||
* PLayer represents a layer shared across thread contexts.
|
* PLayer represents a layer shared across thread contexts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async protocol PLayer {
|
sync protocol PLayer {
|
||||||
manager PLayers;
|
manager PLayers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +32,7 @@ async protocol PLayer {
|
|||||||
* being deleted "soon" (usually immediately).
|
* being deleted "soon" (usually immediately).
|
||||||
*/
|
*/
|
||||||
parent:
|
parent:
|
||||||
async __delete__();
|
__delete__();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // layers
|
} // layers
|
||||||
|
|||||||
@@ -12,14 +12,6 @@ include protocol PLayer;
|
|||||||
include protocol PRenderFrame;
|
include protocol PRenderFrame;
|
||||||
|
|
||||||
include "gfxipc/ShadowLayerUtils.h";
|
include "gfxipc/ShadowLayerUtils.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
|
* The layers protocol is spoken between thread contexts that manage
|
||||||
@@ -43,7 +35,7 @@ struct OpCreateRefLayer { PLayer layer; };
|
|||||||
struct ThebesBuffer {
|
struct ThebesBuffer {
|
||||||
SurfaceDescriptor buffer;
|
SurfaceDescriptor buffer;
|
||||||
nsIntRect rect;
|
nsIntRect rect;
|
||||||
nsIntPoint rotation;
|
nsIntPoint rotation;
|
||||||
};
|
};
|
||||||
union OptionalThebesBuffer { ThebesBuffer; null_t; };
|
union OptionalThebesBuffer { ThebesBuffer; null_t; };
|
||||||
|
|
||||||
@@ -52,129 +44,24 @@ union CanvasSurface {
|
|||||||
null_t;
|
null_t;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CubicBezierFunction {
|
// Change a layer's attributes
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CommonLayerAttributes {
|
struct CommonLayerAttributes {
|
||||||
nsIntRegion visibleRegion;
|
nsIntRegion visibleRegion;
|
||||||
TransformMatrix transform;
|
gfx3DMatrix transform;
|
||||||
float xScale;
|
|
||||||
float yScale;
|
|
||||||
PRUint32 contentFlags;
|
PRUint32 contentFlags;
|
||||||
Opacity opacity;
|
float opacity;
|
||||||
bool useClipRect;
|
bool useClipRect;
|
||||||
nsIntRect clipRect;
|
nsIntRect clipRect;
|
||||||
bool isFixedPosition;
|
bool isFixedPosition;
|
||||||
gfxPoint fixedPositionAnchor;
|
gfxPoint fixedPositionAnchor;
|
||||||
nullable PLayer maskLayer;
|
nullable PLayer maskLayer;
|
||||||
// Animated colors will only honored for ColorLayers.
|
|
||||||
Animation[] animations;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ThebesLayerAttributes {
|
struct ThebesLayerAttributes {
|
||||||
nsIntRegion validRegion;
|
nsIntRegion validRegion;
|
||||||
};
|
};
|
||||||
struct ContainerLayerAttributes{ FrameMetrics metrics; };
|
struct ContainerLayerAttributes{ FrameMetrics metrics; };
|
||||||
struct ColorLayerAttributes { Color color; };
|
struct ColorLayerAttributes { gfxRGBA color; };
|
||||||
struct CanvasLayerAttributes { GraphicsFilterType filter; };
|
struct CanvasLayerAttributes { GraphicsFilterType filter; };
|
||||||
struct RefLayerAttributes { int64_t id; };
|
struct RefLayerAttributes { int64_t id; };
|
||||||
struct ImageLayerAttributes {
|
struct ImageLayerAttributes {
|
||||||
|
|||||||
@@ -292,8 +292,6 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
|
|||||||
CommonLayerAttributes& common = attrs.common();
|
CommonLayerAttributes& common = attrs.common();
|
||||||
common.visibleRegion() = mutant->GetVisibleRegion();
|
common.visibleRegion() = mutant->GetVisibleRegion();
|
||||||
common.transform() = mutant->GetTransform();
|
common.transform() = mutant->GetTransform();
|
||||||
common.xScale() = mutant->GetXScale();
|
|
||||||
common.yScale() = mutant->GetYScale();
|
|
||||||
common.contentFlags() = mutant->GetContentFlags();
|
common.contentFlags() = mutant->GetContentFlags();
|
||||||
common.opacity() = mutant->GetOpacity();
|
common.opacity() = mutant->GetOpacity();
|
||||||
common.useClipRect() = !!mutant->GetClipRect();
|
common.useClipRect() = !!mutant->GetClipRect();
|
||||||
@@ -307,7 +305,6 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies)
|
|||||||
common.maskLayerChild() = NULL;
|
common.maskLayerChild() = NULL;
|
||||||
}
|
}
|
||||||
common.maskLayerParent() = NULL;
|
common.maskLayerParent() = NULL;
|
||||||
common.animations() = mutant->GetAnimations();
|
|
||||||
attrs.specific() = null_t();
|
attrs.specific() = null_t();
|
||||||
mutant->FillSpecificAttributes(attrs.specific());
|
mutant->FillSpecificAttributes(attrs.specific());
|
||||||
|
|
||||||
|
|||||||
@@ -522,11 +522,6 @@ public:
|
|||||||
mShadowVisibleRegion = aRegion;
|
mShadowVisibleRegion = aRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetShadowOpacity(float aOpacity)
|
|
||||||
{
|
|
||||||
mShadowOpacity = aOpacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetShadowClipRect(const nsIntRect* aRect)
|
void SetShadowClipRect(const nsIntRect* aRect)
|
||||||
{
|
{
|
||||||
mUseShadowClipRect = aRect != nsnull;
|
mUseShadowClipRect = aRect != nsnull;
|
||||||
@@ -541,7 +536,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// These getters can be used anytime.
|
// These getters can be used anytime.
|
||||||
float GetShadowOpacity() { return mShadowOpacity; }
|
|
||||||
const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nsnull; }
|
const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nsnull; }
|
||||||
const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
|
const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; }
|
||||||
const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
|
const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; }
|
||||||
@@ -551,7 +545,6 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
ShadowLayer()
|
ShadowLayer()
|
||||||
: mAllocator(nsnull)
|
: mAllocator(nsnull)
|
||||||
, mShadowOpacity(1.0)
|
|
||||||
, mUseShadowClipRect(false)
|
, mUseShadowClipRect(false)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@@ -559,7 +552,6 @@ protected:
|
|||||||
nsIntRegion mShadowVisibleRegion;
|
nsIntRegion mShadowVisibleRegion;
|
||||||
gfx3DMatrix mShadowTransform;
|
gfx3DMatrix mShadowTransform;
|
||||||
nsIntRect mShadowClipRect;
|
nsIntRect mShadowClipRect;
|
||||||
float mShadowOpacity;
|
|
||||||
bool mUseShadowClipRect;
|
bool mUseShadowClipRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -212,10 +212,9 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
|||||||
const CommonLayerAttributes& common = attrs.common();
|
const CommonLayerAttributes& common = attrs.common();
|
||||||
layer->SetVisibleRegion(common.visibleRegion());
|
layer->SetVisibleRegion(common.visibleRegion());
|
||||||
layer->SetContentFlags(common.contentFlags());
|
layer->SetContentFlags(common.contentFlags());
|
||||||
layer->SetOpacity(common.opacity().value());
|
layer->SetOpacity(common.opacity());
|
||||||
layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
|
layer->SetClipRect(common.useClipRect() ? &common.clipRect() : NULL);
|
||||||
layer->SetTransform(common.transform().value());
|
layer->SetTransform(common.transform());
|
||||||
layer->SetScale(common.xScale(), common.yScale());
|
|
||||||
static bool fixedPositionLayersEnabled = getenv("MOZ_ENABLE_FIXED_POSITION_LAYERS") != 0;
|
static bool fixedPositionLayersEnabled = getenv("MOZ_ENABLE_FIXED_POSITION_LAYERS") != 0;
|
||||||
if (fixedPositionLayersEnabled) {
|
if (fixedPositionLayersEnabled) {
|
||||||
layer->SetIsFixedPosition(common.isFixedPosition());
|
layer->SetIsFixedPosition(common.isFixedPosition());
|
||||||
@@ -226,7 +225,6 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
|||||||
} else {
|
} else {
|
||||||
layer->SetMaskLayer(NULL);
|
layer->SetMaskLayer(NULL);
|
||||||
}
|
}
|
||||||
layer->SetAnimations(common.animations());
|
|
||||||
|
|
||||||
typedef SpecificLayerAttributes Specific;
|
typedef SpecificLayerAttributes Specific;
|
||||||
const SpecificLayerAttributes& specific = attrs.specific();
|
const SpecificLayerAttributes& specific = attrs.specific();
|
||||||
@@ -257,7 +255,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray<Edit>& cset,
|
|||||||
MOZ_LAYERS_LOG(("[ParentSide] color layer"));
|
MOZ_LAYERS_LOG(("[ParentSide] color layer"));
|
||||||
|
|
||||||
static_cast<ColorLayer*>(layer)->SetColor(
|
static_cast<ColorLayer*>(layer)->SetColor(
|
||||||
specific.get_ColorLayerAttributes().color().value());
|
specific.get_ColorLayerAttributes().color());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Specific::TCanvasLayerAttributes:
|
case Specific::TCanvasLayerAttributes:
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
|
||||||
|
|
||||||
// Check the maximum texture size supported by GL. glTexImage2D supports
|
// Check the maximum texture size supported by GL. glTexImage2D supports
|
||||||
// images of up to 2 + GL_MAX_TEXTURE_SIZE
|
// images of up to 2 + GL_MAX_TEXTURE_SIZE
|
||||||
GLint texSize = gl()->GetMaxTextureSize();
|
GLint texSize = gl()->GetMaxTextureSize();
|
||||||
@@ -118,7 +118,7 @@ CanvasLayerOGL::Initialize(const Data& aData)
|
|||||||
MakeTextureIfNeeded(gl(), mTexture);
|
MakeTextureIfNeeded(gl(), mTexture);
|
||||||
// This should only ever occur with 2d canvas, WebGL can't already have a texture
|
// This should only ever occur with 2d canvas, WebGL can't already have a texture
|
||||||
// of this size can it?
|
// 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?");
|
"Invalid texture size when WebGL surface already exists at that size?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,7 +223,7 @@ CanvasLayerOGL::RenderLayer(int aPreviousDestination,
|
|||||||
GetMaskLayer() ? Mask2d : MaskNone);
|
GetMaskLayer() ? Mask2d : MaskNone);
|
||||||
} else if (mDelayedUpdates) {
|
} else if (mDelayedUpdates) {
|
||||||
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
|
NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
|
||||||
|
|
||||||
drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
|
drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surf = mCanvasSurface;
|
nsRefPtr<gfxASurface> surf = mCanvasSurface;
|
||||||
@@ -299,7 +299,7 @@ ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
|
|||||||
{
|
{
|
||||||
mImplData = static_cast<LayerOGL*>(this);
|
mImplData = static_cast<LayerOGL*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL()
|
ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
@@ -199,12 +199,6 @@ struct NS_GFX nsRect :
|
|||||||
inline nsIntRect ScaleToInsidePixels(float aXScale, float aYScale,
|
inline nsIntRect ScaleToInsidePixels(float aXScale, float aYScale,
|
||||||
nscoord aAppUnitsPerPixel) const;
|
nscoord aAppUnitsPerPixel) const;
|
||||||
inline nsIntRect ToInsidePixels(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 :
|
struct NS_GFX nsIntRect :
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include "chrome/common/ipc_message_utils.h"
|
#include "chrome/common/ipc_message_utils.h"
|
||||||
|
|
||||||
#include "mozilla/TimeStamp.h"
|
|
||||||
#include "mozilla/Util.h"
|
#include "mozilla/Util.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
|
|
||||||
@@ -440,28 +439,11 @@ struct ParamTraits<gfxPoint>
|
|||||||
|
|
||||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||||
{
|
{
|
||||||
return (ReadParam(aMsg, aIter, &aResult->x) &&
|
if (ReadParam(aMsg, aIter, &aResult->x) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->y));
|
ReadParam(aMsg, aIter, &aResult->y))
|
||||||
}
|
return true;
|
||||||
};
|
|
||||||
|
|
||||||
template<>
|
return false;
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -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<>
|
template<>
|
||||||
struct ParamTraits<nsIntPoint>
|
struct ParamTraits<nsIntPoint>
|
||||||
{
|
{
|
||||||
typedef nsIntPoint paramType;
|
typedef nsIntPoint paramType;
|
||||||
|
|
||||||
static void Write(Message* msg, const paramType& param)
|
static void Write(Message* msg, const paramType& param)
|
||||||
{
|
{
|
||||||
WriteParam(msg, param.x);
|
WriteParam(msg, param.x);
|
||||||
@@ -635,7 +599,7 @@ template<>
|
|||||||
struct ParamTraits<nsIntRect>
|
struct ParamTraits<nsIntRect>
|
||||||
{
|
{
|
||||||
typedef nsIntRect paramType;
|
typedef nsIntRect paramType;
|
||||||
|
|
||||||
static void Write(Message* msg, const paramType& param)
|
static void Write(Message* msg, const paramType& param)
|
||||||
{
|
{
|
||||||
WriteParam(msg, param.x);
|
WriteParam(msg, param.x);
|
||||||
@@ -684,11 +648,11 @@ template<>
|
|||||||
struct ParamTraits<nsIntSize>
|
struct ParamTraits<nsIntSize>
|
||||||
{
|
{
|
||||||
typedef nsIntSize paramType;
|
typedef nsIntSize paramType;
|
||||||
|
|
||||||
static void Write(Message* msg, const paramType& param)
|
static void Write(Message* msg, const paramType& param)
|
||||||
{
|
{
|
||||||
WriteParam(msg, param.width);
|
WriteParam(msg, param.width);
|
||||||
WriteParam(msg, param.height);
|
WriteParam(msg, param.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||||
@@ -702,11 +666,11 @@ template<>
|
|||||||
struct ParamTraits<mozilla::gfx::Size>
|
struct ParamTraits<mozilla::gfx::Size>
|
||||||
{
|
{
|
||||||
typedef mozilla::gfx::Size paramType;
|
typedef mozilla::gfx::Size paramType;
|
||||||
|
|
||||||
static void Write(Message* msg, const paramType& param)
|
static void Write(Message* msg, const paramType& param)
|
||||||
{
|
{
|
||||||
WriteParam(msg, param.width);
|
WriteParam(msg, param.width);
|
||||||
WriteParam(msg, param.height);
|
WriteParam(msg, param.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Read(const Message* msg, void** iter, paramType* result)
|
static bool Read(const Message* msg, void** iter, paramType* result)
|
||||||
@@ -742,7 +706,7 @@ template<>
|
|||||||
struct ParamTraits<nsRect>
|
struct ParamTraits<nsRect>
|
||||||
{
|
{
|
||||||
typedef nsRect paramType;
|
typedef nsRect paramType;
|
||||||
|
|
||||||
static void Write(Message* msg, const paramType& param)
|
static void Write(Message* msg, const paramType& param)
|
||||||
{
|
{
|
||||||
WriteParam(msg, param.x);
|
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 */
|
} /* namespace IPC */
|
||||||
|
|
||||||
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
|
#endif /* __IPC_GLUE_IPCMESSAGEUTILS_H__ */
|
||||||
|
|||||||
@@ -21,9 +21,6 @@
|
|||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "sampler.h"
|
#include "sampler.h"
|
||||||
|
|
||||||
#include "nsAnimationManager.h"
|
|
||||||
#include "nsTransitionManager.h"
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -631,7 +628,7 @@ FrameLayerBuilder::FlashPaint(gfxContext *aContext)
|
|||||||
|
|
||||||
if (!sPaintFlashingPrefCached) {
|
if (!sPaintFlashingPrefCached) {
|
||||||
sPaintFlashingPrefCached = true;
|
sPaintFlashingPrefCached = true;
|
||||||
mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled,
|
mozilla::Preferences::AddBoolVarCache(&sPaintFlashingEnabled,
|
||||||
"nglayout.debug.paint_flashing");
|
"nglayout.debug.paint_flashing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -996,7 +993,7 @@ ContainerState::CreateOrRecycleMaskImageLayerFor(Layer* aLayer)
|
|||||||
result->SetUserData(&gMaskLayerUserData, new MaskLayerUserData());
|
result->SetUserData(&gMaskLayerUserData, new MaskLayerUserData());
|
||||||
result->SetForceSingleTile(true);
|
result->SetForceSingleTile(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.forget();
|
return result.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,7 +1231,7 @@ ContainerState::ThebesLayerData::UpdateCommonClipCount(
|
|||||||
} else {
|
} else {
|
||||||
// first item in the layer
|
// first item in the layer
|
||||||
mCommonClipCount = aCurrentClip.mRoundedClipRects.Length();
|
mCommonClipCount = aCurrentClip.mRoundedClipRects.Length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<ImageContainer>
|
already_AddRefed<ImageContainer>
|
||||||
@@ -1256,7 +1253,7 @@ ContainerState::PopThebesLayerData()
|
|||||||
ThebesLayerData* data = mThebesLayerDataStack[lastIndex];
|
ThebesLayerData* data = mThebesLayerDataStack[lastIndex];
|
||||||
|
|
||||||
nsRefPtr<Layer> layer;
|
nsRefPtr<Layer> layer;
|
||||||
nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer();
|
nsRefPtr<ImageContainer> imageContainer = data->CanOptimizeImageLayer();
|
||||||
|
|
||||||
if ((data->mIsSolidColorInVisibleRegion || imageContainer) &&
|
if ((data->mIsSolidColorInVisibleRegion || imageContainer) &&
|
||||||
data->mLayer->GetValidRegion().IsEmpty()) {
|
data->mLayer->GetValidRegion().IsEmpty()) {
|
||||||
@@ -1282,7 +1279,7 @@ ContainerState::PopThebesLayerData()
|
|||||||
|
|
||||||
// Copy transform
|
// Copy transform
|
||||||
colorLayer->SetTransform(data->mLayer->GetTransform());
|
colorLayer->SetTransform(data->mLayer->GetTransform());
|
||||||
|
|
||||||
// Clip colorLayer to its visible region, since ColorLayers are
|
// Clip colorLayer to its visible region, since ColorLayers are
|
||||||
// allowed to paint outside the visible region. Here we rely on the
|
// allowed to paint outside the visible region. Here we rely on the
|
||||||
// fact that uniform display items fill rectangles; obviously the
|
// fact that uniform display items fill rectangles; obviously the
|
||||||
@@ -1313,7 +1310,7 @@ ContainerState::PopThebesLayerData()
|
|||||||
if (!layer->GetTransform().Is2D(&transform)) {
|
if (!layer->GetTransform().Is2D(&transform)) {
|
||||||
NS_ERROR("Only 2D transformations currently supported");
|
NS_ERROR("Only 2D transformations currently supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImageLayers are already configured with a visible region
|
// ImageLayers are already configured with a visible region
|
||||||
if (!imageContainer) {
|
if (!imageContainer) {
|
||||||
NS_ASSERTION(!transform.HasNonIntegerTranslation(),
|
NS_ASSERTION(!transform.HasNonIntegerTranslation(),
|
||||||
@@ -1643,9 +1640,9 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
|
|
||||||
nsRefPtr<gfxContext> context = aContext;
|
nsRefPtr<gfxContext> context = aContext;
|
||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
nsRefPtr<gfxASurface> surf;
|
nsRefPtr<gfxASurface> surf;
|
||||||
if (gfxUtils::sDumpPainting) {
|
if (gfxUtils::sDumpPainting) {
|
||||||
surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(),
|
surf = gfxPlatform::GetPlatform()->CreateOffscreenSurface(itemVisibleRect.Size(),
|
||||||
gfxASurface::CONTENT_COLOR_ALPHA);
|
gfxASurface::CONTENT_COLOR_ALPHA);
|
||||||
surf->SetDeviceOffset(-itemVisibleRect.TopLeft());
|
surf->SetDeviceOffset(-itemVisibleRect.TopLeft());
|
||||||
context = new gfxContext(surf);
|
context = new gfxContext(surf);
|
||||||
@@ -1678,7 +1675,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
|
|||||||
#ifdef MOZ_DUMP_PAINTING
|
#ifdef MOZ_DUMP_PAINTING
|
||||||
if (gfxUtils::sDumpPainting) {
|
if (gfxUtils::sDumpPainting) {
|
||||||
DumpPaintedImage(aItem, surf);
|
DumpPaintedImage(aItem, surf);
|
||||||
|
|
||||||
surf->SetDeviceOffset(gfxPoint(0, 0));
|
surf->SetDeviceOffset(gfxPoint(0, 0));
|
||||||
aContext->SetSource(surf, itemVisibleRect.TopLeft());
|
aContext->SetSource(surf, itemVisibleRect.TopLeft());
|
||||||
aContext->Rectangle(itemVisibleRect);
|
aContext->Rectangle(itemVisibleRect);
|
||||||
@@ -2124,9 +2121,9 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||||||
scale = gfxSize(1.0, 1.0);
|
scale = gfxSize(1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
aLayer->SetTransform(transform);
|
||||||
// Store the inverse of our resolution-scale on the layer
|
|
||||||
aLayer->SetScale(1.0f/float(scale.width), 1.0f/float(scale.height));
|
|
||||||
|
|
||||||
FrameLayerBuilder::ContainerParameters
|
FrameLayerBuilder::ContainerParameters
|
||||||
result(scale.width, scale.height, aIncomingScale);
|
result(scale.width, scale.height, aIncomingScale);
|
||||||
@@ -2555,8 +2552,8 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi
|
|||||||
gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height);
|
gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height);
|
||||||
bounds.ScaleInverse(aDest->AppUnitsPerDevPixel());
|
bounds.ScaleInverse(aDest->AppUnitsPerDevPixel());
|
||||||
|
|
||||||
nsRefPtr<gfxASurface> surf =
|
nsRefPtr<gfxASurface> surf =
|
||||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
|
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(bounds.width, bounds.height),
|
||||||
gfxASurface::CONTENT_COLOR_ALPHA);
|
gfxASurface::CONTENT_COLOR_ALPHA);
|
||||||
surf->SetDeviceOffset(-bounds.TopLeft());
|
surf->SetDeviceOffset(-bounds.TopLeft());
|
||||||
nsRefPtr<gfxContext> context = new gfxContext(surf);
|
nsRefPtr<gfxContext> context = new gfxContext(surf);
|
||||||
@@ -2566,7 +2563,7 @@ static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDi
|
|||||||
aItem->Paint(aBuilder, ctx);
|
aItem->Paint(aBuilder, ctx);
|
||||||
DumpPaintedImage(aItem, surf);
|
DumpPaintedImage(aItem, surf);
|
||||||
aItem->SetPainted();
|
aItem->SetPainted();
|
||||||
|
|
||||||
surf->SetDeviceOffset(gfxPoint(0, 0));
|
surf->SetDeviceOffset(gfxPoint(0, 0));
|
||||||
aDest->ThebesContext()->SetSource(surf, bounds.TopLeft());
|
aDest->ThebesContext()->SetSource(surf, bounds.TopLeft());
|
||||||
aDest->ThebesContext()->Rectangle(bounds);
|
aDest->ThebesContext()->Rectangle(bounds);
|
||||||
@@ -3024,7 +3021,7 @@ CalculateBounds(nsTArray<FrameLayerBuilder::Clip::RoundedRect> aRects, PRInt32 A
|
|||||||
|
|
||||||
void
|
void
|
||||||
ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
|
ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aClip,
|
||||||
PRUint32 aRoundedRectClipCount)
|
PRUint32 aRoundedRectClipCount)
|
||||||
{
|
{
|
||||||
// don't build an unnecessary mask
|
// don't build an unnecessary mask
|
||||||
nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds();
|
nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds();
|
||||||
@@ -3050,7 +3047,7 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const FrameLayerBuilder::Clip& aCl
|
|||||||
aLayer->SetMaskLayer(maskLayer);
|
aLayer->SetMaskLayer(maskLayer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculate a more precise bounding rect
|
// calculate a more precise bounding rect
|
||||||
const PRInt32 A2D = mContainerFrame->PresContext()->AppUnitsPerDevPixel();
|
const PRInt32 A2D = mContainerFrame->PresContext()->AppUnitsPerDevPixel();
|
||||||
gfxRect boundingRect = CalculateBounds(newData.mRoundedClipRects, A2D);
|
gfxRect boundingRect = CalculateBounds(newData.mRoundedClipRects, A2D);
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
* used during painting and hit testing
|
* used during painting and hit testing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mozilla/layers/PLayers.h"
|
|
||||||
|
|
||||||
#include "nsDisplayList.h"
|
#include "nsDisplayList.h"
|
||||||
|
|
||||||
#include "nsCSSRendering.h"
|
#include "nsCSSRendering.h"
|
||||||
@@ -38,9 +36,6 @@
|
|||||||
#include "nsSVGElement.h"
|
#include "nsSVGElement.h"
|
||||||
#include "nsSVGClipPathFrame.h"
|
#include "nsSVGClipPathFrame.h"
|
||||||
#include "sampler.h"
|
#include "sampler.h"
|
||||||
#include "nsAnimationManager.h"
|
|
||||||
#include "nsTransitionManager.h"
|
|
||||||
#include "nsIViewManager.h"
|
|
||||||
|
|
||||||
#include "mozilla/StandardInteger.h"
|
#include "mozilla/StandardInteger.h"
|
||||||
|
|
||||||
@@ -48,367 +43,6 @@ using namespace mozilla;
|
|||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
typedef FrameMetrics::ViewID ViewID;
|
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,
|
nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
|
||||||
Mode aMode, bool aBuildCaret)
|
Mode aMode, bool aBuildCaret)
|
||||||
: mReferenceFrame(aReferenceFrame),
|
: mReferenceFrame(aReferenceFrame),
|
||||||
@@ -564,11 +198,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
|||||||
nsRect contentBounds = scrollableFrame->GetScrollRange();
|
nsRect contentBounds = scrollableFrame->GetScrollRange();
|
||||||
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
|
contentBounds.width += scrollableFrame->GetScrollPortRect().width;
|
||||||
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
|
contentBounds.height += scrollableFrame->GetScrollPortRect().height;
|
||||||
metrics.mCSSContentRect =
|
metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||||
mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
|
||||||
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
||||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||||
metrics.mViewportScrollOffset = scrollableFrame->GetScrollPosition().ScaleToNearestPixels(
|
metrics.mViewportScrollOffset = scrollableFrame->GetScrollPosition().ScaleToNearestPixels(
|
||||||
@@ -576,11 +209,10 @@ static void RecordFrameMetrics(nsIFrame* aForFrame,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nsRect contentBounds = aForFrame->GetRect();
|
nsRect contentBounds = aForFrame->GetRect();
|
||||||
metrics.mCSSContentRect =
|
metrics.mCSSContentRect = gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
||||||
mozilla::gfx::Rect(nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.x),
|
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.y),
|
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.width),
|
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
||||||
nsPresContext::AppUnitsToFloatCSSPixels(contentBounds.height));
|
|
||||||
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
metrics.mContentRect = contentBounds.ScaleToNearestPixels(
|
||||||
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
aContainerParameters.mXScale, aContainerParameters.mYScale, auPerDevPixel);
|
||||||
}
|
}
|
||||||
@@ -667,7 +299,7 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
|
|||||||
|
|
||||||
if (mIsPaintingToWindow) {
|
if (mIsPaintingToWindow) {
|
||||||
mReferenceFrame->AddPaintedPresShell(state->mPresShell);
|
mReferenceFrame->AddPaintedPresShell(state->mPresShell);
|
||||||
|
|
||||||
state->mPresShell->IncrementPaintCount();
|
state->mPresShell->IncrementPaintCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,7 +362,7 @@ nsDisplayListBuilder::MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect)
|
nsDisplayListBuilder::MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect)
|
||||||
{
|
{
|
||||||
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||||
aDirtyFrame->GetChildLists(&childListArray);
|
aDirtyFrame->GetChildLists(&childListArray);
|
||||||
@@ -1133,8 +765,8 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|||||||
if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) {
|
if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) {
|
||||||
nsAutoTArray<nsIFrame*, 16> outFrames;
|
nsAutoTArray<nsIFrame*, 16> outFrames;
|
||||||
item->HitTest(aBuilder, aRect, aState, &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.
|
// so we can sort them later, otherwise we add them directly to the output list.
|
||||||
nsTArray<nsIFrame*> *writeFrames = aOutFrames;
|
nsTArray<nsIFrame*> *writeFrames = aOutFrames;
|
||||||
if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
|
if (item->GetType() == nsDisplayItem::TYPE_TRANSFORM &&
|
||||||
@@ -1150,7 +782,7 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
|
|||||||
writeFrames = &temp[temp.Length() - 1].mFrames;
|
writeFrames = &temp[temp.Length() - 1].mFrames;
|
||||||
}
|
}
|
||||||
} else {
|
} 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.
|
// so flush these into the destination array before processing our frame list.
|
||||||
FlushFramesArray(temp, aOutFrames);
|
FlushFramesArray(temp, aOutFrames);
|
||||||
}
|
}
|
||||||
@@ -1195,7 +827,7 @@ static void Sort(nsDisplayList* aList, PRInt32 aCount, nsDisplayList::SortLEQ aC
|
|||||||
aList->AppendToTop(&list2);
|
aList->AppendToTop(&list2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sort(&list1, half, aCmp, aClosure);
|
Sort(&list1, half, aCmp, aClosure);
|
||||||
Sort(&list2, aCount - half, aCmp, aClosure);
|
Sort(&list2, aCount - half, aCmp, aClosure);
|
||||||
|
|
||||||
@@ -1259,7 +891,7 @@ void nsDisplayList::ExplodeAnonymousChildLists(nsDisplayListBuilder* aBuilder) {
|
|||||||
i->~nsDisplayItem();
|
i->~nsDisplayItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppendToTop(&tmp);
|
AppendToTop(&tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2346,16 +1978,14 @@ already_AddRefed<Layer>
|
|||||||
nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
|
nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerParameters& aContainerParameters) {
|
const ContainerParameters& aContainerParameters) {
|
||||||
nsRefPtr<Layer> container = GetLayerBuilderForManager(aManager)->
|
nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
|
||||||
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
|
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
|
||||||
aContainerParameters, nsnull);
|
aContainerParameters, nsnull);
|
||||||
if (!container)
|
if (!layer)
|
||||||
return nsnull;
|
return nsnull;
|
||||||
|
|
||||||
container->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
layer->SetOpacity(mFrame->GetStyleDisplay()->mOpacity);
|
||||||
AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_opacity);
|
return layer.forget();
|
||||||
|
|
||||||
return container.forget();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2380,12 +2010,6 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
|
|||||||
if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateOpacityLayer) &&
|
if (mFrame->AreLayersMarkedActive(nsChangeHint_UpdateOpacityLayer) &&
|
||||||
!IsItemTooSmallForActiveLayer(this))
|
!IsItemTooSmallForActiveLayer(this))
|
||||||
return LAYER_ACTIVE;
|
return LAYER_ACTIVE;
|
||||||
if (mFrame->GetContent()) {
|
|
||||||
if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(),
|
|
||||||
eCSSProperty_opacity)) {
|
|
||||||
return LAYER_ACTIVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsIFrame* activeScrolledRoot =
|
nsIFrame* activeScrolledRoot =
|
||||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
||||||
return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot)
|
return !ChildrenCanBeInactive(aBuilder, aManager, aParameters, mList, activeScrolledRoot)
|
||||||
@@ -2735,7 +2359,7 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
|
|||||||
// Layer metadata for a particular scroll frame needs to be unique. Only
|
// Layer metadata for a particular scroll frame needs to be unique. Only
|
||||||
// one nsDisplayScrollLayer (with rendered content) or one
|
// one nsDisplayScrollLayer (with rendered content) or one
|
||||||
// nsDisplayScrollInfoLayer (with only the metadata) should survive the
|
// nsDisplayScrollInfoLayer (with only the metadata) should survive the
|
||||||
// visibility computation.
|
// visibility computation.
|
||||||
return RemoveScrollLayerCount() == 1;
|
return RemoveScrollLayerCount() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3018,7 +2642,7 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
|
|||||||
NS_PRECONDITION(aFrame, "Can't get the bounds of a nonexistent frame!");
|
NS_PRECONDITION(aFrame, "Can't get the bounds of a nonexistent frame!");
|
||||||
|
|
||||||
nsRect result;
|
nsRect result;
|
||||||
|
|
||||||
if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
|
if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
|
||||||
// TODO: SVG needs to define what percentage translations resolve against.
|
// TODO: SVG needs to define what percentage translations resolve against.
|
||||||
return result;
|
return result;
|
||||||
@@ -3045,13 +2669,12 @@ nsDisplayTransform::GetFrameBoundsForTransform(const nsIFrame* aFrame)
|
|||||||
|
|
||||||
/* Returns the delta specified by the -moz-transform-origin property.
|
/* Returns the delta specified by the -moz-transform-origin property.
|
||||||
* This is a positive delta, meaning that it indicates the direction to move
|
* 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
|
* to get from (0, 0) of the frame to the transform origin.
|
||||||
* called off the main thread.
|
|
||||||
*/
|
*/
|
||||||
/* static */ gfxPoint3D
|
static
|
||||||
nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
gfxPoint3D GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
||||||
float aAppUnitsPerPixel,
|
float aAppUnitsPerPixel,
|
||||||
const nsRect* aBoundsOverride)
|
const nsRect* aBoundsOverride)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
||||||
NS_PRECONDITION(aFrame->IsTransformed(),
|
NS_PRECONDITION(aFrame->IsTransformed(),
|
||||||
@@ -3066,7 +2689,8 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
|||||||
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
||||||
|
|
||||||
/* Allows us to access named variables by index. */
|
/* 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] =
|
const nscoord* dimensions[2] =
|
||||||
{&boundingRect.width, &boundingRect.height};
|
{&boundingRect.width, &boundingRect.height};
|
||||||
|
|
||||||
@@ -3077,17 +2701,17 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
|||||||
const nsStyleCoord &coord = display->mTransformOrigin[index];
|
const nsStyleCoord &coord = display->mTransformOrigin[index];
|
||||||
if (coord.GetUnit() == eStyleUnit_Calc) {
|
if (coord.GetUnit() == eStyleUnit_Calc) {
|
||||||
const nsStyleCoord::Calc *calc = coord.GetCalcValue();
|
const nsStyleCoord::Calc *calc = coord.GetCalcValue();
|
||||||
coords[index] =
|
*coords[index] =
|
||||||
NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) *
|
NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) *
|
||||||
calc->mPercent +
|
calc->mPercent +
|
||||||
NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerPixel);
|
NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerPixel);
|
||||||
} else if (coord.GetUnit() == eStyleUnit_Percent) {
|
} else if (coord.GetUnit() == eStyleUnit_Percent) {
|
||||||
coords[index] =
|
*coords[index] =
|
||||||
NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) *
|
NSAppUnitsToFloatPixels(*dimensions[index], aAppUnitsPerPixel) *
|
||||||
coord.GetPercentValue();
|
coord.GetPercentValue();
|
||||||
} else {
|
} else {
|
||||||
NS_ABORT_IF_FALSE(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
|
NS_ABORT_IF_FALSE(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
|
||||||
coords[index] =
|
*coords[index] =
|
||||||
NSAppUnitsToFloatPixels(coord.GetCoordValue(), aAppUnitsPerPixel);
|
NSAppUnitsToFloatPixels(coord.GetCoordValue(), aAppUnitsPerPixel);
|
||||||
}
|
}
|
||||||
if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) &&
|
if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) &&
|
||||||
@@ -3096,32 +2720,31 @@ nsDisplayTransform::GetDeltaToMozTransformOrigin(const nsIFrame* aFrame,
|
|||||||
// user space, not the top left of its bounds, so we must adjust for that:
|
// user space, not the top left of its bounds, so we must adjust for that:
|
||||||
nscoord offset =
|
nscoord offset =
|
||||||
(index == 0) ? aFrame->GetPosition().x : aFrame->GetPosition().y;
|
(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(),
|
*coords[2] = NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
|
||||||
aAppUnitsPerPixel);
|
aAppUnitsPerPixel);
|
||||||
/* Adjust based on the origin of the rectangle. */
|
/* Adjust based on the origin of the rectangle. */
|
||||||
coords[0] += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
|
result.x += NSAppUnitsToFloatPixels(boundingRect.x, aAppUnitsPerPixel);
|
||||||
coords[1] += NSAppUnitsToFloatPixels(boundingRect.y, 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.
|
/* Returns the delta specified by the -moz-perspective-origin property.
|
||||||
* This is a positive delta, meaning that it indicates the direction to move
|
* 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
|
* to get from (0, 0) of the frame to the perspective origin.
|
||||||
* called off the main thread.
|
|
||||||
*/
|
*/
|
||||||
/* static */ gfxPoint3D
|
static
|
||||||
nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
gfxPoint3D GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
||||||
float aAppUnitsPerPixel)
|
float aAppUnitsPerPixel)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
NS_PRECONDITION(aFrame, "Can't get delta for a null frame!");
|
||||||
NS_PRECONDITION(aFrame->IsTransformed(),
|
NS_PRECONDITION(aFrame->IsTransformed(),
|
||||||
"Shouldn't get a delta for an untransformed frame!");
|
"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!");
|
"Can't get delta without a style parent!");
|
||||||
|
|
||||||
/* For both of the coordinates, if the value of -moz-perspective-origin is a
|
/* For both of the coordinates, if the value of -moz-perspective-origin is a
|
||||||
@@ -3179,22 +2802,12 @@ nsDisplayTransform::GetDeltaToMozPerspectiveOrigin(const nsIFrame* aFrame,
|
|||||||
*/
|
*/
|
||||||
gfx3DMatrix
|
gfx3DMatrix
|
||||||
nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
||||||
const nsPoint& aOrigin,
|
const nsPoint &aOrigin,
|
||||||
float aAppUnitsPerPixel,
|
float aAppUnitsPerPixel,
|
||||||
const nsRect* aBoundsOverride,
|
const nsRect* aBoundsOverride,
|
||||||
const nsCSSValueList* aTransformOverride,
|
|
||||||
gfxPoint3D* aToMozOrigin,
|
|
||||||
gfxPoint3D* aToPerspectiveOrigin,
|
|
||||||
nscoord* aChildPerspective,
|
|
||||||
nsIFrame** aOutAncestor)
|
nsIFrame** aOutAncestor)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aFrame || (aToMozOrigin && aBoundsOverride && aToPerspectiveOrigin &&
|
NS_PRECONDITION(aFrame, "Cannot get transform matrix for a null frame!");
|
||||||
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");
|
|
||||||
|
|
||||||
if (aOutAncestor) {
|
if (aOutAncestor) {
|
||||||
*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
*aOutAncestor = nsLayoutUtils::GetCrossDocParentFrame(aFrame);
|
||||||
@@ -3204,7 +2817,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||||||
* coordinate space to the new origin.
|
* coordinate space to the new origin.
|
||||||
*/
|
*/
|
||||||
gfxPoint3D toMozOrigin =
|
gfxPoint3D toMozOrigin =
|
||||||
aFrame ? GetDeltaToMozTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride) : *aToMozOrigin;
|
GetDeltaToMozTransformOrigin(aFrame, aAppUnitsPerPixel, aBoundsOverride);
|
||||||
gfxPoint3D newOrigin =
|
gfxPoint3D newOrigin =
|
||||||
gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
|
gfxPoint3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
|
||||||
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
|
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
|
||||||
@@ -3213,7 +2826,7 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||||||
/* Get the underlying transform matrix. This requires us to get the
|
/* Get the underlying transform matrix. This requires us to get the
|
||||||
* bounds of the frame.
|
* bounds of the frame.
|
||||||
*/
|
*/
|
||||||
const nsStyleDisplay* disp = aFrame ? aFrame->GetStyleDisplay() : nsnull;
|
const nsStyleDisplay* disp = aFrame->GetStyleDisplay();
|
||||||
nsRect bounds = (aBoundsOverride ? *aBoundsOverride :
|
nsRect bounds = (aBoundsOverride ? *aBoundsOverride :
|
||||||
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
nsDisplayTransform::GetFrameBoundsForTransform(aFrame));
|
||||||
|
|
||||||
@@ -3224,12 +2837,9 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||||||
// disp->mSpecifiedTransform, since we still need any transformFromSVGParent.
|
// disp->mSpecifiedTransform, since we still need any transformFromSVGParent.
|
||||||
gfxMatrix svgTransform, transformFromSVGParent;
|
gfxMatrix svgTransform, transformFromSVGParent;
|
||||||
bool hasSVGTransforms =
|
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!) */
|
/* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */
|
||||||
if (aTransformOverride) {
|
if (disp->mSpecifiedTransform) {
|
||||||
result = nsStyleTransformMatrix::ReadTransforms(aTransformOverride, nsnull, nsnull,
|
|
||||||
dummy, bounds, aAppUnitsPerPixel);
|
|
||||||
} else if (disp->mSpecifiedTransform) {
|
|
||||||
result = nsStyleTransformMatrix::ReadTransforms(disp->mSpecifiedTransform,
|
result = nsStyleTransformMatrix::ReadTransforms(disp->mSpecifiedTransform,
|
||||||
aFrame->GetStyleContext(),
|
aFrame->GetStyleContext(),
|
||||||
aFrame->PresContext(),
|
aFrame->PresContext(),
|
||||||
@@ -3241,6 +2851,10 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||||||
svgTransform.x0 *= pixelsPerCSSPx;
|
svgTransform.x0 *= pixelsPerCSSPx;
|
||||||
svgTransform.y0 *= pixelsPerCSSPx;
|
svgTransform.y0 *= pixelsPerCSSPx;
|
||||||
result = gfx3DMatrix::From2D(svgTransform);
|
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()) {
|
if (hasSVGTransforms && !transformFromSVGParent.IsIdentity()) {
|
||||||
@@ -3253,40 +2867,32 @@ nsDisplayTransform::GetResultingTransformMatrix(const nsIFrame* aFrame,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const nsStyleDisplay* parentDisp = nsnull;
|
const nsStyleDisplay* parentDisp = nsnull;
|
||||||
nsStyleContext* parentStyleContext = aFrame ? aFrame->GetStyleContext()->GetParent(): nsnull;
|
nsStyleContext* parentStyleContext = aFrame->GetStyleContext()->GetParent();
|
||||||
if (parentStyleContext) {
|
if (parentStyleContext) {
|
||||||
parentDisp = parentStyleContext->GetStyleDisplay();
|
parentDisp = parentStyleContext->GetStyleDisplay();
|
||||||
}
|
}
|
||||||
nscoord perspectiveCoord = 0;
|
if (nsLayoutUtils::Are3DTransformsEnabled() &&
|
||||||
if (parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord) {
|
parentDisp && parentDisp->mChildPerspective.GetUnit() == eStyleUnit_Coord &&
|
||||||
perspectiveCoord = parentDisp->mChildPerspective.GetCoordValue();
|
parentDisp->mChildPerspective.GetCoordValue() > 0.0) {
|
||||||
}
|
|
||||||
if (aChildPerspective) {
|
|
||||||
perspectiveCoord = *aChildPerspective;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nsLayoutUtils::Are3DTransformsEnabled() && perspectiveCoord > 0.0) {
|
|
||||||
gfx3DMatrix perspective;
|
gfx3DMatrix perspective;
|
||||||
perspective._34 =
|
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.
|
/* 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.
|
* 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);
|
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
|
// Include the transform set on our parent
|
||||||
NS_ASSERTION(aFrame->GetParent() &&
|
NS_ASSERTION(aFrame->GetParent() &&
|
||||||
aFrame->GetParent()->IsTransformed() &&
|
aFrame->GetParent()->IsTransformed() &&
|
||||||
aFrame->GetParent()->Preserves3DChildren(),
|
aFrame->GetParent()->Preserves3DChildren(),
|
||||||
"Preserve3D mismatch!");
|
"Preserve3D mismatch!");
|
||||||
gfx3DMatrix parent =
|
gfx3DMatrix parent = GetResultingTransformMatrix(aFrame->GetParent(), aOrigin - aFrame->GetPosition(),
|
||||||
GetResultingTransformMatrix(aFrame->GetParent(),
|
aAppUnitsPerPixel, nsnull, aOutAncestor);
|
||||||
aOrigin - aFrame->GetPosition(),
|
|
||||||
aAppUnitsPerPixel, nsnull, nsnull, nsnull,
|
|
||||||
nsnull, nsnull, aOutAncestor);
|
|
||||||
return nsLayoutUtils::ChangeMatrixBasis(newOrigin + toMozOrigin, result) * parent;
|
return nsLayoutUtils::ChangeMatrixBasis(newOrigin + toMozOrigin, result) * parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3317,7 +2923,7 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */
|
/* 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()) {
|
if (aMatrix.IsSingular()) {
|
||||||
return false;
|
return false;
|
||||||
@@ -3335,7 +2941,8 @@ nsDisplayTransform::GetTransform(float aAppUnitsPerPixel)
|
|||||||
if (mTransform.IsIdentity() || mCachedAppUnitsPerPixel != aAppUnitsPerPixel) {
|
if (mTransform.IsIdentity() || mCachedAppUnitsPerPixel != aAppUnitsPerPixel) {
|
||||||
mTransform =
|
mTransform =
|
||||||
GetResultingTransformMatrix(mFrame, ToReferenceFrame(),
|
GetResultingTransformMatrix(mFrame, ToReferenceFrame(),
|
||||||
aAppUnitsPerPixel);
|
aAppUnitsPerPixel,
|
||||||
|
nsnull);
|
||||||
mCachedAppUnitsPerPixel = aAppUnitsPerPixel;
|
mCachedAppUnitsPerPixel = aAppUnitsPerPixel;
|
||||||
}
|
}
|
||||||
return mTransform;
|
return mTransform;
|
||||||
@@ -3345,7 +2952,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
|||||||
LayerManager *aManager,
|
LayerManager *aManager,
|
||||||
const ContainerParameters& aContainerParameters)
|
const ContainerParameters& aContainerParameters)
|
||||||
{
|
{
|
||||||
const gfx3DMatrix& newTransformMatrix =
|
const gfx3DMatrix& newTransformMatrix =
|
||||||
GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel());
|
GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||||
|
|
||||||
if (!IsFrameVisible(mFrame, newTransformMatrix)) {
|
if (!IsFrameVisible(mFrame, newTransformMatrix)) {
|
||||||
@@ -3361,8 +2968,6 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
|||||||
if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) {
|
if (mFrame->Preserves3D() || mFrame->Preserves3DChildren()) {
|
||||||
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D);
|
container->SetContentFlags(container->GetContentFlags() | Layer::CONTENT_PRESERVE_3D);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddAnimationsAndTransitionsToLayer(container, this, eCSSProperty_transform);
|
|
||||||
return container.forget();
|
return container.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3377,18 +2982,12 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
|
|||||||
return LAYER_ACTIVE;
|
return LAYER_ACTIVE;
|
||||||
if (!GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel()).Is2D() || mFrame->Preserves3D())
|
if (!GetTransform(mFrame->PresContext()->AppUnitsPerDevPixel()).Is2D() || mFrame->Preserves3D())
|
||||||
return LAYER_ACTIVE;
|
return LAYER_ACTIVE;
|
||||||
if (mFrame->GetContent()) {
|
|
||||||
if (nsLayoutUtils::HasAnimationsForCompositor(mFrame->GetContent(),
|
|
||||||
eCSSProperty_transform)) {
|
|
||||||
return LAYER_ACTIVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsIFrame* activeScrolledRoot =
|
nsIFrame* activeScrolledRoot =
|
||||||
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
nsLayoutUtils::GetActiveScrolledRootFor(mFrame, nsnull);
|
||||||
return !mStoredList.ChildrenCanBeInactive(aBuilder,
|
return !mStoredList.ChildrenCanBeInactive(aBuilder,
|
||||||
aManager,
|
aManager,
|
||||||
aParameters,
|
aParameters,
|
||||||
*mStoredList.GetList(),
|
*mStoredList.GetList(),
|
||||||
activeScrolledRoot)
|
activeScrolledRoot)
|
||||||
? LAYER_ACTIVE : LAYER_INACTIVE;
|
? LAYER_ACTIVE : LAYER_INACTIVE;
|
||||||
}
|
}
|
||||||
@@ -3407,9 +3006,9 @@ bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
|
|||||||
!UntransformRectMatrix(mVisibleRect,
|
!UntransformRectMatrix(mVisibleRect,
|
||||||
GetTransform(factor),
|
GetTransform(factor),
|
||||||
factor,
|
factor,
|
||||||
&untransformedVisibleRect))
|
&untransformedVisibleRect))
|
||||||
{
|
{
|
||||||
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() +
|
untransformedVisibleRect = mFrame->GetVisualOverflowRectRelativeToSelf() +
|
||||||
aBuilder->ToReferenceFrame(mFrame);
|
aBuilder->ToReferenceFrame(mFrame);
|
||||||
}
|
}
|
||||||
nsRegion untransformedVisible = untransformedVisibleRect;
|
nsRegion untransformedVisible = untransformedVisibleRect;
|
||||||
@@ -3474,7 +3073,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
|||||||
NSFloatPixelsToAppUnits(float(rect.Width()), factor),
|
NSFloatPixelsToAppUnits(float(rect.Width()), factor),
|
||||||
NSFloatPixelsToAppUnits(float(rect.Height()), factor));
|
NSFloatPixelsToAppUnits(float(rect.Height()), factor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG_HIT
|
#ifdef DEBUG_HIT
|
||||||
printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
|
printf("Frame: %p\n", dynamic_cast<void *>(mFrame));
|
||||||
@@ -3500,8 +3099,8 @@ nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint)
|
|||||||
gfx3DMatrix matrix = GetTransform(factor);
|
gfx3DMatrix matrix = GetTransform(factor);
|
||||||
|
|
||||||
NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!");
|
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),
|
matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
|
||||||
NSAppUnitsToFloatPixels(aPoint.y, factor)));
|
NSAppUnitsToFloatPixels(aPoint.y, factor)));
|
||||||
|
|
||||||
@@ -3550,7 +3149,7 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
|
|||||||
if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) {
|
if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) {
|
||||||
return nsRegion();
|
return nsRegion();
|
||||||
}
|
}
|
||||||
|
|
||||||
const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel());
|
const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel());
|
||||||
|
|
||||||
nsRegion result;
|
nsRegion result;
|
||||||
@@ -3697,7 +3296,7 @@ bool nsDisplayTransform::UntransformRect(const nsRect &aUntransformedBounds,
|
|||||||
* empty rect.
|
* empty rect.
|
||||||
*/
|
*/
|
||||||
float factor = nsPresContext::AppUnitsPerCSSPixel();
|
float factor = nsPresContext::AppUnitsPerCSSPixel();
|
||||||
gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor);
|
gfx3DMatrix matrix = GetResultingTransformMatrix(aFrame, aOrigin, factor, nsnull);
|
||||||
|
|
||||||
return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect);
|
return UntransformRectMatrix(aUntransformedBounds, matrix, factor, aOutRect);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,10 +108,10 @@ public:
|
|||||||
* display lists that we make.
|
* display lists that we make.
|
||||||
*/
|
*/
|
||||||
enum Mode {
|
enum Mode {
|
||||||
PAINTING,
|
PAINTING,
|
||||||
EVENT_DELIVERY,
|
EVENT_DELIVERY,
|
||||||
PLUGIN_GEOMETRY,
|
PLUGIN_GEOMETRY,
|
||||||
OTHER
|
OTHER
|
||||||
};
|
};
|
||||||
nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
|
nsDisplayListBuilder(nsIFrame* aReferenceFrame, Mode aMode, bool aBuildCaret);
|
||||||
~nsDisplayListBuilder();
|
~nsDisplayListBuilder();
|
||||||
@@ -2324,13 +2324,6 @@ public:
|
|||||||
float aAppUnitsPerPixel,
|
float aAppUnitsPerPixel,
|
||||||
nsRect* aOutRect);
|
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
|
* Returns the bounds of a frame as defined for resolving percentage
|
||||||
* <translation-value>s in CSS transforms. If
|
* <translation-value>s in CSS transforms. If
|
||||||
@@ -2364,10 +2357,6 @@ public:
|
|||||||
const nsPoint& aOrigin,
|
const nsPoint& aOrigin,
|
||||||
float aAppUnitsPerPixel,
|
float aAppUnitsPerPixel,
|
||||||
const nsRect* aBoundsOverride = nsnull,
|
const nsRect* aBoundsOverride = nsnull,
|
||||||
const nsCSSValueList* aTransformOverride = nsnull,
|
|
||||||
gfxPoint3D* aToMozOrigin = nsnull,
|
|
||||||
gfxPoint3D* aToPerspectiveOrigin = nsnull,
|
|
||||||
nscoord* aChildPerspective = nsnull,
|
|
||||||
nsIFrame** aOutAncestor = nsnull);
|
nsIFrame** aOutAncestor = nsnull);
|
||||||
/**
|
/**
|
||||||
* Return true when we should try to prerender the entire contents of the
|
* Return true when we should try to prerender the entire contents of the
|
||||||
|
|||||||
@@ -83,8 +83,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sampler.h"
|
#include "sampler.h"
|
||||||
#include "nsAnimationManager.h"
|
|
||||||
#include "nsTransitionManager.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
@@ -115,32 +113,6 @@ static ContentMap& GetContentMap() {
|
|||||||
return *sContentMap;
|
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
|
bool
|
||||||
nsLayoutUtils::Are3DTransformsEnabled()
|
nsLayoutUtils::Are3DTransformsEnabled()
|
||||||
|
|||||||
@@ -1497,13 +1497,6 @@ public:
|
|||||||
nsMallocSizeOfFun aMallocSizeOf,
|
nsMallocSizeOfFun aMallocSizeOf,
|
||||||
bool clear);
|
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.
|
* Checks if CSS 3D transforms are currently enabled.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -92,8 +92,6 @@
|
|||||||
#include "CSSCalc.h"
|
#include "CSSCalc.h"
|
||||||
#include "nsAbsoluteContainingBlock.h"
|
#include "nsAbsoluteContainingBlock.h"
|
||||||
#include "nsFontInflationData.h"
|
#include "nsFontInflationData.h"
|
||||||
#include "nsAnimationManager.h"
|
|
||||||
#include "nsTransitionManager.h"
|
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
@@ -937,20 +935,9 @@ nsIFrame::GetPaddingRect() const
|
|||||||
bool
|
bool
|
||||||
nsIFrame::IsTransformed() const
|
nsIFrame::IsTransformed() const
|
||||||
{
|
{
|
||||||
return ((mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
|
return (mState & NS_FRAME_MAY_BE_TRANSFORMED) &&
|
||||||
(GetStyleDisplay()->HasTransform() ||
|
(GetStyleDisplay()->HasTransform() ||
|
||||||
IsSVGTransformed() ||
|
IsSVGTransformed());
|
||||||
(mContent &&
|
|
||||||
nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
|
||||||
eCSSProperty_transform))));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
nsIFrame::HasOpacity() const
|
|
||||||
{
|
|
||||||
return GetStyleDisplay()->mOpacity < 1.0f || (mContent &&
|
|
||||||
nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
|
||||||
eCSSProperty_opacity));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -1768,6 +1755,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||||||
nsDisplayList* aList) {
|
nsDisplayList* aList) {
|
||||||
if (GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
|
if (GetStateBits() & NS_FRAME_TOO_DEEP_IN_FRAME_TREE)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
||||||
// Replaced elements have their visibility handled here, because
|
// Replaced elements have their visibility handled here, because
|
||||||
// they're visually atomic
|
// they're visually atomic
|
||||||
if (IsFrameOfType(eReplaced) && !IsVisibleForPainting(aBuilder))
|
if (IsFrameOfType(eReplaced) && !IsVisibleForPainting(aBuilder))
|
||||||
@@ -1775,13 +1763,10 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||||||
|
|
||||||
nsRect clipPropClip;
|
nsRect clipPropClip;
|
||||||
const nsStyleDisplay* disp = GetStyleDisplay();
|
const nsStyleDisplay* disp = GetStyleDisplay();
|
||||||
// We can stop right away if this is a zero-opacity stacking context,
|
// We can stop right away if this is a zero-opacity stacking context and
|
||||||
// we're painting, and we're not animating opacity.
|
// we're painting.
|
||||||
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting() &&
|
if (disp->mOpacity == 0.0 && aBuilder->IsForPainting())
|
||||||
!nsLayoutUtils::HasAnimationsForCompositor(mContent,
|
|
||||||
eCSSProperty_opacity)) {
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
|
||||||
|
|
||||||
bool applyClipPropClipping =
|
bool applyClipPropClipping =
|
||||||
ApplyClipPropClipping(aBuilder, disp, this, &clipPropClip);
|
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
|
// 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
|
// vanishing point. As a workaround we transform the overflow rect into screen space
|
||||||
// and compare in that coordinate system.
|
// and compare in that coordinate system.
|
||||||
|
|
||||||
// Transform the overflow rect into screen space
|
// Transform the overflow rect into screen space
|
||||||
nsRect overflow = GetVisualOverflowRectRelativeToSelf();
|
nsRect overflow = GetVisualOverflowRectRelativeToSelf();
|
||||||
nsPoint offset = aBuilder->ToReferenceFrame(this);
|
nsPoint offset = aBuilder->ToReferenceFrame(this);
|
||||||
@@ -1935,6 +1920,7 @@ nsIFrame::BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
|
|||||||
// resultList was emptied
|
// resultList was emptied
|
||||||
resultList.AppendToTop(item);
|
resultList.AppendToTop(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If there are any SVG effects, wrap the list up in an SVG effects 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
|
* (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
|
* 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
|
/* Else, if the list is non-empty and there is CSS group opacity without SVG
|
||||||
* effects, wrap it up in an opacity item.
|
* effects, wrap it up in an opacity item.
|
||||||
*/
|
*/
|
||||||
else if (HasOpacity() &&
|
else if (disp->mOpacity < 1.0f &&
|
||||||
!nsSVGUtils::CanOptimizeOpacity(this) &&
|
!nsSVGUtils::CanOptimizeOpacity(this) &&
|
||||||
!resultList.IsEmpty()) {
|
!resultList.IsEmpty()) {
|
||||||
rv = resultList.AppendNewToTop(
|
rv = resultList.AppendNewToTop(
|
||||||
@@ -2104,7 +2090,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||||||
// Child is composited if it's transformed, partially transparent, or has
|
// Child is composited if it's transformed, partially transparent, or has
|
||||||
// SVG effects.
|
// SVG effects.
|
||||||
const nsStyleDisplay* disp = child->GetStyleDisplay();
|
const nsStyleDisplay* disp = child->GetStyleDisplay();
|
||||||
bool isVisuallyAtomic = child->HasOpacity()
|
bool isVisuallyAtomic = disp->mOpacity != 1.0f
|
||||||
|| child->IsTransformed()
|
|| child->IsTransformed()
|
||||||
|| nsSVGIntegrationUtils::UsingEffectsForFrame(child);
|
|| nsSVGIntegrationUtils::UsingEffectsForFrame(child);
|
||||||
|
|
||||||
@@ -4753,8 +4739,8 @@ nsIFrame::GetTransformMatrix(nsIFrame* aStopAtAncestor,
|
|||||||
PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
|
PRInt32 scaleFactor = PresContext()->AppUnitsPerDevPixel();
|
||||||
|
|
||||||
gfx3DMatrix result =
|
gfx3DMatrix result =
|
||||||
nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0), scaleFactor, nsnull,
|
nsDisplayTransform::GetResultingTransformMatrix(this, nsPoint(0, 0),
|
||||||
nsnull, nsnull, nsnull, nsnull, aOutAncestor);
|
scaleFactor, nsnull, aOutAncestor);
|
||||||
// XXXjwatt: seems like this will double count offsets in the face of preserve-3d:
|
// XXXjwatt: seems like this will double count offsets in the face of preserve-3d:
|
||||||
nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor);
|
nsPoint delta = GetOffsetToCrossDoc(*aOutAncestor);
|
||||||
/* Combine the raw transform with a translation to our parent. */
|
/* Combine the raw transform with a translation to our parent. */
|
||||||
|
|||||||
@@ -1227,8 +1227,6 @@ public:
|
|||||||
* an SVG viewBox attribute).
|
* an SVG viewBox attribute).
|
||||||
*/
|
*/
|
||||||
bool IsTransformed() const;
|
bool IsTransformed() const;
|
||||||
|
|
||||||
bool HasOpacity() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this frame is an SVG frame that has SVG transforms applied
|
* Returns true if this frame is an SVG frame that has SVG transforms applied
|
||||||
|
|||||||
@@ -246,7 +246,6 @@ TransformShadowTree(nsDisplayListBuilder* aBuilder, nsFrameLoader* aFrameLoader,
|
|||||||
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||||
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
||||||
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
||||||
shadow->SetShadowOpacity(aLayer->GetOpacity());
|
|
||||||
|
|
||||||
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
|
const FrameMetrics* metrics = GetFrameMetrics(aLayer);
|
||||||
|
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
#include "nsRuleData.h"
|
#include "nsRuleData.h"
|
||||||
#include "nsCSSValue.h"
|
#include "nsCSSValue.h"
|
||||||
#include "nsStyleContext.h"
|
#include "nsStyleContext.h"
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsAnimationManager.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace css {
|
namespace css {
|
||||||
@@ -41,7 +39,7 @@ CommonAnimationManager::AddElementData(CommonElementAnimationData* aData)
|
|||||||
nsRefreshDriver *rd = mPresContext->RefreshDriver();
|
nsRefreshDriver *rd = mPresContext->RefreshDriver();
|
||||||
rd->AddRefreshObserver(this, Flush_Style);
|
rd->AddRefreshObserver(this, Flush_Style);
|
||||||
}
|
}
|
||||||
|
|
||||||
PR_INSERT_BEFORE(aData, &mElementData);
|
PR_INSERT_BEFORE(aData, &mElementData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,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 nsAnimationManager::CanAnimateOpacity();
|
|
||||||
}
|
|
||||||
if (aProperty == eCSSProperty_transform && !(frame &&
|
|
||||||
frame->Preserves3D() &&
|
|
||||||
frame->Preserves3DChildren())) {
|
|
||||||
if (frame && frame->IsSVGTransformed()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return nsAnimationManager::CanAnimateTransform();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,12 +107,6 @@ public:
|
|||||||
typedef nsTimingFunction::Type Type;
|
typedef nsTimingFunction::Type Type;
|
||||||
void Init(const nsTimingFunction &aFunction);
|
void Init(const nsTimingFunction &aFunction);
|
||||||
double GetValue(double aPortion) const;
|
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:
|
private:
|
||||||
Type mType;
|
Type mType;
|
||||||
nsSMILKeySpline mTimingFunction;
|
nsSMILKeySpline mTimingFunction;
|
||||||
@@ -148,10 +142,6 @@ struct CommonElementAnimationData : public PRCList
|
|||||||
mElement->DeleteProperty(mElementProperty);
|
mElement->DeleteProperty(mElementProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
CanAnimatePropertyOnCompositor(const dom::Element *aElement,
|
|
||||||
nsCSSProperty aProperty);
|
|
||||||
|
|
||||||
dom::Element *mElement;
|
dom::Element *mElement;
|
||||||
|
|
||||||
// the atom we use in mElement's prop table (must be a static atom,
|
// 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_NAMESPACES = mozilla/css
|
||||||
|
|
||||||
EXPORTS = \
|
EXPORTS = \
|
||||||
AnimationCommon.h \
|
|
||||||
nsAnimationManager.h \
|
|
||||||
nsCSSAnonBoxList.h \
|
nsCSSAnonBoxList.h \
|
||||||
nsCSSAnonBoxes.h \
|
nsCSSAnonBoxes.h \
|
||||||
nsCSSFontDescList.h \
|
nsCSSFontDescList.h \
|
||||||
@@ -57,7 +55,6 @@ EXPORTS = \
|
|||||||
nsRuleNode.h \
|
nsRuleNode.h \
|
||||||
nsRuleProcessorData.h \
|
nsRuleProcessorData.h \
|
||||||
nsRuleWalker.h \
|
nsRuleWalker.h \
|
||||||
nsStyleAnimation.h \
|
|
||||||
nsStyleContext.h \
|
nsStyleContext.h \
|
||||||
nsStyleCoord.h \
|
nsStyleCoord.h \
|
||||||
nsStyleSet.h \
|
nsStyleSet.h \
|
||||||
@@ -127,9 +124,7 @@ FORCE_STATIC_LIB = 1
|
|||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
include $(topsrcdir)/ipc/chromium/chromium-config.mk
|
LOCAL_INCLUDES = \
|
||||||
|
|
||||||
LOCAL_INCLUDES += \
|
|
||||||
-I$(srcdir)/../base \
|
-I$(srcdir)/../base \
|
||||||
-I$(srcdir)/../generic \
|
-I$(srcdir)/../generic \
|
||||||
-I$(srcdir)/../xul/base/src \
|
-I$(srcdir)/../xul/base/src \
|
||||||
|
|||||||
@@ -11,18 +11,113 @@
|
|||||||
#include "nsStyleAnimation.h"
|
#include "nsStyleAnimation.h"
|
||||||
#include "nsSMILKeySpline.h"
|
#include "nsSMILKeySpline.h"
|
||||||
#include "nsEventDispatcher.h"
|
#include "nsEventDispatcher.h"
|
||||||
#include "nsDisplayList.h"
|
|
||||||
#include "nsCSSFrameConstructor.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
|
|
||||||
ElementAnimations::ElementAnimations(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
struct AnimationPropertySegment
|
||||||
nsAnimationManager *aAnimationManager)
|
|
||||||
: CommonElementAnimationData(aElement, aElementProperty,
|
|
||||||
aAnimationManager),
|
|
||||||
mNeedsRefreshes(true)
|
|
||||||
{
|
{
|
||||||
}
|
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
|
static void
|
||||||
ElementAnimationsPropertyDtor(void *aObject,
|
ElementAnimationsPropertyDtor(void *aObject,
|
||||||
@@ -38,114 +133,6 @@ ElementAnimationsPropertyDtor(void *aObject,
|
|||||||
delete ea;
|
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
|
void
|
||||||
ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
||||||
EventArray& aEventsToDispatch)
|
EventArray& aEventsToDispatch)
|
||||||
@@ -178,24 +165,98 @@ ElementAnimations::EnsureStyleRuleFor(TimeStamp aRefreshTime,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeStamp currentTime;
|
TimeDuration currentTimeDuration;
|
||||||
if (anim.IsPaused()) {
|
if (anim.IsPaused()) {
|
||||||
// FIXME: avoid recalculating every time
|
// FIXME: avoid recalculating every time
|
||||||
currentTime = anim.mPauseStart;
|
currentTimeDuration = anim.mPauseStart - anim.mStartTime;
|
||||||
} else {
|
} else {
|
||||||
currentTime = aRefreshTime;
|
currentTimeDuration = aRefreshTime - anim.mStartTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
double positionInIteration =
|
// Set |currentIterationCount| to the (fractional) number of
|
||||||
GetPositionInIteration(anim.mStartTime, currentTime,
|
// iterations we've completed up to the current position.
|
||||||
anim.mIterationDuration, anim.mIterationCount,
|
double currentIterationCount =
|
||||||
anim.mDirection, IsForElement(),
|
currentTimeDuration / anim.mIterationDuration;
|
||||||
&anim, this, &aEventsToDispatch);
|
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,
|
if (!anim.FillsForwards()) {
|
||||||
// so we shouldn't animate.
|
// No animation data.
|
||||||
if (positionInIteration == -1)
|
continue;
|
||||||
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 &&
|
NS_ABORT_IF_FALSE(0.0 <= positionInIteration &&
|
||||||
positionInIteration <= 1.0,
|
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*
|
ElementAnimations*
|
||||||
nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
||||||
nsCSSPseudoElements::Type aPseudoType,
|
nsCSSPseudoElements::Type aPseudoType,
|
||||||
@@ -350,6 +351,10 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
|||||||
if (!ea && aCreateIfNeeded) {
|
if (!ea && aCreateIfNeeded) {
|
||||||
// FIXME: Consider arena-allocating?
|
// FIXME: Consider arena-allocating?
|
||||||
ea = new ElementAnimations(aElement, propName, this);
|
ea = new ElementAnimations(aElement, propName, this);
|
||||||
|
if (!ea) {
|
||||||
|
NS_WARNING("out of memory");
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
nsresult rv = aElement->SetProperty(propName, ea,
|
nsresult rv = aElement->SetProperty(propName, ea,
|
||||||
ElementAnimationsPropertyDtor, nsnull);
|
ElementAnimationsPropertyDtor, nsnull);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
@@ -357,9 +362,6 @@ nsAnimationManager::GetElementAnimations(dom::Element *aElement,
|
|||||||
delete ea;
|
delete ea;
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
if (propName == nsGkAtoms::animationsProperty) {
|
|
||||||
aElement->SetMayHaveAnimations();
|
|
||||||
}
|
|
||||||
|
|
||||||
AddElementData(ea);
|
AddElementData(ea);
|
||||||
}
|
}
|
||||||
@@ -461,8 +463,6 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
|
|||||||
TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
|
TimeStamp refreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
|
||||||
|
|
||||||
if (ea) {
|
if (ea) {
|
||||||
|
|
||||||
// XXXdz: Invalidate the frame since the animation changed.
|
|
||||||
// The cached style rule is invalid.
|
// The cached style rule is invalid.
|
||||||
ea->mStyleRule = nsnull;
|
ea->mStyleRule = nsnull;
|
||||||
ea->mStyleRuleRefreshTime = TimeStamp();
|
ea->mStyleRuleRefreshTime = TimeStamp();
|
||||||
|
|||||||
@@ -11,10 +11,12 @@
|
|||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "nsGUIEvent.h"
|
#include "nsGUIEvent.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
#include "mozilla/Preferences.h"
|
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
class nsCSSKeyframesRule;
|
class nsCSSKeyframesRule;
|
||||||
|
struct AnimationPropertySegment;
|
||||||
|
struct ElementAnimation;
|
||||||
|
struct ElementAnimations;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace css {
|
namespace css {
|
||||||
@@ -22,193 +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
|
class nsAnimationManager : public mozilla::css::CommonAnimationManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsAnimationManager(nsPresContext *aPresContext)
|
nsAnimationManager(nsPresContext *aPresContext)
|
||||||
: mozilla::css::CommonAnimationManager(aPresContext)
|
: mozilla::css::CommonAnimationManager(aPresContext),
|
||||||
, mKeyframesListIsDirty(true)
|
mKeyframesListIsDirty(true)
|
||||||
{
|
{
|
||||||
mKeyframesRules.Init(16); // FIXME: make infallible!
|
mKeyframesRules.Init(16); // FIXME: make infallible!
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CanAnimateOpacity() {
|
struct AnimationEventInfo {
|
||||||
static bool canAnimateOpacity =
|
nsRefPtr<mozilla::dom::Element> mElement;
|
||||||
mozilla::Preferences::GetBool("layers.offmainthreadcomposition.animate-opacity", false) &&
|
nsAnimationEvent mEvent;
|
||||||
mozilla::Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
|
|
||||||
return canAnimateOpacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CanAnimateTransform() {
|
AnimationEventInfo(mozilla::dom::Element *aElement,
|
||||||
static bool canAnimateTransform =
|
const nsString& aAnimationName,
|
||||||
mozilla::Preferences::GetBool("layers.offmainthreadcomposition.animate-transform", false) &&
|
PRUint32 aMessage, mozilla::TimeDuration aElapsedTime)
|
||||||
mozilla::Preferences::GetBool("layers.offmainthreadcomposition.enabled", false);
|
: mElement(aElement),
|
||||||
return canAnimateTransform;
|
mEvent(true, aMessage, aAnimationName, aElapsedTime.ToSeconds())
|
||||||
}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static ElementAnimations* GetAnimationsForCompositor(nsIContent* aContent,
|
// nsAnimationEvent doesn't support copy-construction, so we need
|
||||||
nsCSSProperty aProperty)
|
// to ourselves in order to work with nsTArray
|
||||||
{
|
AnimationEventInfo(const AnimationEventInfo &aOther)
|
||||||
if (!aContent->MayHaveAnimations())
|
: mElement(aOther.mElement),
|
||||||
return nsnull;
|
mEvent(true, aOther.mEvent.message,
|
||||||
ElementAnimations* animations = static_cast<ElementAnimations*>(
|
aOther.mEvent.animationName, aOther.mEvent.elapsedTime)
|
||||||
aContent->GetProperty(nsGkAtoms::animationsProperty));
|
{
|
||||||
if (!animations)
|
}
|
||||||
return nsnull;
|
};
|
||||||
bool propertyMatches = animations->HasAnimationOfProperty(aProperty);
|
|
||||||
return (propertyMatches && animations->CanPerformOnCompositorThread()) ?
|
|
||||||
animations : nsnull;
|
|
||||||
}
|
|
||||||
|
|
||||||
// nsIStyleRuleProcessor (parts)
|
// nsIStyleRuleProcessor (parts)
|
||||||
virtual void RulesMatching(ElementRuleProcessorData* aData);
|
virtual void RulesMatching(ElementRuleProcessorData* aData);
|
||||||
@@ -243,6 +89,8 @@ public:
|
|||||||
mKeyframesListIsDirty = true;
|
mKeyframesListIsDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef InfallibleTArray<AnimationEventInfo> EventArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch any pending events. We accumulate animationend and
|
* Dispatch any pending events. We accumulate animationend and
|
||||||
* animationiteration events only during refresh driver notifications
|
* animationiteration events only during refresh driver notifications
|
||||||
|
|||||||
@@ -1122,9 +1122,9 @@ AddTransformScale(const nsCSSValue &aValue1, double aCoeff1,
|
|||||||
aResult.SetFloatValue(result + 1.0f, eCSSUnit_Number);
|
aResult.SetFloatValue(result + 1.0f, eCSSUnit_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ already_AddRefed<nsCSSValue::Array>
|
static already_AddRefed<nsCSSValue::Array>
|
||||||
nsStyleAnimation::AppendTransformFunction(nsCSSKeyword aTransformFunction,
|
AppendTransformFunction(nsCSSKeyword aTransformFunction,
|
||||||
nsCSSValueList**& aListTail)
|
nsCSSValueList**& aListTail)
|
||||||
{
|
{
|
||||||
nsRefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction);
|
nsRefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction);
|
||||||
nsCSSValueList *item = new nsCSSValueList;
|
nsCSSValueList *item = new nsCSSValueList;
|
||||||
@@ -1284,7 +1284,7 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale,
|
|||||||
/* Normalize the matrix */
|
/* Normalize the matrix */
|
||||||
local.Normalize();
|
local.Normalize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* perspective is used to solve for perspective, but it also provides
|
* perspective is used to solve for perspective, but it also provides
|
||||||
* an easy way to test for singularity of the upper 3x3 component.
|
* 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 is the right hand side of the equation. */
|
||||||
aPerspective = local.TransposedVector(3);
|
aPerspective = local.TransposedVector(3);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Solve the equation by inverting perspective and multiplying
|
* Solve the equation by inverting perspective and multiplying
|
||||||
* aPerspective by the inverse.
|
* aPerspective by the inverse.
|
||||||
*/
|
*/
|
||||||
perspective.Invert();
|
perspective.Invert();
|
||||||
aPerspective = perspective.TransposeTransform4D(aPerspective);
|
aPerspective = perspective.TransposeTransform4D(aPerspective);
|
||||||
|
|
||||||
/* Clear the perspective partition */
|
/* Clear the perspective partition */
|
||||||
local.SetTransposedVector(3, empty);
|
local.SetTransposedVector(3, empty);
|
||||||
} else {
|
} else {
|
||||||
@@ -1326,11 +1326,11 @@ Decompose3DMatrix(const gfx3DMatrix &aMatrix, gfxPoint3D &aScale,
|
|||||||
/* Compute X scale factor and normalize first row. */
|
/* Compute X scale factor and normalize first row. */
|
||||||
aScale.x = local[0].Length();
|
aScale.x = local[0].Length();
|
||||||
local[0] /= aScale.x;
|
local[0] /= aScale.x;
|
||||||
|
|
||||||
/* Compute XY shear factor and make 2nd local orthogonal to 1st. */
|
/* Compute XY shear factor and make 2nd local orthogonal to 1st. */
|
||||||
aShear[XYSHEAR] = local[0].DotProduct(local[1]);
|
aShear[XYSHEAR] = local[0].DotProduct(local[1]);
|
||||||
local[1] -= local[0] * aShear[XYSHEAR];
|
local[1] -= local[0] * aShear[XYSHEAR];
|
||||||
|
|
||||||
/* Now, compute Y scale and normalize 2nd local. */
|
/* Now, compute Y scale and normalize 2nd local. */
|
||||||
aScale.y = local[1].Length();
|
aScale.y = local[1].Length();
|
||||||
local[1] /= aScale.y;
|
local[1] /= aScale.y;
|
||||||
@@ -1407,11 +1407,11 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
|||||||
// Interpolate each of the pieces
|
// Interpolate each of the pieces
|
||||||
gfx3DMatrix result;
|
gfx3DMatrix result;
|
||||||
|
|
||||||
gfxPointH3D perspective =
|
gfxPointH3D perspective =
|
||||||
InterpolateNumerically(perspective1, perspective2, aProgress);
|
InterpolateNumerically(perspective1, perspective2, aProgress);
|
||||||
result.SetTransposedVector(3, perspective);
|
result.SetTransposedVector(3, perspective);
|
||||||
|
|
||||||
gfxPoint3D translate =
|
gfxPoint3D translate =
|
||||||
InterpolateNumerically(translate1, translate2, aProgress);
|
InterpolateNumerically(translate1, translate2, aProgress);
|
||||||
result.Translate(translate);
|
result.Translate(translate);
|
||||||
|
|
||||||
@@ -1440,7 +1440,7 @@ nsStyleAnimation::InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
|||||||
result.SkewXY(xyshear);
|
result.SkewXY(xyshear);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfxPoint3D scale =
|
gfxPoint3D scale =
|
||||||
InterpolateNumerically(scale1, scale2, aProgress);
|
InterpolateNumerically(scale1, scale2, aProgress);
|
||||||
if (scale != gfxPoint3D(1.0, 1.0, 1.0)) {
|
if (scale != gfxPoint3D(1.0, 1.0, 1.0)) {
|
||||||
result.Scale(scale.x, scale.y, scale.z);
|
result.Scale(scale.x, scale.y, scale.z);
|
||||||
@@ -1457,8 +1457,8 @@ AddDifferentTransformLists(const nsCSSValueList* aList1, double aCoeff1,
|
|||||||
nsCSSValueList **resultTail = getter_Transfers(result);
|
nsCSSValueList **resultTail = getter_Transfers(result);
|
||||||
|
|
||||||
nsRefPtr<nsCSSValue::Array> arr;
|
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
|
// FIXME: We should change the other transform code to also only
|
||||||
// take a single progress value, as having values that don't
|
// take a single progress value, as having values that don't
|
||||||
// sum to 1 doesn't make sense for these.
|
// sum to 1 doesn't make sense for these.
|
||||||
@@ -1503,7 +1503,7 @@ AddTransformLists(const nsCSSValueList* aList1, double aCoeff1,
|
|||||||
tfunc != eCSSKeyword_interpolatematrix &&
|
tfunc != eCSSKeyword_interpolatematrix &&
|
||||||
tfunc != eCSSKeyword_rotate3d &&
|
tfunc != eCSSKeyword_rotate3d &&
|
||||||
tfunc != eCSSKeyword_perspective) {
|
tfunc != eCSSKeyword_perspective) {
|
||||||
arr = nsStyleAnimation::AppendTransformFunction(tfunc, resultTail);
|
arr = AppendTransformFunction(tfunc, resultTail);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (tfunc) {
|
switch (tfunc) {
|
||||||
|
|||||||
@@ -15,10 +15,14 @@
|
|||||||
#include "nsCSSProperty.h"
|
#include "nsCSSProperty.h"
|
||||||
#include "nsCoord.h"
|
#include "nsCoord.h"
|
||||||
#include "nsColor.h"
|
#include "nsColor.h"
|
||||||
#include "nsCSSValue.h"
|
|
||||||
|
|
||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsStyleContext;
|
class nsStyleContext;
|
||||||
|
class nsCSSValue;
|
||||||
|
struct nsCSSValueList;
|
||||||
|
struct nsCSSValuePair;
|
||||||
|
struct nsCSSValueTriplet;
|
||||||
|
struct nsCSSValuePairList;
|
||||||
struct nsCSSRect;
|
struct nsCSSRect;
|
||||||
class gfx3DMatrix;
|
class gfx3DMatrix;
|
||||||
|
|
||||||
@@ -128,7 +132,7 @@ public:
|
|||||||
* (property ID + string). A style context is needed in case the
|
* (property ID + string). A style context is needed in case the
|
||||||
* specified value depends on inherited style or on the values of other
|
* specified value depends on inherited style or on the values of other
|
||||||
* properties.
|
* properties.
|
||||||
*
|
*
|
||||||
* @param aProperty The property whose value we're computing.
|
* @param aProperty The property whose value we're computing.
|
||||||
* @param aTargetElement The content node to which our computed value is
|
* @param aTargetElement The content node to which our computed value is
|
||||||
* applicable.
|
* applicable.
|
||||||
@@ -199,13 +203,9 @@ public:
|
|||||||
* @param aProgress Interpolation value in the range [0.0, 1.0]
|
* @param aProgress Interpolation value in the range [0.0, 1.0]
|
||||||
*/
|
*/
|
||||||
static gfx3DMatrix InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
static gfx3DMatrix InterpolateTransformMatrix(const gfx3DMatrix &aMatrix1,
|
||||||
const gfx3DMatrix &aMatrix2,
|
const gfx3DMatrix &aMatrix2,
|
||||||
double aProgress);
|
double aProgress);
|
||||||
|
|
||||||
static already_AddRefed<nsCSSValue::Array>
|
|
||||||
AppendTransformFunction(nsCSSKeyword aTransformFunction,
|
|
||||||
nsCSSValueList**& aListTail);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The types and values for the values that we extract and animate.
|
* The types and values for the values that we extract and animate.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -60,13 +60,12 @@ static nscoord CalcLength(const nsCSSValue &aValue,
|
|||||||
aCanStoreInRuleTree);
|
aCanStoreInRuleTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
static float
|
||||||
ProcessTranslatePart(const nsCSSValue& aValue,
|
ProcessTranslatePart(const nsCSSValue& aValue,
|
||||||
nsStyleContext* aContext,
|
nsStyleContext* aContext,
|
||||||
nsPresContext* aPresContext,
|
nsPresContext* aPresContext,
|
||||||
bool& aCanStoreInRuleTree,
|
bool& aCanStoreInRuleTree,
|
||||||
nscoord aSize,
|
nscoord aSize, float aAppUnitsPerMatrixUnit)
|
||||||
float aAppUnitsPerMatrixUnit)
|
|
||||||
{
|
{
|
||||||
nscoord offset = 0;
|
nscoord offset = 0;
|
||||||
float percent = 0.0f;
|
float percent = 0.0f;
|
||||||
|
|||||||
@@ -30,13 +30,6 @@ namespace nsStyleTransformMatrix {
|
|||||||
*/
|
*/
|
||||||
nsCSSKeyword TransformFunctionOf(const nsCSSValue::Array* aData);
|
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,
|
* Given an nsCSSValueList containing -moz-transform functions,
|
||||||
* returns a matrix containing the value of those functions.
|
* returns a matrix containing the value of those functions.
|
||||||
|
|||||||
@@ -22,8 +22,6 @@
|
|||||||
#include "nsEventDispatcher.h"
|
#include "nsEventDispatcher.h"
|
||||||
#include "nsGUIEvent.h"
|
#include "nsGUIEvent.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "nsIFrame.h"
|
|
||||||
#include "nsCSSFrameConstructor.h"
|
|
||||||
|
|
||||||
using mozilla::TimeStamp;
|
using mozilla::TimeStamp;
|
||||||
using mozilla::TimeDuration;
|
using mozilla::TimeDuration;
|
||||||
@@ -31,12 +29,53 @@ using mozilla::TimeDuration;
|
|||||||
namespace dom = mozilla::dom;
|
namespace dom = mozilla::dom;
|
||||||
namespace css = mozilla::css;
|
namespace css = mozilla::css;
|
||||||
|
|
||||||
ElementTransitions::ElementTransitions(mozilla::dom::Element *aElement, nsIAtom *aElementProperty,
|
/*****************************************************************************
|
||||||
nsTransitionManager *aTransitionManager)
|
* Per-Element data *
|
||||||
: CommonElementAnimationData(aElement, aElementProperty,
|
*****************************************************************************/
|
||||||
aTransitionManager)
|
|
||||||
|
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
|
double
|
||||||
ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const
|
ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const
|
||||||
@@ -66,6 +105,32 @@ ElementPropertyTransition::ValuePortionFor(TimeStamp aRefreshTime) const
|
|||||||
return mTimingFunction.GetValue(timePortion);
|
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
|
static void
|
||||||
ElementTransitionsPropertyDtor(void *aObject,
|
ElementTransitionsPropertyDtor(void *aObject,
|
||||||
nsIAtom *aPropertyName,
|
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 *
|
* nsTransitionManager *
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@@ -195,12 +225,13 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||||||
disp->mTransitions[0].GetDelay() == 0.0f &&
|
disp->mTransitions[0].GetDelay() == 0.0f &&
|
||||||
disp->mTransitions[0].GetDuration() == 0.0f) {
|
disp->mTransitions[0].GetDuration() == 0.0f) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (aNewStyleContext->PresContext()->IsProcessingAnimationStyleChange()) {
|
if (aNewStyleContext->PresContext()->IsProcessingAnimationStyleChange()) {
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aNewStyleContext->GetParent() &&
|
if (aNewStyleContext->GetParent() &&
|
||||||
aNewStyleContext->GetParent()->HasPseudoElementData()) {
|
aNewStyleContext->GetParent()->HasPseudoElementData()) {
|
||||||
// Ignore transitions on things that inherit properties from
|
// Ignore transitions on things that inherit properties from
|
||||||
@@ -229,7 +260,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||||||
property == eCSSProperty_UNKNOWN) {
|
property == eCSSProperty_UNKNOWN) {
|
||||||
// Nothing to do, but need to exclude this from cases below.
|
// Nothing to do, but need to exclude this from cases below.
|
||||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||||
for (nsCSSProperty p = nsCSSProperty(0);
|
for (nsCSSProperty p = nsCSSProperty(0);
|
||||||
p < eCSSProperty_COUNT_no_shorthands;
|
p < eCSSProperty_COUNT_no_shorthands;
|
||||||
p = nsCSSProperty(p + 1)) {
|
p = nsCSSProperty(p + 1)) {
|
||||||
ConsiderStartingTransition(p, t, aElement, et,
|
ConsiderStartingTransition(p, t, aElement, et,
|
||||||
@@ -269,7 +300,7 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||||||
property == eCSSProperty_UNKNOWN) {
|
property == eCSSProperty_UNKNOWN) {
|
||||||
// Nothing to do, but need to exclude this from cases below.
|
// Nothing to do, but need to exclude this from cases below.
|
||||||
} else if (property == eCSSPropertyExtra_all_properties) {
|
} else if (property == eCSSPropertyExtra_all_properties) {
|
||||||
for (nsCSSProperty p = nsCSSProperty(0);
|
for (nsCSSProperty p = nsCSSProperty(0);
|
||||||
p < eCSSProperty_COUNT_no_shorthands;
|
p < eCSSProperty_COUNT_no_shorthands;
|
||||||
p = nsCSSProperty(p + 1)) {
|
p = nsCSSProperty(p + 1)) {
|
||||||
allTransitionProperties.AddProperty(p);
|
allTransitionProperties.AddProperty(p);
|
||||||
@@ -333,7 +364,11 @@ nsTransitionManager::StyleContextChanged(dom::Element *aElement,
|
|||||||
// rule.
|
// rule.
|
||||||
|
|
||||||
nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
|
nsRefPtr<css::AnimValuesStyleRule> coverRule = new css::AnimValuesStyleRule;
|
||||||
|
if (!coverRule) {
|
||||||
|
NS_WARNING("out of memory");
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
|
nsTArray<ElementPropertyTransition> &pts = et->mPropertyTransitions;
|
||||||
for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
for (PRUint32 i = 0, i_end = pts.Length(); i < i_end; ++i) {
|
||||||
ElementPropertyTransition &pt = pts[i];
|
ElementPropertyTransition &pt = pts[i];
|
||||||
@@ -378,19 +413,9 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||||||
pt.mStartValue) &&
|
pt.mStartValue) &&
|
||||||
ExtractComputedValueForTransition(aProperty, aNewStyleContext,
|
ExtractComputedValueForTransition(aProperty, aNewStyleContext,
|
||||||
pt.mEndValue);
|
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 =
|
bool shouldAnimate =
|
||||||
haveValues &&
|
haveValues &&
|
||||||
(haveChange || haveOMTA) &&
|
pt.mStartValue != pt.mEndValue &&
|
||||||
// Check that we can interpolate between these values
|
// Check that we can interpolate between these values
|
||||||
// (If this is ever a performance problem, we could add a
|
// (If this is ever a performance problem, we could add a
|
||||||
// CanInterpolate method, but it seems fine for now.)
|
// 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.
|
// now we'd end up at the current position.
|
||||||
double valuePortion =
|
double valuePortion =
|
||||||
oldPT.ValuePortionFor(mostRecentRefresh) * oldPT.mReversePortion +
|
oldPT.ValuePortionFor(mostRecentRefresh) * oldPT.mReversePortion +
|
||||||
(1.0 - oldPT.mReversePortion);
|
(1.0 - oldPT.mReversePortion);
|
||||||
// A timing function with negative y1 (or y2!) might make
|
// A timing function with negative y1 (or y2!) might make
|
||||||
// valuePortion negative. In this case, we still want to apply our
|
// valuePortion negative. In this case, we still want to apply our
|
||||||
// reversing logic based on relative distances, not make duration
|
// reversing logic based on relative distances, not make duration
|
||||||
@@ -491,7 +516,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||||||
// reduce positive delays.
|
// reduce positive delays.
|
||||||
if (delay < 0.0f)
|
if (delay < 0.0f)
|
||||||
delay *= valuePortion;
|
delay *= valuePortion;
|
||||||
|
|
||||||
duration *= valuePortion;
|
duration *= valuePortion;
|
||||||
|
|
||||||
pt.mStartForReversingTest = oldPT.mEndValue;
|
pt.mStartForReversingTest = oldPT.mEndValue;
|
||||||
@@ -503,6 +527,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||||||
pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
|
pt.mStartTime = mostRecentRefresh + TimeDuration::FromMilliseconds(delay);
|
||||||
pt.mDuration = TimeDuration::FromMilliseconds(duration);
|
pt.mDuration = TimeDuration::FromMilliseconds(duration);
|
||||||
pt.mTimingFunction.Init(tf);
|
pt.mTimingFunction.Init(tf);
|
||||||
|
|
||||||
if (!aElementTransitions) {
|
if (!aElementTransitions) {
|
||||||
aElementTransitions =
|
aElementTransitions =
|
||||||
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
|
GetElementTransitions(aElement, aNewStyleContext->GetPseudoType(),
|
||||||
@@ -512,7 +537,7 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsTArray<ElementPropertyTransition> &pts =
|
nsTArray<ElementPropertyTransition> &pts =
|
||||||
aElementTransitions->mPropertyTransitions;
|
aElementTransitions->mPropertyTransitions;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -536,7 +561,6 @@ nsTransitionManager::ConsiderStartingTransition(nsCSSProperty aProperty,
|
|||||||
nsCSSPseudoElements::ePseudo_NotPseudoElement ?
|
nsCSSPseudoElements::ePseudo_NotPseudoElement ?
|
||||||
eRestyle_Self : eRestyle_Subtree;
|
eRestyle_Self : eRestyle_Subtree;
|
||||||
presContext->PresShell()->RestyleForAnimation(aElement, hint);
|
presContext->PresShell()->RestyleForAnimation(aElement, hint);
|
||||||
// XXXdz: invalidate the frame here, once animations are throttled.
|
|
||||||
|
|
||||||
*aStartedAny = true;
|
*aStartedAny = true;
|
||||||
aWhichStarted->AddProperty(aProperty);
|
aWhichStarted->AddProperty(aProperty);
|
||||||
@@ -570,6 +594,10 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement,
|
|||||||
if (!et && aCreateIfNeeded) {
|
if (!et && aCreateIfNeeded) {
|
||||||
// FIXME: Consider arena-allocating?
|
// FIXME: Consider arena-allocating?
|
||||||
et = new ElementTransitions(aElement, propName, this);
|
et = new ElementTransitions(aElement, propName, this);
|
||||||
|
if (!et) {
|
||||||
|
NS_WARNING("out of memory");
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
nsresult rv = aElement->SetProperty(propName, et,
|
nsresult rv = aElement->SetProperty(propName, et,
|
||||||
ElementTransitionsPropertyDtor, nsnull);
|
ElementTransitionsPropertyDtor, nsnull);
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
@@ -577,9 +605,6 @@ nsTransitionManager::GetElementTransitions(dom::Element *aElement,
|
|||||||
delete et;
|
delete et;
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
}
|
||||||
if (propName == nsGkAtoms::transitionsProperty) {
|
|
||||||
aElement->SetMayHaveAnimations();
|
|
||||||
}
|
|
||||||
|
|
||||||
AddElementData(et);
|
AddElementData(et);
|
||||||
}
|
}
|
||||||
@@ -733,6 +758,8 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime)
|
|||||||
// completion. See comment below.
|
// completion. See comment below.
|
||||||
et->mPropertyTransitions.RemoveElementAt(i);
|
et->mPropertyTransitions.RemoveElementAt(i);
|
||||||
} else if (pt.mStartTime + pt.mDuration <= aTime) {
|
} else if (pt.mStartTime + pt.mDuration <= aTime) {
|
||||||
|
// This transition has completed.
|
||||||
|
|
||||||
// Fire transitionend events only for transitions on elements
|
// Fire transitionend events only for transitions on elements
|
||||||
// and not those on pseudo-elements, since we can't target an
|
// and not those on pseudo-elements, since we can't target an
|
||||||
// event at pseudo-elements.
|
// event at pseudo-elements.
|
||||||
@@ -766,9 +793,6 @@ nsTransitionManager::WillRefresh(mozilla::TimeStamp aTime)
|
|||||||
nsRestyleHint hint = et->mElementProperty == nsGkAtoms::transitionsProperty ?
|
nsRestyleHint hint = et->mElementProperty == nsGkAtoms::transitionsProperty ?
|
||||||
eRestyle_Self : eRestyle_Subtree;
|
eRestyle_Self : eRestyle_Subtree;
|
||||||
mPresContext->PresShell()->RestyleForAnimation(et->mElement, hint);
|
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()) {
|
if (et->mPropertyTransitions.IsEmpty()) {
|
||||||
et->Destroy();
|
et->Destroy();
|
||||||
|
|||||||
@@ -15,86 +15,7 @@ class nsStyleContext;
|
|||||||
class nsPresContext;
|
class nsPresContext;
|
||||||
class nsCSSPropertySet;
|
class nsCSSPropertySet;
|
||||||
struct nsTransition;
|
struct nsTransition;
|
||||||
|
struct ElementTransitions;
|
||||||
/*****************************************************************************
|
|
||||||
* 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class nsTransitionManager : public mozilla::css::CommonAnimationManager
|
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
|
* To be called from nsFrameManager::ReResolveStyleContext when the
|
||||||
* style of an element has changed, to initiate transitions from
|
* 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);
|
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_X11
|
||||||
#ifdef MOZ_WIDGET_GTK2
|
#ifdef MOZ_WIDGET_GTK2
|
||||||
pref("gfx.xrender.enabled",true);
|
pref("gfx.xrender.enabled",true);
|
||||||
|
|||||||
@@ -13,10 +13,6 @@
|
|||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "prlong.h"
|
#include "prlong.h"
|
||||||
|
|
||||||
namespace IPC {
|
|
||||||
template <typename T> struct ParamTraits;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class TimeStamp;
|
class TimeStamp;
|
||||||
@@ -99,9 +95,6 @@ public:
|
|||||||
bool operator>(const TimeDuration& aOther) const {
|
bool operator>(const TimeDuration& aOther) const {
|
||||||
return mValue > aOther.mValue;
|
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,
|
// Return a best guess at the system's current timing resolution,
|
||||||
// which might be variable. TimeDurations below this order of
|
// which might be variable. TimeDurations below this order of
|
||||||
@@ -118,7 +111,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class TimeStamp;
|
friend class TimeStamp;
|
||||||
friend struct IPC::ParamTraits<mozilla::TimeDuration>;
|
|
||||||
|
|
||||||
static TimeDuration FromTicks(PRInt64 aTicks) {
|
static TimeDuration FromTicks(PRInt64 aTicks) {
|
||||||
TimeDuration t;
|
TimeDuration t;
|
||||||
@@ -273,8 +265,6 @@ public:
|
|||||||
static NS_HIDDEN_(void) Shutdown();
|
static NS_HIDDEN_(void) Shutdown();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend struct IPC::ParamTraits<mozilla::TimeStamp>;
|
|
||||||
|
|
||||||
TimeStamp(PRUint64 aValue) : mValue(aValue) {}
|
TimeStamp(PRUint64 aValue) : mValue(aValue) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user