Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Rik Cabanier
On Sun, Mar 9, 2014 at 10:52 PM, Dirk Schulze dschu...@adobe.com wrote:



  On Mar 10, 2014, at 3:44 AM, Rik Cabanier caban...@gmail.com wrote:
 
  On Wed, Mar 5, 2014 at 1:46 PM, Rik Cabanier caban...@gmail.com
 wrote:
 
  While implementing the Path2D object in mozilla, we ran into a
 performance
  issue.
 
  The mozilla implementation uses different backends for the canvas 2D
  context.
  Even within the same document, different canvas objects can be on top of
  different graphics libraries. For best performance, the Path2D object
  should use the same graphics interface as the canvas context you're
  applying it to. If this is not the case, the path segments have to be
  walked and converted which is a costly operation.
 
  To work around this, we could add a couple of constructor methods to the
  2D context:
 
  Path2D createPath();
 
  Creates a new empty Path object.
 
  Path2D createPath(path);
 
  Creates a new Path object that is a copy of the argument.
 
  Path2D createPath(d);
 
  Creates a new path with the path described by the argument, interpreted
 as
  SVG path data. [SVG]
 
  This way, we can guarantee that they use the same underlying technology
  and performance won't be impacted.
  You could still pass these objects to other canvas contexts but
  performance might be impacted.
 
  I was thinking about this a bit more and an alternate solution would be
 to
  pass an optional 2D context to the Path2D constructors.
  A UA could ignore that context, or it could see it as a hint that the
 path
  is going to be used with that context.
 
  Thoughts?

 Slightly better. Still not sure.


What are you not sure about?

The current Path2D interface might be unacceptably slow under certain
circumstances and there's currently no way for authors to work around this.
There has to be a hint. If not, I don't see a way that firefox will ship
this.


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Joe Gregorio
On Mon, Mar 10, 2014 at 2:02 PM, Rik Cabanier caban...@gmail.com wrote:


 What are you not sure about?

 The current Path2D interface might be unacceptably slow under certain
 circumstances and there's currently no way for authors to work around this.
 There has to be a hint. If not, I don't see a way that firefox will ship
 this.


What part is slow, the decoding and re-encoding, or is just always the
encoding step
that is slow?

I thought the speed of Path2D came from the reuse, that is, that the build
cost wasn't
a big concern because the speed came from reusing that same object over and
over
at up to 60fps?


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Rik Cabanier
On Mon, Mar 10, 2014 at 11:07 AM, Joe Gregorio jcgrego...@google.comwrote:




 On Mon, Mar 10, 2014 at 2:02 PM, Rik Cabanier caban...@gmail.com wrote:


 What are you not sure about?

 The current Path2D interface might be unacceptably slow under certain
 circumstances and there's currently no way for authors to work around
 this.
 There has to be a hint. If not, I don't see a way that firefox will ship
 this.


 What part is slow, the decoding and re-encoding, or is just always the
 encoding step
 that is slow?


It's decoding/re-encoding of an already constructed path.


 I thought the speed of Path2D came from the reuse, that is, that the build
 cost wasn't
 a big concern because the speed came from reusing that same object over
 and over
 at up to 60fps?


Yes. The concern is that the re-encoding will happen every time you use the
path.

We could code it in such a way that the path is retargeted when it's used.
It's a bit strange since fill and stroke are not supposed to change the
path.


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Dirk Schulze

On Mar 10, 2014, at 7:02 PM, Rik Cabanier caban...@gmail.com wrote:

 On Sun, Mar 9, 2014 at 10:52 PM, Dirk Schulze dschu...@adobe.com wrote:
 
 
 
 On Mar 10, 2014, at 3:44 AM, Rik Cabanier caban...@gmail.com wrote:
 
 On Wed, Mar 5, 2014 at 1:46 PM, Rik Cabanier caban...@gmail.com
 wrote:
 
 While implementing the Path2D object in mozilla, we ran into a
 performance
 issue.
 
 The mozilla implementation uses different backends for the canvas 2D
 context.
 Even within the same document, different canvas objects can be on top of
 different graphics libraries. For best performance, the Path2D object
 should use the same graphics interface as the canvas context you're
 applying it to. If this is not the case, the path segments have to be
 walked and converted which is a costly operation.
 
 To work around this, we could add a couple of constructor methods to the
 2D context:
 
 Path2D createPath();
 
 Creates a new empty Path object.
 
 Path2D createPath(path);
 
 Creates a new Path object that is a copy of the argument.
 
 Path2D createPath(d);
 
 Creates a new path with the path described by the argument, interpreted
 as
 SVG path data. [SVG]
 
 This way, we can guarantee that they use the same underlying technology
 and performance won't be impacted.
 You could still pass these objects to other canvas contexts but
 performance might be impacted.
 
 I was thinking about this a bit more and an alternate solution would be
 to
 pass an optional 2D context to the Path2D constructors.
 A UA could ignore that context, or it could see it as a hint that the
 path
 is going to be used with that context.
 
 Thoughts?
 
 Slightly better. Still not sure.
 
 
 What are you not sure about?
 
 The current Path2D interface might be unacceptably slow under certain
 circumstances and there's currently no way for authors to work around this.
 There has to be a hint. If not, I don't see a way that firefox will ship
 this.

