Re: [whatwg] Mutation Observer arguments format

2013-03-12 Thread Anne van Kesteren
On Tue, Mar 12, 2013 at 12:41 AM, Alex Russell slightly...@google.com wrote:
 Thoughts?

My main thought is that it's a pita to change the API at this time now
it's unprefixed everywhere and we've been encouraging developers to
use it in favor of mutation events. If Adam/Rafael/Olli/Jonas are
willing to update WebKit/Gecko though I guess I don't really care.


-- 
http://annevankesteren.nl/


Re: [whatwg] Mutation Observer arguments format

2013-03-12 Thread Olli Pettay

On 03/12/2013 12:34 PM, Anne van Kesteren wrote:

On Tue, Mar 12, 2013 at 12:41 AM, Alex Russell slightly...@google.com wrote:

Thoughts?


My main thought is that it's a pita to change the API at this time now
it's unprefixed everywhere and we've been encouraging developers to
use it in favor of mutation events. If Adam/Rafael/Olli/Jonas are
willing to update WebKit/Gecko though I guess I don't really care.




We could keep the old behavior and extend it to support types.
But since the change isn't backward compatible (scripts using types wouldn't 
work in
older browsers), I'd like to understand the need for the change.

-Olli


Re: [whatwg] Mutation Observer arguments format

2013-03-12 Thread Brian Kardell
On Tue, Mar 12, 2013 at 6:22 AM, Olli Pettay olli.pet...@helsinki.fiwrote:

 On 03/12/2013 12:34 PM, Anne van Kesteren wrote:

 On Tue, Mar 12, 2013 at 12:41 AM, Alex Russell slightly...@google.com
 wrote:

 Thoughts?


 My main thought is that it's a pita to change the API at this time now
 it's unprefixed everywhere and we've been encouraging developers to
 use it in favor of mutation events. If Adam/Rafael/Olli/Jonas are
 willing to update WebKit/Gecko though I guess I don't really care.



 We could keep the old behavior and extend it to support types.


I was going to mention this the other day - it works inter-operably today,
so it seems like you probably don't want to break that.  Simultaneously it
does seem to me that the API is more sensible and less confusing - is there
any reason not change the proposal such that the intent is to to deprecate
the existing way and consider the new/proposed API as merely superceeding
the old?  Given that one is merely sugar on the other anyway - it should be
possible to propose the change and augment/prollyfill the mapping I think
and I see no reason you couldn't quickly roll that out natively given its
simplicity.


 But since the change isn't backward compatible (scripts using types
 wouldn't work in
 older browsers), I'd like to understand the need for the change.

 -Olli




-- 
Brian Kardell :: @briankardell :: hitchjs.com


Re: [whatwg] Mutation Observer arguments format

2013-03-12 Thread Anne van Kesteren
On Tue, Mar 12, 2013 at 3:05 PM, Brian Kardell bkard...@gmail.com wrote:
 I was going to mention this the other day - it works inter-operably today,
 so it seems like you probably don't want to break that.  Simultaneously it
 does seem to me that the API is more sensible and less confusing - is there
 any reason not change the proposal such that the intent is to to deprecate
 the existing way and consider the new/proposed API as merely superceeding
 the old?  Given that one is merely sugar on the other anyway - it should be
 possible to propose the change and augment/prollyfill the mapping I think
 and I see no reason you couldn't quickly roll that out natively given its
 simplicity.

Yes, that is the basic argument made time and again. It neglects the
costs. It takes away time from people that should probably work on
other stuff, it increases the API surface area and what needs to be
tested, and thereby increases the chance for mismatching functionality
across user agents. Making changes, even seemingly trivial ones,
across multiple independent engines is not something that should be
taken lightly.


-- 
http://annevankesteren.nl/


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

2013-03-12 Thread Stephen White
On Mon, Mar 11, 2013 at 4:32 PM, Robert O'Callahan rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 8:23 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 7:53 AM, Stephen White senorbla...@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]



Re: [whatwg] Mutation Observer arguments format

2013-03-12 Thread Brian Kardell
On Mar 12, 2013 12:06 PM, Anne van Kesteren ann...@annevk.nl wrote:

 On Tue, Mar 12, 2013 at 3:05 PM, Brian Kardell bkard...@gmail.com wrote:
  I was going to mention this the other day - it works inter-operably
today,
  so it seems like you probably don't want to break that.  Simultaneously
it
  does seem to me that the API is more sensible and less confusing - is
there
  any reason not change the proposal such that the intent is to to
deprecate
  the existing way and consider the new/proposed API as merely
superceeding
  the old?  Given that one is merely sugar on the other anyway - it
should be
  possible to propose the change and augment/prollyfill the mapping I
think
  and I see no reason you couldn't quickly roll that out natively given
its
  simplicity.

 Yes, that is the basic argument made time and again. It neglects the
 costs. It takes away time from people that should probably work on
 other stuff, it increases the API surface area and what needs to be
 tested, and thereby increases the chance for mismatching functionality
 across user agents. Making changes, even seemingly trivial ones,
 across multiple independent engines is not something that should be
 taken lightly.


 --
 http://annevankesteren.nl/

Anne,

I feel like you've misunderstood my comments/observations.  Let me clarify
and see:

1) I think this API is more sensible - I had the same problem with mutation
observers api.

2) we should not be forever stuck with an unintuitive API

3) we have interop now and a mature spec, that sucks in retrospect that we
didn't see this earlier, but it is what it is.

4) this adds nothing in the way of features, it is merely sugar/better API
so it should be easily prollyfillable.  As such, I am suggesting that we
draft a proposal to do so, explain in detail how it would work (I gave a
high-level suggestion), provide test cases, etc... That's what prollyfills
are all about - a way to evolve outside the browser impl itself based on
competition and data which makes that part easier and makes sure we don't
take turns that users have problems with

... and ...

5)  should we reach that point (it is entirely possible we dont) the actual
implementation should be *comparatively *low cost.

Does it make sense?  Do you feel like I am hand-waving away any of your
concerns?  I hope not because the idea there is precisely to help address
concerns like these (as well as many others).


-Brian


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

2013-03-12 Thread Stephen White
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.

Stephen



On Tue, Mar 12, 2013 at 12:53 PM, Stephen White senorbla...@chromium.orgwrote:


 On Mon, Mar 11, 2013 at 4:32 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 8:23 AM, Stephen White 
 senorbla...@chromium.orgwrote:

 On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan rob...@ocallahan.org
  wrote:

 On Tue, Mar 12, 2013 at 7:53 AM, Stephen White 
 senorbla...@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]





Re: [whatwg] Mutation Observer arguments format

2013-03-12 Thread Anne van Kesteren
On Tue, Mar 12, 2013 at 5:02 PM, Brian Kardell bkard...@gmail.com wrote:
 Does it make sense?  Do you feel like I am hand-waving away any of your
 concerns?  I hope not because the idea there is precisely to help address
 concerns like these (as well as many others).

It makes sense and is doable, but given finite resources it's on
balance with everything else we work on. E.g. the effort I put into
drafting a new API and figure out the details will take away time from
improving Fetch and XMLHttpRequest. The effort Adam will put into
implementing the change and making sure it's tested will take away
time from him working on HTML templates. Etc.

And that's not counting that we then have two ways of doing the same
thing. That we need to update documentation. That it's not backwards
compatible.


-- 
http://annevankesteren.nl/


Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Kenneth Russell
It should simply reference the Uint8ClampedArray, not copy it or do
anything else esoteric. The only way to display an ImageData in the 2D
canvas context is via the putImageData API. I am not proposing
changing those semantics.

-Ken



On Mon, Mar 11, 2013 at 5:00 PM, Rik Cabanier caban...@gmail.com wrote:
 Do you expect that createImageData creates an internal copy of the
 Uint8ClampedArray object or is it live?


 On Mon, Mar 11, 2013 at 4:28 PM, Kenneth Russell k...@google.com wrote:

 It would be useful to be able to create an ImageData [1] object with
 preexisting data. The main use case is to display arbitrary data in
 the 2D canvas context with no data copies.

 Proposed IDL:

 [NoInterfaceObject]
 interface ImageDataFactories {
   ImageData createImageData(Uint8ClampedArray data, double sw, double sh);
 };
 Window implements ImageDataFactories;
 WorkerGlobalScope implements ImageDataFactories;

 createImageData would throw an exception if the length of the
 Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
 least, if the length of the array was less than this value. (Similar
 wording would be used to that of CanvasRenderingContext2D's
 createImageData.)

 I don't think it is necessary to provide a createImageDataHD in this
 interface. The caller will know the devicePixelRatio and determine
 whether to generate high-DPI data.

 [1]
 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata

 Comments?

 Thanks,

 -Ken




Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Kenneth Russell
I much prefer your suggestion to just add a constructor to ImageData.
I was not sure whether that style was preferred nowadays. ImageData is
already exposed in the global namespace, so making it a callable
constructor function seems like an easy change.

As mentioned in another reply, the intent here is to reference the
Uint8ClampedArray, not make a copy.

-Ken


