Closed Bug 1684636 Opened 3 years ago Closed 3 years ago

Poor performance on jackbox.tv (radial gradients)

Categories

(Core :: Graphics: WebRender, defect)

Firefox 86
defect

Tracking

()

RESOLVED FIXED
Performance Impact low

People

(Reporter: kirayahiroz, Unassigned)

References

(Blocks 2 open bugs)

Details

(Keywords: perf:responsiveness, power)

Attachments

(2 files)

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:84.0) Gecko/20100101 Firefox/84.0

Steps to reproduce:

On certain games on Jackbox, Firefox struggles with games that are animation heavy. I can reproduce this on both Windows and Android devices. Chromium based browsers do not suffer from this issue. This is easily reproduced in Jackbox Party Pack 6, Push The Button.

Windows 10 64-bit, i5-6300U + HD520, Nightly 86: https://share.firefox.dev/2Mpqe0R

Android, SD855+, Nightly 86: https://share.firefox.dev/384v2Bh

Android, SD670, Nightly 86: https://share.firefox.dev/3rNT7UO

This affects mobile more as it makes the games unplayable, and Jackbox's intended userbase are mobile players.

I don't have an account for this site and you have to pay for all this games. @Andrew, when get a chance, could you please take a look over these memory reports? Thank you!

Flags: needinfo?(continuation)
Component: Untriaged → Performance
Product: Firefox → Core

The profiles do include memory stuff, but looking at comment 0, it sounds like the complaint here is speed and not memory. I'm not an expert on reading these profiles, but it looks like the bulk of the time is being spent in "renderer".

On the desktop profile, it looks like 95% of the renderer time is being spent taking screenshots for the profiler, so it might be worth redoing the profile here without taking screenshots, unless I'm misreading something.

On the two Android profiles, it looks like the bulk of the renderer time is being spent under GLContextEGL::SwapBuffers(), so I'll move this to the Canvas WebGL component. I don't know if this is part of the implementation of screenshots for the profiler or not, but hopefully somebody who is more familiar with diagnosing Android graphics issues can figure that out from looking at the profile.

Component: Performance → Canvas: WebGL
Flags: needinfo?(continuation)

Jeff, maybe you could take a look at this? Thanks.

Flags: needinfo?(jgilbert)

kirayahiroz, do you see the same when you disable webrender? I assume it's enabled by default for you, so setting gfx.webrender.force-disabled to false in about:config should do it. Please restart Firefox afterward.

Flags: needinfo?(kirayahiroz)

Android, SD855+, Nightly 86: https://share.firefox.dev/384v2Bh

90% of Parent process Renderer thread is waiting on ioclt:

_ioctl
ioctl
android::IPCThreadState::talkWithDriver(bool)
android::IPCThreadState::waitForResponse(android::Parcel*, int*)
android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)
android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)
android::IGraphicBufferProducer::QueueBufferOutput::unflatten(void const*&, unsigned long&, int const*&, unsigned long&)
android::Surface::queueBuffer(ANativeWindowBuffer*, int)
GetSubDriverVersion
InitEsxProfile
InitEsxProfile
android::eglBeginFrameImpl(void*, void*)
eglSwapBuffersWithDamageKHR
mozilla::gl::GLContextEGL::SwapBuffers()
fSwapBuffersWithDamage
mozilla::wr::RenderCompositorEGL::EndFrame(nsTArray<mozilla::wr::Rect<int, mozilla::wr::DevicePixel> > const&)
mozilla::wr::RenderThread::UpdateAndRender(mozilla::wr::WrWindowId, mozilla::layers::BaseTransactionId<mozilla::VsyncIdType> const&, mozilla::TimeStamp const&, bool, mozilla::Maybe<mozilla::gfx::IntSizeTyped<mozilla::gfx::UnknownUnits> > const&, mozilla::Maybe<mozilla::wr::ImageFormat> const&, mozilla::Maybe<mozilla::Range<unsigned char> > const&, bool*)
mozilla::wr::RenderThread::HandleFrameOneDoc(mozilla::wr::WrWindowId, bool)
mozilla::detail::RunnableMethodImpl<mozilla::wr::RenderThread*, void (mozilla::wr::RenderThread::*)(mozilla::wr::WrWindowId, bool), true, (mozilla::RunnableKind)0, mozilla::wr::WrWindowId, bool>::Run()
MessageLoop::RunTask(already_AddRefed<nsIRunnable>)
MessageLoop::DeferOrRunPendingTask(MessageLoop::PendingTask&&)
MessageLoop::DoWork()
base::MessagePumpDefault::Run(base::MessagePump::Delegate*)
MessagePumpDefault::Run
MessageLoop::Run()
base::Thread::ThreadMain()
(root)
Component: Canvas: WebGL → Graphics: WebRender
Flags: needinfo?(jgilbert)

Running with sw-wr shows most of the time being spent drawing radial-gradients.

https://share.firefox.dev/3baLxNX

Summary: Poor performance on jackbox.tv → Poor performance on jackbox.tv (radial gradients)
Flags: needinfo?(gwatson)

While Safari causes nearly no CPU load, Chrome is at 10% for the standalone testcase. In Firefox I can see a constant 30% CPU utilization.

Blocks: power-usage
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: power
Whiteboard: [qf]

I added a log of the radial gradients and sizes that are drawn per frame in this test:

-- batching --=
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1007.29034x916.42175 at (547.6257, 285.57828))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(1524.237x1078.1694 at (237.45772, 123.830505))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(2147.3804x1202.0 at (0.0, 0.0))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))
Add RG Rect(702.78015x715.2252 at (730.3319, 380.8567))

