New issue
Advanced search Search tips

Issue 713016 link

Starred by 3 users

Issue metadata

Status: Archived
Owner:
Closed: May 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 2
Type: Bug-Regression



Sign in to add a comment

clearRect not always clearing on some Chromebooks

Reported by ricciad...@gmail.com, Apr 19 2017

Issue description

UserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30

Steps to reproduce the problem:
We are getting reports of our users on Chromebooks having issues with our music exercises at http://www.musictheory.net/exercises 

Specifically, new questions are drawing on top of the old ones, even though we explicitly clear the entire canvas with a clearRect:

    let ctx = element.getContext("2d");

     ctx.beginPath();
     ctx.save();
     ctx.clearRect(0, 0, canvasWidth, canvasHeight);
     // Drawing code here
     ctx.restore();

We are seeing screenshots that can only be explained if the clearRect doesn't work. Users report it worked in Chrome 56 (or possibly 55), but broke around the time 57 was released. Our code related to canvas drawing didn't change.

We are unable to reproduce this on any of our test hardware. The only information we have from a user is that their Chromebook is "my chromebook is model p22t". We believe this may be the Dell Chromebook 11 (Perhaps model CRM3120?).

–

I hate to file a bug without more information, but I'm not sure what can be done to further diagnose this or workaround this on our side. I've tried searching other bugs, and found some mentioning of glClear issues (gl_clear_broken?) on various GPUs. Could this be related?

What is the expected behavior?

What went wrong?
The clearRect does not appear to be working.

Did this work before? Yes 56

Does this work in other browsers? Yes

Chrome version: <Copy from: 'about:version'>  Channel: n/a
OS Version: 
Flash Version:
 
The user agent from another affected user is "X-User-Agent: Mozilla/5.0 (X11; CrOS x86_64 9202.60.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.137 Safari/537.36". That user replied with "thinkpad chromebook" when we asked what model it was. We're trying to get additional details.

Comment 2 by junov@chromium.org, Apr 20 2017

Cc: zmo@chromium.org
Owner: fs...@chromium.org
Status: Assigned (was: Unconfirmed)
@zmo: Is there a known GPU driver bug that has something to do with textures not clearing on ChromeOS?

@ricciadams: Thanks for reporting this. Until we get this fixed on our end, you could try to work around the bug by clearing the canvas using a different method.  For example, by resetting the canvas:

element.width = element.width; 

Note: this does not just clear the canvas. It also resets the context state.
Thanks! I updated our site to reset the canvas via `element.width=element.width`. I also ordered a Dell Chromebook 11 which should arrive tomorrow. Hopefully I'll be able to reproduce the issue and get you more data.
Update: Chromebook 11 came with Chrome 53, no issues found. Upon updating to Chrome 57, the issue reproduces even with the `element.width=element.width` fix.

Issue *does NOT* reproduce if we turn off Accelerated 2D canvas in "about://flags"

I don't think this is as simple as "clearRect isn't working". It seems to be some kind of compositing issue.

Upon a correct answer, we move the music note to its own canvas element and then animate that element with CSS transforms. At the end of the animation, we remove the canvas element from the DOM and redraw the next question. I've verified that all of this code is working correctly on our end (and the animating canvas elements are actually removed).

However, I'm seeing two requestAnimationFrame callbacks getting called at the end of the animation:
1. One tells the master canvas to redraw and removes the animating canvas of the note
2. Another just tells the master canvas to redraw

This isn't ideal from a performance standpoint, but it shouldn't matter visually - each redraw call does a clearRect on the master canvas. However, it looks like the results from #1 and #2 are being composited together.
Even if I do a fillRect (with the white background color) after the clearRect, it still merges the two redraws together.

Curiously, if I alternate between #ffffff and #fefefe with each draw, the problem goes away:

        if (0) { // Changing this to 1 "fixes" the problem.
            ctx.fillStyle = _drawID++ % 2 ? "#fefefe" : "white";
        } else {
            ctx.fillStyle = "white";
        }
        ctx.fillRect(0, 0, pixelsWide, pixelsHigh);

Some kind of GPU optimization gone wrong?
I was incorrect in Comment #4. There aren't two requestAnimationFrame callbacks: there's a setTimeout callback which sets up a requestAnimationFrame callback. Both callbacks clear and then redraw the canvas.

I've been able to reduce this problem to the following fiddle:
https://jsfiddle.net/rkjcpxLc/2/

Expected behavior: Each time the canvas redraws, it increments a counter and draws the counter value. Clicking on the button should perform an animation and then redraw the canvas. Each redraw does a clearRect, so there should never be two numbers overlapping (even though there's one unnecessary draw).

Actual behavior:
On my Dell Chromebook 11, clicking the button results in two numbers overlapping. All other test devices work correctly.
Screenshot from Chromebook showing failure on https://jsfiddle.net/rkjcpxLc/2/
YuKM2iX.png
122 KB View Download
I think I'm running into the similar kind of issue with 2015 13" MacBook Pro. 

At first I thought it was the clearRect not clearing the old content from canvas properly, but after playing a bit I managed to get totally unrelated content painted to the canvas, namely google logo from next browser tab (yes, wtf). 

Similar to above, I tried also changing all clearRect calls to `el.width = el.width`, and that didn't seem to help. I also tried filling the canvas with white instead of clearing, and weirdly enough that didn't seem to work either.

To give bit more context, we use several backing canvases and copy from those to final canvas using drawImage.

Unfortunately in my case it's harder to reproduce consistently (the above jsfiddle works just fine...), but I'll try to create a fiddle that triggers the bug.
glitch.png
459 KB View Download

Comment 9 by junov@chromium.org, Apr 24 2017

Thanks for all the data and repro steps.

I've been able to confirm using a Chromebook Pixel, but it does not repro consistently on this device. Sometimes it is necessary to click the button several times before we see the number overlap.

No repro in 56.0.2924.110
Repro with 57..0.2987.146

Comment 10 by junov@chromium.org, Apr 24 2017

The bug appears to be non-reproducible in Chrome 58 (currently in beta)

We have optimizations that kick-in with opaque draws that cover the entire canvas.  There appears to be a bug with theses optimizations in Chrome 57.  A temporary workaround you can use for now is to clear the canvas in two steps where each step does not cover the entire rectangle:

context.clearRect(0, 0, canvasWidth/2, canvasHeight);
context.clearRect(canvasWidth/2, 0, canvasWidth/2, canvasHeight);

Even though the problem goes away in Chrome 58, we will continue to investigate in order to understand the root cause and to see if there is a reasonable fix we could in apply in an upcoming 57 update.

The issue I'm seeing still persist through Canary  60.0.3079.0. I guess I should file a separate bug then :/

Comment 12 by junov@chromium.org, Apr 24 2017

Yes please file a separate bug
@junov - Thank you! I've added the half-clear workaround to our site.

You are right - the issue doesn't reproduce consistently, although it usually reproduces in the first or second click on my Dell Chromebook 11.
Status: Fixed (was: Assigned)
Since this is clear on 58, and another bug will be created for #8, I'll close this.
Labels: VerifyIn-61

Comment 16 by dchan@chromium.org, Jan 22 2018

Status: Archived (was: Fixed)

Sign in to add a comment