Since no other implementation stood up so far it seems to be a FF only hack at 
the moment.

The question is how common s it to have multiple contexts of different type 
within the same document? How often does it happen that you use the same Path2d 
object in multiple contexts? We need data for that first.

Even switching the context during run-time (as you suggested is happening in 
Firefox) would not help in your proposal. You would still encode and decode the 
path again.

Actually, with the right abstraction it is just the creation of the path object 
which shouldn’t be very slow at all. Especially since you create it once and 
reuse it over and over again.

Having an optional value for the constructor is not as bad as binding the 
Path2d creation to a specific context. I still don’t see the need to do this at 
the moment.

Beside that, the optional argument can be done later if it really turns out to 
be a problem that can not worked around in any other way. Therefore, I would 
like to see efforts in Gecko to speed the specified version up first and 
revisit the proposal later.

Greetings,
Dirk



Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Domenic Denicola
What about making the Path2D constructor a property of each context? E.g.

var path = new myContext.Path2D(...);

Each context would have a different constructor tied to it, allowing this kind 
of optimization.

Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Justin Novosad
On Mon, Mar 10, 2014 at 2:14 PM, Rik Cabanier caban...@gmail.com wrote:

 On Mon, Mar 10, 2014 at 11:07 AM, Joe Gregorio jcgrego...@google.com
 wrote:

 
  What part is slow, the decoding and re-encoding, or is just always the
  encoding step
  that is slow?
 

 It's decoding/re-encoding of an already constructed path.


Can't the implementation just perform that work lazily the first time the
path is rasterized, and retain the cached result for subsequent use of the
path object?


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Tab Atkins Jr.
On Mon, Mar 10, 2014 at 11:38 AM, Justin Novosad ju...@google.com wrote:
 On Mon, Mar 10, 2014 at 2:14 PM, Rik Cabanier caban...@gmail.com wrote:
 On Mon, Mar 10, 2014 at 11:07 AM, Joe Gregorio jcgrego...@google.com
 wrote:
  What part is slow, the decoding and re-encoding, or is just always the
  encoding step
  that is slow?

 It's decoding/re-encoding of an already constructed path.

 Can't the implementation just perform that work lazily the first time the
 path is rasterized, and retain the cached result for subsequent use of the
 path object?

This is also my question.  Given that generating a path for a
particular context isn't a magic bullet *anyway* (because the details
of the context can change), I don't understand why caching isn't the
answer.

~TJ


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Rik Cabanier
On Mon, Mar 10, 2014 at 11:38 AM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 10, 2014 at 2:14 PM, Rik Cabanier caban...@gmail.com wrote:

 On Mon, Mar 10, 2014 at 11:07 AM, Joe Gregorio jcgrego...@google.com
 wrote:

 

  What part is slow, the decoding and re-encoding, or is just always the
  encoding step
  that is slow?
 

 It's decoding/re-encoding of an already constructed path.


 Can't the implementation just perform that work lazily the first time the
 path is rasterized, and retain the cached result for subsequent use of the
 path object?


At usage time, the path could be retargeted to a new backend. I don't think
that should be done as a cached copy since that would require too many
resources.
I will see if this is an acceptable solution for mozilla.


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Justin Novosad
On Mon, Mar 10, 2014 at 4:22 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 10, 2014 at 11:38 AM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 10, 2014 at 2:14 PM, Rik Cabanier caban...@gmail.com wrote:

 On Mon, Mar 10, 2014 at 11:07 AM, Joe Gregorio jcgrego...@google.com
 wrote:

 

  What part is slow, the decoding and re-encoding, or is just always the
  encoding step
  that is slow?
 

 It's decoding/re-encoding of an already constructed path.


 Can't the implementation just perform that work lazily the first time the
 path is rasterized, and retain the cached result for subsequent use of the
 path object?


 At usage time, the path could be retargeted to a new backend. I don't
 think that should be done as a cached copy since that would require too
 many resources.
 I will see if this is an acceptable solution for mozilla.


Isn't caching ideal for that situation? In the case of re-targeting, you
can either replace the cached encoding, or append the new encoding to a
collection of cached encodings.  Both of those options seem more effective
than to stick to an encoding type that was baked-in at construction time.
It may also be great to have a heuristic to chose whether to discard the
previously cached re-encoding. Something like: if we are re-encoding
because the destination backing type changed due to a resize, then discard
previous encodings; if re-encoding because the path is drawn to multiple
canvases, then retain multiple cached encodings.


Re: [whatwg] new constructor method for Path2D

2014-03-10 Thread Rik Cabanier
On Mon, Mar 10, 2014 at 1:33 PM, Justin Novosad ju...@google.com wrote:




 On Mon, Mar 10, 2014 at 4:22 PM, Rik Cabanier caban...@gmail.com wrote:




 On Mon, Mar 10, 2014 at 11:38 AM, Justin Novosad ju...@google.comwrote:




 On Mon, Mar 10, 2014 at 2:14 PM, Rik Cabanier caban...@gmail.comwrote:

 On Mon, Mar 10, 2014 at 11:07 AM, Joe Gregorio jcgrego...@google.com
 wrote:

 

  What part is slow, the decoding and re-encoding, or is just always the
  encoding step
  that is slow?
 

 It's decoding/re-encoding of an already constructed path.


 Can't the implementation just perform that work lazily the first time
 the path is rasterized, and retain the cached result for subsequent use of
 the path object?


 At usage time, the path could be retargeted to a new backend. I don't
 think that should be done as a cached copy since that would require too
 many resources.
  I will see if this is an acceptable solution for mozilla.


 Isn't caching ideal for that situation? In the case of re-targeting, you
 can either replace the cached encoding, or append the new encoding to a
 collection of cached encodings.  Both of those options seem more effective
 than to stick to an encoding type that was baked-in at construction time.


what I forgot to say is that the path would be stored with the new backend.
For instance, if the path had an internal skia path and it was used on a
Direct2D canvas, the internal skia path would be converted to direct2d and
discarded.
(This will typically only happen once.)


 It may also be great to have a heuristic to chose whether to discard the
 previously cached re-encoding. Something like: if we are re-encoding
 because the destination backing type changed due to a resize, then discard
 previous encodings; if re-encoding because the path is drawn to multiple
 canvases, then retain multiple cached encodings.


Yes. If this becomes a performance bottleneck, we could add such an
heuristic.


Re: [whatwg] new constructor method for Path2D

2014-03-09 Thread Rik Cabanier
On Wed, Mar 5, 2014 at 1:46 PM, Rik Cabanier caban...@gmail.com wrote:

 While implementing the Path2D object in mozilla, we ran into a performance
 issue.

 The mozilla implementation uses different backends for the canvas 2D
 context.
 Even within the same document, different canvas objects can be on top of
 different graphics libraries. For best performance, the Path2D object
 should use the same graphics interface as the canvas context you're
 applying it to. If this is not the case, the path segments have to be
 walked and converted which is a costly operation.

 To work around this, we could add a couple of constructor methods to the
 2D context:

 Path2D createPath();

 Creates a new empty Path object.

 Path2D createPath(path);

 Creates a new Path object that is a copy of the argument.

 Path2D createPath(d);

 Creates a new path with the path described by the argument, interpreted as
 SVG path data. [SVG]

 This way, we can guarantee that they use the same underlying technology
 and performance won't be impacted.
 You could still pass these objects to other canvas contexts but
 performance might be impacted.


I was thinking about this a bit more and an alternate solution would be to
pass an optional 2D context to the Path2D constructors.
A UA could ignore that context, or it could see it as a hint that the path
is going to be used with that context.

Thoughts?


Re: [whatwg] new constructor method for Path2D

