Bug 1558001: Use double for DOMMatrix r=bzbarsky

DOMMatrix now internally uses double instead of float. This only fixes DOMMatrix internals so we still have to work on Servo CSS Parser to pass doubles instead of floats.

Differential Revision: https://phabricator.services.mozilla.com/D35284

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Kagami Sascha Rosylight 2019-06-19 15:59:54 +00:00
parent 28fb524a81
commit 3a1f6f85f5
3 changed files with 96 additions and 65 deletions

View File

@ -169,13 +169,13 @@ already_AddRefed<DOMMatrix> DOMMatrixReadOnly::Multiply(
already_AddRefed<DOMMatrix> DOMMatrixReadOnly::FlipX() const {
RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
if (mMatrix3D) {
gfx::Matrix4x4 m;
gfx::Matrix4x4Double m;
m._11 = -1;
retval->mMatrix3D = new gfx::Matrix4x4(m * *mMatrix3D);
retval->mMatrix3D = new gfx::Matrix4x4Double(m * *mMatrix3D);
} else {
gfx::Matrix m;
gfx::MatrixDouble m;
m._11 = -1;
retval->mMatrix2D = new gfx::Matrix(mMatrix2D ? m * *mMatrix2D : m);
retval->mMatrix2D = new gfx::MatrixDouble(mMatrix2D ? m * *mMatrix2D : m);
}
return retval.forget();
@ -184,13 +184,13 @@ already_AddRefed<DOMMatrix> DOMMatrixReadOnly::FlipX() const {
already_AddRefed<DOMMatrix> DOMMatrixReadOnly::FlipY() const {
RefPtr<DOMMatrix> retval = new DOMMatrix(mParent, *this);
if (mMatrix3D) {
gfx::Matrix4x4 m;
gfx::Matrix4x4Double m;
m._22 = -1;
retval->mMatrix3D = new gfx::Matrix4x4(m * *mMatrix3D);
retval->mMatrix3D = new gfx::Matrix4x4Double(m * *mMatrix3D);
} else {
gfx::Matrix m;
gfx::MatrixDouble m;
m._22 = -1;
retval->mMatrix2D = new gfx::Matrix(mMatrix2D ? m * *mMatrix2D : m);
retval->mMatrix2D = new gfx::MatrixDouble(mMatrix2D ? m * *mMatrix2D : m);
}
return retval.forget();
@ -231,9 +231,9 @@ already_AddRefed<DOMPoint> DOMMatrixReadOnly::TransformPoint(
retval->SetZ(transformedPoint.z);
retval->SetW(transformedPoint.w);
} else if (point.mZ != 0 || point.mW != 1.0) {
gfx::Matrix4x4 tempMatrix(gfx::Matrix4x4::From2D(*mMatrix2D));
gfx::Matrix4x4Double tempMatrix(gfx::Matrix4x4Double::From2D(*mMatrix2D));
gfx::Point4D transformedPoint;
gfx::PointDouble4D transformedPoint;
transformedPoint.x = point.mX;
transformedPoint.y = point.mY;
transformedPoint.z = point.mZ;
@ -246,7 +246,7 @@ already_AddRefed<DOMPoint> DOMMatrixReadOnly::TransformPoint(
retval->SetZ(transformedPoint.z);
retval->SetW(transformedPoint.w);
} else {
gfx::Point transformedPoint;
gfx::PointDouble transformedPoint;
transformedPoint.x = point.mX;
transformedPoint.y = point.mY;
@ -376,9 +376,9 @@ void DOMMatrixReadOnly::Stringify(nsAString& aResult) {
// https://drafts.fxtf.org/geometry/#structured-serialization
bool DOMMatrixReadOnly::WriteStructuredClone(
JSStructuredCloneWriter* aWriter) const {
#define WriteFloatPair(f1, f2) \
JS_WriteUint32Pair(aWriter, BitwiseCast<uint32_t>(f1), \
BitwiseCast<uint32_t>(f2))
#define WriteDouble(d) \
JS_WriteUint32Pair(aWriter, (BitwiseCast<uint64_t>(d) >> 32) & 0xffffffff, \
BitwiseCast<uint64_t>(d) & 0xffffffff)
const uint8_t is2D = Is2D();
@ -387,21 +387,21 @@ bool DOMMatrixReadOnly::WriteStructuredClone(
}
if (is2D == 1) {
return WriteFloatPair(mMatrix2D->_11, mMatrix2D->_12) &&
WriteFloatPair(mMatrix2D->_21, mMatrix2D->_22) &&
WriteFloatPair(mMatrix2D->_31, mMatrix2D->_32);
return WriteDouble(mMatrix2D->_11) && WriteDouble(mMatrix2D->_12) &&
WriteDouble(mMatrix2D->_21) && WriteDouble(mMatrix2D->_22) &&
WriteDouble(mMatrix2D->_31) && WriteDouble(mMatrix2D->_32);
}
return WriteFloatPair(mMatrix3D->_11, mMatrix3D->_12) &&
WriteFloatPair(mMatrix3D->_13, mMatrix3D->_14) &&
WriteFloatPair(mMatrix3D->_21, mMatrix3D->_22) &&
WriteFloatPair(mMatrix3D->_23, mMatrix3D->_24) &&
WriteFloatPair(mMatrix3D->_31, mMatrix3D->_32) &&
WriteFloatPair(mMatrix3D->_33, mMatrix3D->_34) &&
WriteFloatPair(mMatrix3D->_41, mMatrix3D->_42) &&
WriteFloatPair(mMatrix3D->_43, mMatrix3D->_44);
return WriteDouble(mMatrix3D->_11) && WriteDouble(mMatrix3D->_12) &&
WriteDouble(mMatrix3D->_13) && WriteDouble(mMatrix3D->_14) &&
WriteDouble(mMatrix3D->_21) && WriteDouble(mMatrix3D->_22) &&
WriteDouble(mMatrix3D->_23) && WriteDouble(mMatrix3D->_24) &&
WriteDouble(mMatrix3D->_31) && WriteDouble(mMatrix3D->_32) &&
WriteDouble(mMatrix3D->_33) && WriteDouble(mMatrix3D->_34) &&
WriteDouble(mMatrix3D->_41) && WriteDouble(mMatrix3D->_42) &&
WriteDouble(mMatrix3D->_43) && WriteDouble(mMatrix3D->_44);
#undef WriteFloatPair
#undef WriteDouble
}
bool DOMMatrixReadOnly::ReadStructuredCloneElements(
@ -409,31 +409,41 @@ bool DOMMatrixReadOnly::ReadStructuredCloneElements(
uint32_t high;
uint32_t low;
#define ReadFloatPair(f1, f2) \
#define ReadDouble(d) \
if (!JS_ReadUint32Pair(aReader, &high, &low)) { \
return false; \
} \
(*(f1) = BitwiseCast<float>(high)); \
(*(f2) = BitwiseCast<float>(low));
(*(d) = BitwiseCast<double>(static_cast<uint64_t>(high) << 32 | low))
if (matrix->Is2D() == 1) {
ReadFloatPair(&(matrix->mMatrix2D->_11), &(matrix->mMatrix2D->_12));
ReadFloatPair(&(matrix->mMatrix2D->_21), &(matrix->mMatrix2D->_22));
ReadFloatPair(&(matrix->mMatrix2D->_31), &(matrix->mMatrix2D->_32));
ReadDouble(&(matrix->mMatrix2D->_11));
ReadDouble(&(matrix->mMatrix2D->_12));
ReadDouble(&(matrix->mMatrix2D->_21));
ReadDouble(&(matrix->mMatrix2D->_22));
ReadDouble(&(matrix->mMatrix2D->_31));
ReadDouble(&(matrix->mMatrix2D->_32));
} else {
ReadFloatPair(&(matrix->mMatrix3D->_11), &(matrix->mMatrix3D->_12));
ReadFloatPair(&(matrix->mMatrix3D->_13), &(matrix->mMatrix3D->_14));
ReadFloatPair(&(matrix->mMatrix3D->_21), &(matrix->mMatrix3D->_22));
ReadFloatPair(&(matrix->mMatrix3D->_23), &(matrix->mMatrix3D->_24));
ReadFloatPair(&(matrix->mMatrix3D->_31), &(matrix->mMatrix3D->_32));
ReadFloatPair(&(matrix->mMatrix3D->_33), &(matrix->mMatrix3D->_34));
ReadFloatPair(&(matrix->mMatrix3D->_41), &(matrix->mMatrix3D->_42));
ReadFloatPair(&(matrix->mMatrix3D->_43), &(matrix->mMatrix3D->_44));
ReadDouble(&(matrix->mMatrix3D->_11));
ReadDouble(&(matrix->mMatrix3D->_12));
ReadDouble(&(matrix->mMatrix3D->_13));
ReadDouble(&(matrix->mMatrix3D->_14));
ReadDouble(&(matrix->mMatrix3D->_21));
ReadDouble(&(matrix->mMatrix3D->_22));
ReadDouble(&(matrix->mMatrix3D->_23));
ReadDouble(&(matrix->mMatrix3D->_24));
ReadDouble(&(matrix->mMatrix3D->_31));
ReadDouble(&(matrix->mMatrix3D->_32));
ReadDouble(&(matrix->mMatrix3D->_33));
ReadDouble(&(matrix->mMatrix3D->_34));
ReadDouble(&(matrix->mMatrix3D->_41));
ReadDouble(&(matrix->mMatrix3D->_42));
ReadDouble(&(matrix->mMatrix3D->_43));
ReadDouble(&(matrix->mMatrix3D->_44));
}
return true;
#undef ReadFloatPair
#undef ReadDouble
}
already_AddRefed<DOMMatrix> DOMMatrix::Constructor(const GlobalObject& aGlobal,
@ -545,7 +555,8 @@ already_AddRefed<DOMMatrix> DOMMatrix::ReadStructuredClone(
void DOMMatrixReadOnly::Ensure3DMatrix() {
if (!mMatrix3D) {
mMatrix3D = new gfx::Matrix4x4(gfx::Matrix4x4::From2D(*mMatrix2D));
mMatrix3D =
new gfx::Matrix4x4Double(gfx::Matrix4x4Double::From2D(*mMatrix2D));
mMatrix2D = nullptr;
}
}
@ -557,7 +568,7 @@ DOMMatrix* DOMMatrix::MultiplySelf(const DOMMatrix& aOther) {
if (aOther.Is2D()) {
if (mMatrix3D) {
*mMatrix3D = gfx::Matrix4x4::From2D(*aOther.mMatrix2D) * *mMatrix3D;
*mMatrix3D = gfx::Matrix4x4Double::From2D(*aOther.mMatrix2D) * *mMatrix3D;
} else {
*mMatrix2D = *aOther.mMatrix2D * *mMatrix2D;
}
@ -576,7 +587,7 @@ DOMMatrix* DOMMatrix::PreMultiplySelf(const DOMMatrix& aOther) {
if (aOther.Is2D()) {
if (mMatrix3D) {
*mMatrix3D = *mMatrix3D * gfx::Matrix4x4::From2D(*aOther.mMatrix2D);
*mMatrix3D = *mMatrix3D * gfx::Matrix4x4Double::From2D(*aOther.mMatrix2D);
} else {
*mMatrix2D = *mMatrix2D * *aOther.mMatrix2D;
}
@ -628,13 +639,13 @@ DOMMatrix* DOMMatrix::ScaleNonUniformSelf(double aScaleX, double aScaleY,
if (mMatrix3D || aScaleZ != 1.0 || aOriginZ != 0) {
Ensure3DMatrix();
gfx::Matrix4x4 m;
gfx::Matrix4x4Double m;
m._11 = aScaleX;
m._22 = aScaleY;
m._33 = aScaleZ;
*mMatrix3D = m * *mMatrix3D;
} else {
gfx::Matrix m;
gfx::MatrixDouble m;
m._11 = aScaleX;
m._22 = aScaleY;
*mMatrix2D = m * *mMatrix2D;
@ -683,7 +694,7 @@ DOMMatrix* DOMMatrix::RotateAxisAngleSelf(double aX, double aY, double aZ,
aAngle *= radPerDegree;
Ensure3DMatrix();
gfx::Matrix4x4 m;
gfx::Matrix4x4Double m;
m.SetRotateAxisAngle(aX, aY, aZ, aAngle);
*mMatrix3D = m * *mMatrix3D;
@ -697,11 +708,11 @@ DOMMatrix* DOMMatrix::SkewXSelf(double aSx) {
}
if (mMatrix3D) {
gfx::Matrix4x4 m;
gfx::Matrix4x4Double m;
m._21 = tan(aSx * radPerDegree);
*mMatrix3D = m * *mMatrix3D;
} else {
gfx::Matrix m;
gfx::MatrixDouble m;
m._21 = tan(aSx * radPerDegree);
*mMatrix2D = m * *mMatrix2D;
}
@ -715,11 +726,11 @@ DOMMatrix* DOMMatrix::SkewYSelf(double aSy) {
}
if (mMatrix3D) {
gfx::Matrix4x4 m;
gfx::Matrix4x4Double m;
m._12 = tan(aSy * radPerDegree);
*mMatrix3D = m * *mMatrix3D;
} else {
gfx::Matrix m;
gfx::MatrixDouble m;
m._12 = tan(aSy * radPerDegree);
*mMatrix2D = m * *mMatrix2D;
}
@ -735,7 +746,7 @@ DOMMatrix* DOMMatrix::InvertSelf() {
} else if (!mMatrix2D->Invert()) {
mMatrix2D = nullptr;
mMatrix3D = new gfx::Matrix4x4();
mMatrix3D = new gfx::Matrix4x4Double();
mMatrix3D->SetNAN();
}
@ -759,7 +770,7 @@ DOMMatrixReadOnly* DOMMatrixReadOnly::SetMatrixValue(
if (!contains3dTransform) {
mMatrix3D = nullptr;
mMatrix2D = new gfx::Matrix();
mMatrix2D = new gfx::MatrixDouble();
SetA(transform._11);
SetB(transform._12);
@ -768,7 +779,7 @@ DOMMatrixReadOnly* DOMMatrixReadOnly::SetMatrixValue(
SetE(transform._41);
SetF(transform._42);
} else {
mMatrix3D = new gfx::Matrix4x4(transform);
mMatrix3D = new gfx::Matrix4x4Double(transform);
mMatrix2D = nullptr;
}

View File

@ -16,7 +16,7 @@
#include "nsCOMPtr.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/TypedArray.h"
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Matrix.h" // for Matrix4x4Double
namespace mozilla {
namespace dom {
@ -30,20 +30,20 @@ struct DOMPointInit;
class DOMMatrixReadOnly : public nsWrapperCache {
public:
explicit DOMMatrixReadOnly(nsISupports* aParent)
: mParent(aParent), mMatrix2D(new gfx::Matrix()) {}
: mParent(aParent), mMatrix2D(new gfx::MatrixDouble()) {}
DOMMatrixReadOnly(nsISupports* aParent, const DOMMatrixReadOnly& other)
: mParent(aParent) {
if (other.mMatrix2D) {
mMatrix2D = new gfx::Matrix(*other.mMatrix2D);
mMatrix2D = new gfx::MatrixDouble(*other.mMatrix2D);
} else {
mMatrix3D = new gfx::Matrix4x4(*other.mMatrix3D);
mMatrix3D = new gfx::Matrix4x4Double(*other.mMatrix3D);
}
}
DOMMatrixReadOnly(nsISupports* aParent, const gfx::Matrix4x4& aMatrix)
: mParent(aParent) {
mMatrix3D = new gfx::Matrix4x4(aMatrix);
mMatrix3D = new gfx::Matrix4x4Double(aMatrix);
}
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(DOMMatrixReadOnly)
@ -190,8 +190,8 @@ class DOMMatrixReadOnly : public nsWrapperCache {
protected:
nsCOMPtr<nsISupports> mParent;
nsAutoPtr<gfx::Matrix> mMatrix2D;
nsAutoPtr<gfx::Matrix4x4> mMatrix3D;
nsAutoPtr<gfx::MatrixDouble> mMatrix2D;
nsAutoPtr<gfx::Matrix4x4Double> mMatrix3D;
virtual ~DOMMatrixReadOnly() {}
@ -201,9 +201,9 @@ class DOMMatrixReadOnly : public nsWrapperCache {
DOMMatrixReadOnly(nsISupports* aParent, bool is2D) : mParent(aParent) {
if (is2D) {
mMatrix2D = new gfx::Matrix();
mMatrix2D = new gfx::MatrixDouble();
} else {
mMatrix3D = new gfx::Matrix4x4();
mMatrix3D = new gfx::Matrix4x4Double();
}
}

View File

@ -538,6 +538,26 @@ class Matrix4x4Typed {
memcpy(components, aOther.components, sizeof(components));
}
template <class T2>
explicit Matrix4x4Typed(
const Matrix4x4Typed<SourceUnits, TargetUnits, T2>& aOther)
: _11(aOther._11),
_12(aOther._12),
_13(aOther._13),
_14(aOther._14),
_21(aOther._21),
_22(aOther._22),
_23(aOther._23),
_24(aOther._24),
_31(aOther._31),
_32(aOther._32),
_33(aOther._33),
_34(aOther._34),
_41(aOther._41),
_42(aOther._42),
_43(aOther._43),
_44(aOther._44) {}
union {
struct {
T _11, _12, _13, _14;
@ -1155,8 +1175,8 @@ class Matrix4x4Typed {
template <typename NewTargetUnits>
Matrix4x4Typed<SourceUnits, NewTargetUnits, T> operator*(
const Matrix4x4Typed<TargetUnits, NewTargetUnits>& aMatrix) const {
Matrix4x4Typed<SourceUnits, NewTargetUnits> matrix;
const Matrix4x4Typed<TargetUnits, NewTargetUnits, T>& aMatrix) const {
Matrix4x4Typed<SourceUnits, NewTargetUnits, T> matrix;
matrix._11 = _11 * aMatrix._11 + _12 * aMatrix._21 + _13 * aMatrix._31 +
_14 * aMatrix._41;