Poor performance on jackbox.tv (radial gradients)
Categories
(Core :: Graphics: WebRender, defect)
Tracking
()
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.
Comment 1•3 years ago
|
||
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!
Updated•3 years ago
|
Comment 2•3 years ago
|
||
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.
Comment 3•3 years ago
|
||
Jeff, maybe you could take a look at this? Thanks.
Comment 4•3 years ago
|
||
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.
Comment 5•3 years ago
|
||
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)
Comment 6•3 years ago
|
||
Comment 7•3 years ago
|
||
Running with sw-wr shows most of the time being spent drawing radial-gradients.
Updated•3 years ago
|
Updated•3 years ago
|
Comment 8•3 years ago
|
||
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.
Comment 9•3 years ago
|
||
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?
Comment 10•3 years ago
|
||
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]
Comment 11•3 years ago
|
||
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.
Comment 12•3 years ago
|
||
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.
Reporter | ||
Comment 13•3 years ago
|
||
(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 inabout:config
should do it. Please restart Firefox afterward.
I can confirm with webrender off, there is no longer any performance issues.
Updated•3 years ago
|
Comment 14•3 years ago
|
||
Updated•3 years ago
|
Comment 15•3 years ago
|
||
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.
Comment 16•3 years ago
|
||
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.
Updated•3 years ago
|
Comment 17•3 years ago
|
||
This was fixed by the radial gradient optimization that landed in bug 1687977.
Comment 18•3 years ago
|
||
kirayahiroz, would you mind checking with a recent Firefox 88 beta if it also fixes your reported problem? Thanks!
Updated•3 years ago
|
Reporter | ||
Comment 19•3 years ago
|
||
(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.
Updated•2 years ago
|
Description
•