Bug 217154

Summary: Absolutely positioned and negative z-index div with canvas child gets drawn with wrong stacking order
Product: WebKit Reporter: Yong Su <jean.timex>
Component: CompositingAssignee: Rob Buis <rbuis>
Status: RESOLVED FIXED    
Severity: Major CC: bfulgham, changseok, darin, esprehn+autocc, ews-watchlist, fred.wang, glenn, kondapallykalyan, pdr, rbuis, simon.fraser, webkit-bug-importer, zalan
Priority: P2 Keywords: InRadar
Version: Safari 14   
Hardware: All   
OS: All   
See Also: https://bugs.webkit.org/show_bug.cgi?id=238589
Attachments:
Description Flags
Screenshot of incorrect stacking order
none
Patch
none
Patch
none
Patch
none
Patch ews-feeder: commit-queue-

Yong Su
Reported 2020-09-30 16:42:53 PDT
Created attachment 410171 [details] Screenshot of incorrect stacking order Steps to reproduce: 1. Navigate to http://jsfiddle.net/jeantimex/Lsvyz0nj/ 2. Notice that there are two divs (blue and red) What to expect: The red div should stack above the blue div. Actual result: The blue div stacks above the red div. Comments: Both blue and red divs are positioned absolutely, the blue div has a canvas child. Both divs have the same negative z-index. This bug does not happen on Chrome, Firefox, IE, Edge. It affects all Safari browsers on all platforms. Workarounds: 1. Change both z-index to positive, e.g., 1 (however, in some business cases, it's expected both divs have the same negative z-index). 2. Change the red view z-index to 0. (however, in some business cases, it's expected both divs have the same negative z-index). 3. Set transform: translateZ(0) or translate3d(0, 0, 0) to the red div. (I guess this will force a paint for the red div in a different layer)
Attachments
Screenshot of incorrect stacking order (220.89 KB, image/png)
2020-09-30 16:42 PDT, Yong Su
no flags
Patch (2.29 KB, patch)
2021-08-30 23:34 PDT, Rob Buis
no flags
Patch (4.43 KB, patch)
2021-08-31 09:08 PDT, Rob Buis
no flags
Patch (4.43 KB, patch)
2021-09-01 01:18 PDT, Rob Buis
no flags
Patch (4.50 KB, patch)
2021-09-02 00:24 PDT, Rob Buis
ews-feeder: commit-queue-
Radar WebKit Bug Importer
Comment 1 2020-09-30 19:08:51 PDT
Rob Buis
Comment 2 2021-08-30 23:34:18 PDT
Rob Buis
Comment 3 2021-08-31 09:08:11 PDT
Simon Fraser (smfr)
Comment 4 2021-08-31 13:36:53 PDT
Comment on attachment 436891 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=436891&action=review > LayoutTests/ChangeLog:11 > + * compositing/composited-canvas-overlaps-absolute-div-expected.html: Added. > + * compositing/composited-canvas-overlaps-absolute-div.html: Added. I think the test name should have "multiple-negative-z" in it since that's key to the bug. And the fact that it's canvas isn't relevant (in fact, it would be better to make a test that doesn't use canvas).
Darin Adler
Comment 5 2021-08-31 13:38:54 PDT
Comment on attachment 436891 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=436891&action=review > Source/WebCore/rendering/RenderLayerCompositor.cpp:1101 > + Vector<RenderLayer*> layerWillCompositeNeeded; If this typically is a small set of layers, we should optimize by adding inline capacity: Vector<RenderLayer*, 2> ... We just need a small number that is almost always higher than the number of layers. > Source/WebCore/rendering/RenderLayerCompositor.cpp:1111 > + if (childLayer) { This isn’t needed. We would be adding null layer pointers to the vector.
Rob Buis
Comment 6 2021-09-01 01:18:57 PDT
Rob Buis
Comment 7 2021-09-01 06:28:13 PDT
Comment on attachment 436891 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=436891&action=review >> Source/WebCore/rendering/RenderLayerCompositor.cpp:1101 >> + Vector<RenderLayer*> layerWillCompositeNeeded; > > If this typically is a small set of layers, we should optimize by adding inline capacity: > > Vector<RenderLayer*, 2> ... > > We just need a small number that is almost always higher than the number of layers. Fair enough, however I now use a simple counter, since we do not need to actually remember the RenderLayers, just how many. >> Source/WebCore/rendering/RenderLayerCompositor.cpp:1111 >> + if (childLayer) { > > This isn’t needed. We would be adding null layer pointers to the vector. See above. >> LayoutTests/ChangeLog:11 >> + * compositing/composited-canvas-overlaps-absolute-div.html: Added. > > I think the test name should have "multiple-negative-z" in it since that's key to the bug. And the fact that it's canvas isn't relevant (in fact, it would be better to make a test that doesn't use canvas). Done.
Darin Adler
Comment 8 2021-09-01 10:02:33 PDT
Comment on attachment 437002 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=437002&action=review > Source/WebCore/rendering/RenderLayerCompositor.cpp:1101 > + unsigned layerWillCompositeNeeded = 0; Style thing: Typically it’s better to name a count with a noun like "number" or "count". A phrase like this can sound like it might be a set, not an integer. Maybe "numberOfLayerWillCompositeCallsNeeded", but that’s a bit long. Maybe "newlyCompositedChildLayerCount"? Out of my depth, I guess, but I’ve got to admit, I am puzzled about why we need to call layerWillComposite over and over again.
Rob Buis
Comment 9 2021-09-02 00:24:27 PDT
EWS
Comment 10 2021-09-02 02:12:08 PDT
Committed r281913 (?): <https://commits.webkit.org/r281913> All reviewed patches have been landed. Closing bug and clearing flags on attachment 437119 [details].
Note You need to log in before you can comment on or make changes to this bug.