Closed Bug 1187209 Opened 9 years ago Closed 7 years ago

Wrong stacking order of blocks rendered with CSS 3D Transforms

Categories

(Core :: Graphics, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
Tracking Status
firefox42 --- affected

People

(Reporter: dholbert, Unassigned)

References

Details

(Whiteboard: [gfx-noted])

Attachments

(4 files, 4 obsolete files)

Filing bug based on tweet: https://twitter.com/anatudor/status/624445629947867136 Testcase: http://codepen.io/thebabydino/pen/ZGqWGv/ Chrome renders something that looks like a bit like a cube made of Jenga tiles. Firefox renders the platforms in the reverse stacking order, so it looks a bit like some planes layered on top of each other.
Attached file testcase 1 (original) (deleted) —
Here's a standalone testcase, taken from the codepen.
Here's a partially reduced testcase. On my Thinkpad W550s laptop monitor, this matches Chrome's rendering if the Firefox window is the full width of my monitor, but it exhibits the broken rendering when it's half the width of my monitor. (And there's a threshold at around 1450px wide where it snaps between the two.) Also, as noted in the testcase's source, the bug goes away if I remove the final <div class="lateral"></div (or various other bits of the testcase).
(This might also be a dupe of bug 1175311, based on bug title at least.)
Summary: Incorrect rendering with CSS 3D Transforms → Wrong stacking order of blocks rendered with CSS 3D Transforms
Also, this gets spammed to my terminal when this bug is reproducing: > [GFX1-]: Failed to allocate a surface due to invalid size Size(0,1)
...and in a debug build, I get this more verbose error output in my terminal (repeated over and over): [GFX3-]: Surface width or height <= 0! [GFX3-]: Surface width or height <= 0! Crash Annotation GraphicsCriticalError: |[0][GFX1-]: Failed to allocate a surface due to invalid size Size(0,1)[GFX1-]: Failed to allocate a surface due to invalid size Size(0,1) [Parent 5053] WARNING: '!temp', file /scratch/work/builds/mozilla-inbound/mozilla/gfx/layers/basic/BasicCompositor.cpp, line 465
I don't 100% follow what's going on, but it looks like things go wrong here: > 362 gfxRect bounds = ThebesRect(aRect); > 363 bounds.TransformBounds(new3DTransform); > 364 bounds.IntersectRect(bounds, gfxRect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height)); > 365 > 366 transformBounds = ToRect(bounds); > 367 transformBounds.RoundOut(); http://mxr.mozilla.org/mozilla-central/source/gfx/layers/basic/BasicCompositor.cpp?rev=7f1489a600e8#360 Here's my gdb output as I go through this (starting just after line 362 has executed, initializing |bounds|): (gdb) p bounds $35 = { <mozilla::gfx::BaseRect<double, gfxRect, gfxPoint, gfxSize, gfxMargin>> = { x = 0, y = 0, width = 32, height = 32 }, <No data fields>} (gdb) n (gdb) p bounds $36 = { <mozilla::gfx::BaseRect<double, gfxRect, gfxPoint, gfxSize, gfxMargin>> = { x = 535.31432634238911, y = 484.95654822981572, width = 26.902272366435227, height = 46.743836532858552 }, <No data fields>} (gdb) n (gdb) p bounds $37 = { <mozilla::gfx::BaseRect<double, gfxRect, gfxPoint, gfxSize, gfxMargin>> = { x = 1253, y = 484.95654822981572, width = 0, height = 0 }, <No data fields>} (gdb) So as you can see, we already have a 0 width & height here. :-/ And then we set transformBounds from that: (gdb) n (gdb) p transformBounds $39 = { <mozilla::gfx::BaseRect<float, mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::PointTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::SizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::MarginTyped<mozilla::gfx::UnknownUnits> >> = { x = 1253, y = 484.956543, width = 0, height = 0 }, <mozilla::gfx::UnknownUnits> = {<No data fields>}, <No data fields>} (gdb) n (gdb) p transformBounds $40 = { <mozilla::gfx::BaseRect<float, mozilla::gfx::RectTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::PointTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::SizeTyped<mozilla::gfx::UnknownUnits>, mozilla::gfx::MarginTyped<mozilla::gfx::UnknownUnits> >> = { x = 1253, y = 484, width = 0, height = 1 }, <mozilla::gfx::UnknownUnits> = {<No data fields>}, <No data fields>} (gdb) The second transformBounds here is after the RoundOut call -- which rounds our height up from approximately-0 to 1. But we still have 0 width, so we fail in our call to Factory::CreateDataSourceSurface below (via its sanity-check call to Factory::CheckSurfaceSize). This failure causes the logging quoted in comment 6.
For completeness, new3DTransform here is: (gdb) p new3DTransform $41 = { _11 = -0.398852468, _12 = -0.709316492, _13 = 0, _14 = -0.00220970879, _21 = 0, _22 = 1, _23 = 0, _24 = 0, _31 = 0, _32 = 0, _33 = 1, _34 = 0, _41 = 537.088623, _42 = 486.563934, _43 = 0, _44 = 1.0033145, static kTransformAndClipRectMaxVerts = 32 } ...and 'offset' is (x=1253, y=71), and buffer.mPtr->mSize is width = 14, height = 685. So the rect formed by these in the IntersectRect() call is nowhere near the |bounds| that we're intersecting with it, in the x direction, in the IntersectRect call. (hence the 0 width & height on their intersection) Not sure how we end up rounding up to 1, in the RoundOut later on.
(ohhhh, we end up with height=1 because we have an intermediate y-value, 484.956543, and RoundOut works by rounding that down to produce Y and rounding it up to produce the resulting YMost, basically. So we get Y = 484, and YMost = 485, which means height = 1. Anyway, this is a bit of a tangent anyway; it doesn't help us if we have a height of 0 instead of 1 here -- we still fail in the same way.)
Looks like kip has touched this code most recently; hoping he can take a look here.
Flags: needinfo?(kgilbert)
(here's one more testcase w/ a slightly different rendering glitch - huge black artifacts across the window.)
Attached image screenshot of testcase 3 (obsolete) (deleted) —
(all my testing here done with latest Nightly 42.0a1 (2015-07-23) on Ubuntu 15.04 on a Thinkpad W550s)
Depends on: 1175311
The first testcase (http://codepen.io/thebabydino/pen/ZGqWGv/) will require sorting to be corrected (Bug 1175311); however, it doesn't appear that plane splitting will be needed for this example (Bug 689498). The black slashes described in Testcase 3 may be related to Bug 1157984, which relates to clipping of projected CSS elements.
Flags: needinfo?(kgilbert)
Whiteboard: [gfx-noted]
Another one of Ana’s demos seems to show the same issue: http://codepen.io/thebabydino/pen/mJojKd . Look at the stacking order of the boxes on the right hand side as they flip.
@Robin, Demo looks fine to me. The issue only appears when you add borders to the boxes: http://codepen.io/anon/pen/PZEeOm I also noticed, that the issue appears not only for border, but also for box-shadow. See Ana's demo with box-shadow instead of borders: http://codepen.io/anon/pen/Goydyr.
Still broken for me. The attached screenshot demos the issue - the boxes on the right are rendered in the wrong order.
Well, apparently we have different results. I'm running on FF 43.0.4, OSX 10.11.2 on MacBook Pro mid 2015.
I created another demo testcase, without borders and box shadow (since the two definetively **** up the stacking order): http://codepen.io/anon/pen/eJyraw. The stacking order ist not revised on 'camera' rotation, instead the order resembles the order in which the cubes are added to the DOM. I suspect the positioning of parent elements to be the trouble maker here. The stacking order might not account for 'classic' two dimensional positioning like left/right/margin/position/.. -properties.
Attached image columns_demo.png (deleted) —
Yep, that’s broken as well. Nightly from yesterday on a mid-2012 Macbook Air, 10.11. Driver issue I guess? This machine has an ‘Intel HD Graphics 5000 1536 MB’.
Ana's Demo might be a driver/system issue, since we get different results with the same FF. But my columns demo along with the border/box-shadow issue is definetively a bug in Geckos render pipeline, since here I get the same result as you and everyone else do.
Summing up the state of things here: (1) I cannot reproduce any issues with attached testcases 2 or 3, in current nightly. (So whatever bugs they trigger seem to have been fixed) (2) ...but I *can* reproduce the original problem in testcase 1 & Ana's original codepen. It renders like layered planes instead of a nice cube, due to swapped stacking order of blocks. (3) ...and I *can* reproduce the issues with other demos mentioned in comment 17 and comment 19. I'm marking testcase 2 & 3 as obsolete, so they don't confuse further progress/diagnosis of the remaining underlying issue(es) here.
Attachment #8638367 - Attachment is obsolete: true
Attachment #8638368 - Attachment is obsolete: true
Attachment #8638382 - Attachment is obsolete: true
Attachment #8638383 - Attachment is obsolete: true
Here yet another more professional failure test case: http://voxelcss.com/demo
Matt's been working on 3d transform stuff - maybe he can take a look?
Flags: needinfo?(matt.woodrow)
As far as I can tell all these demos just suffer from incorrect sorting or plane splitting. Kip is working on fixing these issues in bugs 1175311 and 689498.
Flags: needinfo?(matt.woodrow)
(In reply to Matt Woodrow (:mattwoodrow) from comment #25) > As far as I can tell all these demos just suffer from incorrect sorting or > plane splitting Seems like this was correct. Happily, this is fixed now! Using the original codepen here for testing (http://codepen.io/thebabydino/pen/ZGqWGv/ , also captured as testcase 1): this went from broken (layers splayed out, not cubelike at all) to mostly-working* when bug 1274673 landed. And then it went to fully-working when bug 1323797 landed. So: well done Miko! I'll resolve this as FIXED with dependency on both of those bugs. * In the intermediate "mostly-working" rendering, the layers were nicely stacked in a cube, but several faces in the second-to-top row were incorrectly missing (or perhaps covered up, by being painted in the wrong order or something). This was fixed by bug 1323797 though.
Depends on: 1274673, 1323797
Note: in the current "fixed" rendering, I do actually see some "seams" along some edges here, at most zoom levels (including the default zoom level). I'll attach a screenshot to demonstrate. I'll file a followup for that.
(In reply to Daniel Holbert [:dholbert] from comment #27) > Note: in the current "fixed" rendering, I do actually see some "seams" along > some edges here, at most zoom levels (including the default zoom level). > I'll attach a screenshot to demonstrate. I'll file a followup for that. Filed bug 1399268 (with screenshots over there). Calling this one FIXED per comment 26.
Status: NEW → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: