WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 224322
calc() values resulting from blending mixed type lengths should be simplified
https://bugs.webkit.org/show_bug.cgi?id=224322
Summary
calc() values resulting from blending mixed type lengths should be simplified
Antoine Quint
Reported
2021-04-08 03:52:22 PDT
calc() values resulting from blending mixed type lengths should be simplified
Attachments
Patch
(149.01 KB, patch)
2021-04-08 03:58 PDT
,
Antoine Quint
no flags
Details
Formatted Diff
Diff
Patch
(156.86 KB, patch)
2021-04-08 06:26 PDT
,
Antoine Quint
no flags
Details
Formatted Diff
Diff
Patch
(158.21 KB, patch)
2021-04-08 07:15 PDT
,
Antoine Quint
no flags
Details
Formatted Diff
Diff
Patch
(166.68 KB, patch)
2021-04-08 11:42 PDT
,
Antoine Quint
no flags
Details
Formatted Diff
Diff
Patch
(158.11 KB, patch)
2021-04-09 00:26 PDT
,
Antoine Quint
sam
: review+
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Antoine Quint
Comment 1
2021-04-08 03:58:15 PDT
Created
attachment 425494
[details]
Patch
Antoine Quint
Comment 2
2021-04-08 06:26:39 PDT
Created
attachment 425504
[details]
Patch
Antoine Quint
Comment 3
2021-04-08 07:15:27 PDT
Created
attachment 425505
[details]
Patch
Simon Fraser (smfr)
Comment 4
2021-04-08 09:48:38 PDT
Comment on
attachment 425505
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
> Source/WebCore/ChangeLog:12 > + When seraliazing calc() values, we now check whether they are the result of blending
seraliazing
> Source/WebCore/css/CSSCalculationValue.cpp:2054 > + // CSSCalcOperationNode is only ever created in the context of blending > + // and requires simplification to match serialization rules.
That doesn't seem accurate. CSSCalcOperationNode::createMinOrMaxOrClamp, CSSCalcOperationNode::createProduct all return CSSCalcOperationNodes
Antoine Quint
Comment 5
2021-04-08 10:17:04 PDT
(In reply to Simon Fraser (smfr) from
comment #4
)
> Comment on
attachment 425505
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
> > > Source/WebCore/css/CSSCalculationValue.cpp:2054 > > + // CSSCalcOperationNode is only ever created in the context of blending > > + // and requires simplification to match serialization rules. > > That doesn't seem accurate. CSSCalcOperationNode::createMinOrMaxOrClamp, > CSSCalcOperationNode::createProduct all return CSSCalcOperationNodes
Oh! Should we keep a flag of when we create one for blending and only simplify then, or do those cases also need simplification?
Simon Fraser (smfr)
Comment 6
2021-04-08 10:39:17 PDT
Seems like we only need to simplify after blending.
Sam Weinig
Comment 7
2021-04-08 10:48:08 PDT
Comment on
attachment 425505
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
>>> Source/WebCore/css/CSSCalculationValue.cpp:2054 >>> + // and requires simplification to match serialization rules. >> >> That doesn't seem accurate. CSSCalcOperationNode::createMinOrMaxOrClamp, CSSCalcOperationNode::createProduct all return CSSCalcOperationNodes > > Oh! Should we keep a flag of when we create one for blending and only simplify then, or do those cases also need simplification?
It seems really weird that blending would require different rules than other places. Where is this specified?
Simon Fraser (smfr)
Comment 8
2021-04-08 10:57:53 PDT
(In reply to Sam Weinig from
comment #7
)
> Comment on
attachment 425505
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
> > >>> Source/WebCore/css/CSSCalculationValue.cpp:2054 > >>> + // and requires simplification to match serialization rules. > >> > >> That doesn't seem accurate. CSSCalcOperationNode::createMinOrMaxOrClamp, CSSCalcOperationNode::createProduct all return CSSCalcOperationNodes > > > > Oh! Should we keep a flag of when we create one for blending and only simplify then, or do those cases also need simplification? > > It seems really weird that blending would require different rules than other > places. Where is this specified?
It doesn't require different rules. It's just that we normally simplify after parsing, and blending generates calc() values which are not the result of parsing.
Antoine Quint
Comment 9
2021-04-08 11:42:36 PDT
Created
attachment 425525
[details]
Patch
Darin Adler
Comment 10
2021-04-08 12:12:09 PDT
Comment on
attachment 425505
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
> Source/WebCore/css/CSSCalculationValue.cpp:2056 > + if (is<CSSCalcOperationNode>(node)) > + node = CSSCalcOperationNode::simplify(node.get());
This is what virtual functions are for. Is there a good reason we don’t have a virtual function version of simplify?
Darin Adler
Comment 11
2021-04-08 12:12:55 PDT
Comment on
attachment 425505
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
>> Source/WebCore/css/CSSCalculationValue.cpp:2056 >> + node = CSSCalcOperationNode::simplify(node.get()); > > This is what virtual functions are for. Is there a good reason we don’t have a virtual function version of simplify?
Presumably it would just return "this" on non-calc nodes.
Darin Adler
Comment 12
2021-04-08 12:17:46 PDT
Comment on
attachment 425505
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
>>>>> Source/WebCore/css/CSSCalculationValue.cpp:2054 >>>>> + // and requires simplification to match serialization rules. >>>> >>>> That doesn't seem accurate. CSSCalcOperationNode::createMinOrMaxOrClamp, CSSCalcOperationNode::createProduct all return CSSCalcOperationNodes >>> >>> Oh! Should we keep a flag of when we create one for blending and only simplify then, or do those cases also need simplification? >> >> It seems really weird that blending would require different rules than other places. Where is this specified? > > It doesn't require different rules. It's just that we normally simplify after parsing, and blending generates calc() values which are not the result of parsing.
Could we use a dirty bit to say "already simplified" to deal with this?
Antoine Quint
Comment 13
2021-04-08 12:29:05 PDT
(In reply to Darin Adler from
comment #12
)
> Comment on
attachment 425505
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
> > >>>>> Source/WebCore/css/CSSCalculationValue.cpp:2054 > >>>>> + // and requires simplification to match serialization rules. > >>>> > >>>> That doesn't seem accurate. CSSCalcOperationNode::createMinOrMaxOrClamp, CSSCalcOperationNode::createProduct all return CSSCalcOperationNodes > >>> > >>> Oh! Should we keep a flag of when we create one for blending and only simplify then, or do those cases also need simplification? > >> > >> It seems really weird that blending would require different rules than other places. Where is this specified? > > > > It doesn't require different rules. It's just that we normally simplify after parsing, and blending generates calc() values which are not the result of parsing. > > Could we use a dirty bit to say "already simplified" to deal with this?
We could, it felt to me like more work that necessary to manage setting that bit to false. We generally know that these values need simplification as being, most likely, the result of blending, and this codepath is only used for serializing computed values, so it's unlikely we'll call the simplification code more than necessary.
Antoine Quint
Comment 14
2021-04-08 12:30:17 PDT
(In reply to Darin Adler from
comment #11
)
> Comment on
attachment 425505
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=425505&action=review
> > >> Source/WebCore/css/CSSCalculationValue.cpp:2056 > >> + node = CSSCalcOperationNode::simplify(node.get()); > > > > This is what virtual functions are for. Is there a good reason we don’t have a virtual function version of simplify? > > Presumably it would just return "this" on non-calc nodes.
I don't follow here. This is not about requiring special work to be done for CSSCalcOperationNode, it's just that in the other cases we know simplification happened already at parse-time, whereas for these we don't simplify when creating them – and don't need to until we serialize them.
Sam Weinig
Comment 15
2021-04-08 14:31:48 PDT
Can you point me to the blending code that is calling this? This really feels like the wrong place to be doing this.
Antoine Quint
Comment 16
2021-04-08 14:37:37 PDT
(In reply to Sam Weinig from
comment #15
)
> Can you point me to the blending code that is calling this? This really > feels like the wrong place to be doing this.
https://github.com/WebKit/WebKit/blob/0ebbd8f1ce40d6a78dbe72a826a20a1994c9d0dd/Source/WebCore/platform/Length.cpp#L297
Sam Weinig
Comment 17
2021-04-08 14:58:26 PDT
(In reply to Antoine Quint from
comment #16
)
> (In reply to Sam Weinig from
comment #15
) > > Can you point me to the blending code that is calling this? This really > > feels like the wrong place to be doing this. > >
https://github.com/WebKit/WebKit/blob/
> 0ebbd8f1ce40d6a78dbe72a826a20a1994c9d0dd/Source/WebCore/platform/Length. > cpp#L297
Hm, can you walk me through it a bit more. That creates a CalcExpressionBlendLength. Where does the CSSCalcValue come from?
Antoine Quint
Comment 18
2021-04-08 15:03:52 PDT
This is the first time I look at the calc() code, so it’s quite likely there’s a better way to do this. However, it does seem like simplification is directly related to serialization, and this looked like a good place to do this. Another option is to simplify as we create the expression object, but we don’t need to simplify aside from serialization, so it sounds wasteful.
Antoine Quint
Comment 19
2021-04-08 15:04:31 PDT
(In reply to Sam Weinig from
comment #17
)
> (In reply to Antoine Quint from
comment #16
) > > (In reply to Sam Weinig from
comment #15
) > > > Can you point me to the blending code that is calling this? This really > > > feels like the wrong place to be doing this. > > > >
https://github.com/WebKit/WebKit/blob/
> > 0ebbd8f1ce40d6a78dbe72a826a20a1994c9d0dd/Source/WebCore/platform/Length. > > cpp#L297 > > Hm, can you walk me through it a bit more. That creates a > CalcExpressionBlendLength. > > Where does the CSSCalcValue come from?
We really need Simon to help here, I think he wrote most of this code.
Sam Weinig
Comment 20
2021-04-08 15:05:57 PDT
(In reply to Sam Weinig from
comment #17
)
> (In reply to Antoine Quint from
comment #16
) > > (In reply to Sam Weinig from
comment #15
) > > > Can you point me to the blending code that is calling this? This really > > > feels like the wrong place to be doing this. > > > >
https://github.com/WebKit/WebKit/blob/
> > 0ebbd8f1ce40d6a78dbe72a826a20a1994c9d0dd/Source/WebCore/platform/Length. > > cpp#L297 > > Hm, can you walk me through it a bit more. That creates a > CalcExpressionBlendLength. > > Where does the CSSCalcValue come from?
I think I worked it out. I think it probably the CSSPrimitiveValue constructor that takes a Length and when it is a calculated length calls `CSSCalcValue::create(length.calculationValue(), style)`. I think the right time to do simplification is in CSSCalcValue::create(const CalculationValue&, const RenderStyle&). Just as the CSSCalcValue::create(CSSValueID, const CSSParserTokenRange&, CalculationCategory) does simplification via parser.parseCalc(), the create taking a CalculationValue should do it upfront. This will maintain the invariant that CSSCalcValue is always in its simplified form. If we want to optimize not simplifying until it is actually needed, we could do that for both forms, but I don't think that is required.
Sam Weinig
Comment 21
2021-04-08 15:09:03 PDT
(In reply to Sam Weinig from
comment #20
)
> (In reply to Sam Weinig from
comment #17
) > > (In reply to Antoine Quint from
comment #16
) > > > (In reply to Sam Weinig from
comment #15
) > > > > Can you point me to the blending code that is calling this? This really > > > > feels like the wrong place to be doing this. > > > > > >
https://github.com/WebKit/WebKit/blob/
> > > 0ebbd8f1ce40d6a78dbe72a826a20a1994c9d0dd/Source/WebCore/platform/Length. > > > cpp#L297 > > > > Hm, can you walk me through it a bit more. That creates a > > CalcExpressionBlendLength. > > > > Where does the CSSCalcValue come from? > > I think I worked it out. I think it probably the CSSPrimitiveValue > constructor that takes a Length and when it is a calculated length calls > `CSSCalcValue::create(length.calculationValue(), style)`. > > I think the right time to do simplification is in CSSCalcValue::create(const > CalculationValue&, const RenderStyle&). Just as the > CSSCalcValue::create(CSSValueID, const CSSParserTokenRange&, > CalculationCategory) does simplification via parser.parseCalc(), the create > taking a CalculationValue should do it upfront. This will maintain the > invariant that CSSCalcValue is always in its simplified form. > > If we want to optimize not simplifying until it is actually needed, we could > do that for both forms, but I don't think that is required.
Something like this: RefPtr<CSSCalcValue> CSSCalcValue::create(const CalculationValue& value, const RenderStyle& style) { auto expression = createCSS(value.expression(), style); if (!expression) return nullptr; auto simplifiedExpression = CSSCalcOperationNode::simplify(expression.releaseNonNull()); auto result = adoptRef(new CSSCalcValue(WTFMove(simplifiedExpression), value.shouldClampToNonNegative())); LOG_WITH_STREAM(Calc, stream << "CSSCalcValue::create from CalculationValue: " << *result); return result; }
Sam Weinig
Comment 22
2021-04-08 15:10:52 PDT
(In reply to Antoine Quint from
comment #18
)
> This is the first time I look at the calc() code, so it’s quite likely > there’s a better way to do this. However, it does seem like simplification > is directly related to serialization, and this looked like a good place to > do this. Another option is to simplify as we create the expression object, > but we don’t need to simplify aside from serialization, so it sounds > wasteful.
Given we already simplify all calc()s that are parsed, doing it in this case doesn't sound like a problem. I think you are optimizing for a problem we don't know exists. Ifs its a perf issue here, we should do it for both cases.
Antoine Quint
Comment 23
2021-04-08 15:20:26 PDT
(In reply to Sam Weinig from
comment #22
)
> (In reply to Antoine Quint from
comment #18
) > > This is the first time I look at the calc() code, so it’s quite likely > > there’s a better way to do this. However, it does seem like simplification > > is directly related to serialization, and this looked like a good place to > > do this. Another option is to simplify as we create the expression object, > > but we don’t need to simplify aside from serialization, so it sounds > > wasteful. > > Given we already simplify all calc()s that are parsed, doing it in this case > doesn't sound like a problem. I think you are optimizing for a problem we > don't know exists. Ifs its a perf issue here, we should do it for both cases.
Maybe so. But we end up creating those blended calc() values for each frame we resolve an animation that blends between mixed types. Meanwhile, serialization may never be needed.
Antoine Quint
Comment 24
2021-04-09 00:26:09 PDT
Created
attachment 425590
[details]
Patch
Antoine Quint
Comment 25
2021-04-09 08:58:28 PDT
Committed
r275763
(
236341@main
): <
https://commits.webkit.org/236341@main
>
Radar WebKit Bug Importer
Comment 26
2021-04-09 09:00:01 PDT
<
rdar://problem/76455027
>
Simon Fraser (smfr)
Comment 27
2021-04-09 09:12:54 PDT
Comment on
attachment 425590
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=425590&action=review
> Source/WebCore/css/CSSCalculationValue.cpp:2125 > LOG_WITH_STREAM(Calc, stream << "CSSCalcValue::create from CalculationValue: " << *result);
Would be nice if the logging revealed that simplification had taken place.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug