Bug 1592822 - Use Serde for Transform. r=emilio

Though this may make us use more space when serializing
StyleTransform, but we don't have to do extra conversion on the compostior
side, and this makes us easier to maintain the Rust type.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Chiou 2020-01-22 18:40:09 +00:00
Родитель 73f0ae66a9
Коммит 9735c2e972
11 изменённых файлов: 126 добавлений и 299 удалений

Просмотреть файл

@ -877,6 +877,7 @@ IMPL_PARAMTRAITS_BY_SERDE(RayFunction)
IMPL_PARAMTRAITS_BY_SERDE(StyleRotate)
IMPL_PARAMTRAITS_BY_SERDE(StyleScale)
IMPL_PARAMTRAITS_BY_SERDE(StyleTranslate)
IMPL_PARAMTRAITS_BY_SERDE(StyleTransform)
} /* namespace IPC */

Просмотреть файл

@ -64,6 +64,7 @@ using mozilla::RayReferenceData from "mozilla/MotionPathUtils.h";
using mozilla::StyleRotate from "mozilla/ServoStyleConsts.h";
using mozilla::StyleScale from "mozilla/ServoStyleConsts.h";
using mozilla::StyleTranslate from "mozilla/ServoStyleConsts.h";
using mozilla::StyleTransform from "mozilla/ServoStyleConsts.h";
namespace mozilla {
namespace layers {
@ -124,46 +125,6 @@ struct CSSAngle {
};
struct LayerColor { Color value; };
struct Perspective { float value; };
struct RotationX { CSSAngle angle; };
struct RotationY { CSSAngle angle; };
struct RotationZ { CSSAngle angle; };
struct Rotation { CSSAngle angle; };
struct Rotation3D {
float x;
float y;
float z;
CSSAngle angle;
};
struct Scale {
float x;
float y;
float z;
};
struct Skew { CSSAngle x; CSSAngle y; };
struct SkewX { CSSAngle x; };
struct SkewY { CSSAngle y; };
struct TransformMatrix { Matrix4x4 value; };
struct Translation {
float x;
float y;
float z;
};
union TransformFunction {
Perspective;
RotationX;
RotationY;
RotationZ;
Rotation;
Rotation3D;
Scale;
Skew;
SkewX;
SkewY;
Translation;
TransformMatrix;
};
struct MoveTo { Point point; };
struct LineTo { Point point; };
@ -232,7 +193,7 @@ union Animatable {
StyleRotate;
StyleScale;
StyleTranslate;
TransformFunction[];
StyleTransform;
OffsetPath;
LengthPercentage;
OffsetRotate;

Просмотреть файл

@ -207,17 +207,16 @@ static inline CSSAngle MakeCSSAngle(const StyleAngle& aValue) {
return CSSAngle(aValue.ToDegrees(), eCSSUnit_Degree);
}
static Translation GetTranslate(
static StyleTransformOperation ResolveTranslate(
TransformReferenceBox& aRefBox, const LengthPercentage& aX,
const LengthPercentage& aY = LengthPercentage::Zero(),
const Length& aZ = Length{0}) {
Translation result(0, 0, 0);
result.x() = nsStyleTransformMatrix::ProcessTranslatePart(
float x = nsStyleTransformMatrix::ProcessTranslatePart(
aX, &aRefBox, &TransformReferenceBox::Width);
result.y() = nsStyleTransformMatrix::ProcessTranslatePart(
float y = nsStyleTransformMatrix::ProcessTranslatePart(
aY, &aRefBox, &TransformReferenceBox::Height);
result.z() = aZ.ToCSSPixels();
return result;
return StyleTransformOperation::Translate3D(
LengthPercentage::FromPixels(x), LengthPercentage::FromPixels(y), aZ);
}
static StyleTranslate ResolveTranslate(const StyleTranslate& aValue,
@ -236,169 +235,85 @@ static StyleTranslate ResolveTranslate(const StyleTranslate& aValue,
return StyleTranslate::None();
}
static void AddTransformFunctions(const StyleTransform& aTransform,
TransformReferenceBox& aRefBox,
nsTArray<TransformFunction>& aFunctions) {
static StyleTransform ResolveTransformOperations(
const StyleTransform& aTransform, TransformReferenceBox& aRefBox) {
auto convertMatrix = [](const Matrix4x4& aM) {
return StyleTransformOperation::Matrix3D(StyleGenericMatrix3D<StyleNumber>{
aM._11, aM._12, aM._13, aM._14, aM._21, aM._22, aM._23, aM._24, aM._31,
aM._32, aM._33, aM._34, aM._41, aM._42, aM._43, aM._44});
};
Vector<StyleTransformOperation> result;
MOZ_RELEASE_ASSERT(
result.initCapacity(aTransform.Operations().Length()),
"Allocating vector of transform operations should be successful.");
for (const StyleTransformOperation& op : aTransform.Operations()) {
switch (op.tag) {
case StyleTransformOperation::Tag::RotateX: {
CSSAngle theta = MakeCSSAngle(op.AsRotateX());
aFunctions.AppendElement(RotationX(theta));
case StyleTransformOperation::Tag::TranslateX:
result.infallibleAppend(ResolveTranslate(aRefBox, op.AsTranslateX()));
break;
}
case StyleTransformOperation::Tag::RotateY: {
CSSAngle theta = MakeCSSAngle(op.AsRotateY());
aFunctions.AppendElement(RotationY(theta));
case StyleTransformOperation::Tag::TranslateY:
result.infallibleAppend(ResolveTranslate(
aRefBox, LengthPercentage::Zero(), op.AsTranslateY()));
break;
}
case StyleTransformOperation::Tag::RotateZ: {
CSSAngle theta = MakeCSSAngle(op.AsRotateZ());
aFunctions.AppendElement(RotationZ(theta));
case StyleTransformOperation::Tag::TranslateZ:
result.infallibleAppend(
ResolveTranslate(aRefBox, LengthPercentage::Zero(),
LengthPercentage::Zero(), op.AsTranslateZ()));
break;
}
case StyleTransformOperation::Tag::Rotate: {
CSSAngle theta = MakeCSSAngle(op.AsRotate());
aFunctions.AppendElement(Rotation(theta));
break;
}
case StyleTransformOperation::Tag::Rotate3D: {
const auto& rotate = op.AsRotate3D();
CSSAngle theta = MakeCSSAngle(rotate._3);
aFunctions.AppendElement(
Rotation3D(rotate._0, rotate._1, rotate._2, theta));
break;
}
case StyleTransformOperation::Tag::ScaleX: {
aFunctions.AppendElement(Scale(op.AsScaleX(), 1., 1.));
break;
}
case StyleTransformOperation::Tag::ScaleY: {
aFunctions.AppendElement(Scale(1., op.AsScaleY(), 1.));
break;
}
case StyleTransformOperation::Tag::ScaleZ: {
aFunctions.AppendElement(Scale(1., 1., op.AsScaleZ()));
break;
}
case StyleTransformOperation::Tag::Scale: {
const auto& scale = op.AsScale();
aFunctions.AppendElement(Scale(scale._0, scale._1, 1.));
break;
}
case StyleTransformOperation::Tag::Scale3D: {
const auto& scale = op.AsScale3D();
aFunctions.AppendElement(Scale(scale._0, scale._1, scale._2));
break;
}
case StyleTransformOperation::Tag::TranslateX: {
aFunctions.AppendElement(GetTranslate(aRefBox, op.AsTranslateX()));
break;
}
case StyleTransformOperation::Tag::TranslateY: {
aFunctions.AppendElement(
GetTranslate(aRefBox, LengthPercentage::Zero(), op.AsTranslateY()));
break;
}
case StyleTransformOperation::Tag::TranslateZ: {
aFunctions.AppendElement(GetTranslate(aRefBox, LengthPercentage::Zero(),
LengthPercentage::Zero(),
op.AsTranslateZ()));
break;
}
case StyleTransformOperation::Tag::Translate: {
const auto& translate = op.AsTranslate();
aFunctions.AppendElement(
GetTranslate(aRefBox, translate._0, translate._1));
result.infallibleAppend(
ResolveTranslate(aRefBox, translate._0, translate._1));
break;
}
case StyleTransformOperation::Tag::Translate3D: {
const auto& translate = op.AsTranslate3D();
aFunctions.AppendElement(
GetTranslate(aRefBox, translate._0, translate._1, translate._2));
break;
}
case StyleTransformOperation::Tag::SkewX: {
CSSAngle x = MakeCSSAngle(op.AsSkewX());
aFunctions.AppendElement(SkewX(x));
break;
}
case StyleTransformOperation::Tag::SkewY: {
CSSAngle y = MakeCSSAngle(op.AsSkewY());
aFunctions.AppendElement(SkewY(y));
break;
}
case StyleTransformOperation::Tag::Skew: {
const auto& skew = op.AsSkew();
aFunctions.AppendElement(
Skew(MakeCSSAngle(skew._0), MakeCSSAngle(skew._1)));
break;
}
case StyleTransformOperation::Tag::Matrix: {
gfx::Matrix4x4 matrix;
const auto& m = op.AsMatrix();
matrix._11 = m.a;
matrix._12 = m.b;
matrix._13 = 0;
matrix._14 = 0;
matrix._21 = m.c;
matrix._22 = m.d;
matrix._23 = 0;
matrix._24 = 0;
matrix._31 = 0;
matrix._32 = 0;
matrix._33 = 1;
matrix._34 = 0;
matrix._41 = m.e;
matrix._42 = m.f;
matrix._43 = 0;
matrix._44 = 1;
aFunctions.AppendElement(TransformMatrix(matrix));
break;
}
case StyleTransformOperation::Tag::Matrix3D: {
const auto& m = op.AsMatrix3D();
gfx::Matrix4x4 matrix;
matrix._11 = m.m11;
matrix._12 = m.m12;
matrix._13 = m.m13;
matrix._14 = m.m14;
matrix._21 = m.m21;
matrix._22 = m.m22;
matrix._23 = m.m23;
matrix._24 = m.m24;
matrix._31 = m.m31;
matrix._32 = m.m32;
matrix._33 = m.m33;
matrix._34 = m.m34;
matrix._41 = m.m41;
matrix._42 = m.m42;
matrix._43 = m.m43;
matrix._44 = m.m44;
aFunctions.AppendElement(TransformMatrix(matrix));
result.infallibleAppend(ResolveTranslate(aRefBox, translate._0,
translate._1, translate._2));
break;
}
case StyleTransformOperation::Tag::InterpolateMatrix: {
Matrix4x4 matrix;
nsStyleTransformMatrix::ProcessInterpolateMatrix(matrix, op, aRefBox);
aFunctions.AppendElement(TransformMatrix(matrix));
result.infallibleAppend(convertMatrix(matrix));
break;
}
case StyleTransformOperation::Tag::AccumulateMatrix: {
Matrix4x4 matrix;
nsStyleTransformMatrix::ProcessAccumulateMatrix(matrix, op, aRefBox);
aFunctions.AppendElement(TransformMatrix(matrix));
result.infallibleAppend(convertMatrix(matrix));
break;
}
case StyleTransformOperation::Tag::Perspective: {
aFunctions.AppendElement(Perspective(op.AsPerspective().ToCSSPixels()));
case StyleTransformOperation::Tag::RotateX:
case StyleTransformOperation::Tag::RotateY:
case StyleTransformOperation::Tag::RotateZ:
case StyleTransformOperation::Tag::Rotate:
case StyleTransformOperation::Tag::Rotate3D:
case StyleTransformOperation::Tag::ScaleX:
case StyleTransformOperation::Tag::ScaleY:
case StyleTransformOperation::Tag::ScaleZ:
case StyleTransformOperation::Tag::Scale:
case StyleTransformOperation::Tag::Scale3D:
case StyleTransformOperation::Tag::SkewX:
case StyleTransformOperation::Tag::SkewY:
case StyleTransformOperation::Tag::Skew:
case StyleTransformOperation::Tag::Matrix:
case StyleTransformOperation::Tag::Matrix3D:
case StyleTransformOperation::Tag::Perspective:
result.infallibleAppend(op);
break;
}
default:
MOZ_ASSERT_UNREACHABLE("Function not handled yet!");
}
}
auto transform = StyleTransform{StyleOwnedSlice(std::move(result))};
MOZ_ASSERT(!transform.HasPercent());
MOZ_ASSERT(transform.Operations().Length() ==
aTransform.Operations().Length());
return transform;
}
static TimingFunction ToTimingFunction(
@ -467,12 +382,10 @@ static void SetAnimatable(nsCSSPropertyID aProperty,
aAnimatable =
ResolveTranslate(aAnimationValue.GetTranslateProperty(), aRefBox);
break;
case eCSSProperty_transform: {
aAnimatable = nsTArray<TransformFunction>();
AddTransformFunctions(aAnimationValue.GetTransformProperty(), aRefBox,
aAnimatable.get_ArrayOfTransformFunction());
case eCSSProperty_transform:
aAnimatable = ResolveTransformOperations(
aAnimationValue.GetTransformProperty(), aRefBox);
break;
}
case eCSSProperty_offset_path:
aAnimatable = GetOffsetPath(aAnimationValue.GetOffsetPathProperty());
break;
@ -838,10 +751,8 @@ static void AddNonAnimatingTransformLikePropertiesStyles(
case eCSSProperty_transform:
if (!display->mTransform.IsNone()) {
TransformReferenceBox refBox(aFrame);
nsTArray<TransformFunction> transformFunctions;
AddTransformFunctions(display->mTransform, refBox,
transformFunctions);
appendFakeAnimation(id, Animatable(std::move(transformFunctions)));
appendFakeAnimation(
id, ResolveTransformOperations(display->mTransform, refBox));
}
break;
case eCSSProperty_translate:

Просмотреть файл

@ -69,6 +69,7 @@ BASIC_SERDE_FUNCS(RayFunction)
BASIC_SERDE_FUNCS(StyleRotate)
BASIC_SERDE_FUNCS(StyleScale)
BASIC_SERDE_FUNCS(StyleTranslate)
BASIC_SERDE_FUNCS(StyleTransform)
#undef BASIC_SERDE_FUNCS

Просмотреть файл

@ -26,6 +26,7 @@
# include "mozilla/MemoryReporting.h"
# include "mozilla/ServoTypes.h"
# include "mozilla/ServoBindingTypes.h"
# include "mozilla/Vector.h"
# include "nsCSSPropertyID.h"
# include "nsCompatibility.h"
# include "nsIURI.h"

Просмотреть файл

@ -68,6 +68,23 @@ inline StyleOwnedSlice<T>::StyleOwnedSlice(StyleOwnedSlice&& aOther)
SwapElements(aOther);
}
template <typename T>
inline StyleOwnedSlice<T>::StyleOwnedSlice(Vector<T>&& aVector)
: StyleOwnedSlice() {
if (!aVector.length()) {
return;
}
// We could handle this if Vector provided the relevant APIs, see bug 1610702.
MOZ_DIAGNOSTIC_ASSERT(aVector.length() == aVector.capacity(),
"Shouldn't over-allocate");
len = aVector.length();
ptr = aVector.extractRawBuffer();
MOZ_ASSERT(ptr,
"How did extractRawBuffer return null if we're not using inline "
"capacity?");
}
template <typename T>
inline StyleOwnedSlice<T>& StyleOwnedSlice<T>::operator=(
const StyleOwnedSlice& aOther) {

Просмотреть файл

@ -51,100 +51,6 @@ static inline StyleAngle GetCSSAngle(const layers::CSSAngle& aAngle) {
return StyleAngle{aAngle.value()};
}
static StyleTransformOperation OperationFromLayers(
const layers::TransformFunction& aFunction) {
switch (aFunction.type()) {
case layers::TransformFunction::TRotationX: {
const layers::CSSAngle& angle = aFunction.get_RotationX().angle();
return StyleTransformOperation::RotateX(GetCSSAngle(angle));
}
case layers::TransformFunction::TRotationY: {
const layers::CSSAngle& angle = aFunction.get_RotationY().angle();
return StyleTransformOperation::RotateY(GetCSSAngle(angle));
}
case layers::TransformFunction::TRotationZ: {
const layers::CSSAngle& angle = aFunction.get_RotationZ().angle();
return StyleTransformOperation::RotateZ(GetCSSAngle(angle));
}
case layers::TransformFunction::TRotation: {
const layers::CSSAngle& angle = aFunction.get_Rotation().angle();
return StyleTransformOperation::Rotate(GetCSSAngle(angle));
}
case layers::TransformFunction::TRotation3D: {
float x = aFunction.get_Rotation3D().x();
float y = aFunction.get_Rotation3D().y();
float z = aFunction.get_Rotation3D().z();
const layers::CSSAngle& angle = aFunction.get_Rotation3D().angle();
return StyleTransformOperation::Rotate3D(x, y, z, GetCSSAngle(angle));
}
case layers::TransformFunction::TScale: {
float x = aFunction.get_Scale().x();
float y = aFunction.get_Scale().y();
float z = aFunction.get_Scale().z();
return StyleTransformOperation::Scale3D(x, y, z);
}
case layers::TransformFunction::TTranslation: {
float x = aFunction.get_Translation().x();
float y = aFunction.get_Translation().y();
float z = aFunction.get_Translation().z();
return StyleTransformOperation::Translate3D(
LengthPercentage::FromPixels(x), LengthPercentage::FromPixels(y),
Length{z});
}
case layers::TransformFunction::TSkewX: {
const layers::CSSAngle& x = aFunction.get_SkewX().x();
return StyleTransformOperation::SkewX(GetCSSAngle(x));
}
case layers::TransformFunction::TSkewY: {
const layers::CSSAngle& y = aFunction.get_SkewY().y();
return StyleTransformOperation::SkewY(GetCSSAngle(y));
}
case layers::TransformFunction::TSkew: {
const layers::CSSAngle& x = aFunction.get_Skew().x();
const layers::CSSAngle& y = aFunction.get_Skew().y();
return StyleTransformOperation::Skew(GetCSSAngle(x), GetCSSAngle(y));
}
case layers::TransformFunction::TTransformMatrix: {
const gfx::Matrix4x4& matrix = aFunction.get_TransformMatrix().value();
return StyleTransformOperation::Matrix3D({
matrix._11,
matrix._12,
matrix._13,
matrix._14,
matrix._21,
matrix._22,
matrix._23,
matrix._24,
matrix._31,
matrix._32,
matrix._33,
matrix._34,
matrix._41,
matrix._42,
matrix._43,
matrix._44,
});
}
case layers::TransformFunction::TPerspective: {
float perspective = aFunction.get_Perspective().value();
return StyleTransformOperation::Perspective(Length{perspective});
}
default:
MOZ_ASSERT_UNREACHABLE("All functions should be implemented?");
return StyleTransformOperation::TranslateX(LengthPercentage::Zero());
}
}
static nsTArray<StyleTransformOperation> CreateTransformList(
const nsTArray<layers::TransformFunction>& aFunctions) {
nsTArray<StyleTransformOperation> result;
result.SetCapacity(aFunctions.Length());
for (const layers::TransformFunction& function : aFunctions) {
result.AppendElement(OperationFromLayers(function));
}
return result;
}
static StylePathCommand CommandFromLayers(const layers::PathCommand& aCommand) {
switch (aCommand.type()) {
case layers::PathCommand::TMoveTo:
@ -388,11 +294,11 @@ already_AddRefed<RawServoAnimationValue> AnimationValue::FromAnimatable(
switch (aAnimatable.type()) {
case layers::Animatable::Tnull_t:
break;
case layers::Animatable::TArrayOfTransformFunction: {
nsTArray<StyleTransformOperation> ops =
CreateTransformList(aAnimatable.get_ArrayOfTransformFunction());
return Servo_AnimationValue_Transform(ops.Elements(), ops.Length())
.Consume();
case layers::Animatable::TStyleTransform: {
const StyleTransform& transform = aAnimatable.get_StyleTransform();
MOZ_ASSERT(!transform.HasPercent(),
"Received transform operations should have been resolved.");
return Servo_AnimationValue_Transform(&transform).Consume();
}
case layers::Animatable::Tfloat:
return Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();

Просмотреть файл

@ -23,8 +23,10 @@ use style_traits::{CssWriter, ToCss};
Clone,
Copy,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
@ -51,8 +53,10 @@ pub use self::GenericMatrix as Matrix;
Clone,
Copy,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
@ -141,8 +145,10 @@ fn is_same<N: PartialEq>(x: &N, y: &N) -> bool {
#[derive(
Clone,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToComputedValue,
ToCss,
@ -267,8 +273,10 @@ pub use self::GenericTransformOperation as TransformOperation;
#[derive(
Clone,
Debug,
Deserialize,
MallocSizeOf,
PartialEq,
Serialize,
SpecifiedValueInfo,
ToComputedValue,
ToCss,

Просмотреть файл

@ -7,6 +7,8 @@
//! A replacement for `Box<[T]>` that cbindgen can understand.
use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps};
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
@ -171,3 +173,22 @@ impl<T> iter::FromIterator<T> for OwnedSlice<T> {
Vec::from_iter(iter).into()
}
}
impl<T: Serialize> Serialize for OwnedSlice<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.deref().serialize(serializer)
}
}
impl<'de, T: Deserialize<'de>> Deserialize<'de> for OwnedSlice<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let r = Box::<[T]>::deserialize(deserializer)?;
Ok(r.into())
}
}

Просмотреть файл

@ -467,6 +467,7 @@ renaming_overrides_prefixing = true
inline StyleOwnedSlice(const StyleOwnedSlice&);
inline StyleOwnedSlice(StyleOwnedSlice&&);
inline explicit StyleOwnedSlice(Vector<T>&&);
inline ~StyleOwnedSlice();

Просмотреть файл

@ -909,16 +909,9 @@ pub unsafe extern "C" fn Servo_AnimationValue_Scale(
#[no_mangle]
pub unsafe extern "C" fn Servo_AnimationValue_Transform(
list: *const computed::TransformOperation,
len: usize,
transform: &computed::Transform,
) -> Strong<RawServoAnimationValue> {
use style::values::generics::transform::Transform;
let slice = std::slice::from_raw_parts(list, len);
Arc::new(AnimationValue::Transform(Transform(
slice.iter().cloned().collect(),
)))
.into_strong()
Arc::new(AnimationValue::Transform(transform.clone())).into_strong()
}
#[no_mangle]
@ -1097,6 +1090,12 @@ impl_basic_serde_funcs!(
computed::transform::Translate
);
impl_basic_serde_funcs!(
Servo_StyleTransform_Serialize,
Servo_StyleTransform_Deserialize,
computed::transform::Transform
);
#[no_mangle]
pub extern "C" fn Servo_SVGPathData_Normalize(
input: &specified::SVGPathData,