Closed Bug 1592038 Opened 4 months ago Closed 2 months ago

Share depth buffers between IOSurfaces on macOS in the WR OS compositor configuration

Categories

(Core :: Graphics: WebRender, enhancement, P3)

All
macOS
enhancement

Tracking

()

RESOLVED FIXED
mozilla73
Tracking Status
firefox73 --- fixed

People

(Reporter: mstange, Assigned: mstange)

References

(Blocks 1 open bug)

Details

Attachments

(4 files)

The current OS compositor implementation on macOS creates a separate depth buffer for each allocated IOSurface. This wastes a lot of memory: The depth buffer is only used during rendering within a tile. Once rendering is done, it has no useful output.
At a minimum, we should share depth buffers between the IOSurfaces of the same tile (i.e. across the tile's swap chain). But since we're also drawing to one tile at a time, we could even share depth buffers between all tiles of the same size.
We just need to add a comment to the Compositor trait that says that depth buffer contents are not preserved between draws, and that the depth buffer contents of a freshly-bound surface needs to be considered garbage and should be cleared before use.

Priority: -- → P3
Assignee: nobody → mstange
Attachment #9111820 - Attachment description: Bug 1592038 - Allow sharing depth and stencil buffers between multiple MozFramebuffers. → Bug 1592038 - Allow sharing depth and stencil buffers between multiple MozFramebuffers. r=jgilbert
Attachment #9111821 - Attachment description: Bug 1592038 - Share depth buffers across IOSurface framebuffers with the same size. → Bug 1592038 - Share depth buffers across IOSurface framebuffers with the same size. r=jgilbert

This makes a staggering difference to the amount of memory consumed by WebRender in the OS compositor configuration: It saves between 100MB and 200MB per window!

I took some measurements right after startup, with a single mozilla.org tab that was being session-restored.
Example profile without depth buffer sharing: https://perfht.ml/2LdV0Xa (252MB taken up by SurfacePool)
Example profile with depth buffer sharing: https://perfht.ml/37YQO7l (142MB taken up by SurfacePool)

The memory difference is also visible in Activity Monitor. I did 3 runs each and got the following values:
Without depth buffer sharing: 557MB, 530MB, 566MB
With depth buffer sharing: 348MB, 330MB, 342MB
These differences are even higher than the differences that SurfacePoolCA::LockedPool::EstimateTotalMemory() calculates!

Status: NEW → ASSIGNED
Attached image depth-sharing-330MB.png

compare the "Nightly" process

Posting in-bug for better visibility, but an important note on depth-buffer reuse:

FRAMEBUFFER_INCOMPLETE_DIMENSIONS is actually ES2-only!

ES3 and (at least) GL3.2core+ are designed to allow rendering to any common subrect of the framebuffer's attachments. (e.g. reuse a 1920x1080 scratch depth buffer with your 300x150 color layer!)

FYI :mstange

Flags: needinfo?(mstange)

Oh, important addendum to that though: It probably won't work well on ANGLE, since D3D11 does not support differing rendertarget attachment sizes. They surely support the functionality to hit ES3 conformance, but it's probably not a fastpath.

That's pretty cool, but I don't think I need it. WebRender has three tile sizes it uses for everything: 1024x512, 512x16, and 16x512. So in theory I could have one 1024x512 buffer and use it for all three tile sizes, but it doesn't seem worth the trouble: 2 * 4 * 512 * 16B = 64KiB.

Flags: needinfo?(mstange)
Pushed by mstange@themasta.com:
https://hg.mozilla.org/integration/autoland/rev/a5fea8db70db
Allow sharing depth and stencil buffers between multiple MozFramebuffers. r=jgilbert
https://hg.mozilla.org/integration/autoland/rev/bcf15799e3a2
Share depth buffers across IOSurface framebuffers with the same size. r=jgilbert
Status: ASSIGNED → RESOLVED
Closed: 2 months ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla73
You need to log in before you can comment on or make changes to this bug.