Closed Bug 994554 Opened 10 years ago Closed 3 years ago

Avoid double buffering the BasicCompositor whenever possible

Categories

(Core :: Graphics: Layers, defect)

29 Branch
x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: mattwoodrow, Unassigned)

References

(Blocks 1 open bug)

Details

On some operating systems, the contents of our window can get copied to the display in the middle of a paint/composite.

If we touch the same pixel twice (like when we have overlapping layers), then we risk getting visible flickering as some screen refreshes only show a partial layer tree. This is a very real issue on Windows (like DWM) at least.

To solve this, we redirect all compositing to a temporary surface, and then copy that to the window in a single pass.

BasicCompositor does this here: http://mxr.mozilla.org/mozilla-central/source/gfx/layers/basic/BasicCompositor.cpp#432

This can be really expensive though (since we're allocating a screen-sized surface every frame, and then adding a copy of that size), so there's a few things we can do to combat this:

1) Don't double buffer unless the OS actually needs us to. The widget code figures this out as a value of BufferMode, see http://mxr.mozilla.org/mozilla-central/ident?i=BUFFERED

We pass this into BasicLayerManager, we could do something very similar, probably via the nsIWidget::StartRemoteDrawing call in BasicCompositor::BeginFrame.

This should be really easy, but it won't actually have any effect on windows or linux which is probably all we care about.

2) Only double buffering overlapping layers. We only need to double buffer when there actually is overlap. BasicLayerManager does some analysis to figure out if any layers actually overlap within the current invalid region and which minimal sub-tree of the layer tree needs to be double buffered to fix it. This massively reduces the rate that we have to double buffer, and reduces the area when we do.

The BasicLayerManager code for this is: http://mxr.mozilla.org/mozilla-central/source/gfx/layers/basic/BasicLayerManager.cpp#469

3) Cache the buffer surface. Allocating this each composite is expensive, we can probably just cache it (with an exipiry timeout). We used to do this in BasicLayerManager, but it looks like it got broken with the Moz2D conversion.
See Also: → 1019856
See Also: → 1019867
See Also: → 1019870
I have split this bug into three bugs: bug 1019856, bug 1019867 and bug 1019870 - one per proposed solution.
Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.