Needs more investigation, a few starting points:

  • Several gradients with the same size - possibly benefit from caching them if they're the same content?
  • Enough gradients of different size that we need to cache them if we do in fact need them at that size.
  • Radial gradients probably assume alpha at the moment, should probably fix that (but prob not relevant in this case).
  • Drawn gradients seem much larger than anything visible - perhaps just a bug, and we should be drawing them at smaller scale?
  • Seems to be a lot more overdraw given what's visible - something we can detect / optimize?
Flags: needinfo?(gwatson)

The gradient prims look mostly similar to:

    SetGradientStops([
     (
      offset: 0,
      color: (
       r: 1,
       g: 1,
       b: 1,
       a: 1,
      ),
     ),// [0]
     (
      offset: 0.9,
      color: (
       r: 1,
       g: 1,
       b: 1,
       a: 1,
      ),
     ),// [1]
     (
      offset: 1,
      color: (
       r: 0,
       g: 0,
       b: 0,
       a: 0,
      ),
     ),
    ]),// [37]
    RadialGradient((
     common: (
      clip_rect: (
       origin: (0, 0),
       size: (2304, 1201.5),
      ),
      clip_id: Clip(0, (1, 2)),
      spatial_id: (4, (1, 2)),
      flags: (
       bits: 1,
      ),
     ),
     bounds: (
      origin: (-348, -299.25),
      size: (2652, 1500.75),
     ),
     gradient: (
      center: (390, 150),
      radius: (1.5, 1.5),
      start_offset: 0,
      end_offset: 1,
      extend_mode: Clamp,
     ),
     tile_size: (600, 600),
     tile_spacing: (0, 0),
    )),// [38]

One possible fix for this is:

If the last stop of a radial gradient has 0 alpha, modify the prim's bounding rect such that it's clamped to the bounds of the gradient center / radius, so it doesn't extend further than any visible pixels.

This is quite a specific hack rather than a general fix, but I think will result in much better performance than other alternatives I can think of.

It's also a relatively simple / trivial change to make.

If the gradient doesn't have any alpha in the stop, we should (if we don't already) detect that the gradient is opaque. This would mean in cases like this where there are multiple gradients the overdraw is kept under control by the z-rejection due to the fragments being opaque.

(In reply to Henrik Skupin (:whimboo) [⌚️UTC+2] from comment #4)

kirayahiroz, do you see the same when you disable webrender? I assume it's enabled by default for you, so setting gfx.webrender.force-disabled to false in about:config should do it. Please restart Firefox afterward.

I can confirm with webrender off, there is no longer any performance issues.

Flags: needinfo?(kirayahiroz)
Severity: -- → S2
Whiteboard: [qf] → [qf:p3:responsiveness]

Can I help move this bug investigation forward with testing procedures?

I have to mention that the test case provided in comment 14 to not show any sign of stuttering on Windows 10 with Nightly v87.0a1 from 2021-02-02, Release v85.0 or ESR v78.7.0esr, but I can observe severe stuttering in Beta v86.0b3 and v86.0b5. This is pretty weird, then I discovered that the affected Beta build had an unexpected compositing profile by default: WebRender (Software D3D11).

TEST RESULTS:

Windows 10:

  • ESR v78.7.0 (default compositing: Direct3D 11 (Advanced Layers)): no stuttering
  • Release v85.0 (default compositing: Direct3D 11): no stuttering
  • Beta v86.0b5 (default compositing: WebRender (Software D3D11)): SEVERE STUTTERING AND PERFORMANCE ISSUES
  • Nightly v87.0a1 (default compositing: WebRender): shows some lite stuttering

Mac OS 11.2:

  • ESR v78.7.0 (default compositing: OpenGL): shows stuttering when moving the cursor over the animation
  • Release v85.0 (default compositing: WebRender): no stuttering or not easily observable
  • Beta v86.0b5 (default compositing: WebRender): no stuttering or not easily observable
  • Nightly v87.0a1 (default compositing: WebRender): shows stuttering when moving the cursor over the animation

Ubuntu 20:

  • ESR v78.7.0 (default compositing: Basic): shows stuttering when moving the cursor over the animation
  • Release v85.0 (default compositing: Basic): shows stuttering when moving the cursor over the animation
  • Beta v86.0b5 (default compositing: WebRender): no stuttering or not easily observable
  • Nightly v87.0a1 (default compositing: WebRender): no stuttering or not easily observable

My test results are pretty diverse. If you would provide me with a way to render a build as affected or unaffected, I could re-test all channels and major platforms and investigate for a possible regressor; Afterward, a fix could be verified. Thank you.

Flags: needinfo?(jmathies)
Flags: needinfo?(gwatson)

I think we have a reasonable understanding of the underlying cause of this problem - we just need to find resources to investigate and implement the possible optimizations in WR.

Flags: needinfo?(gwatson)
Blocks: gfx-triage
Flags: needinfo?(jmathies)
Depends on: 1687977

This was fixed by the radial gradient optimization that landed in bug 1687977.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → FIXED

kirayahiroz, would you mind checking with a recent Firefox 88 beta if it also fixes your reported problem? Thanks!

Flags: needinfo?(kirayahiroz)
No longer blocks: gfx-triage

(In reply to Henrik Skupin (:whimboo) [⌚️UTC+1] from comment #18)

kirayahiroz, would you mind checking with a recent Firefox 88 beta if it also fixes your reported problem? Thanks!

Can confirm it seems to be fixed. No more performance issues on devices tested previously.

Flags: needinfo?(kirayahiroz)
Performance Impact: --- → P3
Whiteboard: [qf:p3:responsiveness]
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: