Intent to Implement: Geometry Interfaces

907 views
Skip to first unread message

Jinho Bang

unread,
Jun 25, 2014, 12:51:27 PM6/25/14
to blin...@chromium.org

Contact emails

jinho...@samsung.com, caba...@adobe.com, dsch...@chromium.org


Spec

http://dev.w3.org/fxtf/geometry/


Summary

The specification provides basic geometric interfaces to represent points, rectangles,

quadrilaterals and transformation matrices that can be used by other modules or specifications.


We will implement following things:

- DOMMatrix Interface

- DOMRect Interface

- DOMRectList Interface

- DOMQuad Interface

- DOMPoint interface


Motivation

The SVG interfaces SVGPoint, SVGRect and SVGMatrix are aliasing the here defined interfaces

in favor for common interfaces used by SVG, Canvas 2D Context  and CSS Transforms.


Compatibility Risk

Low, These are already being implemented in Firefox and WebKit (Rik and Dirk)


Ongoing technical constraints

None


Will this feature be supported on all five Blink platforms (Windows, Mac, Linux, Chrome OS and Android)?

Yes


OWP launch tracking bug?

http://crbug.com/388780


Link to entry on the feature dashboard

http://www.chromestatus.com/features/6015941766807552


Requesting approval to ship?

No


Domenic Denicola

unread,
Jun 25, 2014, 1:03:07 PM6/25/14
to blin...@chromium.org
On Wednesday, June 25, 2014 12:51:27 PM UTC-4, Jinho Bang wrote:

- DOMRectList Interface



We should not implement this. New fake-arrays are an antipattern. Raised in standards space by Anne at https://www.w3.org/Bugs/Public/show_bug.cgi?id=26200

I have also filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=26201 to add constructors to the *ReadOnly interfaces.

Rik Cabanier

unread,
Jun 25, 2014, 1:06:00 PM6/25/14
to Jinho Bang, blink-dev
On Wed, Jun 25, 2014 at 9:51 AM, Jinho Bang <jinho...@samsung.com> wrote:

Contact emails

jinho...@samsung.com, caba...@adobe.com, dsch...@chromium.org


Spec

http://dev.w3.org/fxtf/geometry/


Summary

The specification provides basic geometric interfaces to represent points, rectangles,

quadrilaterals and transformation matrices that can be used by other modules or specifications.


We will implement following things:

- DOMMatrix Interface

- DOMRect Interface

- DOMRectList Interface

- DOMQuad Interface

- DOMPoint interface


Motivation

The SVG interfaces SVGPoint, SVGRect and SVGMatrix are aliasing the here defined interfaces

in favor for common interfaces used by SVG, Canvas 2D Context  and CSS Transforms.


Compatibility Risk

Low, These are already being implemented in Firefox and WebKit (Rik and Dirk)


FYI all these interfaces landed in Firefox and are available in the nightly builds.
 

Ongoing technical constraints

None


Will this feature be supported on all five Blink platforms (Windows, Mac, Linux, Chrome OS and Android)?

Yes


OWP launch tracking bug?

http://crbug.com/388780


Link to entry on the feature dashboard

http://www.chromestatus.com/features/6015941766807552


Requesting approval to ship?

No


To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Dirk Schulze

unread,
Jun 25, 2014, 1:31:57 PM6/25/14
to Domenic Denicola, blin...@chromium.org

On Jun 25, 2014, at 7:03 PM, Domenic Denicola <dom...@domenicdenicola.com> wrote:

> On Wednesday, June 25, 2014 12:51:27 PM UTC-4, Jinho Bang wrote:
>
> - DOMRectList Interface
>

Thanks for filing the bug reports. I commented to all of them.

>
> We should not implement this. New fake-arrays are an antipattern. Raised in standards space by Anne at https://www.w3.org/Bugs/Public/show_bug.cgi?id=26200

DOMRectList has been an ArrayClass before. This was discussed and the WebIDL editor strongly suggested not to use ArrayClass. But the getter and the length attribute make it behave similar to arrays.

>
> I have also filed https://www.w3.org/Bugs/Public/show_bug.cgi?id=26201 to add constructors to the *ReadOnly interfaces.

I commented on this bug report as well. There is no need for authors to construct a DOMRectReadOnly or any of the other interfaces. These interfaces are designed for the use by the UA directly. The UA can provide metrics that update live but are not modifiable by the author. Strong candidates to use these interfaces are CSSOM View[1] and SVG.

Greetings,
Dirk

[1] http://dev.w3.org/csswg/cssom-view/#the-geometryutils-interface

Boris Zbarsky

unread,
Jun 25, 2014, 2:57:10 PM6/25/14
to blink-dev
On 6/25/14, 1:29 PM, Dirk Schulze wrote:
> DOMRectList has been an ArrayClass before. This was discussed and the WebIDL editor strongly suggested not to use ArrayClass. But the getter and the length attribute make it behave similar to arrays.

I think the point Domenic is making is that the places that currently
return DOMRectList should just return a sequence<DOMRect>.

This is only viable if existing consumers don't use item() on these
lists, of course... Apart from that, I think returning a sequence here
is totally the way to go.

-Boris

Domenic Denicola

unread,
Jun 25, 2014, 3:11:12 PM6/25/14
to Boris Zbarsky, blink-dev
From: blin...@chromium.org <blin...@chromium.org> on behalf of Boris Zbarsky <bzba...@MIT.EDU>

> I think the point Domenic is making is that the places that currently return DOMRectList should just return a sequence<DOMRect>.

Yes, exactly.

When I originally wrote the email, I wasn't aware that there are parts of the platform already making use of DOMRectList, since my impression this was an intent to implement new interfaces. It looks like at the least getClientRects does; does anyone else?

I see two paths forward:

- If implementers are willing to try it, converting to a real array (WebIDL "sequence") would be ideal and greatly improve the developer experience.
- If we don't want to spend the time testing such a change (which is understandable), then I'd recommend DOMRectList get [NoInterfaceObject], and rename it LegacyGetClientRectsReturnValueType or some such so that it gets hidden as far away from developers as possible, and so no spec uses it in the future.

Rik Cabanier

unread,
Jun 25, 2014, 3:33:17 PM6/25/14
to Boris Zbarsky, blink-dev

Boris Zbarsky

unread,
Jun 25, 2014, 3:39:57 PM6/25/14
to Domenic Denicola, blink-dev
On 6/25/14, 3:11 PM, Domenic Denicola wrote:
> It looks like at the least getClientRects does; does anyone else?

Not that I can see. (Gecko has another use, but it's in an internal
paint-region event that's not standardized.)

Note that a possible viable option is to return an actual Array
subclass; then we can keep our item() method and all that.

-Boris

Anne van Kesteren

unread,
Jun 25, 2014, 3:55:23 PM6/25/14
to Boris Zbarsky, Domenic Denicola, blink-dev
On Wed, Jun 25, 2014 at 9:39 PM, Boris Zbarsky <bzba...@mit.edu> wrote:
> Note that a possible viable option is to return an actual Array subclass;
> then we can keep our item() method and all that.

I think we should consider that if there's more places we could use
such an Array.


--
http://annevankesteren.nl/

Rik Cabanier

unread,
Jun 25, 2014, 4:05:23 PM6/25/14
to Anne van Kesteren, Boris Zbarsky, Domenic Denicola, blink-dev
Are you saying that we should replace the current API with a subclassed array class but only if this subclass will be used in other places? 

Also, does anyone know of other web platform classes that subclasses a javascript array?

Anne van Kesteren

unread,
Jun 25, 2014, 4:08:22 PM6/25/14
to Rik Cabanier, Boris Zbarsky, Domenic Denicola, blink-dev
On Wed, Jun 25, 2014 at 10:05 PM, Rik Cabanier <caba...@gmail.com> wrote:
> Are you saying that we should replace the current API with a subclassed
> array class but only if this subclass will be used in other places?

I'm not sure introducing a subclass of Array with item() is worth it
for this specific legacy *List interface. But if we can replace a
bunch of them...


> Also, does anyone know of other web platform classes that subclasses a
> javascript array?

It's ES6 territory, so not implemented. But there's query()/queryAll()
that want it.


--
http://annevankesteren.nl/

Erik Arvidsson

unread,
Jun 25, 2014, 4:17:16 PM6/25/14
to Rik Cabanier, Anne van Kesteren, Boris Zbarsky, Domenic Denicola, blink-dev
DOMExceptions have Error.prototype in their prototype chain but the instance is an exotic object and not an ordinary object.



--
erik


Rik Cabanier

unread,
Jun 25, 2014, 5:32:19 PM6/25/14
to Anne van Kesteren, Boris Zbarsky, Domenic Denicola, blink-dev
On Wed, Jun 25, 2014 at 1:08 PM, Anne van Kesteren <ann...@annevk.nl> wrote:
On Wed, Jun 25, 2014 at 10:05 PM, Rik Cabanier <caba...@gmail.com> wrote:
> Are you saying that we should replace the current API with a subclassed
> array class but only if this subclass will be used in other places?

I'm not sure introducing a subclass of Array with item() is worth it
for this specific legacy *List interface. But if we can replace a
bunch of them...

Given this, maybe we should just stick with the current definition.
If we decide later that it needs the additional array-like behavior, we can add it then.

I do agree with Dominic that we should make it a [NoInterfaceObject] object.

Domenic Denicola

unread,
Jun 25, 2014, 5:36:45 PM6/25/14
to Rik Cabanier, Anne van Kesteren, Boris Zbarsky, blink-dev
From: Rik Cabanier <caba...@gmail.com>

> Given this, maybe we should just stick with the current definition.
> If we decide later that it needs the additional array-like behavior, we can add it then.

The question is, do we ever expect developers to use this type? If so, we should fix it as soon as is feasible (i.e., as soon as browser ship ES6 built-in subclassing). If no new code uses getClientRects(), e.g. because getBoxQuads() is better, then I guess we can just leave it as another warty old API.

> I do agree with Dominic that we should make it a [NoInterfaceObject] object.

We should also ensure no other specs ever use this type, with an appropriately-scary name, and probably a note in the spec as well.

Rik Cabanier

unread,
Jun 25, 2014, 5:56:15 PM6/25/14
to Domenic Denicola, Anne van Kesteren, Boris Zbarsky, blink-dev
On Wed, Jun 25, 2014 at 2:36 PM, Domenic Denicola <dom...@domenicdenicola.com> wrote:
From: Rik Cabanier <caba...@gmail.com>

> Given this, maybe we should just stick with the current definition.
> If we decide later that it needs the additional array-like behavior, we can add it then.

The question is, do we ever expect developers to use this type? If so, we should fix it as soon as is feasible (i.e., as soon as browser ship ES6 built-in subclassing). If no new code uses getClientRects(), e.g. because getBoxQuads() is better, then I guess we can just leave it as another warty old API.

This is a legacy API. As you note, getBoxQuads() is the way forward and it returns a proper array.
 
> I do agree with Dominic that we should make it a [NoInterfaceObject] object.

We should also ensure no other specs ever use this type, with an appropriately-scary name, and probably a note in the spec as well.

I agree that we need a note, but changing the name seems like overkill,

Tab Atkins Jr.

unread,
Jun 25, 2014, 7:43:40 PM6/25/14
to Rik Cabanier, Domenic Denicola, Anne van Kesteren, Boris Zbarsky, blink-dev
Eh, names that clearly indicate legacy-ness are great; without it,
even with a note it's too easy for other spec authors to accidentally
use it. If they're forced to type a stupid-looking name when writing
their spec, they'll at least question their decision, and it'll jump
out at any reviewers.

~TJ

Rik Cabanier

unread,
Jun 25, 2014, 11:01:29 PM6/25/14
to Tab Atkins Jr., Domenic Denicola, Anne van Kesteren, Boris Zbarsky, blink-dev
Are there examples where objects or methods were given names to indicate that they are legacy?
I worry about possible pushback if this would be the first one. 

Boris Zbarsky

unread,
Jun 25, 2014, 11:14:23 PM6/25/14
to Rik Cabanier, Tab Atkins Jr., Domenic Denicola, Anne van Kesteren, blink-dev
On 6/25/14, 11:01 PM, Rik Cabanier wrote:
> Are there examples where objects or methods were given names to indicate
> that they are legacy?

Web IDL has "legacycaller".

Typically you don't get to change the name of something that is legacy
because people are depending on the existing name. We're just assuming
that in this case no one in fact depends on the name. If that's the
case, clearly labeling it as legacy makes sense to me.

-Boris

Domenic Denicola

unread,
Jun 25, 2014, 11:53:45 PM6/25/14
to Boris Zbarsky, Rik Cabanier, Tab Atkins Jr., Anne van Kesteren, blink-dev
From: blin...@chromium.org [mailto:blin...@chromium.org] On Behalf Of Boris Zbarsky

> We're just assuming that in this case no one in fact depends on the name.

And notably, the CSSWG also assumes this, since they're changing it from ClientRectList to DOMRectList.

Rik Cabanier

unread,
Jun 26, 2014, 12:02:18 AM6/26/14
to Domenic Denicola, Boris Zbarsky, Tab Atkins Jr., Anne van Kesteren, blink-dev
WebKit/Blink currently use 'ClientRectList' while Mozilla always had 'DOMRectList'.
Given the feedback, we should rename DOMRectList to LegacyDOMRectList and put a note in the spec.

Dirk has some reservations about adding [NoInterfaceObject]. Is the intent of adding it just to discourage people from extending it?
We might run into compat issues since this object is available and not guarded by this flag.

Anne van Kesteren

unread,
Jun 26, 2014, 2:02:28 AM6/26/14
to Rik Cabanier, Domenic Denicola, Boris Zbarsky, Tab Atkins Jr., blink-dev
On Thu, Jun 26, 2014 at 6:02 AM, Rik Cabanier <caba...@gmail.com> wrote:
> Dirk has some reservations about adding [NoInterfaceObject]. Is the intent
> of adding it just to discourage people from extending it?

From relying on it being there. So that e.g. we can introduce a
subclass of Array later or some such.


> We might run into compat issues since this object is available and not
> guarded by this flag.

We just discussed how it has different names across engines. We would
likely have already run into issues.


--
http://annevankesteren.nl/

Rik Cabanier

unread,
Jun 26, 2014, 2:43:55 AM6/26/14
to Anne van Kesteren, Domenic Denicola, Boris Zbarsky, Tab Atkins Jr., blink-dev
Do you need to know the name? It seems you could use 'getProtoTypeOf' [1] to extend an instance.
I don't have data on people extending it that way though.

Dirk Schulze

unread,
Jun 26, 2014, 4:32:31 AM6/26/14
to Anne van Kesteren, Rik Cabanier, Domenic Denicola, Boris Zbarsky, Tab Atkins Jr., blink-dev
I do not really care about the name of the interface. Should everyone agree that DOMRectList must not be used with the exception of getClientRects than we can rename it to LegacyDOMRectList and Simon or I can clearly state the restrictions in the spec.

I am not sure if [NoInterfaceObject] is really relevant. After talking with Cameron again, he now thinks it is fine to use [ArrayClass]. However, since it seems that we don’t want to use DOMRectList anywhere else than for getClientRects, I would prefer going with the minimal subset implemented by all browsers. The currently specified behavior is the subset that is implemented by WebKit, Blink and Gecko (didn’t check IE yet).

Greetings,
Dirk

>
>
> --
> http://annevankesteren.nl/

Ojan Vafai

unread,
Jul 15, 2014, 6:53:55 PM7/15/14
to Dirk Schulze, Anne van Kesteren, Rik Cabanier, Domenic Denicola, Boris Zbarsky, Tab Atkins Jr., blink-dev
The API owners discussed this and this sounds good to implement as there doesn't seem be significant opposition and the spec is in last call.

Personally, I'd really like to see the list vs array thing resolved before we ship though. I think it's really a bummer for us to ship  array-like types that don't have all the array built-ins. I'm not sure what the reason was for recommending not to use ArrayClass. I'd be happy with any solution that exposes array built-ins on the list, including sequence, ArrayClass or Boris's idea of using a subclass of array.

PhistucK

unread,
Jul 18, 2014, 5:29:35 PM7/18/14
to Rik Cabanier, Boris Zbarsky, blink-dev
Note that only the first link is a JavaScript file. The other two are C# and unrelated.


PhistucK


To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Philip Rogers

unread,
Aug 26, 2014, 3:41:21 PM8/26/14
to PhistucK, Rik Cabanier, Boris Zbarsky, blink-dev
I am concerned about the performance of these APIs, particularly DOMMatrix.

A javascript polyfill will be faster than the native DOMMatrix as it's implemented today. I do not think we should be dropping performance landmines for graphics developers to trip over, even at the cost of making the APIs more complex (e.g., taking typed arrays instead of slow objects).

Is performance a concern? Can we do something better on the implementation side?

Rik Cabanier

unread,
Aug 26, 2014, 5:27:22 PM8/26/14
to Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Tue, Aug 26, 2014 at 12:40 PM, Philip Rogers <p...@chromium.org> wrote:
I am concerned about the performance of these APIs, particularly DOMMatrix.

A javascript polyfill will be faster than the native DOMMatrix as it's implemented today. I do not think we should be dropping performance landmines for graphics developers to trip over, even at the cost of making the APIs more complex (e.g., taking typed arrays instead of slow objects).

Is performance a concern?

It would be great to have some data on the performance. It's likely that crossing into the c++ side takes up more cycles than the actual implementation :-)
Jinho did want to implement it using blink-in-javascript but had to abandon that idea since it doesn't support constructors.
 
Can we do something better on the implementation side?

For the typical use case of querying the DOM or manipulating values in it, I doubt that this will have an impact since that wouldn't involve that many matrices (compared to something like WebGL)

Maybe we can do a simple benchmark that measures the duration of matrix operations?
With that information, we can guess how much time is spent in DOMMatrix when you animate a large number of elements at 60fps.

Philip Rogers

unread,
Aug 26, 2014, 6:01:31 PM8/26/14
to Rik Cabanier, PhistucK, Boris Zbarsky, blink-dev
Rik,

I've now read the webkit [1] and mozilla [2] threads on this topic and it looks like these issues have been covered before. I do not think we should ship the geometry interfaces in Blink. DOMMatrix and friends will be slow in Blink for the same reasons WebKit balked at them [3]. As the blink-in-js docs [4] say, blink-in-js should not be used for high-performance apis like this. Maybe we can use typed arrays for these APIs instead?

An alternative is to implement and standardize these interfaces as first-class citizens in Ecmascript.

Adam Barth

unread,
Aug 26, 2014, 8:05:38 PM8/26/14
to Rik Cabanier, Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Tue Aug 26 2014 at 2:27:20 PM Rik Cabanier <caba...@gmail.com> wrote:
On Tue, Aug 26, 2014 at 12:40 PM, Philip Rogers <p...@chromium.org> wrote:
I am concerned about the performance of these APIs, particularly DOMMatrix.

A javascript polyfill will be faster than the native DOMMatrix as it's implemented today. I do not think we should be dropping performance landmines for graphics developers to trip over, even at the cost of making the APIs more complex (e.g., taking typed arrays instead of slow objects).

Is performance a concern?

It would be great to have some data on the performance. It's likely that crossing into the c++ side takes up more cycles than the actual implementation :-)
Jinho did want to implement it using blink-in-javascript but had to abandon that idea since it doesn't support constructors.

To clarify: Blink-in-JS is not fast.  It's strictly slower than the current implementation.  Blink-in-JS is optimized for maintainability, not performance.

Adam

Rik Cabanier

unread,
Aug 27, 2014, 2:24:23 PM8/27/14
to Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Tue, Aug 26, 2014 at 3:01 PM, Philip Rogers <p...@chromium.org> wrote:
Rik,

I've now read the webkit [1] and mozilla [2] threads on this topic and it looks like these issues have been covered before. I do not think we should ship the geometry interfaces in Blink. DOMMatrix and friends will be slow in Blink for the same reasons WebKit balked at them [3]. As the blink-in-js docs [4] say, blink-in-js should not be used for high-performance apis like this. Maybe we can use typed arrays for these APIs instead?

Like you said, we covered that approach in the past. Typed arrays are not author friendly and will need additional JS libraries to make them useful.
I also doubt that type arrays will be faster as the C++ side will now have to look into the JS VM to get the values out.

DOMMatrix as currently proposed, is basically a drop-in replacement of the existing SVGMatrix class along with some extra methods and abstractions to address its shortcomings. (I noticed that we didn't add DOMMatrixInit to the spec yet. It's a dictionary with the attributes of DOMMatrix and will be used in methods that take a DOMMatrix as an argument)
 
An alternative is to implement and standardize these interfaces as first-class citizens in Ecmascript.

I believe Dirk looked into this and it didn't look encouraging.

I think we need hard data to see if there's actually a problem. I will try to run some tests and come back with results.

Adam Barth

unread,
Aug 27, 2014, 2:32:14 PM8/27/14
to Rik Cabanier, Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Wed Aug 27 2014 at 11:24:18 AM Rik Cabanier <caba...@gmail.com> wrote:
On Tue, Aug 26, 2014 at 3:01 PM, Philip Rogers <p...@chromium.org> wrote:
Rik,

I've now read the webkit [1] and mozilla [2] threads on this topic and it looks like these issues have been covered before. I do not think we should ship the geometry interfaces in Blink. DOMMatrix and friends will be slow in Blink for the same reasons WebKit balked at them [3]. As the blink-in-js docs [4] say, blink-in-js should not be used for high-performance apis like this. Maybe we can use typed arrays for these APIs instead?

Like you said, we covered that approach in the past. Typed arrays are not author friendly and will need additional JS libraries to make them useful.
I also doubt that type arrays will be faster as the C++ side will now have to look into the JS VM to get the values out.

DOMMatrix as currently proposed, is basically a drop-in replacement of the existing SVGMatrix class along with some extra methods and abstractions to address its shortcomings. (I noticed that we didn't add DOMMatrixInit to the spec yet. It's a dictionary with the attributes of DOMMatrix and will be used in methods that take a DOMMatrix as an argument)
 
An alternative is to implement and standardize these interfaces as first-class citizens in Ecmascript.

I believe Dirk looked into this and it didn't look encouraging.

What's not encouraging about it?  It would be a shame to not build the technically best solution.

I think we need hard data to see if there's actually a problem. I will try to run some tests and come back with results.

Thanks!
Adam

Rik Cabanier

unread,
Sep 3, 2014, 1:30:19 PM9/3/14
to Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Tue, Aug 26, 2014 at 3:01 PM, Philip Rogers <p...@chromium.org> wrote:
Rik,

I've now read the webkit [1] and mozilla [2] threads on this topic and it looks like these issues have been covered before. I do not think we should ship the geometry interfaces in Blink. DOMMatrix and friends will be slow in Blink for the same reasons WebKit balked at them [3]. As the blink-in-js docs [4] say, blink-in-js should not be used for high-performance apis like this. Maybe we can use typed arrays for these APIs instead?

I wrote a small test case: http://jsperf.com/dommatrix-perf
It applies a typical translate/scale/rotate sequence to a DOMMatrix and a JS equivalent.

Benchmarking this in Firefox Nightly (because the functionality is not in Chrome yet) shows that the JS implementation is 3 to 4 times faster. This is expected since crossing into the c++ side slows things down.

To make a more realistic case, I added another test that calls setLineDash with the JS array to simulate a DOM crossing. I verified that the C++ side just verifies the contents of that array and stores it in the canvas state. That test is almost twice as slow as the DOMMatrix test.
(I also tried typed arrays but they were slower than native JS arrays)

This tells me that there is no performance problem with DOMMatrix.

In addition, jsperf reports that on my core i-7 3.4 GHz, I can do 360,000 translate/scale/rotate sequences per second.
So, if I animate 100 objects simultaneously, DOMMatrix will only take up: 100 objects * 60fps / 360,0000 ops = 0.017s
 
An alternative is to implement and standardize these interfaces as first-class citizens in Ecmascript.

Yes, that is something that we could do if we discover that people use DOMMatrix so much that it becomes a bottleneck. 
However, since that has no effect on actual author code, it shouldn't stop us from implementing this in c++ today

Adam Barth

unread,
Sep 3, 2014, 4:06:32 PM9/3/14
to Rik Cabanier, Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Wed Sep 03 2014 at 10:30:16 AM Rik Cabanier <caba...@gmail.com> wrote:
On Tue, Aug 26, 2014 at 3:01 PM, Philip Rogers <p...@chromium.org> wrote:
Rik,

I've now read the webkit [1] and mozilla [2] threads on this topic and it looks like these issues have been covered before. I do not think we should ship the geometry interfaces in Blink. DOMMatrix and friends will be slow in Blink for the same reasons WebKit balked at them [3]. As the blink-in-js docs [4] say, blink-in-js should not be used for high-performance apis like this. Maybe we can use typed arrays for these APIs instead?

I wrote a small test case: http://jsperf.com/dommatrix-perf
It applies a typical translate/scale/rotate sequence to a DOMMatrix and a JS equivalent.

Benchmarking this in Firefox Nightly (because the functionality is not in Chrome yet) shows that the JS implementation is 3 to 4 times faster. This is expected since crossing into the c++ side slows things down.

To make a more realistic case, I added another test that calls setLineDash with the JS array to simulate a DOM crossing. I verified that the C++ side just verifies the contents of that array and stores it in the canvas state. That test is almost twice as slow as the DOMMatrix test.
(I also tried typed arrays but they were slower than native JS arrays)

This tells me that there is no performance problem with DOMMatrix.

3-4x slower seems like a performance problem...

In addition, jsperf reports that on my core i-7 3.4 GHz, I can do 360,000 translate/scale/rotate sequences per second.
So, if I animate 100 objects simultaneously, DOMMatrix will only take up: 100 objects * 60fps / 360,0000 ops = 0.017s

How long does it take on a phone?  Do you think the web platform can afford to give away 3-4x performance and still be competitive on mobile?

Adam

Rik Cabanier

unread,
Sep 3, 2014, 5:35:55 PM9/3/14
to Adam Barth, Philip Rogers, PhistucK, Boris Zbarsky, blink-dev
On Wed, Sep 3, 2014 at 1:06 PM, Adam Barth <aba...@chromium.org> wrote:
On Wed Sep 03 2014 at 10:30:16 AM Rik Cabanier <caba...@gmail.com> wrote:
On Tue, Aug 26, 2014 at 3:01 PM, Philip Rogers <p...@chromium.org> wrote:
Rik,

I've now read the webkit [1] and mozilla [2] threads on this topic and it looks like these issues have been covered before. I do not think we should ship the geometry interfaces in Blink. DOMMatrix and friends will be slow in Blink for the same reasons WebKit balked at them [3]. As the blink-in-js docs [4] say, blink-in-js should not be used for high-performance apis like this. Maybe we can use typed arrays for these APIs instead?

I wrote a small test case: http://jsperf.com/dommatrix-perf
It applies a typical translate/scale/rotate sequence to a DOMMatrix and a JS equivalent.

Benchmarking this in Firefox Nightly (because the functionality is not in Chrome yet) shows that the JS implementation is 3 to 4 times faster. This is expected since crossing into the c++ side slows things down.

To make a more realistic case, I added another test that calls setLineDash with the JS array to simulate a DOM crossing. I verified that the C++ side just verifies the contents of that array and stores it in the canvas state. That test is almost twice as slow as the DOMMatrix test.
(I also tried typed arrays but they were slower than native JS arrays)

This tells me that there is no performance problem with DOMMatrix.

3-4x slower seems like a performance problem...

I talked to the mozilla people and this is a bug in the JIT in Firefox for Windows. 
On Mac and Linux, DOMMatrix is actually faster than the JS implementation with no DOM interaction.

I also added tests that use float arrays. They are about the same speed as DOMMatrix as long as you don't interact with the DOM. As soon as you cross the DOM, native JS is 4 to 5 times slower than DOMMatrix.

Test results:
Browser              |  Native  |   JS equivalent  | JS equivalent + DOM access | JS equivalent floatArray |  JS equivalent floatArray + DOM access
Firefox Mac            11.57            10.77                             7.88                                    11.78                                           3.27
FireFox Android       9.11              6.34                             1.89                                    14.08                                           0.52
Chrome Mac            NA                9.27                             3.46                                    10.7                                             3.08
Safari                       NA                9.28                             0.67                                    10.96                                           0.66

Across the board, you can see that interacting with the DOM has a significant impact on performance.
 
In addition, jsperf reports that on my core i-7 3.4 GHz, I can do 360,000 translate/scale/rotate sequences per second.
So, if I animate 100 objects simultaneously, DOMMatrix will only take up: 100 objects * 60fps / 360,0000 ops = 0.017s

How long does it take on a phone?  Do you think the web platform can afford to give away 3-4x performance and still be competitive on mobile?

With the latest numbers, DOMMatrix is much faster than going with a JS or float array implementation. 
It even rivals pure JS implementations if you use raw matrices.

In addition, one of DOMMatrix' main use cases it to interact with the CSS OM for matrix CSS transforms. 
Today people have to run regular expressions and stringifiers to get/set that information which is extremely slow. I can write another benchmark if you want precise numbers.

Boris Zbarsky

unread,
Sep 3, 2014, 7:21:46 PM9/3/14
to blink-dev
On 9/3/14, 5:35 PM, Rik Cabanier wrote:
> I talked to the mozilla people and this is a bug in the JIT in Firefox
> for Windows.
> On Mac and Linux, DOMMatrix is actually faster than the JS
> implementation with no DOM interaction.

I doubt it's a bug in the JIT. It's the _native_ version that's slower
on Windows, not the JS version! In any case, it's definitely a
Windows-specific issue.

> I also added tests that use float arrays. They are about the same speed
> as DOMMatrix as long as you don't interact with the DOM. As soon as you
> cross the DOM, native JS is 4 to 5 times slower than DOMMatrix.

If you pass to a DOM method that expects a sequence<float>, sure: Gecko
doesn't have a fast path for convering a Float32Array to a
sequence<float> in the DOM bindings at the moment.

-Boris

Rik Cabanier

unread,
Sep 3, 2014, 7:38:29 PM9/3/14
to Boris Zbarsky, blink-dev
On Wed, Sep 3, 2014 at 4:21 PM, Boris Zbarsky <bzba...@mit.edu> wrote:
On 9/3/14, 5:35 PM, Rik Cabanier wrote:
I talked to the mozilla people and this is a bug in the JIT in Firefox
for Windows.
On Mac and Linux, DOMMatrix is actually faster than the JS
implementation with no DOM interaction.

I doubt it's a bug in the JIT.  It's the _native_ version that's slower on Windows, not the JS version!  In any case, it's definitely a Windows-specific issue.

Yeah, I was a bit puzzled about that too when I logged the bug [1] . Maybe Olli misunderstood what code path was slow.
 
I also added tests that use float arrays. They are about the same speed
as DOMMatrix as long as you don't interact with the DOM. As soon as you
cross the DOM, native JS is 4 to 5 times slower than DOMMatrix.

If you pass to a DOM method that expects a sequence<float>, sure: Gecko doesn't have a fast path for convering a Float32Array to a sequence<float> in the DOM bindings at the moment.

I'll update the test so it calls into a real Float32Array method. This should be fast since you can just the pass the raw buffer, correct?

Rik Cabanier

unread,
Sep 3, 2014, 8:11:17 PM9/3/14