On Mon, Mar 11, 2013 at 7:03 PM, Boris Zbarsky bzbar...@mit.edu wrote:
 On 3/11/13 7:28 PM, Kenneth Russell wrote:

 Proposed IDL:

 [NoInterfaceObject]
 interface ImageDataFactories {
ImageData createImageData(Uint8ClampedArray data, double sw, double
 sh);
 };
 Window implements ImageDataFactories;
 WorkerGlobalScope implements ImageDataFactories;


 How about just:

   [Constructor(Uint8ClampedArray data, double sw, double sh)]
   interface ImageData {
 /* Whatever is currently there */
   };

 and then you create one with:

   new ImageData(someData, someWidth, someHeight);

 Other than needing to specify whether the array is copied or held on to by
 reference, and specifying that this interface should be exposed in workers,
 this seems fine to me.

 -Boris


Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Rik Cabanier
sounds good!
I think this is a convenient and useful addition.

do you want to keep doubles to define the dimensions instead of integers?
If so, the size should probably  4 * ceil(sw) * ceil(sh)

On Tue, Mar 12, 2013 at 10:50 AM, Kenneth Russell k...@google.com wrote:

 It should simply reference the Uint8ClampedArray, not copy it or do
 anything else esoteric. The only way to display an ImageData in the 2D
 canvas context is via the putImageData API. I am not proposing
 changing those semantics.

 -Ken



 On Mon, Mar 11, 2013 at 5:00 PM, Rik Cabanier caban...@gmail.com wrote:
  Do you expect that createImageData creates an internal copy of the
  Uint8ClampedArray object or is it live?
 
 
  On Mon, Mar 11, 2013 at 4:28 PM, Kenneth Russell k...@google.com wrote:
 
  It would be useful to be able to create an ImageData [1] object with
  preexisting data. The main use case is to display arbitrary data in
  the 2D canvas context with no data copies.
 
  Proposed IDL:
 
  [NoInterfaceObject]
  interface ImageDataFactories {
ImageData createImageData(Uint8ClampedArray data, double sw, double
 sh);
  };
  Window implements ImageDataFactories;
  WorkerGlobalScope implements ImageDataFactories;
 
  createImageData would throw an exception if the length of the
  Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
  least, if the length of the array was less than this value. (Similar
  wording would be used to that of CanvasRenderingContext2D's
  createImageData.)
 
  I don't think it is necessary to provide a createImageDataHD in this
  interface. The caller will know the devicePixelRatio and determine
  whether to generate high-DPI data.
 
  [1]
 
 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
 
  Comments?
 
  Thanks,
 
  -Ken
 
 



Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Kenneth Russell
On Tue, Mar 12, 2013 at 11:15 AM, Rik Cabanier caban...@gmail.com wrote:
 sounds good!
 I think this is a convenient and useful addition.

Great.

 do you want to keep doubles to define the dimensions instead of integers? If
 so, the size should probably  4 * ceil(sw) * ceil(sh)

I would prefer to use integers, and only used doubles to be consistent
with the other APIs like getImageData and createImageData. In this
case it would make more sense to use integers, since the width and
height are simply being used to interpret preexisting data in the
Uint8ClampedArray.

-Ken


 On Tue, Mar 12, 2013 at 10:50 AM, Kenneth Russell k...@google.com wrote:

 It should simply reference the Uint8ClampedArray, not copy it or do
 anything else esoteric. The only way to display an ImageData in the 2D
 canvas context is via the putImageData API. I am not proposing
 changing those semantics.

 -Ken



 On Mon, Mar 11, 2013 at 5:00 PM, Rik Cabanier caban...@gmail.com wrote:
  Do you expect that createImageData creates an internal copy of the
  Uint8ClampedArray object or is it live?
 
 
  On Mon, Mar 11, 2013 at 4:28 PM, Kenneth Russell k...@google.com wrote:
 
  It would be useful to be able to create an ImageData [1] object with
  preexisting data. The main use case is to display arbitrary data in
  the 2D canvas context with no data copies.
 
  Proposed IDL:
 
  [NoInterfaceObject]
  interface ImageDataFactories {
ImageData createImageData(Uint8ClampedArray data, double sw, double
  sh);
  };
  Window implements ImageDataFactories;
  WorkerGlobalScope implements ImageDataFactories;
 
  createImageData would throw an exception if the length of the
  Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
  least, if the length of the array was less than this value. (Similar
  wording would be used to that of CanvasRenderingContext2D's
  createImageData.)
 
  I don't think it is necessary to provide a createImageDataHD in this
  interface. The caller will know the devicePixelRatio and determine
  whether to generate high-DPI data.
 
  [1]
 
  http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
 
  Comments?
 
  Thanks,
 
  -Ken
 
 




Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Rik Cabanier
On Tue, Mar 12, 2013 at 11:40 AM, Kenneth Russell k...@google.com wrote:

 On Tue, Mar 12, 2013 at 11:15 AM, Rik Cabanier caban...@gmail.com wrote:
  sounds good!
  I think this is a convenient and useful addition.

 Great.

  do you want to keep doubles to define the dimensions instead of
 integers? If
  so, the size should probably  4 * ceil(sw) * ceil(sh)

 I would prefer to use integers, and only used doubles to be consistent
 with the other APIs like getImageData and createImageData. In this
 case it would make more sense to use integers, since the width and
 height are simply being used to interpret preexisting data in the
 Uint8ClampedArray.


