зеркало из https://github.com/mozilla/gecko-dev.git
Bug 952977: More gfx::Matrix cleanup in FrameLayerBuilder r=nical
This commit is contained in:
Родитель
ecf49e22a2
Коммит
6cf4dc1afd
|
@ -224,6 +224,16 @@ public:
|
|||
!FuzzyEqual(_12, 0.0) || !FuzzyEqual(_21, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the matrix has any transform other
|
||||
* than a translation or a -1 y scale (y axis flip)
|
||||
*/
|
||||
bool HasNonTranslationOrFlip() const {
|
||||
return !FuzzyEqual(_11, 1.0) ||
|
||||
(!FuzzyEqual(_22, 1.0) && !FuzzyEqual(_22, -1.0)) ||
|
||||
!FuzzyEqual(_21, 0.0) || !FuzzyEqual(_12, 0.0);
|
||||
}
|
||||
|
||||
/* Returns true if the matrix is an identity matrix.
|
||||
*/
|
||||
bool IsIdentity() const
|
||||
|
@ -603,6 +613,36 @@ public:
|
|||
gfx::FuzzyEqual(_43, o._43) && gfx::FuzzyEqual(_44, o._44);
|
||||
}
|
||||
|
||||
bool IsBackfaceVisible() const
|
||||
{
|
||||
// Inverse()._33 < 0;
|
||||
Float det = Determinant();
|
||||
Float __33 = _12*_24*_41 - _14*_22*_41 +
|
||||
_14*_21*_42 - _11*_24*_42 -
|
||||
_12*_21*_44 + _11*_22*_44;
|
||||
return (__33 * det) < 0;
|
||||
}
|
||||
|
||||
void NudgeToIntegersFixedEpsilon()
|
||||
{
|
||||
static const float error = 1e-5;
|
||||
NudgeToInteger(&_11, error);
|
||||
NudgeToInteger(&_12, error);
|
||||
NudgeToInteger(&_13, error);
|
||||
NudgeToInteger(&_14, error);
|
||||
NudgeToInteger(&_21, error);
|
||||
NudgeToInteger(&_22, error);
|
||||
NudgeToInteger(&_23, error);
|
||||
NudgeToInteger(&_24, error);
|
||||
NudgeToInteger(&_31, error);
|
||||
NudgeToInteger(&_32, error);
|
||||
NudgeToInteger(&_33, error);
|
||||
NudgeToInteger(&_34, error);
|
||||
NudgeToInteger(&_41, error);
|
||||
NudgeToInteger(&_42, error);
|
||||
NudgeToInteger(&_43, error);
|
||||
NudgeToInteger(&_44, error);
|
||||
}
|
||||
|
||||
// Set all the members of the matrix to NaN
|
||||
void SetNAN();
|
||||
|
|
|
@ -3564,7 +3564,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
nsDisplayListBuilder* aDisplayListBuilder,
|
||||
nsIFrame* aContainerFrame,
|
||||
const nsRect& aVisibleRect,
|
||||
const gfx3DMatrix* aTransform,
|
||||
const Matrix4x4* aTransform,
|
||||
const ContainerLayerParameters& aIncomingScale,
|
||||
ContainerLayer* aLayer,
|
||||
LayerState aState,
|
||||
|
@ -3572,8 +3572,8 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
{
|
||||
nsIntPoint offset;
|
||||
|
||||
gfx3DMatrix transform =
|
||||
gfx3DMatrix::ScalingMatrix(aIncomingScale.mXScale, aIncomingScale.mYScale, 1.0);
|
||||
Matrix4x4 transform =
|
||||
Matrix4x4().Scale(aIncomingScale.mXScale, aIncomingScale.mYScale, 1.0);
|
||||
if (aTransform) {
|
||||
// aTransform is applied first, then the scale is applied to the result
|
||||
transform = (*aTransform)*transform;
|
||||
|
@ -3584,7 +3584,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
// to depend on the scroll position.
|
||||
transform.NudgeToIntegersFixedEpsilon();
|
||||
}
|
||||
gfxMatrix transform2d;
|
||||
Matrix transform2d;
|
||||
if (aContainerFrame &&
|
||||
(aState == LAYER_INACTIVE || aState == LAYER_SVG_EFFECTS) &&
|
||||
(!aTransform || (aTransform->Is2D(&transform2d) &&
|
||||
|
@ -3602,7 +3602,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
NS_lround(NSAppUnitsToDoublePixels(appUnitOffset.x, appUnitsPerDevPixel)*aIncomingScale.mXScale),
|
||||
NS_lround(NSAppUnitsToDoublePixels(appUnitOffset.y, appUnitsPerDevPixel)*aIncomingScale.mYScale));
|
||||
}
|
||||
transform = transform * gfx3DMatrix::Translation(offset.x + aIncomingScale.mOffset.x, offset.y + aIncomingScale.mOffset.y, 0);
|
||||
transform = transform * Matrix4x4().Translate(offset.x + aIncomingScale.mOffset.x, offset.y + aIncomingScale.mOffset.y, 0);
|
||||
|
||||
if (transform.IsSingular()) {
|
||||
return false;
|
||||
|
@ -3620,14 +3620,14 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
scale = nsLayoutUtils::ComputeSuitableScaleForAnimation(aContainerFrame->GetContent());
|
||||
} else {
|
||||
// Scale factors are normalized to a power of 2 to reduce the number of resolution changes
|
||||
scale = RoundToFloatPrecision(transform2d.ScaleFactors(true));
|
||||
scale = RoundToFloatPrecision(ThebesMatrix(transform2d).ScaleFactors(true));
|
||||
// For frames with a changing transform that's not just a translation,
|
||||
// round scale factors up to nearest power-of-2 boundary so that we don't
|
||||
// keep having to redraw the content as it scales up and down. Rounding up to nearest
|
||||
// power-of-2 boundary ensures we never scale up, only down --- avoiding
|
||||
// jaggies. It also ensures we never scale down by more than a factor of 2,
|
||||
// avoiding bad downscaling quality.
|
||||
gfxMatrix frameTransform;
|
||||
Matrix frameTransform;
|
||||
if (ActiveLayerTracker::IsStyleAnimated(aContainerFrame, eCSSProperty_transform) &&
|
||||
aTransform &&
|
||||
(!aTransform->Is2D(&frameTransform) || frameTransform.HasNonTranslationOrFlip())) {
|
||||
|
@ -3665,7 +3665,7 @@ ChooseScaleAndSetTransform(FrameLayerBuilder* aLayerBuilder,
|
|||
}
|
||||
|
||||
// Store the inverse of our resolution-scale on the layer
|
||||
aLayer->SetBaseTransform(ToMatrix4x4(transform));
|
||||
aLayer->SetBaseTransform(transform);
|
||||
aLayer->SetPreScale(1.0f/float(scale.width),
|
||||
1.0f/float(scale.height));
|
||||
aLayer->SetInheritedScale(aIncomingScale.mXScale,
|
||||
|
@ -3728,7 +3728,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
|
|||
nsDisplayItem* aContainerItem,
|
||||
nsDisplayList* aChildren,
|
||||
const ContainerLayerParameters& aParameters,
|
||||
const gfx3DMatrix* aTransform,
|
||||
const Matrix4x4* aTransform,
|
||||
uint32_t aFlags)
|
||||
{
|
||||
uint32_t containerDisplayItemKey =
|
||||
|
|
|
@ -29,6 +29,10 @@ class BasicLayerManager;
|
|||
class ThebesLayer;
|
||||
}
|
||||
|
||||
namespace gfx {
|
||||
class Matrix4x4;
|
||||
}
|
||||
|
||||
class FrameLayerBuilder;
|
||||
class LayerManagerData;
|
||||
class ThebesLayerData;
|
||||
|
@ -229,7 +233,7 @@ public:
|
|||
nsDisplayItem* aContainerItem,
|
||||
nsDisplayList* aChildren,
|
||||
const ContainerLayerParameters& aContainerParameters,
|
||||
const gfx3DMatrix* aTransform,
|
||||
const gfx::Matrix4x4* aTransform,
|
||||
uint32_t aFlags = 0);
|
||||
|
||||
/**
|
||||
|
|
|
@ -4747,7 +4747,7 @@ nsDisplayTransform::ShouldPrerenderTransformedContent(nsDisplayListBuilder* aBui
|
|||
}
|
||||
|
||||
/* If the matrix is singular, or a hidden backface is shown, the frame won't be visible or hit. */
|
||||
static bool IsFrameVisible(nsIFrame* aFrame, const gfx3DMatrix& aMatrix)
|
||||
static bool IsFrameVisible(nsIFrame* aFrame, const Matrix4x4& aMatrix)
|
||||
{
|
||||
if (aMatrix.IsSingular()) {
|
||||
return false;
|
||||
|
@ -4798,7 +4798,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
|
|||
LayerManager *aManager,
|
||||
const ContainerLayerParameters& aContainerParameters)
|
||||
{
|
||||
const gfx3DMatrix& newTransformMatrix = To3DMatrix(GetTransform());
|
||||
const Matrix4x4& newTransformMatrix = GetTransform();
|
||||
|
||||
if (mFrame->StyleDisplay()->mBackfaceVisibility == NS_STYLE_BACKFACE_VISIBILITY_HIDDEN &&
|
||||
newTransformMatrix.IsBackfaceVisible()) {
|
||||
|
@ -4912,7 +4912,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
|||
*/
|
||||
// GetTransform always operates in dev pixels.
|
||||
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
gfx3DMatrix matrix = To3DMatrix(GetTransform());
|
||||
Matrix4x4 matrix = GetTransform();
|
||||
|
||||
if (!IsFrameVisible(mFrame, matrix)) {
|
||||
return;
|
||||
|
@ -4927,7 +4927,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
|||
nsRect resultingRect;
|
||||
if (aRect.width == 1 && aRect.height == 1) {
|
||||
// Magic width/height indicating we're hit testing a point, not a rect
|
||||
gfxPointH3D point = matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
|
||||
gfxPointH3D point = To3DMatrix(matrix).Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aRect.x, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.y, factor)));
|
||||
if (!point.HasPositiveWCoord()) {
|
||||
return;
|
||||
|
@ -4945,7 +4945,7 @@ void nsDisplayTransform::HitTest(nsDisplayListBuilder *aBuilder,
|
|||
NSAppUnitsToFloatPixels(aRect.width, factor),
|
||||
NSAppUnitsToFloatPixels(aRect.height, factor));
|
||||
|
||||
gfxRect rect = matrix.Inverse().ProjectRectBounds(originalRect);
|
||||
gfxRect rect = To3DMatrix(matrix).Inverse().ProjectRectBounds(originalRect);
|
||||
|
||||
bool snap;
|
||||
nsRect childBounds = mStoredList.GetBounds(aBuilder, &snap);
|
||||
|
@ -4988,17 +4988,17 @@ nsDisplayTransform::GetHitDepthAtPoint(nsDisplayListBuilder* aBuilder, const nsP
|
|||
{
|
||||
// GetTransform always operates in dev pixels.
|
||||
float factor = mFrame->PresContext()->AppUnitsPerDevPixel();
|
||||
gfx3DMatrix matrix = To3DMatrix(GetTransform());
|
||||
Matrix4x4 matrix = GetTransform();
|
||||
|
||||
NS_ASSERTION(IsFrameVisible(mFrame, matrix), "We can't have hit a frame that isn't visible!");
|
||||
|
||||
gfxPointH3D point = matrix.Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
|
||||
gfxPointH3D point = To3DMatrix(matrix).Inverse().ProjectPoint(gfxPoint(NSAppUnitsToFloatPixels(aPoint.x, factor),
|
||||
NSAppUnitsToFloatPixels(aPoint.y, factor)));
|
||||
NS_ASSERTION(point.HasPositiveWCoord(), "Why are we trying to get the depth for a point we didn't hit?");
|
||||
|
||||
gfxPoint point2d = point.As2DPoint();
|
||||
|
||||
gfxPoint3D transformed = matrix.Transform3D(gfxPoint3D(point2d.x, point2d.y, 0));
|
||||
Point3D transformed = matrix * Point3D(point2d.x, point2d.y, 0);
|
||||
return transformed.z;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче