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 42965
CSS: Add fast-path for rgba() color parsing
https://bugs.webkit.org/show_bug.cgi?id=42965
Summary
CSS: Add fast-path for rgba() color parsing
Andreas Kling
Reported
2010-07-26 04:45:47 PDT
Currently #HHEEXX, #HEX, rgb() and named colors are supported by the CSSParser::parseColor() fast-path. We should add support for rgba() colors as well. Example of a page which spends way too much time parsing rgba() colors:
http://www.mrspeaker.net/dev/parcycle/
Attachments
Proposed patch
(3.37 KB, patch)
2010-07-26 04:47 PDT
,
Andreas Kling
no flags
Details
Formatted Diff
Diff
Proposed patch v2
(4.07 KB, patch)
2010-07-27 07:58 PDT
,
Andreas Kling
no flags
Details
Formatted Diff
Diff
Proposed patch v2
(3.36 KB, patch)
2010-07-27 07:59 PDT
,
Andreas Kling
darin
: review-
Details
Formatted Diff
Diff
Proposed patch v3
(404.37 KB, patch)
2010-08-02 00:59 PDT
,
Andreas Kling
eric
: review-
Details
Formatted Diff
Diff
Proposed patch v4
(38.87 KB, patch)
2010-08-04 06:23 PDT
,
Andreas Kling
darin
: review+
Details
Formatted Diff
Diff
Show Obsolete
(4)
View All
Add attachment
proposed patch, testcase, etc.
Andreas Kling
Comment 1
2010-07-26 04:47:59 PDT
Created
attachment 62561
[details]
Proposed patch
Eric Seidel (no email)
Comment 2
2010-07-26 04:57:09 PDT
Attachment 62561
[details]
did not build on mac: Build output:
http://queues.webkit.org/results/3601387
Andreas Kling
Comment 3
2010-07-27 07:58:52 PDT
Created
attachment 62689
[details]
Proposed patch v2 Same patch with fixes for the 2 warnings from the EWS.
Andreas Kling
Comment 4
2010-07-27 07:59:37 PDT
Created
attachment 62690
[details]
Proposed patch v2
Darin Adler
Comment 5
2010-07-27 10:22:46 PDT
Comment on
attachment 62690
[details]
Proposed patch v2
> +static inline bool parseAlphaDouble(const UChar*& string, const UChar* end, UChar terminator, double& value) > +{ > + int length = end - string; > + if (!length) > + return false; > + > + Vector<char, 256> bytes(length + 1); > + for (int i = 0; i < length; ++i) { > + if (!isASCIIDigit(string[i]) && string[i] != '.' && string[i] != ')') > + return false; > + bytes[i] = string[i]; > + } > + bytes[length] = '\0'; > + char* foundTerminator; > + value = WTF::strtod(bytes.data(), &foundTerminator); > + value = max(0.0, min(value, 1.0)); > + string += (foundTerminator - bytes.data()) + 1; > + return *foundTerminator == terminator; > +}
For the typical alpha values like 0, 1, and the tenths and simple powers of too we can do a *lot* faster than calling the general purpose strtod function every time, perhaps even avoiding floating point math altogether.
> + rgb = makeRGBA(red, green, blue, static_cast<int>(lroundf(255.0f * static_cast<float>(alpha))));
I don’t think it’s correct to multiply the alpha value by 255. At other call sites you'll see code more like this: nextafter(256, 0) * alpha We need some test cases that cover the edge cases, the boundaries between alpha of 254 and 255 for example, and alpha of 0 and 1. The relevant functions to look at are CSSParser::parseColorParameters and the various functions in the Color.cpp file. There may be some cases where multiplying by 255 is right. Maybe we can also do code sharing. If the test cases prove that you are not changing behavior, then I suppose you could put this patch up for review again. review- because of the 255/256 thing.
Andreas Kling
Comment 6
2010-08-02 00:59:30 PDT
Created
attachment 63183
[details]
Proposed patch v3 Updated patch. * Use nextafter(256.0, 0.0) * Avoid strtod() for "0", "1", and "0.x" * Added a test to verify that we're not inconsistent with the slow-path.
Eric Seidel (no email)
Comment 7
2010-08-02 01:03:59 PDT
Attachment 63183
[details]
did not build on mac: Build output:
http://queues.webkit.org/results/3619464
Andreas Kling
Comment 8
2010-08-02 04:22:26 PDT
(In reply to
comment #7
)
>
Attachment 63183
[details]
did not build on mac: > Build output:
http://queues.webkit.org/results/3619464
/Users/eseidel/Projects/MacEWS/WebCore/css/CSSParser.cpp: In static member function 'static bool WebCore::CSSParser::parseColor(const WebCore::String&, WebCore::RGBA32&, bool)': /Users/eseidel/Projects/MacEWS/WebCore/css/CSSParser.cpp:3811: warning: 'alpha' may be used uninitialized in this function False alarm AFAICS. I can jam a "value = 0;" at the start of parseAlphaValue() to silence it if desired.
Eric Seidel (no email)
Comment 9
2010-08-02 07:30:53 PDT
Comment on
attachment 63183
[details]
Proposed patch v3 False alarm or not, it breaks Mac, which is a No-Go. It's definitely possible to return out of parseAlphaValue without setting "value" which may be what's confusing the compiler? Then again the compiler could be right and we could be reading something wrong here.
Darin Adler
Comment 10
2010-08-02 10:55:09 PDT
Comment on
attachment 63183
[details]
Proposed patch v3 Initializing alpha to 0 is probably the simplest way to get rid of that warning. Are strings like ".1" or ".9" valid for alpha, as opposed to "0.1" and "0.9"? Do we have test cases that cover that?
Andreas Kling
Comment 11
2010-08-04 06:23:11 PDT
Created
attachment 63446
[details]
Proposed patch v4 Updated to support ".0" through ".9" as well. Fleshed out the layout test a bit.
Darin Adler
Comment 12
2010-08-04 14:21:14 PDT
Comment on
attachment 63446
[details]
Proposed patch v4 What is an alpha value such as "2" supposed to do? Does it still do what it used to do before?
Andreas Kling
Comment 13
2010-08-05 04:17:42 PDT
(In reply to
comment #12
)
> (From update of
attachment 63446
[details]
) > What is an alpha value such as "2" supposed to do? Does it still do what it used to do before?
Alpha values should be clamped between 0.0 and 1.0, so "2" will result in 1.0 (via the slow-path.)
Andreas Kling
Comment 14
2010-08-16 15:44:24 PDT
Here's the relevant spec bit about alpha value clamping:
http://www.w3.org/TR/css3-color/#alphavaluedt
@Darin: Ping. :-)
Darin Adler
Comment 15
2010-08-16 16:30:03 PDT
Comment on
attachment 63446
[details]
Proposed patch v4
> + int length = end - string; > + if (length < 2) > + return false;
So just plain "0" and "1" are not in the fast path?
> + if ((length == 4 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]) > + || (length == 3 && string[0] == '.' && isASCIIDigit(string[1])))) {
Might be nice to use a helper function just to make this if statement easier to read.
> + switch (string[length - 2]) { > + case '0': value = 0; break; > + case '1': value = 25; break; > + case '2': value = 51; break; > + case '3': value = 76; break; > + case '4': value = 102; break; > + case '5': value = 127; break; > + case '6': value = 153; break; > + case '7': value = 179; break; > + case '8': value = 204; break; > + case '9': value = 230; break; > + }
Seems like a small array would work better here than a switch.
> + Vector<char, 256> bytes(length + 1);
The number 256 seems a little high here. r=me
Andreas Kling
Comment 16
2010-08-16 16:33:59 PDT
(In reply to
comment #15
)
> (From update of
attachment 63446
[details]
) > > + int length = end - string; > > + if (length < 2) > > + return false; > > So just plain "0" and "1" are not in the fast path?
'length' includes the terminating character.
> r=me
Hugs! Will make the requested adjustments before landing.
Andreas Kling
Comment 17
2010-08-16 18:10:21 PDT
Committed
r65475
: <
http://trac.webkit.org/changeset/65475
>
Simon Hausmann
Comment 18
2010-08-24 05:45:50 PDT
Revision
r65475
cherry-picked into qtwebkit-2.1 with commit aa4d1183733f4669dcf3ef89b48ae01b2fbc3fa0
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