The current canvas spec doesn't specifically state what happens with
partial pixels. What happens today?
(Also is there a definition somewhere that states when a pixel is
considered filled?)

 I don't think it is necessary to provide a createImageDataHD in this
 interface. The caller will know the devicePixelRatio and determine
 whether to generate high-DPI data.

That probably won't work since it results in code that executes differently
on devices that are HD.



  On Tue, Mar 12, 2013 at 10:50 AM, Kenneth Russell k...@google.com
 wrote:
 
  It should simply reference the Uint8ClampedArray, not copy it or do
  anything else esoteric. The only way to display an ImageData in the 2D
  canvas context is via the putImageData API. I am not proposing
  changing those semantics.
 
  -Ken
 
 
 
  On Mon, Mar 11, 2013 at 5:00 PM, Rik Cabanier caban...@gmail.com
 wrote:
   Do you expect that createImageData creates an internal copy of the
   Uint8ClampedArray object or is it live?
  
  
   On Mon, Mar 11, 2013 at 4:28 PM, Kenneth Russell k...@google.com
 wrote:
  
   It would be useful to be able to create an ImageData [1] object with
   preexisting data. The main use case is to display arbitrary data in
   the 2D canvas context with no data copies.
  
   Proposed IDL:
  
   [NoInterfaceObject]
   interface ImageDataFactories {
 ImageData createImageData(Uint8ClampedArray data, double sw, double
   sh);
   };
   Window implements ImageDataFactories;
   WorkerGlobalScope implements ImageDataFactories;
  
   createImageData would throw an exception if the length of the
   Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
   least, if the length of the array was less than this value. (Similar
   wording would be used to that of CanvasRenderingContext2D's
   createImageData.)
  
   I don't think it is necessary to provide a createImageDataHD in this
   interface. The caller will know the devicePixelRatio and determine
   whether to generate high-DPI data.
  
   [1]
  
  
 http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#imagedata
  
   Comments?
  
   Thanks,
  
   -Ken
  
  
 
 



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

2013-03-12 Thread Robert O'Callahan
On Wed, Mar 13, 2013 at 5:53 AM, Stephen White senorbla...@chromium.orgwrote:

 I'm a little leery of spec'ing something that has negative performance
 implications.


So am I, but surely making non-over operators slower is better than making
them not work at all --- especially if the former situation is temporary.
The latter decision would have to be permanent.

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]


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

2013-03-12 Thread Ian Hickson
On Tue, 12 Mar 2013, Stephen White wrote:

 As an example, the darker compositing mode was removed from the spec 
 due to hardware-accelerated performance concerns, IIRC.

'darker' was removed because it wasn't defined anywhere so couldn't be 
implemented interoperably.

-- 
Ian Hickson   U+1047E)\._.,--,'``.fL
http://ln.hixie.ch/   U+263A/,   _.. \   _\  ;`._ ,.
Things that are impossible just take longer.   `._.-(,_..'--(,_..'`-.;.'


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

