Closed Bug 1421481 Opened 2 years ago Closed 2 years ago

The mobile limit of 2 WebGL contexts per principal breaks GL-based images on tier-1 Google Search pages.


(Core :: Canvas: WebGL, defect, P3)




Tracking Status
firefox59 --- fixed


(Reporter: wisniewskit, Assigned: jnicol)


(Blocks 1 open bug, )


(Whiteboard: [webcompat][gfx-noted])


(2 files)

It seems that Fennec has a hard-coded limit of 2 WebGL contexts per principal (kMaxWebGLContextsPerPrincipal in dom/canvas/WebGLContext.cpp). The comment there states that this is because some devices cannot handle more than 8 GL contexts.

However, the Google Search pages are using more contexts than that for their tier-1 (currently served to Chrome) variants, which is causing a webcompat issue where tapping on a image thumbnail in user reviews causes a never-ended loading indicator, due to a page script error caused by the GL context limit. If one builds a custom Fennec nightly with the limit raised (I just went with 16), the error goes away.

Chrome for Android seems to have a higher limit, but I'm not sure if it's a hard-coded value or one chosen via some heuristic. Either way, it would be good to head off webcompat issues by adopting their solution, since if Google are using it for their tier-1 content, then it's likely other sites will do so as well (though I'm not sure if many sites currently experience this kind of breakage).

In the interest of brevity, I'll re-post the STR from the issue here:
1. Alter Fennec's UA to a Chrome mobile UA (one quick way is to install my addon:
2. Visit
3. Scroll down to one of the images in the user reviews and tap on it.
4. Observe the never-ending loading indicator, and console warnings of too many GL contexts (and the obscure GL-related script errors that break the load).
Milan, who would be the best person to comment on this? Thanks.
Flags: needinfo?(milan)
Chrome's implementation of context limiting is here I think:

Looks like we support 8 concurrent contexts on OS_ANDROID, 16 elsewhere. The limit appears to be per-renderer-process, so approximately that equates to per-site.
Flags: needinfo?(milan) → needinfo?(jnicol)
Whiteboard: [webcompat] → [webcompat][gfx-noted]
These limits were added a long time ago so I'm unsure how strict they were at the time. I presume nowadays we can afford to relax them somewhat, especially if it's to match Chrome. We could always re-tighten the limits for certain devices if there are issues.

I'd say increase the constants to 8 and 16. Snorp, do you agree?
Flags: needinfo?(jnicol) → needinfo?(snorp)
Sounds ok to me.
Flags: needinfo?(snorp)
Comment on attachment 8933263 [details]
Bug 1421481 - Increase allowed number of webgl contexts on mobile.
Attachment #8933263 - Flags: review?(snorp) → review+
Milan asked that this be made a pref in case there are any issues.
Pushed by
Increase allowed number of webgl contexts on mobile. r=snorp
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla59
Man, I really need to be watching my own component.
This sounds fine.
Assignee: nobody → jnicol
Comment on attachment 8933263 [details]
Bug 1421481 - Increase allowed number of webgl contexts on mobile.

::: dom/canvas/WebGLContext.cpp:1157
(Diff revision 3)
>  }
>  void
>  WebGLContext::LoseOldestWebGLContextIfLimitExceeded()
>  {
> +    const size_t maxWebGLContexts = gfxPrefs::WebGLMaxContexts();

These should probably be uint32_t to match the prefs. `auto` would handle this.

::: dom/canvas/WebGLContext.cpp:1162
(Diff revision 3)
> -    // some mobile devices can't have more than 8 GL contexts overall
> -    const size_t kMaxWebGLContextsPerPrincipal = 2;
> -    const size_t kMaxWebGLContexts             = 4;
> -#else
> -    const size_t kMaxWebGLContextsPerPrincipal = 16;
> +    const size_t maxWebGLContexts = gfxPrefs::WebGLMaxContexts();
> +    size_t maxWebGLContextsPerPrincipal = gfxPrefs::WebGLMaxContextsPerPrincipal();
> +
> +    // maxWebGLContextsPerPrincipal must be less than maxWebGLContexts
> +    MOZ_ASSERT(maxWebGLContextsPerPrincipal < maxWebGLContexts);
> +    maxWebGLContextsPerPrincipal = std::min(maxWebGLContextsPerPrincipal, maxWebGLContexts - 1);

Why is this -1?

::: gfx/thebes/gfxPrefs.h:743
(Diff revision 3)
>    DECL_GFX_PREF(Live, "webgl.enable-webgl2",                   WebGL2Enabled, bool, true);
>    DECL_GFX_PREF(Live, "webgl.force-enabled",                   WebGLForceEnabled, bool, false);
>    DECL_GFX_PREF(Once, "webgl.force-layers-readback",           WebGLForceLayersReadback, bool, false);
>    DECL_GFX_PREF(Live, "webgl.force-index-validation",          WebGLForceIndexValidation, int32_t, 0);
>    DECL_GFX_PREF(Live, "webgl.lose-context-on-memory-pressure", WebGLLoseContextOnMemoryPressure, bool, false);
> +  DECL_GFX_PREF(Once, "webgl.max-contexts",                    WebGLMaxContexts, uint32_t, 32);

Why is this `Once`? Default should be `Live`.
Flags: needinfo?(jnicol)
Comment on attachment 8933263 [details]
Bug 1421481 - Increase allowed number of webgl contexts on mobile.

I'll post the patch to fix these issues outwith mozreview because I think it'd just get confused
Comment on attachment 8933263 [details]
Bug 1421481 - Increase allowed number of webgl contexts on mobile.

> These should probably be uint32_t to match the prefs. `auto` would handle this.


> Why is this -1?

The previous code asserted maxWebGLContextsPerPrincipal < maxWebGLContexts, so I was making sure that still held. I'm guessing that's not necessary so I'll drop the -1 and make the assertion <=

> Why is this `Once`? Default should be `Live`.

Flags: needinfo?(jnicol)
Attachment #8939556 - Flags: review?(jgilbert)
Attachment #8939556 - Flags: review?(jgilbert) → review+
Pushed by
Post-review follow-up for webgl context initialization. r=jgilbert
You need to log in before you can comment on or make changes to this bug.