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

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

From: Rik Cabanier <cabanier@gmail.com>
Date: Tue, 12 Mar 2013 20:51:47 -0700
Message-ID: <CAGN7qDD3Q3o53g9HYPppZCt6RaGiZ-8+kfACqfuGjFvJvUNCRQ@mail.gmail.com>
To: Stephen White <senorblanco@chromium.org>
Cc: WHAT Working Group <whatwg@whatwg.org>, Ian Hickson <ian@hixie.ch>, Robert O'Callahan <robert@ocallahan.org>
On Tue, Mar 12, 2013 at 3:08 PM, Stephen White <senorblanco@chromium.org>wrote:

> On Tue, Mar 12, 2013 at 5:36 PM, Rik Cabanier <cabanier@gmail.com> wrote:
>
>>
>>
>> On Tue, Mar 12, 2013 at 10:03 AM, Stephen White <senorblanco@chromium.org
>> > wrote:
>>
>>> Here's a draft of proposal (1) above:
>>>
>>> Motivation:  Compositing a <canvas> element into the page can be
>>> expensive, due to blending operations, and lack of opportunity for culling.
>>>  Since arbitrary graphics operations can affect the opacity of the canvas,
>>> it is difficult to determine programmatically whether the canvas is opaque.
>>>  Allowing the developer to explicitly mark a canvas as opaque allows the
>>> user agent to optimize blending at page composite time, as well to cull
>>> fully-obscured elements behind the canvas.
>>>
>>> Description:
>>>
>>> The "opaque" attribute is a boolean attribute of the canvas element,
>>> whose presence indicates that the alpha values in the canvas backing store
>>> must be 1.0 at all times.  All canvas operations are modified to preserve
>>> this invariant.  If the "opaque" attribute is not present, or if parsing
>>> its value returns an error, then the default value (false) must be used
>>> instead.
>>>
>>> When a canvas has the opaque attribute, the backing store must be
>>> initialized to opaque black (rgba(0, 0, 0, 1.0)), instead of transparent
>>> black (rgba(0, 0, 0, 0.0)).  Setting, changing, removing or setting the
>>> attribute redundantly to its existing value causes the canvas to be cleared
>>> to the appropriate value.
>>>
>>> When a canvas has the opaque attribute, clearRect() clears to opaque
>>> black instead of transparent black.
>>>
>>> The behaviour of putImageData() and putImageDataHD() when a canvas has
>>> the opaque attribute is to premultiply the RGB components by the alpha
>>> component as usual, but write 1.0 into destination alpha.  In other words,
>>> if (r, g, b, a) are the component values in a given pixel passed to
>>> putImageData[HD](), then r' = ar, g' = ag, b' = ab are the colour
>>> components of the resulting canvas pixel, and (r', g', b', 1.0) is written
>>> to the canvas backing store.
>>>
>>> When a canvas has the opaque attribute, all globalCompositeOperation
>>> modes behave as normal and the resulting RGB components are written to the
>>> canvas backing store, but the alpha component is left unchanged at 1.0.
>>>
>>
>> What does 'normal' mean? Is it 'composite with the usual formula' or
>> 'composite with source-over'?
>>
>
> Normal means composite with the usual formula.  Composite with source-over
> would be proposal 2) above (but only for those modes which could leave
> destination alpha at something other than 1.0).
>
> Here is what I think the modified compositing math would be for proposal
> 1) above:
>
>     mode result opaque result would require opaque mode
>
> clear [0, 0] [1, 0] 0 == 1 clear-opaque
>
> source-over [Sa + (1 - Sa) * Da, Sc + (1 - Sa) * Dc] [1, Sc + (1 - Sa) *
> Dc] 1 == 1 source-over
>
> source-in [Da * Sa, Da * Sc] [1, Sc] Sa == 1 copy-opaque
>
> source-out [(1 - Da) * Sa, (1 - Da) * Sc] [1, 0] 0 == 1 clear-opaque
>
> source-atop [Da, Da * Sc + (1 - Sa) * Dc] [1, Sc + (1 - Sa) * Dc] 1 == 1source-atop
>
> destination-over [(1 - Da) * Sa + Da, (1 - Da) * Sc + Dc] [1, Dc + (1 -
> Da) * Sc] 1 == 1 destination-over
>
> destination-in [Sa * Da, Sa * Dc] [1, Sa * Dc] Sa == 1destination-in-opaque
>
> destination-out [(1 - Sa) * Da, (1 - Sa) * Dc] [1, (1 - Sa) * Dc] Sa == 0xor-opaque
>
> destination-atop [Sa, (1 - Da) * Sc + Sa * Dc] [1, Sa * Dc] Sa == 1destination-in-opaque
>
> lighter [Sa + Da, Sc + Dc] [1, Sc + Dc] Sa >= 0 lighter
>
> darker sc * da < dc * sa ? srcover : dstover sc < dc * sa ? srcover :
> dstover 1 == 1 darker
>
> copy [Sa, Sc] [1, Sc] Sa == 1 copy-opaque
>
> xor [(1 - Da) * Sa + (1 - Sa) * Da, (1 - Da) * Sc + (1 - Sa) * Dc] [1, (1
> - Sa) * Dc] Sa == 1 xor-opaque
>
> (Note:  the "opaque mode" contains some names I made up for the 4 new
> required modes, but that's just for reference -- these names would not
> appear in the spec or the API).
>

That looks correct. Did you add darker because you believe it should be
added to the list of supported compositing modes?

Also, should opaque go on CanvasRenderingContext2D or the canvas object? If
it's applied to the canvas object, it seems that it should apply to WebGL
too. Does Firefox apply this to WebGL contexts?
Received on Wednesday, 13 March 2013 03:52:15 GMT

This archive was generated by hypermail 2.3.1 : Wednesday, 13 March 2013 03:52:16 GMT