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

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

From: Rik Cabanier <cabanier@gmail.com>
Date: Thu, 14 Feb 2013 10:50:42 -0800
Message-ID: <CAGN7qDD1n41DgY=_rZZwHR3xhwZxi9eaSSMO5JcvXCHioJ8+1A@mail.gmail.com>
To: Stephen White <senorblanco@chromium.org>
Cc: whatwg@whatwg.org, Ian Hickson <ian@hixie.ch>, robert@ocallahan.org
On Thu, Feb 14, 2013 at 10:14 AM, Stephen White <senorblanco@chromium.org>wrote:

> 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
> putImageData().
>

no. Not if you use an opaque ImageDataSourece (such as a JPEG image or a
canvas source that knows that it's opaque.


> 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.
>

partially loaded images are supposed to be ignored when you draw with them.


> 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.\
>

Yes. You'd have to explicitly matte the other canvas too (if you use
putImageData or certain compositing modes).
That's still better than breaking compositing though...


>
>
>> 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
> "incorrectly",
> > 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
> antialiasing
> > 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.)
>

What is the technical issue? Why does anti-aliasing only work if you have
an opaque canvas?


>
>
>>
>>>
>>> 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.
>

How about the accelerated core graphics backend? Direct2D?


>
> Stephen
>
>>
>>
>>>
>>>
>>>> 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:51:08 UTC

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