Closed Bug 1581650 Opened 5 years ago Closed 5 years ago

Provide picture cache dirty rects in WR render outputs

Categories

(Core :: Graphics: WebRender, enhancement)

enhancement
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla71
Tracking Status
firefox71 --- fixed

People

(Reporter: gw, Assigned: gw)

References

Details

Attachments

(1 file)

No description provided.

This provides the internal device-space dirty rects calculated
during picture cache updates to the external render() method.

This allows clients to provide these to OS partial present APIs,
to reduce power usage and improve performance.

In this initial implementation, if a scroll or scale of the main
picture cache has occurred, the dirty rect will be the entire
screen. This should ensure correctness. In future, we can handle
this case by supplying the picture cache transforms to the OS
compositor integration.

However, the dirty rects will be valid for any non-scroll cases,
such as animations or video playback. This should result in some
significant power savings and performance improvements for these
use cases.

Assignee: nobody → gwatson

API looks good for partial present. The patch expose dirty rects, but non-dirty rects area are also rendered by WR with the patch. Is it possible not to render non-dirty rects by WR and WR exposes rects that are actually rendered to default frame buffer? It could reduce GPU tasks at WR and RenderCompositorANGLE.

The following has related information.
https://docs.microsoft.com/en-us/windows/win32/direct3ddxgi/dxgi-1-2-presentation-improvements

Blocks: 1575159
Pushed by gwatson@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/113d50437293
Provide picture cache dirty rects in WR render outputs r=nical
Status: NEW → RESOLVED
Closed: 5 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla71

Do you mean change WR to scissor out the main framebuffer so that it only draws into the dirty regions?

This should be possible, but I think WR would need to know from Gecko how many dirty rects this GPU / OS supports. Otherwise, WR may only render into the set of dirty rects, but if the GPU only supports a single, unioned dirty rect, then WR won't have drawn those other parts.

Does that sound right?

Just to clarify on the above - WR already scissors to dirty rect boundaries when updating the contents of the cached tiles. But the extra step mentioned above would be also applying this scissor rect when compositing the tile into the framebuffer.

So, I'm thinking we add something like the following to RendererOptions, which would be set by Gecko when initializing WR:

struct PresentConfig {
    max_dirty_rects: usize,
    // todo: when using DC / CA, we'll also have max_layers, and perhaps capabilities of OS compositor layers, such as scrolling / transform support
}

And then, I'll add support to WR for only doing partial updates of the framebuffer when this config is enabled, which should be a very small patch.

Thoughts?

Cool! It seems to work. There is one concern about it. We could not use partial present at first rendering after frame buffer allocation. It happens at WR first rendering and WR rendering after frame buffer re-allocation(during resizing window). We could know if it happens just before Renderer::render() call. Can the case be handled?

(In reply to Glenn Watson [:gw] from comment #6)

So, I'm thinking we add something like the following to RendererOptions, which would be set by Gecko when initializing WR

CoreAnimation cannot support this. I don't think we can squeeze CoreAnimation and IDXGISwapChain1::Present1 into the same API. So how about something like this:

enum PresentConfig {
  /// The entire framebuffer needs to be drawn on every frame.
  NoPartialPresent,
  /// WebRender is allowed to update only parts of the framebuffer (with a rect count limit given below) and leave garbage in the other parts. The up-to-date framebuffer region is exposed in `RenderResults::dirty_rects`.
  PartialPresentWithMaxDirtyRects(usize)
}

I was thinking that platforms without partial present would just have set max_dirty_rects to be 0, but the enum above is more explicit, so that sounds good. I'm sure we'll need to change the interface once we start using DC/CA scrolling layers anyway :)

For sure!

Sotaro, Markus - I added a very hacky implementation of what we discussed in https://bugzilla.mozilla.org/show_bug.cgi?id=1582624 - this might be useful to take a look at proposed API and do some experiments / measurements with partial present + WR?

I will plan to have a proper, cleanup up implementation of this next week anyway, but thought it might be worth hacking something together for some early testing.

You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: