Bug 65535

Summary: A .style like API for setting transform values
Product: WebKit Reporter: Paul Bakaus <pbakaus>
Component: CSSAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: annevk, cmarrin, dino, eoconnor, marsjaninzmarsa, simon.fraser
Priority: P2 Keywords: InRadar
Version: 528+ (Nightly build)   
Hardware: All   
OS: All   
Bug Depends on: 67167    
Bug Blocks:    

Description Paul Bakaus 2011-08-02 07:00:12 PDT
"Our engine spends a lot of time creating CSS transform strings (string building alone uses 7% CPU on a i7 Mac Book Pro)

This (plus the overhead of parsing the strings to get out the transform data) makes stuff really slow.

A .style like API for setting transform values would be highly appreciated:
   
   node.transform.translateX = 20;
   node.transform.translateY = 10;
   node.transform.translateZ = 30;
   node.transform.scaleY = 1.0;
   node.transform.scaleX = 1.5;
   etc.


Note: We do not want to create strings here so omitting the px should be possible."
Comment 1 Simon Fraser (smfr) 2011-08-02 08:15:42 PDT
This would fall under the new CSS OM work <http://dev.w3.org/csswg/cssom>
Comment 2 Paul Bakaus 2011-08-02 08:42:26 PDT
True, thanks for the pointer. It's important to note that the current JS way of modifying transforms via Matrices somehow is even slower than just setting the styles directly. Maybe somebody can shed some light into why that is.
Comment 3 Chris Marrin 2011-08-03 11:30:38 PDT
(In reply to comment #2)
> True, thanks for the pointer. It's important to note that the current JS way of modifying transforms via Matrices somehow is even slower than just setting the styles directly. Maybe somebody can shed some light into why that is.

Can you give an example of what you mean by "modifying transforms via matrices? If you're talking about something like:

    var mat = new webKitCSSMatrix();
    mat = mat.rotate(45);
    elt.style.webkitTransform = mat;

I believe WebKit will convert that CSSMatrix into a string and pass that to the CSS value. So that would explain your performance problem  there.

I believe what might be achievable with the CSS OM API is something like:

    node.style.transform.append(new CSSTransformTranslate(0, 0, 0));

That would be the equivalent of:

    node.style.transform = "translate3d(0, 0, 0);

Then to change translation values you'd go:

    node.style.transform[0][0] = 20;
    node.style.transform[0][1] = 10;
    node.style.transform[0][2] = 30;

That's as close you could get because the CSS transform is a CSSValueList of transform primitive objects. You need to be able to represent any primitive followed by any other, including multiple translates, scales, etc. So you'd first have to know the primitive order (or construct a CSS value with the desired order) and then interact with each primitive appropriately.
Comment 4 Paul Bakaus 2011-08-04 00:36:52 PDT
(In reply to comment #3)
> (In reply to comment #2)
> > True, thanks for the pointer. It's important to note that the current JS way of modifying transforms via Matrices somehow is even slower than just setting the styles directly. Maybe somebody can shed some light into why that is.
> 
> Can you give an example of what you mean by "modifying transforms via matrices? If you're talking about something like:
> 
>     var mat = new webKitCSSMatrix();
>     mat = mat.rotate(45);
>     elt.style.webkitTransform = mat;
> 
> I believe WebKit will convert that CSSMatrix into a string and pass that to the CSS value. So that would explain your performance problem  there.

Yeah, I think that was what we tried, and had a performance problem worse than the current way of simply putting in strings.

> 
> I believe what might be achievable with the CSS OM API is something like:
> 
>     node.style.transform.append(new CSSTransformTranslate(0, 0, 0));
> 
> That would be the equivalent of:
> 
>     node.style.transform = "translate3d(0, 0, 0);
> 
> Then to change translation values you'd go:
> 
>     node.style.transform[0][0] = 20;
>     node.style.transform[0][1] = 10;
>     node.style.transform[0][2] = 30;
> 
> That's as close you could get because the CSS transform is a CSSValueList of transform primitive objects. You need to be able to represent any primitive followed by any other, including multiple translates, scales, etc. So you'd first have to know the primitive order (or construct a CSS value with the desired order) and then interact with each primitive appropriately.

That's pretty cool! We use CSS transforms to pretty much move everything on the scene around, so my guess is that this removes the GC running crazy because of too many strings and the string parsing alltogether.

Very much looking forward to it.
Comment 5 Simon Fraser (smfr) 2011-10-24 15:06:56 PDT
<rdar://problem/10042687>