Closed Bug 638002 Opened 13 years ago Closed 3 years ago

Massive GDI usage and leaks from using Cufon Font replacement

Categories

(Core :: Graphics: Canvas2D, defect)

x86
Windows XP
defect
Not set
critical

Tracking

()

RESOLVED WORKSFORME

People

(Reporter: ppak_98, Unassigned)

References

()

Details

Attachments

(3 files)

User-Agent:       Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b12) Gecko/20100101 Firefox/4.0b12
Build Identifier: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b12) Gecko/20100101 Firefox/4.0b12

When this page is loaded, it causes firefox to use ALL the GDI Objects available to Firefox.  This page exposes numerous problems in a simple test case.

1) The GDI Limit of 10,000 is hit too easily.  Chrome deals with this by opening multiple processes which means each tab can have 10,000 gdi objects.  Firefox on the other hand has all the tab's GDI objects in a SINGLE process which means that it hits the 10,000 GDI object limit MUCH more easily and not only does firefox go berserk, but windows goes crazy too.
2) This code is an example of a situation where the GDI objects are not cleaned up properly.  Once the page is loaded and cleared, over 1500 GDI objects are not released.  Chrome releases ALL the GDI objects when the tab is closed.
3) Cufon should not cause so many GDI objects to be used.  I'm not sure what is going on there, but it's uses twice the GDI objects that Chrome uses for the same page.


Reproducible: Always

Steps to Reproduce:
1. Load the test page and watch the GDI object count hit 10,000
2. Hit reload and watch Firefox redrawing go berserk
3. Close the tab and watch Firefox not release over 1500 GDI objects.


Expected Results:  
Firefox needs to have process separation to deal with the GDI object limit in Windows.  The current method of dealing with GDI objects is completely inadequate and Chrome is FAR better at stability than Firefox because of it.
In case it wasn't clear, the test case is at http://www.yellowseo.com/leaktest.html
I can not reproduce on Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b13pre) Gecko/20110301 Firefox/4.0b13pre ID:20110301030403.
GDI Object is only 61.
I just downloaded the 4.0b13pre and it crashed the browser.  It definately is NOT fixed.  It happens on any version of Firefox on Windows XP, 7 and probably all the ones in between.  What are you using to measure the GDI object count?  

I'm using the task manager.  I go to "view, select columns" and check off GDI objects and see the GDI objects for firefox in my task manager.  It clearly shows over 10,000 objects.
I've tested on three different machines with Windows XP SP3, Windows 7 x64, and Windows 7 x64 SP1 with Firefox 3.6.13, 4b12, and 4 Minefield and they all exhibit the same problems.  I can only conclude that there is something specific to your system that causes it to work properly.  Can you replicate my issues with the latest version of minefield or 4b12?  Every machine I've checked it on seems to have the same problem.  Can you try a different machine?
I can reproduced if disabled D2D/DW.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Product: Firefox → Core
QA Contact: general → general
I tried enabling the D2D/DW to see if the GDI objects issue is fixed and I still get the same problem.

I did the following steps to enable it in Minefield and can't understand why or how you were able to get it to work.

Enter ‘about:config’
Click through the warning, if necessary
Enter gfx.font in the ‘Filter’ box
Double-click on ‘gfx.font_rendering.directwrite.enabled’ to set it to true
Below this, right click and select New > Integer to add a pref setting
Enter ‘mozilla.widget.render-mode’ for the preference name, 6 for the value

I still get the same behavior with D2D/DW
Ok, I was able to replicate Alice's results by forcing the d2d to be enabled.  Odd that it didn't work before I forced it.  It is nice to know that the GDI issue is fixed for Windows Vista and Windows 7 users if they enable it.  It still seems like a major problem for XP users and everyone else until the d2d is enabled by default.
Judging by comments 7 and 8, it seems that this occurs with GDI rendering, regardless of whether GDI or DirectWrite fonts are used. Alice, can you confirm that _disabling_ D2D and explicitly _enabling_ directwrite still shows the problem? That would suggest we're leaking something like device contexts, rather than GDI font objects, for example.

Does this happen with Firefox 3.6, or only 4.0beta? Assuming it's 4.0b-only, does it happen with older betas, or is this a recent regression?
(In reply to comment #9)
> Judging by comments 7 and 8, it seems that this occurs with GDI rendering,
> regardless of whether GDI or DirectWrite fonts are used. Alice, can you confirm
> that _disabling_ D2D and explicitly _enabling_ directwrite still shows the
> problem? That would suggest we're leaking something like device contexts,
> rather than GDI font objects, for example.

The GDI objects overflow and the browser stops working.

Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b13pre) Gecko/20110301 Firefox/4.0b13pre ID:20110301030403

