Bug 199260

Summary: Rotated composited elements with clipping descendants sometimes don't respecting original layering
Product: WebKit Reporter: iztok.oder
Component: CompositingAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Other   
Hardware: All   
OS: Unspecified   
Attachments:
Description Flags
Minimal reproduction case
none
Better testcase
none
Correct testcase
none
Testcase none

Description iztok.oder 2019-06-27 00:25:29 PDT
Created attachment 373005 [details]
Minimal reproduction case

Overview:
Ele
Drag-selecting any page crashes Mac builds in the NSGetFactory function.
Steps to Reproduce: Minimized, easy-to-follow steps that will trigger the bug. Include any special setup steps.

Steps to reproduce:
1) Open the attached html in chrome or safari.
2) Open inspector tools and select div with 'object' class.
3) Change object's transform property function 'rotate' to use various angles.
3) Observe div elements with class names 'element-1' and 'element-2'.

Expected results:
The layering of most inner elements should be the same regardless of the rotation angle of their parent.

Actual Results:
With some angles used in rotate function the innermost div elements are correctly layered while with others they are not.

Hardware and browsers:
Mac OS 10.13.3
Chrome Version 75.0.3770.100 (Official Build) (64-bit)
Safari Version 11.0.3 (13604.5.6)

Additional Builds and Platforms:
Safari on Iphone 7 with iOS 12.3.1
Chrome Version 75.0.3770.100 (Official Build) (64-bit) on Windows 10

Additional Information:

Experimenting with the minimal reproduction case we figured out
Comment 1 iztok.oder 2019-06-27 00:33:20 PDT
Seems I accidentally submitted this too soon.

Overview:

Layering of elements within rotated parent with overflow hidden is not respected when one of the elements is sent to GPU.

Experimenting with the attached minimal reproduction case we figured out that the combination of overflow: hidden on element 'container' class, rotated element with class 'object' and sending one of the elements within 'container' element produces this result. Sending all elements within 'container' element will fix this issue.
Comment 2 Radar WebKit Bug Importer 2019-06-27 10:40:37 PDT
<rdar://problem/52269393>
Comment 3 Alexey Proskuryakov 2019-06-27 10:42:47 PDT
The test case shows a green square on my iPhone. Does that mean that the test passes?
Comment 4 Simon Fraser (smfr) 2019-06-27 10:47:54 PDT Comment hidden (obsolete)
Comment 5 Simon Fraser (smfr) 2019-06-27 11:03:27 PDT
Created attachment 373037 [details]
Better testcase
Comment 6 Simon Fraser (smfr) 2019-06-27 13:29:21 PDT
Created attachment 373049 [details]
Correct testcase
Comment 7 Simon Fraser (smfr) 2019-06-27 13:30:34 PDT
In the bad case we're not detecting that the blue box needs compositing because overlap testing fails.
Comment 8 Simon Fraser (smfr) 2019-06-27 13:54:26 PDT
In RenderLayerCompositor::addToOverlapMap(), 'clipRect' seems wrong, and then we intersect it with clippedBounds and get a rect that is too small.
Comment 9 Simon Fraser (smfr) 2019-06-27 14:12:48 PDT
RenderLayer::calculateClipRects() just offsets the clip rect by renderer().localToContainerPoint(FloatPoint(), &clipRectsContext.rootLayer->renderer()), which is clearly wrong with rotations.
Comment 10 Simon Fraser (smfr) 2019-06-27 14:15:14 PDT
Created attachment 373052 [details]
Testcase