- From: Rik Cabanier <cabanier@gmail.com>
- Date: Tue, 12 Mar 2013 14:36:07 -0700
- 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 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'? I still think a matteColor can accomplish the same and have the added benefit of flexibility and easy of specification... > > > > On Tue, Mar 12, 2013 at 12:53 PM, Stephen White <senorblanco@chromium.org>wrote: > >> >> On Mon, Mar 11, 2013 at 4:32 PM, Robert O'Callahan <robert@ocallahan.org>wrote: >> >>> On Tue, Mar 12, 2013 at 8:23 AM, Stephen White <senorblanco@chromium.org >>> > wrote: >>> >>>> On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan < >>>> robert@ocallahan.org> wrote: >>>> >>>>> On Tue, Mar 12, 2013 at 7:53 AM, Stephen White < >>>>> senorblanco@chromium.org> wrote: >>>>> >>>>>> All other canvas functionality behaves as normal, including >>>>>> operations which modify the alpha values of the backing store. However, >>>>>> any such transparency values will be ignored when compositing the canvas >>>>>> into the page, and the canvas will be treated as if every pixel has an >>>>>> alpha of 1.0. >>>>>> >>>>> >>>>> That would mean getImageData can return non-1.0 alpha values, which is >>>>> probably not what you want to implement. >>>>> >>>> >>>> That's what Firefox/Linux does (in fact, it always seems to return 0.0 >>>> alpha from getImageData()). >>>> >>> >>> We definitely shouldn't spec that! And I'm pretty sure that behavior >>> would vary across Firefox platforms. But we need to have consistent >>> behavior here. >>> >>> I considered three options: >>>> >>>> 1) Prevent non-1.0 alpha ever getting into the canvas. At a minimum, >>>> this would require the following: >>>> >>>> - For putImageData, apply premultiplication, then write 1.0 alpha >>>> into the canvas. >>>> - Change initialization and clearRect() to clear to opaque black >>>> instead of transparent black. >>>> - Modify all canvas compositing modes to leave destination alpha >>>> unchanged >>>> >>>> The latter is easy to do in OpenGL and CoreGraphics, but hard to do in >>>> Skia, and hard to do in accelerated CoreGraphics (IOSurfaces don't seem to >>>> support any opaque formats, although I could be wrong -- that was just from >>>> an hour or so of experimentation). I'm not sure about Cairo. >>>> >>> >>> You can always implement it slowly using readback. I think we should >>> just spec this, and maybe note that authors shouldn't use non-over >>> operators on opaque canvases. Over time we'll probably find a way to make >>> it fast everywhere. >>> >> >> I'm a little leery of spec'ing something that has negative performance >> implications. As an example, the "darker" compositing mode was removed >> from the spec due to hardware-accelerated performance concerns, IIRC. >> OTOH, unlike that change, this spec should not have performance >> implications for OpenGL or Direct3D acceleration, only CoreGraphics via >> IOSurface and skia (so far). >> >> How would you feel about simply mapping the dest-alpha-modifying >> compositing modes to source-over, as in proposal 2) above? >> >> Stephen >> >> >> >>> >>> 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 Tuesday, 12 March 2013 21:36:34 UTC