New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 4 users

Issue metadata

Status: Fixed
Owner:
Closed: Apr 2012
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Windows
Pri: 2
Type: Bug

Restricted
  • Only users with EditIssue permission may comment.



Sign in to add a comment

Enable GPU Accelerated 2D canvas cause massive slow down when drawing small canvases to large canvas

Reported by yangjin0...@gmail.com, Dec 7 2011 Back to list

Issue description

Chrome Version       : 17.0.948.0
OS Version: Linux 32bit.
URLs (if applicable) :http://www.craftymind.com/guimark3/
Other browsers tested:
Add OK or FAIL after other browsers where you have tested this issue:
Safari 5:
Firefox 4.x:
IE 7/8/9:

What steps will reproduce the problem?
1.Turn on HW Acceleration
2.Run GUIMark3 "Bitmap Test" benchmark with normal and cached mode


What is the expected result?
when enable GPU accelerated 2D canvas, normal and cached mode should both show about 60FPS

What happens instead?
normal mode show about 60 FPS but cached mode show 12-15 FPS.
disable GPU accelerated 2D canvas, normal and cached mode both show 60FPS.

Please provide any additional information below. Attach a screenshot if
possible.

The normal mode: draw several small images(less than 128*128) into onscreen canvas(480*640) by call context.drawImage() when running.
The cached mode: when initialize, create a canvas for each image and draw image into this canvas. When running, just draw these cached canvases into the onscreen canvas.

The root cause is: in cached mode, when draw the cached canvas to onscreen canvas, it will load the cached canvas(ImageBuffer) into texture, but the generation id bounded with this ImageBuffer's bitmap is not saved because every time in ImageBuffer::draw(), we create a new Image based on the bitmap.
So it will not be found in the cached texture next time and will be loaded to gpu texture every time which show poor performance.

The bug reported for this in webkit is:
https://bugs.webkit.org/show_bug.cgi?id=73186

Please have a look at it.



 
Actually, when I got today my chrome browser updated to v18, gpu acceleration is enabled by default and I experience same issue.
Yesterday, on previous browser version it was ok.

I have simple app, where many tile sprites are drawn on big canvas.
There is objects Tile, each of them have method getSprite() it's used in mainCanvas.drawImage(tile.getSprite(), someX, someY);

If return value of getSprite is Image object, then it's fine, there is 60fps all the time.
But if return value is canvas object, then fps drops down to 1-2fps.

Here is few simplified code samples:
This one is 1-2fps;
	getSprite: function(){
		var baseSprite = g.sprites.getSprite(1231);
		
		var cnv = document.createElement('canvas');  //returns cached Image object
			cnv.width = baseSprite.width;
			cnv.height = baseSprite.height;
			
		var ctx = cnv.getContext('2d');
		ctx.drawImage(baseSprite, 0, 0);

		return cnv;
	}

But this is 60fps: (the difference is only in return string.)
	getSprite: function(){
		var baseSprite = g.sprites.getSprite(1231); //returns cached Image object
		
		var cnv = document.createElement('canvas');
			cnv.width = baseSprite.width;
			cnv.height = baseSprite.height;
			
		var ctx = cnv.getContext('2d');
		ctx.drawImage(baseSprite, 0, 0);

		return baseSprite;
	}

I think it's problem width drawImage, which get return value of getSprite. 
P.s. it's on windows 7 32bit system, amd hd5670 gpu.
I've written a test page which reproduces this issue:
http://guac-dev.org/pub/tests/large-move-test.html

Chrome version 17.0.963.83:

   387ms (1.51171875ms per frame)

After updating Chrome to version 18.0.1025.142:

   2616ms (10.21875ms per frame)

After running the updated Chrome with --disable-accelerated-2d-canvas:

   367ms (1.43359375ms per frame)

The above numbers are all from 64-bit Windows 7, but I am also able to reproduce this on my Chromebook. As of the latest update, the above test page takes several minutes to render at 495.2 ms per frame.

Note that because hardware acceleration is now enabled by default in Chrome 18, this regression now affects all users by default.
large-move-test.html
2.0 KB View Download
Cc: junov@chromium.org vangelis@chromium.org bsalomon@chromium.org
Labels: -Area-Undefined Area-Internals Internals-Graphics Feature-GPU-Canvas2D
Owner: senorblanco@chromium.org
Status: Started
OK, I've upstreamed the bug in comment #3 to WebKit as https://bugs.webkit.org/show_bug.cgi?id=83295.

On my machine I see:

460ms non-accelerated
3705ms accelerated before patch
32ms accelerated after patch

I think the original bug is a different one, which was fixed today in WebKit as https://bugs.webkit.org/show_bug.cgi?id=74183.

When those changes roll into chrome, I'll mark this bug as fixed.
OK, just to clarify:  I think there are three separate bugs referenced in these comments.

The original bug was fixed in https://bugs.webkit.org/show_bug.cgi?id=73186 -- I'm seeing 60FPS is both cached and uncached cases.

The bug in comment #2 was (probably) fixed in https://bugs.webkit.org/show_bug.cgi?id=74183, yet to be rolled into Chrome.

And the bug in comment #3 is pending review upstream as https://bugs.webkit.org/show_bug.cgi?id=83295.

(Normally, I'd open three Chrome bugs for these different issues, but since they already have their own WebKit bugs, I won't bother).
Status: Fixed
OK, all patches have landed and rolled in as of Chrome r131073.  yangjin0912, d.narushevich, mike.jumper:  If possible, could you install the Canary channel build to verify that your bugs have been fixed?  It's available at

http://tools.google.com/dlpage/chromesxs

and can install alongside your regular Chrome installation, so no uninstall is necessary.
Confirmed:

352ms non-accelerated
2650ms accelerated
347ms patched, non-accelerated
9ms patched, accelerated
Cc: lafo...@chromium.org
Labels: Mstone-19 Merge-Requested
laforge@:  I can haz merge?

(for WebKit changes:  http://trac.webkit.org/changeset/113345 and http://trac.webkit.org/changeset/113373).

Comment 9 by laforge@google.com, Apr 9 2012

I'd like to see these changes bake in Canary/Dev(from trunk this week) before are considered for merge.

Comment 10 by laforge@google.com, Apr 10 2012

Labels: -Merge-Requested Merge-Rejected
This isn't a regression over 18, I can live w/ it landing in 20.

Comment 11 by laforge@google.com, Apr 10 2012

Labels: -Merge-Rejected Merge-Approved
My brain is fresh w/ seeing lots of OOM w/ SkiaFonts in the stacks.  

I'll grudgingly approve http://trac.webkit.org/changeset/113373, but I'm candidly very risk averse to this area of code.

Comment 12 Deleted

Comment 13 Deleted

I've installed Canary build, checked comment #2 test and it was ok now, but I still have problems with comment #1 described problem.

If im drawing one instance of Image object for many many times on main canvas - it works ok, with 60fps.
But if i draw this same image on small canvas(which is created once and then cached) and then draw small canvas to the main canvas, then its 1fps.

But also i've noticed, that "drawImage(imageToCanvas(image))" case works ok if i want to draw only, for example, for 100times. - then performance is ok.
But if increase it to for example 101 times, then it drop to 1fps in one go.


I just tought, maybe it's not a bug at all, but i'm just overflowing gpu memory?
d.narushevich:  A reduced (but complete!) test case would be very helpful.  It's hard to say what you're encountering from only snippets of code and descriptions of algorithms.

If you could post a self-contained HTML file which demonstrates the performance slowdown you're seeing, that would be awesome.
Ok, so here's reduced test case.(in attachment. uncomment lines in source code)
case #1 - drawing small canvases.
case #2 - drawing image.

My results (Standard Chrome 18.0.1025.152):
  --disable-accelerated-2d-canvas:
  Case #1: 30fps
  Case #2: 30fps

  gpu acc enabled:
  Case #1: smoothly rises from 2 to 10fps
  Case #2: 60fps;

Also notice, i get this results if cache size (N) is 2048, if it's lower, for example, 1024, then in both cases i can get 60fps, but with smooth slow rising in case #1 with gpu enabled.
test.html
1.4 KB View Download

Comment 17 by junov@chromium.org, Apr 11 2012

@d.narushevich: You appear to be hitting the GPU memory limit in case 1. In case 2, because you are reusing the same image over and over, the image stays resident in the GPU memory.  With case 1, the graphics driver is constantly swapping images in and out of GPU memory, which is causing the performance degradation.  I noticed that if you access the 2048 sprites sequentially rather than randomly, performance is much better, at least with an nVidia GPU.  The driver is probably better suited for dealing with regular access patterns (predictive prefetching? contiguous memory access?).  Also, I noticed that the same problem happens in Firefox, except that the threshold is a little higher, perhaps because of the GPU memory consumed by Chrome's compositor.  

When the GPU memory limit is reached, the performance degradation is catastrophic right now.  I think we can do a better job here of degrading more gracefully.  I will spin-off a separate issue for that specific problem.

Comment 18 by junov@chromium.org, Apr 11 2012

New bug  crbug.com/122983 
Based on test case submitted in comment 16.

Comment 19 by k...@google.com, Aug 8 2012

Labels: -Merge-Approved
Removing Merge-Approved from past milestones.
Project Member

Comment 20 by bugdroid1@chromium.org, Oct 13 2012

Labels: Restrict-AddIssueComment-Commit
This issue has been closed for some time. No one will pay attention to new comments.
If you are seeing this bug or have new data, please click New Issue to start a new bug.
Project Member

Comment 21 by bugdroid1@chromium.org, Mar 10 2013

Labels: -Area-Internals -Internals-Graphics -Feature-GPU-Canvas2D -Mstone-19 Cr-Internals-Graphics Cr-Internals-GPU-Canvas2D M-19 Cr-Internals
Project Member

Comment 22 by bugdroid1@chromium.org, Mar 14 2013

Labels: -Restrict-AddIssueComment-Commit Restrict-AddIssueComment-EditIssue
Components: -Internals>Graphics Internals>GPU
Moving old issues out of Internal>Graphics to delete this obsolete component ( crbug.com/685425  for details)
Components: -Internals>Graphics Internals>GPU
Moving old issues out of Internal>Graphics to delete this obsolete component ( crbug.com/685425  for details)

Sign in to add a comment