2013-03-12 Thread Rik Cabanier
On Tue, Mar 12, 2013 at 10:03 AM, Stephen White senorbla...@chromium.orgwrote:

 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 
 senorbla...@chromium.orgwrote:


 On Mon, Mar 11, 2013 at 4:32 PM, Robert O'Callahan 
 rob...@ocallahan.orgwrote:

 On Tue, Mar 12, 2013 at 8:23 AM, Stephen White senorbla...@chromium.org
  wrote:

 On Mon, Mar 11, 2013 at 2:56 PM, Robert O'Callahan 
 rob...@ocallahan.org wrote:

 On Tue, Mar 12, 2013 at 7:53 AM, Stephen White 
 senorbla...@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, 

Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Rik Cabanier
On Tue, Mar 12, 2013 at 3:03 PM, Kenneth Russell k...@google.com wrote:

 On Tue, Mar 12, 2013 at 2:04 PM, Rik Cabanier caban...@gmail.com wrote:
 
 
  On Tue, Mar 12, 2013 at 11:40 AM, Kenneth Russell k...@google.com
 wrote:
 
  On Tue, Mar 12, 2013 at 11:15 AM, Rik Cabanier caban...@gmail.com
 wrote:
   sounds good!
   I think this is a convenient and useful addition.
 
  Great.
 
   do you want to keep doubles to define the dimensions instead of
   integers? If
   so, the size should probably  4 * ceil(sw) * ceil(sh)
 
  I would prefer to use integers, and only used doubles to be consistent
  with the other APIs like getImageData and createImageData. In this
  case it would make more sense to use integers, since the width and
  height are simply being used to interpret preexisting data in the
  Uint8ClampedArray.
 
 
  The current canvas spec doesn't specifically state what happens with
 partial
  pixels. What happens today?
  (Also is there a definition somewhere that states when a pixel is
 considered
  filled?)

 Safari, Firefox and Chrome all round the double arguments to
 putImageData to integers using the truncate rounding mode and then
 draw the source ImageData pixel-for-pixel. For example, passing 64.5
 or 64.99 for the dx or dy arguments is equivalent to passing 64.
 Here's a test case.

 canvas id=canvas width=256 height=256/canvas
 script
 var canvas = document.getElementById(canvas);
 var ctx = canvas.getContext(2d);
 var width = canvas.width;
 var height = canvas.height;
 ctx.fillRect(0, 0, width, height);
 var imageData = ctx.createImageData(width / 2, height / 2);
 for (var ii = 0; ii  imageData.data.length; ii += 4) {
   imageData.data[ii + 0] = 0;
   imageData.data[ii + 1] = 255;
   imageData.data[ii + 2] = 0;
   imageData.data[ii + 3] = 255;
 }
 // Try passing 64.5, 64.99, or 65 for one or both of these arguments
 and see the results
 ctx.putImageData(imageData, 64, 64);
 /script

 In other words, the source ImageData would not be rendered into the
 canvas at a half-pixel offset if ctx.putImageData(imageData, 64.5,
 64.5) were called.


Thanks for investigating this. The fact that 'truncate' is called, should
probably go in the spec.
Maybe we should change the IDL to integer.




  I don't think it is necessary to provide a createImageDataHD in this
  interface. The caller will know the devicePixelRatio and determine
  whether to generate high-DPI data.
 
  That probably won't work since it results in code that executes
 differently
  on devices that are HD.

 I think it works. The application will call the new ImageData
 constructor and pass it to either putImageData or putImageDataHD.
 These interpret the incoming ImageData differently depending on the
 devicePixelRatio.

 In contrast, CanvasRenderingContext2D's existing createImageDataHD and
 getImageDataHD methods will create an ImageData that may have a
 different width and height from those passed in. The reason for this
 is that these methods are referring to the canvas's backing store. For
 this new constructor which simply wraps existing pixel data, the
 application knows exactly how many pixels are contained in the array,
 so it makes the most sense to take the incoming width and height
 verbatim. I don't see any advantage to having an alternate high-DPI
 constructor which would multiply the width and height by the
 devicePixelRatio behind the scenes.


Your proposal is:

createImageData would throw an exception if the length of the
Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
least, if the length of the array was less than this value.


So, if you create an imageData that is going to be used in putImageDataHD,
the bounds checking happens when you pass it into putImageDataHD?
It seems the imageData object should know if it was meant for an HD call.
There is no real reason why you could use it in both HD and non-HD APIs.


 
 
   On Tue, Mar 12, 2013 at 10:50 AM, Kenneth Russell k...@google.com
   wrote:
  
   It should simply reference the Uint8ClampedArray, not copy it or do
   anything else esoteric. The only way to display an ImageData in the
 2D
   canvas context is via the putImageData API. I am not proposing
   changing those semantics.
  
   -Ken
  
  
  
   On Mon, Mar 11, 2013 at 5:00 PM, Rik Cabanier caban...@gmail.com
   wrote:
Do you expect that createImageData creates an internal copy of the
Uint8ClampedArray object or is it live?
   
   
On Mon, Mar 11, 2013 at 4:28 PM, Kenneth Russell k...@google.com
wrote:
   
It would be useful to be able to create an ImageData [1] object
 with
preexisting data. The main use case is to display arbitrary data
 in
the 2D canvas context with no data copies.
   
Proposed IDL:
   
[NoInterfaceObject]
interface ImageDataFactories {
  ImageData createImageData(Uint8ClampedArray data, double sw,
double
sh);
};
Window implements ImageDataFactories;
WorkerGlobalScope implements ImageDataFactories;
 

Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Glenn Maynard
On Tue, Mar 12, 2013 at 12:14 AM, Boris Zbarsky bzbar...@mit.edu wrote:

 CSE can get rid of the redundant .data gets.  Similarly, .data gets can be
 loop-hoisted in many cases.


Doing COW based on page-faults is nicer anyway, but I don't know about the
data structures of JS engines to know whether this is feasible.  (For
example, if an object in JS is preceded by a header that gets written by
the engine now and then, it'll probably lie on the same page as the data,
which would trigger an expensive fault each time.)

I suppose padding the backing store so it doesn't share pages with anything
else might be reasonable here: up to about 8k of waste on a system with 4kb
pages.  The cost of marking the pages read-only would only have to be paid
when the copy-on-write action (eg. a call to putImageData) is actually
made.  Very small buffers could simply disable copy-on-write and always
perform a copy, where the waste for padding is more significant and the
benefits of avoiding a copy are smaller.

(For what it's worth, marking a 128 MB buffer read-only in Linux with
mprotect takes on the order of 3 microseconds on my typical desktop-class
system.  I don't know if Windows's VirtualProtect is slower.)

On Tue, Mar 12, 2013 at 4:04 PM, Rik Cabanier caban...@gmail.com wrote:

  I don't think it is necessary to provide a createImageDataHD in this

  interface. The caller will know the devicePixelRatio and determine
  whether to generate high-DPI data.

 That probably won't work since it results in code that executes differently
 on devices that are HD.


The difference between getImageData(HD) and putImageData(HD) is in the
canvas operation, not the ImageData: it determines how pixels are scaled
when being read out of and written into the canvas backing store.  It
doesn't apply to this API; ImageData objects don't know anything beyond
their pixel data and dimensions.

(Code executing differently on high-DPI devices is a bridge we've already
crossed.  getImageData scales pixels down from the device's pixel ratio;
getImageDataHD doesn't, copying backing store pixels one to one.)

There is no real reason why you could use it in both HD and non-HD APIs.


Rather, there's no reason you couldn't.  You can definitely create an
ImageData with getImageData and then pass it to putImageDataHD (which would
cause the image to be scaled on devices with a pixel ratio other than 1, of
course).

-- 
Glenn Maynard


Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Kenneth Russell
On Tue, Mar 12, 2013 at 3:49 PM, Rik Cabanier caban...@gmail.com wrote:


 On Tue, Mar 12, 2013 at 3:03 PM, Kenneth Russell k...@google.com wrote:

 On Tue, Mar 12, 2013 at 2:04 PM, Rik Cabanier caban...@gmail.com wrote:
 
 
  On Tue, Mar 12, 2013 at 11:40 AM, Kenneth Russell k...@google.com
  wrote:
 
  On Tue, Mar 12, 2013 at 11:15 AM, Rik Cabanier caban...@gmail.com
  wrote:
   sounds good!
   I think this is a convenient and useful addition.
 
  Great.
 
   do you want to keep doubles to define the dimensions instead of
   integers? If
   so, the size should probably  4 * ceil(sw) * ceil(sh)
 
  I would prefer to use integers, and only used doubles to be consistent
  with the other APIs like getImageData and createImageData. In this
  case it would make more sense to use integers, since the width and
  height are simply being used to interpret preexisting data in the
  Uint8ClampedArray.
 
 
  The current canvas spec doesn't specifically state what happens with
  partial
  pixels. What happens today?
  (Also is there a definition somewhere that states when a pixel is
  considered
  filled?)

 Safari, Firefox and Chrome all round the double arguments to
 putImageData to integers using the truncate rounding mode and then
 draw the source ImageData pixel-for-pixel. For example, passing 64.5
 or 64.99 for the dx or dy arguments is equivalent to passing 64.
 Here's a test case.

 canvas id=canvas width=256 height=256/canvas
 script
 var canvas = document.getElementById(canvas);
 var ctx = canvas.getContext(2d);
 var width = canvas.width;
 var height = canvas.height;
 ctx.fillRect(0, 0, width, height);
 var imageData = ctx.createImageData(width / 2, height / 2);
 for (var ii = 0; ii  imageData.data.length; ii += 4) {
   imageData.data[ii + 0] = 0;
   imageData.data[ii + 1] = 255;
   imageData.data[ii + 2] = 0;
   imageData.data[ii + 3] = 255;
 }
 // Try passing 64.5, 64.99, or 65 for one or both of these arguments
 and see the results
 ctx.putImageData(imageData, 64, 64);
 /script

 In other words, the source ImageData would not be rendered into the
 canvas at a half-pixel offset if ctx.putImageData(imageData, 64.5,
 64.5) were called.


 Thanks for investigating this. The fact that 'truncate' is called, should
 probably go in the spec.
 Maybe we should change the IDL to integer.

I think that would be a good idea. I believe it would be backward
compatible and leave the definition of double - long conversion to
the Web IDL and ECMAScript specs.


  I don't think it is necessary to provide a createImageDataHD in this
  interface. The caller will know the devicePixelRatio and determine
  whether to generate high-DPI data.
 
  That probably won't work since it results in code that executes
  differently
  on devices that are HD.

 I think it works. The application will call the new ImageData
 constructor and pass it to either putImageData or putImageDataHD.
 These interpret the incoming ImageData differently depending on the
 devicePixelRatio.

 In contrast, CanvasRenderingContext2D's existing createImageDataHD and
 getImageDataHD methods will create an ImageData that may have a
 different width and height from those passed in. The reason for this
 is that these methods are referring to the canvas's backing store. For
 this new constructor which simply wraps existing pixel data, the
 application knows exactly how many pixels are contained in the array,
 so it makes the most sense to take the incoming width and height
 verbatim. I don't see any advantage to having an alternate high-DPI
 constructor which would multiply the width and height by the
 devicePixelRatio behind the scenes.


 Your proposal is:

 createImageData would throw an exception if the length of the
 Uint8ClampedArray was not equal to 4 * floor(sw) * floor(sh), or at
 least, if the length of the array was less than this value.

Yes.

 So, if you create an imageData that is going to be used in putImageDataHD,
 the bounds checking happens when you pass it into putImageDataHD?
 It seems the imageData object should know if it was meant for an HD call.
 There is no real reason why you could use it in both HD and non-HD APIs.

Glenn already answered this, but you can already call getImageData and
pass the result to putImageDataHD (and vice versa --
getImageDataHD/putImageData). The only difference between putImageData
and putImageDataHD is that on high-DPI displays putImageDataHD will
take the same image data and display it in a smaller region. All of
the size checking would be performed in the new ImageData constructor
we're discussing. I don't think ImageData itself should know anything
about high DPI because it's designed for pixel-by-pixel manipulation.

-Ken



 
 
   On Tue, Mar 12, 2013 at 10:50 AM, Kenneth Russell k...@google.com
   wrote:
  
   It should simply reference the Uint8ClampedArray, not copy it or do
   anything else esoteric. The only way to display an ImageData in the
   2D
   canvas context is via the putImageData API. I am not 

Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Rik Cabanier
On Tue, Mar 12, 2013 at 4:16 PM, Glenn Maynard gl...@zewt.org wrote:

 On Tue, Mar 12, 2013 at 12:14 AM, Boris Zbarsky bzbar...@mit.edu wrote:

  CSE can get rid of the redundant .data gets.  Similarly, .data gets can
 be
  loop-hoisted in many cases.
 

 Doing COW based on page-faults is nicer anyway, but I don't know about the
 data structures of JS engines to know whether this is feasible.  (For
 example, if an object in JS is preceded by a header that gets written by
 the engine now and then, it'll probably lie on the same page as the data,
 which would trigger an expensive fault each time.)

 I suppose padding the backing store so it doesn't share pages with anything
 else might be reasonable here: up to about 8k of waste on a system with 4kb
 pages.  The cost of marking the pages read-only would only have to be paid
 when the copy-on-write action (eg. a call to putImageData) is actually
 made.  Very small buffers could simply disable copy-on-write and always
 perform a copy, where the waste for padding is more significant and the
 benefits of avoiding a copy are smaller.

 (For what it's worth, marking a 128 MB buffer read-only in Linux with
 mprotect takes on the order of 3 microseconds on my typical desktop-class
 system.  I don't know if Windows's VirtualProtect is slower.)

 On Tue, Mar 12, 2013 at 4:04 PM, Rik Cabanier caban...@gmail.com wrote:

   I don't think it is necessary to provide a createImageDataHD in this
 
   interface. The caller will know the devicePixelRatio and determine
   whether to generate high-DPI data.
 
  That probably won't work since it results in code that executes
 differently
  on devices that are HD.
 

 The difference between getImageData(HD) and putImageData(HD) is in the
 canvas operation, not the ImageData: it determines how pixels are scaled
 when being read out of and written into the canvas backing store.  It
 doesn't apply to this API; ImageData objects don't know anything beyond
 their pixel data and dimensions.

 (Code executing differently on high-DPI devices is a bridge we've already
 crossed.  getImageData scales pixels down from the device's pixel ratio;
 getImageDataHD doesn't, copying backing store pixels one to one.)

 There is no real reason why you could use it in both HD and non-HD APIs.
 

 Rather, there's no reason you couldn't.  You can definitely create an
 ImageData with getImageData and then pass it to putImageDataHD (which would
 cause the image to be scaled on devices with a pixel ratio other than 1, of
 course).


It feels like something is missing. How does putImageDataHD know that the
bitmap should be scaled? Width and height refer to the pixel dimensions and
not the 'px' unit


Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Kenneth Russell
On Tue, Mar 12, 2013 at 4:54 PM, Rik Cabanier caban...@gmail.com wrote:
 On Tue, Mar 12, 2013 at 4:16 PM, Glenn Maynard gl...@zewt.org wrote:

 On Tue, Mar 12, 2013 at 12:14 AM, Boris Zbarsky bzbar...@mit.edu wrote:

  CSE can get rid of the redundant .data gets.  Similarly, .data gets can
 be
  loop-hoisted in many cases.
 

 Doing COW based on page-faults is nicer anyway, but I don't know about the
 data structures of JS engines to know whether this is feasible.  (For
 example, if an object in JS is preceded by a header that gets written by
 the engine now and then, it'll probably lie on the same page as the data,
 which would trigger an expensive fault each time.)

 I suppose padding the backing store so it doesn't share pages with anything
 else might be reasonable here: up to about 8k of waste on a system with 4kb
 pages.  The cost of marking the pages read-only would only have to be paid
 when the copy-on-write action (eg. a call to putImageData) is actually
 made.  Very small buffers could simply disable copy-on-write and always
 perform a copy, where the waste for padding is more significant and the
 benefits of avoiding a copy are smaller.

 (For what it's worth, marking a 128 MB buffer read-only in Linux with
 mprotect takes on the order of 3 microseconds on my typical desktop-class
 system.  I don't know if Windows's VirtualProtect is slower.)

 On Tue, Mar 12, 2013 at 4:04 PM, Rik Cabanier caban...@gmail.com wrote:

   I don't think it is necessary to provide a createImageDataHD in this
 
   interface. The caller will know the devicePixelRatio and determine
   whether to generate high-DPI data.
 
  That probably won't work since it results in code that executes
 differently
  on devices that are HD.
 

 The difference between getImageData(HD) and putImageData(HD) is in the
 canvas operation, not the ImageData: it determines how pixels are scaled
 when being read out of and written into the canvas backing store.  It
 doesn't apply to this API; ImageData objects don't know anything beyond
 their pixel data and dimensions.

 (Code executing differently on high-DPI devices is a bridge we've already
 crossed.  getImageData scales pixels down from the device's pixel ratio;
 getImageDataHD doesn't, copying backing store pixels one to one.)

 There is no real reason why you could use it in both HD and non-HD APIs.
 

 Rather, there's no reason you couldn't.  You can definitely create an
 ImageData with getImageData and then pass it to putImageDataHD (which would
 cause the image to be scaled on devices with a pixel ratio other than 1, of
 course).


 It feels like something is missing. How does putImageDataHD know that the
 bitmap should be scaled? Width and height refer to the pixel dimensions and
 not the 'px' unit

putImageData measures the affected region of the scratch bitmap in CSS
pixels and putImageDataHD measures it in device pixels.
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-putimagedata


Re: [whatwg] Proposal: ImageData constructor or factory method with preexisting data

2013-03-12 Thread Glenn Maynard
On Tue, Mar 12, 2013 at 6:54 PM, Rik Cabanier caban...@gmail.com wrote:

 It feels like something is missing. How does putImageDataHD know that the
 bitmap should be scaled? Width and height refer to the pixel dimensions and
 not the 'px' unit


It's putImageData that scales, not putImageDataHD.

putImageData *always* scales by the pixel ratio.  If you're on a system
with a ratio of 2, calling putImageData with a 500x1000 buffer will always
draw a 1000x2000 image, scaling the image up.  putImageDataHD on a 500x1000
buffer will always draw a 500x1000 image, regardless of the pixel ratio.

In other words, the blitter knows whether to scale or not based on whether
it was putImageData or putImageDataHD that you called, not on something
inside the ImageData you passed in.

-- 
Glenn Maynard


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

2013-03-12 Thread Rik Cabanier
On Tue, Mar 12, 2013 at 3:08 PM, Stephen White senorbla...@chromium.orgwrote:

 On Tue, Mar 12, 2013 at 5:36 PM, Rik Cabanier caban...@gmail.com wrote:



 On Tue, Mar 12, 2013 at 10:03 AM, Stephen White senorbla...@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?