Bug 1274962 - Part 4: Reorder how we compute transforms for preserve-3d. r=mstange,thinker

This commit is contained in:
Matt Woodrow 2016-06-03 14:23:27 +12:00
Родитель a3ac199d7f
Коммит 64b86ea169
4 изменённых файлов: 37 добавлений и 45 удалений

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

@ -5655,8 +5655,6 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
{
const nsIFrame *frame = aProperties.mFrame;
NS_ASSERTION(frame || !(aFlags & INCLUDE_PERSPECTIVE), "Must have a frame to compute perspective!");
MOZ_ASSERT((aFlags & (OFFSET_BY_ORIGIN|BASIS_AT_ORIGIN)) != (OFFSET_BY_ORIGIN|BASIS_AT_ORIGIN),
"Can't specify offset by origin as well as basis at origin!");
// Get the underlying transform matrix:
@ -5698,16 +5696,6 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
result = Matrix4x4::From2D(svgTransform);
}
/* Account for the transform-origin property by translating the
* coordinate space to the new origin.
*/
Point3D newOrigin =
Point3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
0.0f);
Point3D roundedOrigin(hasSVGTransforms ? newOrigin.x : NS_round(newOrigin.x),
hasSVGTransforms ? newOrigin.y : NS_round(newOrigin.y),
0);
Matrix4x4 perspectiveMatrix;
bool hasPerspective = aFlags & INCLUDE_PERSPECTIVE;
@ -5751,12 +5739,6 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
result = result * perspectiveMatrix;
}
if (aFlags & OFFSET_BY_ORIGIN) {
result.PostTranslate(roundedOrigin);
} else if (aFlags & BASIS_AT_ORIGIN) {
result.ChangeBasis(roundedOrigin);
}
if ((aFlags & INCLUDE_PRESERVE3D_ANCESTORS) &&
frame && frame->Combines3DTransformWithAncestors()) {
// Include the transform set on our parent
@ -5768,24 +5750,27 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
aAppUnitsPerPixel,
nullptr);
// If this frame isn't transformed (but we exist for backface-visibility),
// then we're not a reference frame so no offset to origin will be added. Our
// parent transform however *is* the reference frame, so we pass
// OFFSET_BY_ORIGIN to convert into the correct coordinate space.
uint32_t flags = aFlags & (INCLUDE_PRESERVE3D_ANCESTORS|INCLUDE_PERSPECTIVE);
if (!frame->IsTransformed()) {
flags |= OFFSET_BY_ORIGIN;
} else {
flags |= BASIS_AT_ORIGIN;
// If this frame isn't transformed (but we exist for backface-visibility),
// then we're not a reference frame so no offset to origin will be added.
// Otherwise we need to manually translate into our parent's coordinate
// space.
if (frame->IsTransformed()) {
nsLayoutUtils::PostTranslate(result, frame->GetPosition(), aAppUnitsPerPixel, !hasSVGTransforms);
}
Matrix4x4 parent =
GetResultingTransformMatrixInternal(props,
aOrigin - frame->GetPosition(),
nsPoint(0, 0),
aAppUnitsPerPixel, flags,
nullptr);
result = result * parent;
}
if (aFlags & OFFSET_BY_ORIGIN) {
nsLayoutUtils::PostTranslate(result, aOrigin, aAppUnitsPerPixel, !hasSVGTransforms);
}
return result;
}
@ -5932,11 +5917,10 @@ nsDisplayTransform::GetAccumulatedPreserved3DTransform(nsDisplayListBuilder* aBu
establisher && establisher->Combines3DTransformWithAncestors();
establisher = nsLayoutUtils::GetCrossDocParentFrame(establisher)) {
}
establisher = nsLayoutUtils::GetCrossDocParentFrame(establisher);
const nsIFrame* establisherReference =
aBuilder->FindReferenceFrameFor(establisher);
aBuilder->FindReferenceFrameFor(nsLayoutUtils::GetCrossDocParentFrame(establisher));
nsPoint offset = mFrame->GetOffsetToCrossDoc(establisherReference);
nsPoint offset = establisher->GetOffsetToCrossDoc(establisherReference);
float scale = mFrame->PresContext()->AppUnitsPerDevPixel();
uint32_t flags = INCLUDE_PRESERVE3D_ANCESTORS|INCLUDE_PERSPECTIVE|OFFSET_BY_ORIGIN;
mTransformPreserves3D =

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

