[Webkit-unassigned] [Bug 202692] New: transform/transform-origin not taken into account in RenderLayer::intersectsDamageRect()

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Tue Oct 8 05:36:38 PDT 2019


https://bugs.webkit.org/show_bug.cgi?id=202692

            Bug ID: 202692
           Summary: transform/transform-origin not taken into account in
                    RenderLayer::intersectsDamageRect()
           Product: WebKit
           Version: WebKit Nightly Build
          Hardware: Unspecified
                OS: Unspecified
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: Layout and Rendering
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: zimmermann at kde.org
                CC: bfulgham at webkit.org, simon.fraser at apple.com,
                    zalan at apple.com

Testcase:
<!DOCTYPE html>
<html>
<body>
<div style="position: absolute; transform-origin: 0 0; transform: rotate(90deg); left: 100px; top: -100px; width: 150px; height: 50px; background-color: green">
</div>
</body>
</html>

Content-Type: text/plain
layer at (0,0) size 800x600
  RenderView at (0,0) size 800x600
layer at (0,0) size 800x8
  RenderBlock {HTML} at (0,0) size 800x8 [color=#3D3D3D]
    RenderBody {BODY} at (8,8) size 784x0
#EOF
#EOF
#EOF

The object is correctly painted, but missing from the dump.
This happens because the writeLayers() function in RenderTreeAsText.cpp incorrectly flags the layer with shouldPaint=false:

    bool shouldPaint = (behavior.contains(RenderAsTextFlag::ShowAllLayers)) ? true : layer.intersectsDamageRect(layerBounds, damageRect.rect(), &rootLayer, layer.offsetFromAncestor(&rootLayer));

I've added some logging to clarify why:

    LOG_WITH_STREAM(SVG, stream << " shouldPaint=" << shouldPaint << " layerBounds=" << layerBounds << " damageRect=" << damageRect.rect() << " offfsetFromAnc=" << layer.offsetFromAncestor(&rootLayer););

--> shouldPaint=0 layerBounds=(100,-100) width=150 height=50 damageRect=(0,0) width=800 height=600 offfsetFromAnc=width=100.00 height=-100.00

So indeed, RenderLayer::intersectsDamageRect() incorrectly returns false in this case. Why?
RenderLayer::intersectsDamageRect() calls "boundingBox(rootLayer, offsetFromRoot).intersects(damageRect)".

RenderLayer::boundingBox() calls RenderLayer::localBoundingBox() (which simply returns the visualOverflowRect() -> (0,0,150,50)) and moves the rect by the passed in "offsetFromRoot" (100,-100):

For the testcase above this results in a a LayoutRect(100, -100, 150, 50), which clearly does not intersect with LayoutRect(0, 0, 800, 600) (damageRect).

The transform-origin is completely ignored here but plays an important role. With the default transform-origin (50% 50%) the <div> above is invisible, and thus correctly flagged as shouldPaint=false.

For transform-origin: 50% 50%, the originTranslate evaluates to (75, 25) (see RenderStyle::applyTransform), but to (0, 0) when using transform-origin: 0 0. The additional translation needs to be respected, otherwise one cannot judge whether the layer is painted (aka. visible) or not.

Since it is now clear that neither transform nor transform-origin are taken into account, one can construct an even simpler testcase, not involving transform-origin / rotations:

<div style="position: absolute; transform: translate(0px,100px); left: 100px; top: -100px; width: 150px; height: 50px; background-color: green">

This is visible but excluded from the dump, as the "untransformed" boundingBox() does not intersect the damageRect.

I'd like to hear the expert opinion on the sanest way to fix this :-)

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20191008/a620e6e8/attachment-0001.html>


More information about the webkit-unassigned mailing list