2014-03-09 Thread Dirk Schulze


 On Mar 10, 2014, at 3:44 AM, Rik Cabanier caban...@gmail.com wrote:
 
 On Wed, Mar 5, 2014 at 1:46 PM, Rik Cabanier caban...@gmail.com wrote:
 
 While implementing the Path2D object in mozilla, we ran into a performance
 issue.
 
 The mozilla implementation uses different backends for the canvas 2D
 context.
 Even within the same document, different canvas objects can be on top of
 different graphics libraries. For best performance, the Path2D object
 should use the same graphics interface as the canvas context you're
 applying it to. If this is not the case, the path segments have to be
 walked and converted which is a costly operation.
 
 To work around this, we could add a couple of constructor methods to the
 2D context:
 
 Path2D createPath();
 
 Creates a new empty Path object.
 
 Path2D createPath(path);
 
 Creates a new Path object that is a copy of the argument.
 
 Path2D createPath(d);
 
 Creates a new path with the path described by the argument, interpreted as
 SVG path data. [SVG]
 
 This way, we can guarantee that they use the same underlying technology
 and performance won't be impacted.
 You could still pass these objects to other canvas contexts but
 performance might be impacted.
 
 I was thinking about this a bit more and an alternate solution would be to
 pass an optional 2D context to the Path2D constructors.
 A UA could ignore that context, or it could see it as a hint that the path
 is going to be used with that context.
 
 Thoughts?

Slightly better. Still not sure.

Dirk


Re: [whatwg] new constructor method for Path2D

2014-03-06 Thread Dirk Schulze

On Mar 5, 2014, at 11:54 PM, Rik Cabanier caban...@gmail.com wrote:

 On Wed, Mar 5, 2014 at 2:43 PM, Ian Hickson i...@hixie.ch wrote:
 
 On Wed, 5 Mar 2014, Jeff Muizelaar wrote:
 On Mar 5, 2014, at 5:34 PM, Ian Hickson i...@hixie.ch wrote:
 On Wed, 5 Mar 2014, Rik Cabanier wrote:
 
 To work around this, we could add a couple of constructor methods to
 the 2D context:
 
 Path2D createPath();
 
 Creates a new empty Path object [...]
 
 This used to be how many Web APIs worked, but over the years we've
 received enormous volumes of feedback to the effect that
 constructor-based APIs are way better than factory-based APIs. Is
 there no way we could at least have all the canvases within a Document
 in Firefox use the same backend? It would be really unfortunate to
 have to use factories here to get around an implementation detail in
 one browser.
 
 The choice of backend depends on the size of the canvas. So it wouldn't
 be easy to have all canvases within a document use the same backend.
 
 Ah, ok.
 
 This makes a factory method somewhat less useful, because what if the
 canvas changes size later? Do all the paths have to be re-bound?
 
 
 for optimal performance, yes.
 Rescaling a canvas is not that common of a scenario though.

To switch the context of a created Path2d, you still need an abstraction of the 
path, don’t you? Some platforms are not able to return the created path. Many 
more are not able to return an unflattened path (which might not be an issue). 
So if you might need an abstraction anyway, is the performance problem that you 
need to do it on each drawing operation? There are clearly ways to work around 
such an issue.

 
 Maybe this hint would be useful for Chrome since they switch to software
 under certain circumstances too

I am unsure if it would. It is the same graphic library that manages the path 
object. Even if uses a different backend.

Greetings,
Dirk



Re: [whatwg] new constructor method for Path2D

2014-03-06 Thread Rik Cabanier
On Thu, Mar 6, 2014 at 2:28 AM, Dirk Schulze dschu...@adobe.com wrote:


 On Mar 5, 2014, at 11:54 PM, Rik Cabanier caban...@gmail.com wrote:

  On Wed, Mar 5, 2014 at 2:43 PM, Ian Hickson i...@hixie.ch wrote:
 
  On Wed, 5 Mar 2014, Jeff Muizelaar wrote:
  On Mar 5, 2014, at 5:34 PM, Ian Hickson i...@hixie.ch wrote:
  On Wed, 5 Mar 2014, Rik Cabanier wrote:
 
  To work around this, we could add a couple of constructor methods to
  the 2D context:
 
  Path2D createPath();
 
  Creates a new empty Path object [...]
 
  This used to be how many Web APIs worked, but over the years we've
  received enormous volumes of feedback to the effect that
  constructor-based APIs are way better than factory-based APIs. Is
  there no way we could at least have all the canvases within a Document
  in Firefox use the same backend? It would be really unfortunate to
  have to use factories here to get around an implementation detail in
  one browser.
 
  The choice of backend depends on the size of the canvas. So it wouldn't
  be easy to have all canvases within a document use the same backend.
 
  Ah, ok.
 
  This makes a factory method somewhat less useful, because what if the
  canvas changes size later? Do all the paths have to be re-bound?
 
 
  for optimal performance, yes.
  Rescaling a canvas is not that common of a scenario though.

 To switch the context of a created Path2d, you still need an abstraction
 of the path, don't you? Some platforms are not able to return the created
 path. Many more are not able to return an unflattened path (which might not
 be an issue). So if you might need an abstraction anyway, is the
 performance problem that you need to do it on each drawing operation? There
 are clearly ways to work around such an issue.


At least for the Firefox backends (Cairo, Skia, D2D and Core Graphics) this
is not a problem. Paths are just groups of line segments so it should be
trivial to walk them


 
  Maybe this hint would be useful for Chrome since they switch to software
  under certain circumstances too

 I am unsure if it would. It is the same graphic library that manages the
 path object. Even if uses a different backend.


It seems like it could help but the Chrome people would know best.


Re: [whatwg] new constructor method for Path2D

2014-03-05 Thread Ian Hickson
On Wed, 5 Mar 2014, Rik Cabanier wrote:
 
 To work around this, we could add a couple of constructor methods to the 
 2D context:
 
 Path2D createPath();
 
 Creates a new empty Path object [...]

This used to be how many Web APIs worked, but over the years we've 
received enormous volumes of feedback to the effect that constructor-based 
APIs are way better than factory-based APIs. Is there no way we could at 
least have all the canvases within a Document in Firefox use the same 
backend? It would be really unfortunate to have to use factories here to 
get around an implementation detail in one browser.

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


Re: [whatwg] new constructor method for Path2D

2014-03-05 Thread Jeff Muizelaar

On Mar 5, 2014, at 5:34 PM, Ian Hickson i...@hixie.ch wrote:

 On Wed, 5 Mar 2014, Rik Cabanier wrote:
 
 To work around this, we could add a couple of constructor methods to the 
 2D context:
 
 Path2D createPath();
 
 Creates a new empty Path object [...]
 
 This used to be how many Web APIs worked, but over the years we've 
 received enormous volumes of feedback to the effect that constructor-based 
 APIs are way better than factory-based APIs. Is there no way we could at 
 least have all the canvases within a Document in Firefox use the same 
 backend? It would be really unfortunate to have to use factories here to 
 get around an implementation detail in one browser.

The choice of backend depends on the size of the canvas. So it wouldn’t be easy 
to have all canvases within a document use the same backend.

-Jeff

Re: [whatwg] new constructor method for Path2D

2014-03-05 Thread Ian Hickson
On Wed, 5 Mar 2014, Jeff Muizelaar wrote:
 On Mar 5, 2014, at 5:34 PM, Ian Hickson i...@hixie.ch wrote:
  On Wed, 5 Mar 2014, Rik Cabanier wrote:
  
  To work around this, we could add a couple of constructor methods to 
  the 2D context:
  
  Path2D createPath();
  
  Creates a new empty Path object [...]
  
  This used to be how many Web APIs worked, but over the years we've 
  received enormous volumes of feedback to the effect that 
  constructor-based APIs are way better than factory-based APIs. Is 
  there no way we could at least have all the canvases within a Document 
  in Firefox use the same backend? It would be really unfortunate to 
  have to use factories here to get around an implementation detail in 
  one browser.
 
 The choice of backend depends on the size of the canvas. So it wouldn’t 
 be easy to have all canvases within a document use the same backend.

Ah, ok.

This makes a factory method somewhat less useful, because what if the 
canvas changes size later? Do all the paths have to be re-bound?

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

Re: [whatwg] new constructor method for Path2D

2014-03-05 Thread Rik Cabanier
On Wed, Mar 5, 2014 at 2:43 PM, Ian Hickson i...@hixie.ch wrote:

 On Wed, 5 Mar 2014, Jeff Muizelaar wrote:
  On Mar 5, 2014, at 5:34 PM, Ian Hickson i...@hixie.ch wrote:
   On Wed, 5 Mar 2014, Rik Cabanier wrote:
  
   To work around this, we could add a couple of constructor methods to
   the 2D context:
  
   Path2D createPath();
  
   Creates a new empty Path object [...]
  
   This used to be how many Web APIs worked, but over the years we've
   received enormous volumes of feedback to the effect that
   constructor-based APIs are way better than factory-based APIs. Is
   there no way we could at least have all the canvases within a Document
   in Firefox use the same backend? It would be really unfortunate to
   have to use factories here to get around an implementation detail in
   one browser.
 
  The choice of backend depends on the size of the canvas. So it wouldn't
  be easy to have all canvases within a document use the same backend.

 Ah, ok.

 This makes a factory method somewhat less useful, because what if the
 canvas changes size later? Do all the paths have to be re-bound?


for optimal performance, yes.
Rescaling a canvas is not that common of a scenario though.

Maybe this hint would be useful for Chrome since they switch to software
under certain circumstances too