Bug 1274158 part 1 - Handle zero perspective gracefully. r?mattwoodrow
MozReview-Commit-ID: CEX39wo6oX8
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -9,16 +9,17 @@
* structures that represent things to be painted (ordered in z-order),
* used during painting and hit testing
*/
#include "nsDisplayList.h"
#include <stdint.h>
#include <algorithm>
+#include <limits>
#include "gfxUtils.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/KeyframeEffect.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/layers/PLayerTransaction.h"
#include "nsCSSRendering.h"
#include "nsRenderingContext.h"
@@ -5632,17 +5633,17 @@ nsDisplayTransform::ComputePerspectiveMa
/* Grab the values for perspective and perspective-origin (if present) */
const nsStyleDisplay* cbDisplay = cbFrame->StyleDisplay();
if (cbDisplay->mChildPerspective.GetUnit() != eStyleUnit_Coord) {
return false;
}
nscoord perspective = cbDisplay->mChildPerspective.GetCoordValue();
- if (perspective <= 0) {
+ if (perspective < 0) {
return true;
}
TransformReferenceBox refBox(cbFrame);
/* Allows us to access named variables by index. */
Point3D perspectiveOrigin;
gfx::Float* coords[2] = {&perspectiveOrigin.x, &perspectiveOrigin.y};
@@ -5685,18 +5686,20 @@ nsDisplayTransform::ComputePerspectiveMa
NSAppUnitsToFloatPixels(frameToCbOffset.y, aAppUnitsPerPixel),
0.0f);
/* Move the perspective origin to be relative to aFrame, instead of relative
* to the containing block which is how it was specified in the style system.
*/
perspectiveOrigin += frameToCbGfxOffset;
- aOutMatrix._34 =
- -1.0 / NSAppUnitsToFloatPixels(perspective, aAppUnitsPerPixel);
+ Float perspectivePx = std::max(NSAppUnitsToFloatPixels(perspective,
+ aAppUnitsPerPixel),
+ std::numeric_limits<Float>::epsilon());
+ aOutMatrix._34 = -1.0 / perspectivePx;
aOutMatrix.ChangeBasis(perspectiveOrigin);
return true;
}
nsDisplayTransform::FrameTransformProperties::FrameTransformProperties(const nsIFrame* aFrame,
float aAppUnitsPerPixel,
const nsRect* aBoundsOverride)
: mFrame(aFrame)
--- a/layout/style/nsStyleTransformMatrix.cpp
+++ b/layout/style/nsStyleTransformMatrix.cpp
@@ -12,16 +12,18 @@
#include "nsLayoutUtils.h"
#include "nsPresContext.h"
#include "nsRuleNode.h"
#include "nsSVGUtils.h"
#include "nsCSSKeywords.h"
#include "mozilla/StyleAnimationValue.h"
#include "gfxMatrix.h"
+#include <limits>
+
using namespace mozilla;
using namespace mozilla::gfx;
namespace nsStyleTransformMatrix {
/* Note on floating point precision: The transform matrix is an array
* of single precision 'float's, and so are most of the input values
* we get from the style system, but intermediate calculations
@@ -547,19 +549,20 @@ static void
ProcessPerspective(Matrix4x4& aMatrix,
const nsCSSValue::Array* aData,
nsStyleContext *aContext,
nsPresContext *aPresContext,
RuleNodeCacheConditions& aConditions)
{
NS_PRECONDITION(aData->Count() == 2, "Invalid array!");
- float depth = ProcessTranslatePart(aData->Item(1), aContext,
- aPresContext, aConditions,
- nullptr);
+ float depth = std::max(ProcessTranslatePart(aData->Item(1), aContext,
+ aPresContext, aConditions,
+ nullptr),
+ std::numeric_limits<float>::epsilon());
aMatrix.Perspective(depth);
}
/**
* SetToTransformFunction is essentially a giant switch statement that fans
* out to many smaller helper functions.
*/