[whatwg] Enabling LCD Text and antialiasing in canvas

Stephen White senorblanco at chromium.org
Mon Feb 18 15:01:15 PST 2013

On Sat, Feb 16, 2013 at 4:09 AM, Robert O'Callahan <robert at ocallahan.org>wrote:

> On Sat, Feb 16, 2013 at 11:09 AM, Stephen White <senorblanco at chromium.org>wrote:
>> On Fri, Feb 15, 2013 at 2:37 PM, Robert O'Callahan <robert at ocallahan.org>wrote:
>>> On Sat, Feb 16, 2013 at 4:35 AM, Stephen White <senorblanco at chromium.org
>>> > wrote:
>>>> Even within canvas, there may be a way to break it if the LCD AA text
>>>> is drawn first and a dest-alpha compositing mode is used overtop (I haven't
>>>> verified this though).
>>> I don't think that's a problem. All destination alpha values will be 1
>>> even after the subpixel AA test is painted, and you'll treat it as normal.
>>  I was thinking something like this:
>> - draw subpixel AA text over an opaque background
>> - draw a partially-transparent rect with destination-atop mode over the
>> subpixel AA text
>>  Now some of the subpixel AA text is still there, but the destination
>> alpha is non-1, so things will go bad when you composite into the page.
>>  (At least I think it will.. Porter-Duff makes my head spin sometimes.)
> I don't see the problem. After the first step, you have an RGBA buffer
> that represents exactly the result of the rendering. The second step treats
> it exactly like any other RGBA buffer. Am I being dense?

No, it's probably me.  I was thinking that since there was a way to
introduce non-1 alpha into the backing store after-the-fact, it would break
the previously-performed subpixel coverage blending.  But perhaps not.

>> The suggestion on the list earlier was to keep two versions of the canvas
>>> buffer: one with grayscale AA, another with subpixel AA, and composite with
>>> the subpixel AA buffer when we can do that safely, otherwise use the
>>> grayscale AA version. In many implementations there would be a performance
>>> hit for this, so it would make sense to have authors opt-in to that
>>> performance hit.
>> It would also be a needless performance hit if the developer knew that
>> they always wanted subpixel AA, and that their app would never fringe.
> I don't think the developer can ever know that. They'd have to assume the
> browser/platform does not have a quick-zoom feature, which is an assumption
> developers shouldn't be making. Although I guess we could just declare that
> that case isn't important enough to matter.

Well, pretty much all devices that have pinch-zoom today are high-DPI, and
don't implement subpixel AA.  :)   But no, I don't think that's not a good
assumption to bake into the web platform.

> So let me take a stab at a brief summary of the proposals so far, and the
>> pros and cons of each (correct me if I missed anything):
>> moz-opaque
>> pro:  fairly easy to implement
>> pro:  no performance hit over regular rendering
>> pro:  many opportunities for optimization
>> pro:  catches all in-canvas cases of color fringing
>> con:  does not handle any out-of-canvas color fringing
>> con:  opt-in
> Additional con: requires changes to canvas compositing spec and possibly
> implementations.

Yes, since it's new behaviour it'll require spec changes.  I guess we can
consider that as part of "con" of being opt-in.

automatic opacity detection
>> pro:  catches most (all?) cases of in-canvas color fringing
>> pro:  some opportunties for optimization (must be conservative in some
>> cases)
> con:  does not catch color fringing on CSS transforms, canvas -> WebGL, etc
>> context attribute (something like:  context.textAntialising = { 'none',
>> 'grayscale', 'subpixel' })
>> pro:  very easy to implement
>> pro:  no performance hit
>> con:  does not catch any cases of color fringing; completely up to web
>> developer
>> con:  opt-in
> Additional con: requires specification and implementation of what happens
> when subpixel AA is drawn over transparent background.

> deferred canvas rendering (collect commands into a buffer, flush buffer
>> only when compositing canvas to page, and decide on subpixel AA at that
>> point)
>> pro:  catches all cases of color fringing
>> con:  in some cases, requires an infinite buffer (e.g., a canvas that
>> never clears, and only accumulates drawing frame-to-frame means you must
>> accumulate commands indefinitely)
> Not really true, you can just give up on the complex cases and draw
> grayscale whenever you feel like it.

And leave the behaviour unspecified, I'm guessing?  Doesn't that least to
inconsistent behaviour between browsers?  Even within one implementation,
if you had content whose command stream varied over the maximum buffer
length threshold, it'd toggle between subpixel and grayscale AA. Not sure
if this is a case worth worrying about, but it does feel like it's exposing
more of the implementation that one would like.


>> con:  difficult to implement (e.g., canvas-to-canvas drawImage(), etc)
>> con:  may introduce performance hit due to re-rendering with and without
>> subpixel AA (in cases where you would rather have just gone without)
>> two buffers (one grayscale, one LCD AA)
>> pro:  handles all cases of color fringing
>> pro:  moderately easy to implement
>> con:  RAM (or VRAM) usage is doubled
>> con:  possibly-unnecessary performance hit
>> con:  must be opt-in
> Sounds right with the above modifications.

> Rob
> --
> Wrfhf pnyyrq gurz gbtrgure naq fnvq, “Lbh xabj gung gur ehyref bs gur
> Tragvyrf ybeq vg bire gurz, naq gurve uvtu bssvpvnyf rkrepvfr nhgubevgl
> bire gurz. Abg fb jvgu lbh. Vafgrnq, jubrire jnagf gb orpbzr terng nzbat
> lbh zhfg or lbhe freinag, naq jubrire jnagf gb or svefg zhfg or lbhe fynir
> — whfg nf gur Fba bs Zna qvq abg pbzr gb or freirq, ohg gb freir, naq gb
> tvir uvf yvsr nf n enafbz sbe znal.” [Znggurj 20:25-28]

More information about the whatwg mailing list