Bug 952977: Convert SetBaseTransform to gfx::Matrix4x4 r=nical

This commit is contained in:
David Zbarsky 2014-01-27 10:28:33 -05:00
parent 9288df6e4d
commit bab894b2de
18 changed files with 107 additions and 45 deletions

View File

@ -346,6 +346,16 @@ public:
return *this;
}
Matrix4x4 &Translate(Float aX, Float aY, Float aZ)
{
_41 += aX * _11 + aY * _21 + aZ * _31;
_42 += aX * _12 + aY * _22 + aZ * _32;
_43 += aX * _13 + aY * _23 + aZ * _33;
_44 += aX * _14 + aY * _24 + aZ * _34;
return *this;
}
bool operator==(const Matrix4x4& o) const
{
// XXX would be nice to memcmp here, but that breaks IEEE 754 semantics

View File

@ -80,6 +80,32 @@ struct ParamTraits<mozilla::gfx::Matrix>
}
};
template<>
struct ParamTraits<mozilla::gfx::Matrix4x4>
{
typedef mozilla::gfx::Matrix4x4 paramType;
static void Write(Message* msg, const paramType& param)
{
#define Wr(_f) WriteParam(msg, param. _f)
Wr(_11); Wr(_12); Wr(_13); Wr(_14);
Wr(_21); Wr(_22); Wr(_23); Wr(_24);
Wr(_31); Wr(_32); Wr(_33); Wr(_34);
Wr(_41); Wr(_42); Wr(_43); Wr(_44);
#undef Wr
}
static bool Read(const Message* msg, void** iter, paramType* result)
{
#define Rd(_f) ReadParam(msg, iter, &result-> _f)
return (Rd(_11) && Rd(_12) && Rd(_13) && Rd(_14) &&
Rd(_21) && Rd(_22) && Rd(_23) && Rd(_24) &&
Rd(_31) && Rd(_32) && Rd(_33) && Rd(_34) &&
Rd(_41) && Rd(_42) && Rd(_43) && Rd(_44));
#undef Rd
}
};
template<>
struct ParamTraits<gfxPoint>
{

View File

@ -306,7 +306,7 @@ CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
case TransformFunction::TTransformMatrix:
{
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_matrix3d, resultTail);
const gfx3DMatrix& matrix = aFunctions[i].get_TransformMatrix().value();
const gfx::Matrix4x4& 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);

View File

@ -885,16 +885,18 @@ public:
* Tell this layer what its transform should be. The transformation
* is applied when compositing the layer into its parent container.
*/
void SetBaseTransform(const gfx3DMatrix& aMatrix)
void SetBaseTransform(const gfx::Matrix4x4& aMatrix)
{
NS_ASSERTION(!aMatrix.IsSingular(),
"Shouldn't be trying to draw with a singular matrix!");
mPendingTransform = nullptr;
if (mTransform == aMatrix) {
gfx3DMatrix transform;
gfx::To3DMatrix(aMatrix, transform);
if (mTransform == transform) {
return;
}
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) BaseTransform", this));
mTransform = aMatrix;
mTransform = transform;
Mutated();
}
@ -906,9 +908,11 @@ public:
* method enqueues a new transform value to be set immediately after
* the next transaction is opened.
*/
void SetBaseTransformForNextTransaction(const gfx3DMatrix& aMatrix)
void SetBaseTransformForNextTransaction(const gfx::Matrix4x4& aMatrix)
{
mPendingTransform = new gfx3DMatrix(aMatrix);
gfx3DMatrix matrix;
gfx::To3DMatrix(aMatrix, matrix);
mPendingTransform = new gfx3DMatrix(matrix);
}
void SetPostScale(float aXScale, float aYScale)

View File

@ -392,7 +392,9 @@ SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aSta
transform.Translate(scaledOrigin);
InfallibleTArray<TransformFunction> functions;
functions.AppendElement(TransformMatrix(transform));
Matrix4x4 realTransform;
ToMatrix4x4(transform, realTransform);
functions.AppendElement(TransformMatrix(realTransform));
*aValue = functions;
}
@ -447,7 +449,8 @@ SampleAnimations(Layer* aLayer, TimeStamp aPoint)
}
case eCSSProperty_transform:
{
gfx3DMatrix matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value();
gfx3DMatrix matrix;
gfx::To3DMatrix(interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value(), matrix);
if (ContainerLayer* c = aLayer->AsContainerLayer()) {
matrix.ScalePost(c->GetInheritedXScale(),
c->GetInheritedYScale(),

View File

@ -20,6 +20,7 @@ include "ImageLayers.h";
using mozilla::GraphicsFilterType from "mozilla/GfxMessageUtils.h";
using struct gfxRGBA from "gfxColor.h";
using struct gfxPoint3D from "gfxPoint3D.h";
using class mozilla::gfx::Matrix4x4 from "mozilla/gfx/Matrix.h";
using class gfx3DMatrix from "gfx3DMatrix.h";
using nscoord from "nsCoord.h";
using struct nsIntPoint from "nsPoint.h";
@ -110,7 +111,7 @@ struct Scale {
struct Skew { float x; float y; };
struct SkewX { float x; };
struct SkewY { float y; };
struct TransformMatrix { gfx3DMatrix value; };
struct TransformMatrix { Matrix4x4 value; };
struct Translation {
float x;
float y;

View File

@ -489,7 +489,9 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray<EditReply>* aReplies, bool
common.eventRegions() = mutant->GetEventRegions();
common.postXScale() = mutant->GetPostXScale();
common.postYScale() = mutant->GetPostYScale();
common.transform() = mutant->GetBaseTransform();
gfx::Matrix4x4 transform;
gfx::ToMatrix4x4(mutant->GetBaseTransform(), transform);
common.transform() = transform;
common.contentFlags() = mutant->GetContentFlags();
common.opacity() = mutant->GetOpacity();
common.useClipRect() = !!mutant->GetClipRect();

View File

@ -815,8 +815,8 @@ TEST(APZCTreeManager, HitTesting2) {
gfx3DMatrix transformToGecko;
// Set a CSS transform on one of the layers.
gfx3DMatrix transform;
transform.ScalePost(2, 1, 1);
Matrix4x4 transform;
transform = transform * Matrix4x4().Scale(2, 1, 1);
layers[2]->SetBaseTransform(transform);
// Make some other layers scrollable.

View File

@ -218,7 +218,9 @@ already_AddRefed<Layer> CreateLayerTree(
} else {
nsRefPtr<Layer> layer = CreateLayer(aLayerTreeDescription[i], manager.get());
layer->SetVisibleRegion(aVisibleRegions[layerNumber]);
layer->SetBaseTransform(aTransforms[layerNumber]);
Matrix4x4 transform;
ToMatrix4x4(aTransforms[layerNumber], transform);
layer->SetBaseTransform(transform);
aLayersOut.AppendElement(layer);
layerNumber++;
if (rootLayer && !parentContainerLayer) {

View File

@ -1497,15 +1497,15 @@ ContainerState::CreateOrRecycleThebesLayer(const nsIFrame* aAnimatedGeometryRoot
RoundToMatchResidual(scaledOffset.y, data->mAnimatedGeometryRootPosition.y));
data->mTranslation = pixOffset;
pixOffset += mParameters.mOffset;
gfxMatrix matrix;
matrix.Translate(gfxPoint(pixOffset.x, pixOffset.y));
layer->SetBaseTransform(gfx3DMatrix::From2D(matrix));
Matrix matrix;
matrix.Translate(pixOffset.x, pixOffset.y);
layer->SetBaseTransform(Matrix4x4::From2D(matrix));
// FIXME: Temporary workaround for bug 681192 and bug 724786.
#ifndef MOZ_ANDROID_OMTC
// Calculate exact position of the top-left of the active scrolled root.
// This might not be 0,0 due to the snapping in ScaleToNearestPixels.
gfxPoint animatedGeometryRootTopLeft = scaledOffset - matrix.GetTranslation() + mParameters.mOffset;
gfxPoint animatedGeometryRootTopLeft = scaledOffset - ThebesPoint(matrix.GetTranslation()) + mParameters.mOffset;
// If it has changed, then we need to invalidate the entire layer since the
// pixels in the layer buffer have the content at a (subpixel) offset
// from what we need.
@ -1780,7 +1780,9 @@ ContainerState::PopThebesLayerData()
colorLayer->SetColor(data->mSolidColor);
// Copy transform
colorLayer->SetBaseTransform(data->mLayer->GetBaseTransform());
Matrix4x4 base;
ToMatrix4x4(data->mLayer->GetBaseTransform(), base);
colorLayer->SetBaseTransform(base);
colorLayer->SetPostScale(data->mLayer->GetPostXScale(), data->mLayer->GetPostYScale());
nsIntRect visibleRect = data->mVisibleRegion.GetBounds();
@ -2985,7 +2987,9 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
}
// Store the inverse of our resolution-scale on the layer
aLayer->SetBaseTransform(transform);
Matrix4x4 baseTransform;
ToMatrix4x4(transform, baseTransform);
aLayer->SetBaseTransform(baseTransform);
aLayer->SetPreScale(1.0f/float(scale.width),
1.0f/float(scale.height));
aLayer->SetInheritedScale(aIncomingScale.mXScale,
@ -3830,8 +3834,8 @@ ContainerState::SetupMaskLayer(Layer *aLayer, const DisplayItemClip& aClip,
maskLayer->SetContainer(container);
maskTransform.Invert();
gfx3DMatrix matrix = gfx3DMatrix::From2D(ThebesMatrix(maskTransform));
matrix.Translate(gfxPoint3D(mParameters.mOffset.x, mParameters.mOffset.y, 0));
Matrix4x4 matrix = Matrix4x4::From2D(maskTransform);
matrix.Translate(mParameters.mOffset.x, mParameters.mOffset.y, 0);
maskLayer->SetBaseTransform(matrix);
// save the details of the clip in user data

View File

@ -224,7 +224,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
}
case eCSSKeyword_matrix:
{
gfx3DMatrix matrix;
gfx::Matrix4x4 matrix;
matrix._11 = array->Item(1).GetFloatValue();
matrix._12 = array->Item(2).GetFloatValue();
matrix._13 = 0;
@ -246,7 +246,7 @@ static void AddTransformFunctions(nsCSSValueList* aList,
}
case eCSSKeyword_matrix3d:
{
gfx3DMatrix matrix;
gfx::Matrix4x4 matrix;
matrix._11 = array->Item(1).GetFloatValue();
matrix._12 = array->Item(2).GetFloatValue();
matrix._13 = array->Item(3).GetFloatValue();
@ -275,7 +275,9 @@ static void AddTransformFunctions(nsCSSValueList* aList,
canStoreInRuleTree,
aBounds,
aAppUnitsPerPixel);
aFunctions.AppendElement(TransformMatrix(matrix));
gfx::Matrix4x4 transform;
gfx::ToMatrix4x4(matrix, transform);
aFunctions.AppendElement(TransformMatrix(transform));
break;
}
case eCSSKeyword_perspective:
@ -1967,11 +1969,12 @@ nsDisplayBackgroundImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& a
mozilla::gfx::IntSize imageSize = mImageContainer->GetCurrentSize();
NS_ASSERTION(imageSize.width != 0 && imageSize.height != 0, "Invalid image size!");
gfxMatrix transform;
transform.Translate(mDestRect.TopLeft() + aOffset);
gfxPoint p = mDestRect.TopLeft() + aOffset;
gfx::Matrix transform;
transform.Translate(p.x, p.y);
transform.Scale(mDestRect.width/imageSize.width,
mDestRect.height/imageSize.height);
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageSize.width, imageSize.height));
}

View File

@ -4851,7 +4851,9 @@ nsIFrame::TryUpdateTransformOnly()
!gfx::FuzzyEqual(transform.yx, previousTransform.yx, kError)) {
return false;
}
layer->SetBaseTransformForNextTransaction(transform3d);
gfx::Matrix4x4 matrix;
gfx::ToMatrix4x4(transform3d, matrix);
layer->SetBaseTransformForNextTransaction(matrix);
return true;
}

View File

@ -266,10 +266,11 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
presContext->AppUnitsToGfxUnits(area.height));
// Transform the canvas into the right place
gfxMatrix transform;
transform.Translate(r.TopLeft() + aContainerParameters.mOffset);
gfx::Matrix transform;
gfxPoint p = r.TopLeft() + aContainerParameters.mOffset;
transform.Translate(p.x, p.y);
transform.Scale(r.Width()/canvasSize.width, r.Height()/canvasSize.height);
layer->SetBaseTransform(gfx3DMatrix::From2D(transform));
layer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
layer->SetVisibleRegion(nsIntRect(0, 0, canvasSize.width, canvasSize.height));

View File

@ -1360,11 +1360,12 @@ nsDisplayImage::ConfigureLayer(ImageLayer *aLayer, const nsIntPoint& aOffset)
const gfxRect destRect = GetDestRect();
gfxMatrix transform;
transform.Translate(destRect.TopLeft() + aOffset);
gfx::Matrix transform;
gfxPoint p = destRect.TopLeft() + aOffset;
transform.Translate(p.x, p.y);
transform.Scale(destRect.Width()/imageWidth,
destRect.Height()/imageHeight);
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
}

View File

@ -1637,10 +1637,11 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
}
// Set a transform on the layer to draw the plugin in the right place
gfxMatrix transform;
transform.Translate(r.TopLeft() + aContainerParameters.mOffset);
Matrix transform;
gfxPoint p = r.TopLeft() + aContainerParameters.mOffset;
transform.Translate(p.x, p.y);
layer->SetBaseTransform(gfx3DMatrix::From2D(transform));
layer->SetBaseTransform(Matrix4x4::From2D(transform));
layer->SetVisibleRegion(ThebesIntRect(IntRect(IntPoint(0, 0), size)));
return layer.forget();
}

View File

@ -215,10 +215,11 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
layer->SetFilter(nsLayoutUtils::GetGraphicsFilterForFrame(this));
layer->SetContentFlags(Layer::CONTENT_OPAQUE);
// Set a transform on the layer to draw the video in the right place
gfxMatrix transform;
transform.Translate(r.TopLeft() + aContainerParameters.mOffset);
gfx::Matrix transform;
gfxPoint p = r.TopLeft() + aContainerParameters.mOffset;
transform.Translate(p.x, p.y);
transform.Scale(r.Width()/frameSize.width, r.Height()/frameSize.height);
layer->SetBaseTransform(gfx3DMatrix::From2D(transform));
layer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
layer->SetVisibleRegion(nsIntRect(0, 0, frameSize.width, frameSize.height));
nsRefPtr<Layer> result = layer.forget();
return result.forget();

View File

@ -850,8 +850,8 @@ RenderFrameParent::BuildLayer(nsDisplayListBuilder* aBuilder,
// container, but our display item is LAYER_ACTIVE_FORCE which
// forces all layers above to be active.
MOZ_ASSERT(aContainerParameters.mOffset == nsIntPoint());
gfx3DMatrix m =
gfx3DMatrix::Translation(offset.x, offset.y, 0.0);
gfx::Matrix4x4 m;
m.Translate(offset.x, offset.y, 0.0);
// Remote content can't be repainted by us, so we multiply down
// the resolution that our container expects onto our container.
m.Scale(aContainerParameters.mXScale, aContainerParameters.mYScale, 1.0);

View File

@ -400,11 +400,12 @@ nsDisplayXULImage::ConfigureLayer(ImageLayer* aLayer, const nsIntPoint& aOffset)
NS_ASSERTION(imageWidth != 0 && imageHeight != 0, "Invalid image size!");
gfxMatrix transform;
transform.Translate(destRect.TopLeft() + aOffset);
gfxPoint p = destRect.TopLeft() + aOffset;
gfx::Matrix transform;
transform.Translate(p.x, p.y);
transform.Scale(destRect.Width()/imageWidth,
destRect.Height()/imageHeight);
aLayer->SetBaseTransform(gfx3DMatrix::From2D(transform));
aLayer->SetBaseTransform(gfx::Matrix4x4::From2D(transform));
aLayer->SetVisibleRegion(nsIntRect(0, 0, imageWidth, imageHeight));
}