[whatwg] Enabling LCD Text and antialiasing in canvas
senorblanco at chromium.org
Thu Feb 14 10:14:11 PST 2013
On Thu, Feb 14, 2013 at 12:32 PM, Rik Cabanier <cabanier at gmail.com> wrote:
> On Thu, Feb 14, 2013 at 2:59 AM, Stephen White <senorblanco at chromium.org>wrote:
>> On Wed, Feb 13, 2013 at 11:35 PM, Robert O'Callahan <robert at ocallahan.org
>> > wrote:
>>> On Thu, Feb 14, 2013 at 5:16 PM, Rik Cabanier <cabanier at gmail.com>wrote:
>>>> Looking at the WebKit implementation, I'm unsure how 'opaque' can
>>>> implemented for accelerated canvas. It might work with non-accelerated
>>>> canvas but would have to run some experiments.
>>>> I also look at mozilla's Core Graphics implementation and unless I'm
>>>> missing something, it doesn't have special code to handle 'opaque'. When do
>>>> you use this parameter?
>>> CanvasRenderingContext2D::GetSurfaceFormat is part of the process. That
>>> selects a surface format that is passed down to the graphics layer when
>>> creating the canvas surface. It's true that we don't currently do anything
>>> with that when drawing with CoreGraphics. That would need to be cleaned up
>>> before we started promoting this feature.
>>> Now that you mention it, having to modify the definition of compositing
>>> is a bit of a bummer for the 'opaque' attribute approach. I think we could
>>> do everything we want using your approach --- internally keeping a flag to
>>> indicate whether the alpha values of the canvas are all 1, setting it when
>>> the canvas is filled with a solid color and clearing it when non-over
>>> drawing (or clear()) are used. Let's try that!
>> I think this is difficult to do in the general case, such as
>> putImageData() or drawImage() or patterns, since you would need to examine
>> all the pixels of the source image to determine if they contain non-1
>> alpha. This would be cost-prohibitive.
> You only have to do that if you use compositing modes such as source-in
putImageData() ignores compositing mode, though, so it would always have to
be treated as alpha-modifying. If you declare with moz-opaque that the
canvas is opaque, you can still apply the optimization even with
In addition, you could detect at low cost that the CanvasImageSource is
> opaque so some compositing modes would not reset.
Not always. For example, a partially-loaded bitmap has to be treated as
non-opaque until fully loaded, IIRC. And for canvas-to-canvas draws, you'd
be applying the same conservative algorithm that determined the opacity of
the source canvas, so it might miss some optimization cases that an
explicit declaration wouldn't.
> If it's just for the purposes of optimization, you could be conservative
>> and simply clear the flag when there's the potential for (but not certainty
>> of) non-1 alpha. But if you're also using that flag to allow subpixel AA,
>> the behaviour becomes quite unpredictable for the web developer and hard to
>> spec crisply.
> Yes, that is worrisome. It seems another flag is in ordre.
>> We could consider separating the two concepts again. In an earlier
>> thread, there was an attempt to automatically determine all the places
>> where it's safe to enabled subpixel AA, but that seemed to result in a
>> complex implementation, with all cases still not being covered (such as
>> canvas-to-canvas drawImage()). The other alternative is programmatic
>> control over subpixel AA, using a context attribute. That was the first
>> thing that Justin proposed in the earlier thread, and would be my
>> preference as well (a fully-loaded footgun: you can shoot yourself with
>> it, but the behaviour and performance characteristics are very easy to
>> understand and spec). But there didn't seem to be agreement around that
> Can you refresh me on the issue with that? Is the cost too high?
> We'd have to define what happens when you use subpixel antialiasing "inco
> because we can be pretty sure authors will use it incorrectly and expect
to get interoperable behavior.
Ian Hickson's comment earlier in this thread:
> Do we have any reason to believe the majority of authors would make the
> right decisions here?
> (The main reason we haven't provided control over things like
> is that many authors tend to make terribly bad decisions.) (Before anyone
> gets offended, by the way: that you are reading this almost guarantees
> that you are above average in terms of authoring ability.)
>> Which is how I ended up at the "moz-opaque" flag. it restricts canvas to
>> the subset of operations which result in a 1 alpha in the backing store, to
>> allow optimizations and the use of subpixel AA. I think that is actually
>> quite a useful subset (generally, the subset that doesn't need destination
>> alpha). I believe the same thing can be achieved in WebGL by setting the
>> "alpha" attribute to false in WebGLContextAttributes.
> My fear is that this is too disruptive as it changes how canvas
> compositing works.
It's opt-in, so it wouldn't affect existing content.
> It might also not be implemented easily on all platforms (especially the
> ones that use the operating system to draw)
It's pretty straightforward to implement with OpenGL: allocate the backing
store as GL_RGB instead of GL_RGBA, or (if unsupported) clear the buffer to
opaque black and use glColorMask() to disable alpha writes. Then for speed
during page compositing, disable blending.
>>> But I think "matte" is unnecessarily obscure. How about adding a
>>> clear(DOMString) method that does a 'copy' of the color to the entire
>>> canvas buffer? The color could default to rgba(0,0,0,0).
>>> 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