Bug 828531; fix scaling CSS pixels for animations; r=roc

--HG--
extra : rebase_source : 0e24bf2ee472a37b742efe3d142c2c25fef3e572
This commit is contained in:
Nicholas Cameron 2013-02-13 10:00:54 +13:00
parent be7caffeb4
commit 4dcee2ea37
4 changed files with 30 additions and 12 deletions

View File

@ -861,6 +861,8 @@ public:
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
Layer* GetMaskLayer() { return mMaskLayer; }
// Note that all lengths in animation data are either in CSS pixels or app
// units and must be converted to device pixels by the compositor.
AnimationArray& GetAnimations() { return mAnimations; }
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }

View File

@ -718,21 +718,30 @@ SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aSta
TransformData& data = aAnimation.data().get_TransformData();
nsPoint origin = data.origin();
int32_t auPerCSSPixel = nsDeviceContext::AppUnitsPerCSSPixel();
// we expect all our transform data to arrive in css pixels, so here we must
// adjust to dev pixels.
double cssPerDev = double(nsDeviceContext::AppUnitsPerCSSPixel())
/ double(data.appUnitsPerDevPixel());
gfxPoint3D mozOrigin = data.mozOrigin();
mozOrigin.x = mozOrigin.x * cssPerDev;
mozOrigin.y = mozOrigin.y * cssPerDev;
gfxPoint3D perspectiveOrigin = data.perspectiveOrigin();
perspectiveOrigin.x = perspectiveOrigin.x * cssPerDev;
perspectiveOrigin.y = perspectiveOrigin.y * cssPerDev;
nsDisplayTransform::FrameTransformProperties props(interpolatedList,
data.mozOrigin(),
data.perspectiveOrigin(),
mozOrigin,
perspectiveOrigin,
data.perspective());
gfx3DMatrix transform =
nsDisplayTransform::GetResultingTransformMatrix(props, data.origin(),
nsDeviceContext::AppUnitsPerCSSPixel(),
nsDisplayTransform::GetResultingTransformMatrix(props, origin,
data.appUnitsPerDevPixel(),
&data.bounds());
// NB: See nsDisplayTransform::GetTransform().
gfxPoint3D newOrigin =
gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(origin.x, auPerCSSPixel)),
NS_round(NSAppUnitsToFloatPixels(origin.y, auPerCSSPixel)),
gfxPoint3D scaledOrigin =
gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(origin.x, data.appUnitsPerDevPixel())),
NS_round(NSAppUnitsToFloatPixels(origin.y, data.appUnitsPerDevPixel())),
0.0f);
transform.Translate(newOrigin);
transform.Translate(scaledOrigin);
InfallibleTArray<TransformFunction> functions;
functions.AppendElement(TransformMatrix(transform));

View File

@ -139,11 +139,15 @@ struct AnimationSegment {
// 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 {
// the origin of the frame being transformed in app units
nsPoint origin;
// the -moz-transform-origin property for the transform in css pixels
gfxPoint3D mozOrigin;
// the -moz-perspective-origin property for the transform in css pixels
gfxPoint3D perspectiveOrigin;
nsRect bounds;
nscoord perspective;
int32_t appUnitsPerDevPixel;
};
union AnimationData {

View File

@ -300,7 +300,8 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsCSSProperty aProperty,
nsStyleContext* styleContext = aFrame->GetStyleContext();
nsPresContext* presContext = aFrame->PresContext();
nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(aFrame);
float scale = presContext->AppUnitsPerDevPixel();
// all data passed directly to the compositor should be in css pixels
float scale = nsDeviceContext::AppUnitsPerCSSPixel();
TimeStamp startTime = ea->mStartTime + ea->mDelay;
TimeDuration duration = ea->mIterationDuration;
@ -379,6 +380,7 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
AnimationData data;
if (aProperty == eCSSProperty_transform) {
nsRect bounds = nsDisplayTransform::GetFrameBoundsForTransform(frame);
// all data passed directly to the compositor should be in css pixels
float scale = nsDeviceContext::AppUnitsPerCSSPixel();
gfxPoint3D offsetToTransformOrigin =
nsDisplayTransform::GetDeltaToMozTransformOrigin(frame, scale, &bounds);
@ -395,7 +397,8 @@ AddAnimationsAndTransitionsToLayer(Layer* aLayer, nsDisplayListBuilder* aBuilder
nsPoint origin = aItem->ToReferenceFrame();
data = TransformData(origin, offsetToTransformOrigin,
offsetToPerspectiveOrigin, bounds, perspective);
offsetToPerspectiveOrigin, bounds, perspective,
frame->PresContext()->AppUnitsPerDevPixel());
} else if (aProperty == eCSSProperty_opacity) {
data = null_t();
}