On Wed, Feb 13, 2013 at 5:31 PM, Rik Cabanier <[email protected]> wrote:
> On Wed, Feb 13, 2013 at 11:25 AM, Stephen White <[email protected] > >wrote: > > > On Wed, Feb 13, 2013 at 12:22 PM, Rik Cabanier <[email protected]> > wrote: > > > >> For blending optimizations, it might be better to introduce a function > >> instead of a boolean attribute like 'opaque'. > >> What you really want, is to matte [1] the canvas with a solid color so > >> you can optimize compositing. > >> > >> How about this API: > >> > >> void applyMatte(DOMString color); // color is a CSS rgb color value > >> (alpha is ignored) > >> > >> > >> When you call this function, the canvas is matted with that color. If > >> it's the first drawing call, you can just fill the canvas with that > color > >> (no compositing needed) > >> After matting, you no longer have to read or update the alpha channel > >> since it's always 1 which should speed up drawing. > >> > > > > Just to be sure we're on the same page, when I mentioned compositing > > optimizations, I was referring to compositing the canvas backing store > into > > the page, not compositing operations within the canvas itself. > > > > sorry, I didn't mean to say blending. This is for optimizing compositing > within the canvas and of the canvas into the page. > > > > > > One advantage of using an element attribute is that it could be used at > > backing store allocation time, to allocate RGB instead of RGBA. Forcing > a > > reallocation of the backing store on attribute change would be consistent > > with changing width and height of the canvas, which have the same effect. > > Doing so on a context operation would not. > > > > why not? There is no reason for you to allocate the backing store until > it's needed. > True. I was just trying to understand when you would use this function more than once during canvas lifetime. Presumably, that's the reason for having a function, no? If so, and you don't maintain any special state about the opacity of the canvas, how is this different from an rgb() fillRect()? > The strange thing with an element attribute is that you can't change it > back and it's also detached from the JS code that does the drawing. > > You can change it back programmatically through the DOM, as you can with the element width and height. > > If we did use a context function approach as you suggest, how would > > subpixel AA be handled? Would it be enabled on first call of the > function > > and never disabled? > > > > I did not think about subpixel AA. > If I read the mozilla proposal correctly, they do AA if they know that the > canvas is opaque. > So, with my proposal, there would be no AA until you call 'applyMatte' > (assuming you follow the mozilla way of doing AA). OK, so there would have to be a bit of state saved at that point, in order to know if subpixel AA is allowable? At any rate, I don't think this works if you subsequently modify the canvas's alpha (see below). > > > > Is there a way to query if the canvas is opaque once it's called? > > > > Wouldn't the user know that he called 'applyMatte'? Also why do you want to > query it? > > > (I'm assuming that all changes to canvas alpha after the first call > would > > have to be ignored, since otherwise you'd have to sniff every operation > to > > see if it affected alpha, and "reset the bit", although perhaps I'm > > misunderstanding your proposal.) > > > > No, you don't have to do that and can still use alpha. > Simple alpha compositing is defined as follows [1] (in premultiplied > alpha): > > co = cs + cb x (1 - αs) > αo = αs + αb x (1 - αs) > > > If you know that the backdrop is matted (αb = 1), the second formula always > resolves to 1 so you can skip it. > The problem is, canvas supports more than simple (source-over) compositing, so there are ways of modifying the destination alpha back to non-1, e.g., a primitive with non-1 alpha drawn with source-copy, or via putImageData(). At that point, the state of the canvas's alpha is unknown, so the page compositor can make no assumptions about its opacity. Stephen
