Bug 67203 - Absolutely positioned div with canvas child does not move with parent div.
Summary: Absolutely positioned div with canvas child does not move with parent div.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac (Intel) OS X 10.7
: P2 Normal
Assignee: Simon Fraser (smfr)
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2011-08-30 09:13 PDT by madsenat
Modified: 2014-10-31 20:35 PDT (History)
6 users (show)

See Also:


Attachments
simpler test case (2.75 KB, text/html)
2011-10-02 22:27 PDT, Brendan Kenny
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description madsenat 2011-08-30 09:13:12 PDT
The above URL shows a simple process block we use in our online diagramming application. After a few seconds I highlight the divs, remove some extra DOM elements that are not needed for the demo, and add the event handlers for the demo. The final DOM structure is as follows:

<p /> - hidden
<p />
<div>
    <div>
        <canvas /> (shape canvas)
        <div>
            <canvas /> (text canvas)
        </div>
    </div>
</div>

If you drag around the element you will see that the canvas the text is rendered on (in blue) stays in place while the div parent of the canvas (green) stays where it should be. You can press the 'x' key to toggle the visibility of the text canvas (css display set to 'none' and 'block' appropriately) and when you show it again it will be in the right place.

Another interesting note is that if you reverse the order of the outer canvas (where the block shape is rendered) and it's sibling div (the parent of the text canvas) then they stay together just fine. You can use the 'y' key to see this in action.

We see the same issues on the beta channel of Chrome and it appears to be a GPU acceleration thing as we can locate a GPU acceleration related process and kill it and everything snaps back to the right place.

To see this issue in our production environment you can visit lucidchart.com/demo and drag a block from the left hand column onto the page then drag it around.
Comment 1 madsenat 2011-08-30 09:15:15 PDT
Just as a note, I have created the same DOM structure as the example and manually drawn some lines and shapes on the different canvases but it would not reproduce the problem. We are only able to get it to happen when the canvases are drawn from our system.
Comment 2 Brendan Kenny 2011-10-02 22:27:33 PDT
Created attachment 109437 [details]
simpler test case

Here is a simpler test case with the same DOM structure but without the Lucid Chart js library. The static HTML and CSS are sufficient to set up the buggy render tree, but js is necessary to move the div to see the child canvas not being repainted.

The key requirements in this example seem to be to have all the elements positioned, and the top-most div be overflow clipped. When the rectangle's div is moved, layout appears to happen correctly, but the text canvas isn't repainted until a larger repaint is forced (selecting in dev tools, window resizing, etc).

As the original testcase demonstrated, adding one of several style properties to the rectangle's div makes it properly repaint the text canvas (opacity and transforms work; overflow:hidden makes both the text canvas and its parent div not repaint).

As noted in the matching Chromium bug (http://crbug.com/95275), painting can also be fixed by making the text canvas not positioned (so it's not in its own compositing layer).

I'm seeing this bug in
Chrome 16 (103657) but not Safari on Windows 7
Safari 5.1 on OS X 10.7.1 (but not on 10.6.8)

bisecting Chromium puts the problem within
http://build.chromium.org/f/chromium/perf/dashboard/ui/changelog.html?url=/trunk/src&range=86508:86542

but that may be just because accelerated canvas was turned on in 86510
Comment 3 Vangelis Kokkevis 2011-10-03 15:52:35 PDT
My first hunch was that the behavior was unrelated to canvas but had something to do with composited layers and absolute positioning.  Replacing the outer canvas (rect_canvas) by a div with a translateZ(0) webkit transform still reproduces the problem.  Further replacing the inner canvas (text_canvas) by a div makes the issue go away even though we still correctly get two composited layers.

I'm pretty sure that the recent behavior change is a result of the introduction of the accelerated canvas both Safari in 10.7 and Chrome version 15+. 

CC-ing a couple more folks familiar with this part of the code.
Comment 4 Radar WebKit Bug Importer 2011-10-04 10:11:20 PDT
<rdar://problem/10231214>
Comment 5 Simon Fraser (smfr) 2012-02-17 09:07:53 PST
To work around this you can put z-index: 0 on #fullscreen_div.
Comment 6 Simon Fraser (smfr) 2012-02-17 09:25:21 PST
The bug here is that changing the position of #rect_div results in an incremental layout which doesn't encompass the layer for #text_canvas.
Comment 7 Simon Fraser (smfr) 2012-02-17 09:26:45 PST
This is a more subtle version of bug 26430.
Comment 8 Simon Fraser (smfr) 2014-10-31 20:35:35 PDT
No longer reproduces.