W3C home > Mailing lists > Public > whatwg@whatwg.org > February 2013

Re: [whatwg] Enabling LCD Text and antialiasing in canvas

From: Stephen White <senorblanco@chromium.org>
Date: Thu, 14 Feb 2013 13:14:11 -0500
Message-ID: <CAPeKFThC=e-gXWV=F_r8JtA6D+jgHnvZCeyXZ4NGXLVzmDupNQ@mail.gmail.com>
To: Rik Cabanier <cabanier@gmail.com>
Cc: whatwg@whatwg.org, Ian Hickson <ian@hixie.ch>, robert@ocallahan.org
On Thu, Feb 14, 2013 at 12:32 PM, Rik Cabanier <cabanier@gmail.com> wrote:

> On Thu, Feb 14, 2013 at 2:59 AM, Stephen White <senorblanco@chromium.org>wrote:
>> On Wed, Feb 13, 2013 at 11:35 PM, Robert O'Callahan <robert@ocallahan.org
>> > wrote:
>>> On Thu, Feb 14, 2013 at 5:16 PM, Rik Cabanier <cabanier@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
> though.

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
>> either.
> Can you refresh me on the issue with that? Is the cost too high?

Robert's comment:

> 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).
>>> 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]
Received on Thursday, 14 February 2013 18:14:50 UTC

This archive was generated by hypermail 2.3.1 : Monday, 13 April 2015 23:09:19 UTC