зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1469649 Part 1 - Promote floating point precision when computing the weight of flex items. r=dholbert
The precision of `double` is needed when we are distributing large `sizeDelta` via `availableFreeSpace * myShareOfRemainingSpace`. Without this patch, the wpt test added in Part 2 will fail. Differential Revision: https://phabricator.services.mozilla.com/D123267
This commit is contained in:
Родитель
00be3c92c2
Коммит
1902424bff
|
@ -464,7 +464,7 @@ class nsFlexContainerFrame::FlexItem final {
|
|||
nscoord BaselineOffsetFromOuterCrossEdge(mozilla::Side aStartSide,
|
||||
bool aUseFirstLineBaseline) const;
|
||||
|
||||
float ShareOfWeightSoFar() const { return mShareOfWeightSoFar; }
|
||||
double ShareOfWeightSoFar() const { return mShareOfWeightSoFar; }
|
||||
|
||||
bool IsFrozen() const { return mIsFrozen; }
|
||||
|
||||
|
@ -676,8 +676,8 @@ class nsFlexContainerFrame::FlexItem final {
|
|||
mMainSize = aNewMainSize;
|
||||
}
|
||||
|
||||
void SetShareOfWeightSoFar(float aNewShare) {
|
||||
MOZ_ASSERT(!mIsFrozen || aNewShare == 0.0f,
|
||||
void SetShareOfWeightSoFar(double aNewShare) {
|
||||
MOZ_ASSERT(!mIsFrozen || aNewShare == 0.0,
|
||||
"shouldn't be giving this item any share of the weight "
|
||||
"after it's frozen");
|
||||
mShareOfWeightSoFar = aNewShare;
|
||||
|
@ -876,7 +876,7 @@ class nsFlexContainerFrame::FlexItem final {
|
|||
// overlay the same memory as some other member vars that aren't touched
|
||||
// until after main-size has been resolved. In particular, these could share
|
||||
// memory with mMainPosn through mAscent, and mIsStretched.
|
||||
float mShareOfWeightSoFar = 0.0f;
|
||||
double mShareOfWeightSoFar = 0.0;
|
||||
|
||||
bool mIsFrozen = false;
|
||||
bool mHadMinViolation = false;
|
||||
|
@ -3100,14 +3100,14 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
|
|||
// its "share" multiplied by the remaining available space.
|
||||
//
|
||||
// SPECIAL CASE: If the sum of the weights is larger than the
|
||||
// maximum representable float (overflowing to infinity), then we can't
|
||||
// maximum representable double (overflowing to infinity), then we can't
|
||||
// sensibly divide out proportional shares anymore. In that case, we
|
||||
// simply treat the flex item(s) with the largest weights as if
|
||||
// their weights were infinite (dwarfing all the others), and we
|
||||
// distribute all of the available space among them.
|
||||
float weightSum = 0.0f;
|
||||
float flexFactorSum = 0.0f;
|
||||
float largestWeight = 0.0f;
|
||||
double weightSum = 0.0;
|
||||
double flexFactorSum = 0.0;
|
||||
double largestWeight = 0.0;
|
||||
uint32_t numItemsWithLargestWeight = 0;
|
||||
|
||||
// Since this loop only operates on unfrozen flex items, we can break as
|
||||
|
@ -3121,17 +3121,17 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
|
|||
if (!item.IsFrozen()) {
|
||||
numUnfrozenItemsToBeSeen--;
|
||||
|
||||
float curWeight = item.GetWeight(isUsingFlexGrow);
|
||||
float curFlexFactor = item.GetFlexFactor(isUsingFlexGrow);
|
||||
MOZ_ASSERT(curWeight >= 0.0f, "weights are non-negative");
|
||||
MOZ_ASSERT(curFlexFactor >= 0.0f, "flex factors are non-negative");
|
||||
const double curWeight = item.GetWeight(isUsingFlexGrow);
|
||||
const double curFlexFactor = item.GetFlexFactor(isUsingFlexGrow);
|
||||
MOZ_ASSERT(curWeight >= 0.0, "weights are non-negative");
|
||||
MOZ_ASSERT(curFlexFactor >= 0.0, "flex factors are non-negative");
|
||||
|
||||
weightSum += curWeight;
|
||||
flexFactorSum += curFlexFactor;
|
||||
|
||||
if (IsFinite(weightSum)) {
|
||||
if (curWeight == 0.0f) {
|
||||
item.SetShareOfWeightSoFar(0.0f);
|
||||
if (curWeight == 0.0) {
|
||||
item.SetShareOfWeightSoFar(0.0);
|
||||
} else {
|
||||
item.SetShareOfWeightSoFar(curWeight / weightSum);
|
||||
}
|
||||
|
@ -3152,11 +3152,11 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
|
|||
|
||||
MOZ_ASSERT(numUnfrozenItemsToBeSeen == 0, "miscounted frozen items?");
|
||||
|
||||
if (weightSum != 0.0f) {
|
||||
MOZ_ASSERT(flexFactorSum != 0.0f,
|
||||
if (weightSum != 0.0) {
|
||||
MOZ_ASSERT(flexFactorSum != 0.0,
|
||||
"flex factor sum can't be 0, if a weighted sum "
|
||||
"of its components (weightSum) is nonzero");
|
||||
if (flexFactorSum < 1.0f) {
|
||||
if (flexFactorSum < 1.0) {
|
||||
// Our unfrozen flex items don't want all of the original free space!
|
||||
// (Their flex factors add up to something less than 1.)
|
||||
// Hence, make sure we don't distribute any more than the portion of
|
||||
|
@ -3204,17 +3204,17 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
|
|||
// item, and then subtract it from the remaining available space.
|
||||
nscoord sizeDelta = 0;
|
||||
if (IsFinite(weightSum)) {
|
||||
float myShareOfRemainingSpace = item.ShareOfWeightSoFar();
|
||||
double myShareOfRemainingSpace = item.ShareOfWeightSoFar();
|
||||
|
||||
MOZ_ASSERT(myShareOfRemainingSpace >= 0.0f &&
|
||||
myShareOfRemainingSpace <= 1.0f,
|
||||
MOZ_ASSERT(myShareOfRemainingSpace >= 0.0 &&
|
||||
myShareOfRemainingSpace <= 1.0,
|
||||
"my share should be nonnegative fractional amount");
|
||||
|
||||
if (myShareOfRemainingSpace == 1.0f) {
|
||||
// (We special-case 1.0f to avoid float error from converting
|
||||
// availableFreeSpace from integer*1.0f --> float --> integer)
|
||||
if (myShareOfRemainingSpace == 1.0) {
|
||||
// (We special-case 1.0 to avoid float error from converting
|
||||
// availableFreeSpace from integer*1.0 --> double --> integer)
|
||||
sizeDelta = availableFreeSpace;
|
||||
} else if (myShareOfRemainingSpace > 0.0f) {
|
||||
} else if (myShareOfRemainingSpace > 0.0) {
|
||||
sizeDelta = NSToCoordRound(availableFreeSpace *
|
||||
myShareOfRemainingSpace);
|
||||
}
|
||||
|
@ -3223,7 +3223,7 @@ void FlexLine::ResolveFlexibleLengths(nscoord aFlexContainerMainSize,
|
|||
// the available space equally among the items that are tied for
|
||||
// having the largest weight (and this is one of those items).
|
||||
sizeDelta = NSToCoordRound(availableFreeSpace /
|
||||
float(numItemsWithLargestWeight));
|
||||
double(numItemsWithLargestWeight));
|
||||
numItemsWithLargestWeight--;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче