Closed Bug 952011 Opened 6 years ago Closed 6 years ago

css 3d transformation (for creating environments at least) is not working in firefox

Categories

(Core :: Layout, defect, P4)

defect

Tracking

()

VERIFIED FIXED
mozilla30

People

(Reporter: mehryaar, Unassigned)

References

()

Details

(Keywords: css-moz, css3)

Attachments

(9 files, 3 obsolete files)

14.07 KB, text/html
Details
483 bytes, text/html
Details
292.73 KB, image/jpeg
Details
165.40 KB, text/plain
Details
402.55 KB, application/x-7z-compressed
Details
12.56 KB, patch
roc
: review+
Details | Diff | Splinter Review
3.80 KB, patch
bjacob
: review+
Details | Diff | Splinter Review
15.71 KB, patch
roc
: review+
Details | Diff | Splinter Review
2.67 KB, patch
bjacob
: review+
Details | Diff | Splinter Review
User Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36

Steps to reproduce:

we have used css 3d transformation to create a realistic environment for a shop in web.
you can see the correct version in "beta-gigamall.inanidea.com" in chrome or opera or safari (blink/webkit). (note the stands and banners are link and cause animations and also please try to drag and drop some product in basket and click on green button for checkout and see other animations. (the current version is only in persian, no english yet, sorry for inconvenience)


Actual results:

it's totally broken in firefox, you can see the same link in firefox (any version)
actually we have used all pertinent propeties (transform-style, perspective-origin, etc) both with -moz prefix and un-prefixed (along with -webkit etc).


Expected results:

it should look like the in chrome/safari!
Summary: we have developed a 3d shop with css 3d transformation and it's not woring in firefox → css 3d transformation (for creating environments at least) is not woring in firefox
Keywords: css-moz, css3
I can confirm that this is broken in Firefox 27 beta 2, latest Aurora and Nightly on all OS`s.
Status: UNCONFIRMED → NEW
Component: Untriaged → Layout
Ever confirmed: true
OS: Windows 8 → All
Product: Firefox → Core
Hardware: x86_64 → All
Version: 26 Branch → Trunk
(In reply to Mehdi Shams from comment #0)
> we have used css 3d transformation to create a realistic environment for a
> shop in web.

If you could try to create a reduced testcase that demonstrates the difference, that would be very helpful in determining what's going wrong.
Keywords: testcase-wanted
Priority: -- → P4
Note that Chrome dev and Safari 6 give totally different renderings on the site in question...
Keywords: qawanted
(In reply to Vacation Dec 19 to Jan 1 from comment #3)
> Note that Chrome dev and Safari 6 give totally different renderings on the
> site in question...

if you mean chrome dev vs safari, as far as i have tested (chrome 31 on windows, safari 6.1 on mac)it seems chrome have a bug in determining depth and overlaps, but it's overaly OK.
No, for me (both on Mac) they just look totally different when I load the page.

As Daniel said, what this bug needs is a smallish testcase that still shows the rendering difference...
unfortunately we are a bit busy but we try to create such test case ASAP.
I tried to create a testcase myself from "beta-gigamall.inanidea.com". This is the best I could reduce the code to. Is this sufficient to work with? http://goo.gl/sYZ3Sk
Keywords: qawanted
Since that testcase hangs every text editor I tried it on....
Summary: css 3d transformation (for creating environments at least) is not woring in firefox → css 3d transformation (for creating environments at least) is not working in firefox
I can open the testcase in emacs (after a few second hang), but yeah, it's still pretty huge. (much huger than should be necessary)

@Bogdan: For future reference, here are a few techniques that would've helped you reduce this further:
 - If the file has a gazillion tags on one line (as this one seems to), search-and-replace ">" with ">[newline]", so that you end up with a file with a gazillion relatively-short lines (one tag per line), instead of a file with just one (or a few) enormous lines. That makes it *much* easier to work with and reduce further (and it tends to make text-editors less likely to hang, too).

 - From that point, you can try deleting huge chunks of the file (e.g. delete the second half of the lines), check if you can still reproduce, and repeat.

 - When there are references to external resources, delete them unless they're necessary. (Of the three stylesheets pulled in, it looks like only "app.css" is needed.)  (or even better: merge any necessary external resources into the testcase, e.g. as a <style> block)

I'm working on a somewhat-further-reduced testcase right now, in any case.
Here's a somewhat-reduced testcase. This one's highlighting the rendering difference in the "exit" sign -- it's upside down in Firefox, with respect to Chrome. (it's oriented such that its arrow points down in Chrome, but points up in Firefox)

Looking at the original testcase again, it almost looks like Firefox is rendering the scene from behind and upside down, or something like that.
Daniel, I don't see an "exit" sign in that testcase...
(reduced a bit more to remove all the references to external images -- replaced wood-pattern background images with solid colors, and replaced the exit sign with a data-URI-encoded happy face image. The face is upside-down in Firefox, not in Chrome.)
OK -- so I think I've isolated the problem.

It looks like bit that's messing us up is:
=====
.world,.stand-world {
-webkit-perspective-origin:50% 250px;
-moz-perspective-origin:50% 250px;
-ms-perspective-origin:50% 250px;
perspective-origin:50% 250px;
-webkit-perspective:400px;
-moz-perspective:400px;
-ms-perspective:400px;
perspective:400px;
=====
from http://beta-gigamall.inanidea.com/css/app.css

Those style settings appear to have *no effect* on Chrome's rendering (i.e. if I remove them, nothing changes).

However, they *do* affect Firefox's rendering, and I can fix Firefox (make it match Chrome) by removing that style.

I don't know enough about those properties to know if Firefox is reacting to them exactly correctly -- but given that Chrome's not reacting to them *at all*, I don't see any reason to assume it's correct and Firefox is wrong.

The simplest solution is probably to just drop that chunk of style from http://beta-gigamall.inanidea.com/ -- if I do that manually using our developer tools, then we match Chrome's rendering.

Mehdi, does that solve the problem on your end?
Flags: needinfo?(mehryaar)
(Also, side note -- bz noticed styles like this in the page, which will definitely fail to parse in non-webkit browsers:
 -webkit-transition:-webkit-transform .2s ease-in-out;
 -moz-transition:-webkit-transform .2s ease-in-out;
 -o-transition:-webkit-transform .2s ease-in-out;
 -ms-transition:-webkit-transform .2s ease-in-out;
 transition:-webkit-transform .2s ease-in-out;

Those should have the respective vendor-prefixed versions of "transform".

Technically, you might even need something more verbose (e.g. 2 lines, with prefixed and unprefixed versions of transform, for each "transition" variant) -- you'd need that if any browsers have prefixed support for transition but only unprefixed support for transform, or vice versa... ugh, prefixes.)
(the bogus "-moz-transition:-webkit-transform" etc. styles are in http://beta-gigamall.inanidea.com/css/app.css )
And just to be super-clear, the lines that I'm suggesting dropping (in comment 13) are *just* the "perspective" and "perspective-origin" lines from the .world,.stand-world {...} rule from app.css.

(There are other properties set in that same rule; those ones don't need dropping.)
Sigh. I'm also starting to think that "-webkit-perspective"/"-webkit-perspective-origin" might only be broken in my local version of Chrome (Version 33 dev, on Linux64)... at least, the first answer at http://stackoverflow.com/questions/14462021/enabling-perspective-css-transform-in-chrome suggested that it worked for some folks, as of a year ago...  (The fiddle there renders as a 2D rectangle for me)

If that's the case, then the reduced testcases I've posted may not demonstrate the actual rendering difference that the reporter was talking about. (If that's the case, reduced testcases and/or screenshots of the expected rendering would be very very welcome...)
(In reply to Daniel Holbert [:dholbert] from comment #14)
> Technically, you might even need something more verbose (e.g. 2 lines, with
> prefixed and unprefixed versions of transform, for each "transition"
> variant) -- you'd need that if any browsers have prefixed support for
> transition but only unprefixed support for transform, or vice versa... ugh,
> prefixes.)

One bright side is "-ms-" prefixes can be completely dropped here to reduce the permulation. Internet Explorer didn't support transform until version 10 and it supported unprefixed transform and transition since version 10.
After rebooting in Windows, I'm now seeing a lot more 3D stuff (and chrome does indeed handle perspective properties there). Like bz in comment 10, I'm not seeing the exit sign (or happy face) in the reduced testcases.

Starting over again, at bogdan's testcase, here's a reduced version with the inline data URIs replaced with background colors.

Chrome (ver 31 on Windows) shows dark brown shelves going off into the distance (projecting out from each teal ending); Firefox does not.
Attachment #8356451 - Attachment description: testcase 1 (partly reduced) → testcase 1 (partly reduced, but probably demonstrates the wrong issue)
Attachment #8356468 - Attachment description: testcase 2 (partly reduced) → testcase 2 (partly reduced, but probably demonstrates the wrong issue)
Attachment #8356477 - Attachment description: testcase 3 (more reduced) → testcase 3 (more reduced, but probably demonstrates the wrong issue)
Flags: needinfo?(mehryaar)
Here's a reduced all-in-one testcase (which I reduced on Windows 8, with 3d support in my browsers).

In both Firefox and Chrome (on Windows 8), this renders as a trapezoidal green shape. However, if I increase the height of my Firefox window, the shape disappears.
Attachment #8356451 - Attachment is obsolete: true
Attachment #8356468 - Attachment is obsolete: true
Attachment #8356477 - Attachment is obsolete: true
I've now tested & reproduced the issue with Testcase 5 (attachment 8356803 [details]) in Firefox Nightly on Linux and Firefox Aurora on Windows.

STR are: Load the testcase in a short Firefox window. Hopefully you'll see a green shape. If you make your window taller (maybe ~20 pixels past when the vertical scrollbar is no longer needed), the shape suddenly disappears.

Matt, would you be the right person to look into this? (And can you reproduce what I'm describing on testcase 5?)
Flags: needinfo?(matt.woodrow)
(In reply to Daniel Holbert [:dholbert] from comment #13)
> OK -- so I think I've isolated the problem.
> 
> It looks like bit that's messing us up is:
> =====
> .world,.stand-world {
> -webkit-perspective-origin:50% 250px;
> -moz-perspective-origin:50% 250px;
> -ms-perspective-origin:50% 250px;
> perspective-origin:50% 250px;
> -webkit-perspective:400px;
> -moz-perspective:400px;
> -ms-perspective:400px;
> perspective:400px;
> =====
> from http://beta-gigamall.inanidea.com/css/app.css
> 
> Those style settings appear to have *no effect* on Chrome's rendering (i.e.
> if I remove them, nothing changes).
> 
> However, they *do* affect Firefox's rendering, and I can fix Firefox (make
> it match Chrome) by removing that style.
> 
> I don't know enough about those properties to know if Firefox is reacting to
> them exactly correctly -- but given that Chrome's not reacting to them *at
> all*, I don't see any reason to assume it's correct and Firefox is wrong.
> 
> The simplest solution is probably to just drop that chunk of style from
> http://beta-gigamall.inanidea.com/ -- if I do that manually using our
> developer tools, then we match Chrome's rendering.
> 
> Mehdi, does that solve the problem on your end?


no it does not solved the problem, but it flattened the scene, now it's just like IE that does not support preserve-3d for the children of a node.
(In reply to Daniel Holbert [:dholbert] from comment #14)
> (Also, side note -- bz noticed styles like this in the page, which will
> definitely fail to parse in non-webkit browsers:
>  -webkit-transition:-webkit-transform .2s ease-in-out;
>  -moz-transition:-webkit-transform .2s ease-in-out;
>  -o-transition:-webkit-transform .2s ease-in-out;
>  -ms-transition:-webkit-transform .2s ease-in-out;
>  transition:-webkit-transform .2s ease-in-out;
> 
> Those should have the respective vendor-prefixed versions of "transform".
> 
> Technically, you might even need something more verbose (e.g. 2 lines, with
> prefixed and unprefixed versions of transform, for each "transition"
> variant) -- you'd need that if any browsers have prefixed support for
> transition but only unprefixed support for transform, or vice versa... ugh,
> prefixes.)

thank you for your guide, actually we use nib with stylus to generate vendor prefixes for us, and the version of nib used had bugs in producing so. we updated stylus and nib and now everything is ok.
I can't reproduce this on OSX with aurora or nightly. The green shape is visible at all browser sizes.
Flags: needinfo?(matt.woodrow)
OK. (I can still reproduce on Linux nightly, FWIW)  That testcase may be too reduced vs. how powerful your machine is, or something.

Any chance you can reproduce this rendering-difference mentioned in comment 20, in the less-reduced testcase 4 (attachment 8356488 [details]), then?
{
> Chrome (ver 31 on Windows) shows dark brown shelves going off into the
> distance (projecting out from each teal ending); Firefox does not.
}
Flags: needinfo?(matt.woodrow)
I get nothing rendered at all with testcase 4 :(

That's with firefox aurora, chrome 32 and safari 7.
Flags: needinfo?(matt.woodrow)
Ah, right -- sorry, forgot to mention -- that's because it pulls in stylesheets over HTTP from a remote server, and they get blocked as mixed content (by default) since Bugzilla serves the testcase over HTTPS.

You can either use the shield icon in the location bar to allow the remote content, or you can just view it entirely over HTTP (which won't trigger the mixed content blocker) here:
 http://people.mozilla.org/~dholbert/tests/952011/test4.html
Attached file More reduced test case
Great, thanks Daniel!

I reduced this down to a single image that renders on chrome for me and not on firefox.

I suspect that there's more than one bug here, but I narrowed this particular test case down to an issue in gfx3DMatrix.

I've emailed some people which much better linear algebra knowledge than me to ask for some suggestions on what the best fix is. Will cc them on this bug too.
Attachment #8364810 - Attachment is patch: false
the result of test case 4 for me on win8, chome 32, firefox 26
I think it makes most sense to move the child bounds intersection into gfx3DMatrix, to avoid repeating it at all call sites.

Ideally the ProjectPoint/Bounds functions will become private, still need to fix the APZC users of them though.
Attachment #8365748 - Flags: review?(bjacob)
Quick summary of the issue:

We can't necessarily reverse transform a point in screen space to the equivalent point on the transformed plane when the transform contains perspective. Points that lie past the vanishing point have no equivalent, and our code wasn't handling this.

Passing in the bounds of the transformed plane lets us restrict our input to values that we know have finite equivalents.
Comment on attachment 8365748 [details] [diff] [review]
Part 2: Add new API for untransforming points

Review of attachment 8365748 [details] [diff] [review]:
-----------------------------------------------------------------

Yup, that is it. One semantic adjustment you might want to make in the comments is consistently use the term "projective transformation" instead of "perspective transformation". "Projective" is the correct terminology for this type of transformation (i.e. a transformation of affine coordinates that comes from a linear transformation of homogeneous coordinates) while "perspective" is only one particular application that projective transforms are used for.
Attachment #8365748 - Flags: review?(bjacob) → review+
Comment on attachment 8365749 [details] [diff] [review]
Part 3: Use the new API

Review of attachment 8365749 [details] [diff] [review]:
-----------------------------------------------------------------

::: layout/base/nsDisplayList.cpp
@@ +4722,1 @@
>    /* We want to untransform the matrix, so invert the transformation first! */

Fix this comment

::: layout/base/nsLayoutUtils.cpp
@@ +1876,5 @@
>                      NSAppUnitsToFloatPixels(aPoint.y, factor));
>  
>      if (text) {
> +        if (!TransformGfxPointFromAncestor(text, result, aAncestor, &result)) {
> +            return nsPoint(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);

Please add a comment to TransformAncestorPointToFrame that it can return one of these "bad points" (and what that means).
Attachment #8365749 - Flags: review?(roc) → review+
Comment on attachment 8368343 [details] [diff] [review]
Part 4: Avoid doing extra transforms for non-projective matrices

Review of attachment 8368343 [details] [diff] [review]:
-----------------------------------------------------------------

::: gfx/thebes/gfx3DMatrix.cpp
@@ +727,5 @@
> +  if (_14 != 0.0f || _24 != 0.0f ||
> +      _34 != 0.0f || _44 != 1.0f) {
> +    return true;
> +  }
> +  return false;

this function could consist only of a return statement, no if.

@@ +820,5 @@
>  }
>  
>  gfxRect gfx3DMatrix::UntransformBounds(const gfxRect& aRect, const gfxRect& aChildBounds) const
>  {
> +  if (!IsProjective()) {

Please explain the motivation for this code.
Once we go down this route of branching for special cases of matrices, how far are we going to go this way? Are we going to detect the more special cases of translations, rotations, etc? If not, then what is particular to the class of affine transformations, which you are describing here? In my understanding (and assumption that it is sane), CSS lets authors specify when their transforms are special cases such as translations or rotations. I need to understand why, then, we need to do manual detection here --- is it because CSS is not expressive enough to let authors express all that is special about their transforms, or is it because authors are being naughty and pass special affine transforms as general projective transforms?
(In reply to Benoit Jacob [:bjacob] from comment #41)

> this function could consist only of a return statement, no if.

Yes, true, I'll do that.


> Please explain the motivation for this code.
> Once we go down this route of branching for special cases of matrices, how
> far are we going to go this way? Are we going to detect the more special
> cases of translations, rotations, etc? If not, then what is particular to
> the class of affine transformations, which you are describing here? In my
> understanding (and assumption that it is sane), CSS lets authors specify
> when their transforms are special cases such as translations or rotations. I
> need to understand why, then, we need to do manual detection here --- is it
> because CSS is not expressive enough to let authors express all that is
> special about their transforms, or is it because authors are being naughty
> and pass special affine transforms as general projective transforms?

This change is basically just an optimization.

Transforming the bounds passed in is something that we only need to do for projective matrices, since those are the only ones where we can't map every point in the parent to an equivalent in the child.

We could probably do a bunch more detection like this, an optimize multiplying matrices together, but I doubt it's worth it.
Comment on attachment 8368343 [details] [diff] [review]
Part 4: Avoid doing extra transforms for non-projective matrices

Review of attachment 8368343 [details] [diff] [review]:
-----------------------------------------------------------------

Well, I don't really care strongly, and I understand that gfx3DMatrix is specialized to serve to implement CSS transform, and inherits lots of constraints from there. If I understand correctly, the problem is that CSS makes authors specify affine transforms as fully general projective transforms, so we don't have a better way to optimize for the affine case than to do these floating point checks. But really, this is not the right way to do a matrix API. Even with the existing constraints from the CSS API, if we really care about performance here, there should be a lot of room for improvement over having to have if() branches for various matrix special cases in each matrix operation. Maybe having a flags field on gfx3DMatrix storing what we know about this matrix, and correctly propagated along matrix operations, would be a better way to do this, scaling up to more special cases with less overhead.
Attachment #8368343 - Flags: review?(bjacob) → review+
I very much agree :)

I've considered doing this in the past, the main limiting factor is that we currently expose the data members publicly. Until we fix that we can't cache information about the state of the matrix.

Might be worth it one day if we find a test case that suffers because of this.
I still see a few issues with the page.

One is that we don't sort 3d transformed planes correctly, so you sometimes see background objects draw on top of foreground ones.

The other is that the right wall and ceiling are missing, filed 972703 for that.
Reproduced on Nightly 2014-02-01 with the attached TC from comment 22.
Verified as fixed with Fx 30 beta 7 (Build ID: 20140522105902) on Windows 7 x64, Ubuntu 13.10 x32 and Mac OS X 10.9.2:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0		
Mozilla/5.0 (X11; Linux i686; rv:30.0) Gecko/20100101 Firefox/30.0
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0
Status: RESOLVED → VERIFIED
Keywords: verifyme
You need to log in before you can comment on or make changes to this bug.