@ -1123,15 +1123,7 @@ public:
};
const nsRect GetPreserves3DDirtyRect(const nsIFrame *aFrame) const {
nsRect dirty = mPreserves3DCtx.mDirtyRect;
// Translate the dirty rect to make it positioned relative to the
// origin of aFrame.
const nsIFrame *rootPreserves3D = aFrame;
while (rootPreserves3D && rootPreserves3D->Combines3DTransformWithAncestors()) {
dirty.MoveBy(-rootPreserves3D->GetPosition());
rootPreserves3D = rootPreserves3D->GetParent();
}
return dirty;
return mPreserves3DCtx.mDirtyRect;
}
void SetPreserves3DDirtyRect(const nsRect &aDirtyRect) {
mPreserves3DCtx.mDirtyRect = aDirtyRect;
@ -4074,9 +4066,6 @@ public:
* specify a value.
* @param aFlags OFFSET_BY_ORIGIN The resulting matrix will be translated
* by aOrigin. This translation is applied *before* the CSS transform.
* @param aFlags BASIS_AT_ORIGIN The resulting matrix will have its basis
* changed to be at aOrigin. This is mutually exclusive with
* OFFSET_BY_ORIGIN.
* @param aFlags INCLUDE_PRESERVE3D_ANCESTORS The computed transform will
* include the transform of any ancestors participating in the same
* 3d rendering context.
@ -4085,9 +4074,8 @@ public:
*/
enum {
OFFSET_BY_ORIGIN = 1 << 0,
BASIS_AT_ORIGIN = 1 << 1,
INCLUDE_PRESERVE3D_ANCESTORS = 1 << 2,
INCLUDE_PERSPECTIVE = 1 << 3,
INCLUDE_PRESERVE3D_ANCESTORS = 1 << 1,
INCLUDE_PERSPECTIVE = 1 << 2,
};
static Matrix4x4 GetResultingTransformMatrix(const nsIFrame* aFrame,
const nsPoint& aOrigin,

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

@ -2558,6 +2558,20 @@ nsLayoutUtils::MatrixTransformPoint(const nsPoint &aPoint,
NSFloatPixelsToAppUnits(float(image.y), aFactor));
}
void
nsLayoutUtils::PostTranslate(Matrix4x4& aTransform, const nsPoint& aOrigin, float aAppUnitsPerPixel, bool aRounded)
{
Point3D gfxOrigin =
Point3D(NSAppUnitsToFloatPixels(aOrigin.x, aAppUnitsPerPixel),
NSAppUnitsToFloatPixels(aOrigin.y, aAppUnitsPerPixel),
0.0f);
if (aRounded) {
gfxOrigin.x = NS_round(gfxOrigin.x);
gfxOrigin.y = NS_round(gfxOrigin.y);
}
aTransform.PostTranslate(gfxOrigin);
}
Matrix4x4
nsLayoutUtils::GetTransformToAncestor(nsIFrame *aFrame, const nsIFrame *aAncestor)
{

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

@ -912,6 +912,12 @@ public:
static TransformResult TransformRect(nsIFrame* aFromFrame, nsIFrame* aToFrame,
nsRect& aRect);
/**
* Converts app units to pixels (with optional snapping) and appends as a
* translation to aTransform.
*/
static void PostTranslate(Matrix4x4& aTransform, const nsPoint& aOrigin, float aAppUnitsPerPixel, bool aRounded);
/**
* Get the border-box of aElement's primary frame, transformed it to be
* relative to aFrame.