New Profile + user.js as follows,
user_pref("gfx.direct2d.disabled", true);
user_pref("gfx.font_rendering.directwrite.enabled", true);

Graphics
  Adapter Description : ATI Radeon HD 4300/4500 Series     
  Vendor ID : 1002
  Device ID : 954f
  Adapter RAM : 512
  Adapter Drivers : aticfx64 aticfx64 aticfx32 aticfx32 atiumd64 atidxx64 atiumdag atidxx32 atiumdva atiumd6a atitmm64
  Driver Version : 8.821.0.0
  Driver Date : 1-26-2011
  Direct2D Enabled : false
  DirectWrite Enabled : true (6.1.7601.17514, font cache n/a)
  WebGL Renderer : Google Inc. -- ANGLE -- OpenGL ES 2.0 (ANGLE 0.0.0.541)
  GPU Accelerated Windows : 1/1 Direct3D 9

> Does this happen with Firefox 3.6, or only 4.0beta? 
> Assuming it's 4.0b-only,
> does it happen with older betas, or is this a recent regression?

It happens Firefox3.6 too.
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.15pre) Gecko/20110301 Namoroka/3.6.15pre ID:20110301033302
This seems to be a GDI resource issue related to <canvas>. This testcase tries to add 5000 <canvas> elements to the document, and draw a simple diagonal line in each (so that we can see them). It works fine in Chrome, but crashes Firefox; Task Manager shows that the GDI resource count hits 10,000, and then the process vanishes.

Reducing the count to 4000 allows the document to load in Firefox; it appears that GDI resource consumption is 2 per <canvas>, plus a couple of hundred overhead (assuming no other windows/tabs are open), so with 4000 canvas elements we require about 8,200 GDI resources, which works OK for me (but obviously opening two such tabs would crash).
Component: General → Canvas: 2D
QA Contact: general → canvas.2d
(In reply to comment #11)
> Created attachment 516260 [details]
> reduced testcase - attempt to draw 5000 simple <canvas>es

Oops, I attached a copy where the count is actually 4000, not 5000, so it won't necessarily crash right away.
OS: Windows 7 → Windows XP
It looks like each <canvas> has its own nsCanvasRenderingContext2D, and (under GDI) each of these uses two GDI resources until it gets deleted. And to make things worse, the contexts don't get deleted immediately the page is closed; they're cleaned up later by garbage collection. So this means that a page with, say, 2500 <canvas> elements will crash the browser if the user hits Reload, for example, because the new set of 2500 contexts (5000 GDI resources) will be created while the old ones are still hanging around.

Because Cufon replaces each word with an individual <canvas> element, it's not hard to hit these limits if a page uses Cufon for substantial amounts of text.
One other thing that is important is that there is also a bug with the garbage collection or something is holding on to the gdi objects in some situations related to cufon.  Even after the tab is closed, there were still a large amount of GDI objects not being released back.  I was not able to create a test case that I could upload, but I have a web page in development which does cause it to happen consistently.  If I disable Cufon on my page, it works ok.  If I enable it, the gdi leak occurs.  But if I do it on a page without my other code, it does not cause the leak.  I believe it has to do with dynamically loading in new content into a div with jquery and then applying the cufon.replace on all the content with some of the content already having a reference.  I believe in that situation the gdi objects are not garbage collected.  The reason I discovered this problem is that I was doing web development and kept reloading a page with cufon and the gdi objects kept going up without being garbage collected.  As the GDI object count went up, the browser slowed down and eventually crashed.
If you have a testcase showing the GC issue (does the one in the url field?), please file a separate bug on that?
Unfortunately, the only working test case I have is my code, which is not public yet.  I tried to recreate it in a smaller test case with this code, but I must have missed something because it seems to be doing some garbage collection.  However, with this test case, even though it is doing some garbage collection, it still shows a substantial amount of GDI objects that are not being released back to firefox long after the tab is closed.

Following the reporter's steps I am able to confirm that the issues doesn't happen anymore on Windows 10 on any of the current versions of Firefox Nightly 87.0a1 (2021-02-18), beta 86.0 and release 85.0.2. Cross-checked with Chrome and has the same behaviour; there aren't any crashes either as Comment 12 suggests it.

Closing this issue as Resolved > Worksforme.
Feel free to re-open or file a new bug if this issue reoccurs again.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: