diff --git a/gfx/2d/Matrix.h b/gfx/2d/Matrix.h index 1e39ac4bc383..2646bc45c54a 100644 --- a/gfx/2d/Matrix.h +++ b/gfx/2d/Matrix.h @@ -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 diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index fafb452dc347..cad41d60fec9 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -80,6 +80,32 @@ struct ParamTraits } }; +template<> +struct ParamTraits +{ + 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 { diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index 793eee23b600..76cc9b17d25b 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -306,7 +306,7 @@ CreateCSSValueList(const InfallibleTArray& 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); diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 34fb5c0f602f..02497abe456b 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -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) diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 398eb64aa912..573b41073880 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -392,7 +392,9 @@ SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aSta transform.Translate(scaledOrigin); InfallibleTArray 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(), diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index 405361aabc7d..9690fa66884a 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -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; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 22bb5a5cd7f4..8570929c6adf 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -489,7 +489,9 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* 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(); diff --git a/gfx/tests/gtest/TestAsyncPanZoomController.cpp b/gfx/tests/gtest/TestAsyncPanZoomController.cpp index 96a1c03638ad..438bd75d4fc2 100644 --- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -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. diff --git a/gfx/tests/gtest/TestLayers.cpp b/gfx/tests/gtest/TestLayers.cpp index f6a5f595f123..81851624ec1f 100644 --- a/gfx/tests/gtest/TestLayers.cpp +++ b/gfx/tests/gtest/TestLayers.cpp @@ -218,7 +218,9 @@ already_AddRefed CreateLayerTree( } else { nsRefPtr 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) { diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 21752e9a9802..e300782b1c23 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -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 diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index f40931f3fff4..9c02f8bb0db5 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -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)); } diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index e7a40b172735..eeda421b0104 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -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; } diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index e3533b4ade81..3731479df9b1 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -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)); diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp index b3adc35a53e4..28dfe2d9bf12 100644 --- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -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)); } diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 508f02062c84..2d663f07c2ec 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -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(); } diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index d0558b6d8429..1a7565e7de1a 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -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 result = layer.forget(); return result.forget(); diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 3a0a93164cf7..d88c3a4cf417 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -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); diff --git a/layout/xul/nsImageBoxFrame.cpp b/layout/xul/nsImageBoxFrame.cpp index 9bd4854ffaa1..2c0df3349acd 100644 --- a/layout/xul/nsImageBoxFrame.cpp +++ b/layout/xul/nsImageBoxFrame.cpp @@ -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)); }