Positioned descendants of positioned frames escape the child display list to
their parent's positioned descendants list when they don't have a z-index set.
This caused their invalidations to be logged against the incorrect layer.
To fix this, wrap each extra positioned descendant of a fixed-position frame
in its own nsDisplayFixedPosition so they receive their own layers.
A comment in ApplyThebesLayerInvalidation says that it preserves the content
of ThebesLayerInvalidRegion, in case there are multiple container layers for
the same frame. SetHasContainerLayer, however, immediately clears said property.
This was causing invalidations to be lost since Bug 758620 on fixed-position
elements, as they were being separated out onto their own layers but were still
merged in the root scroll layer. This is tracked in Bug 769541.
This fixes the problem by storing the new invalid region in DisplayItemDataEntry
and clearing/setting the ThebesLayerInvalidRegion property in the
UpdateDisplayItemData callback from FrameLayerBuilder::WillEndTransaction.
Introduce a new display-list item 'nsDisplayFixedPosition' that represents
fixed-position elements. This item cannot be merged, which forces fixed
position elements to have their own layer, and has a BuildLayer implementation
that sets the necessary metadata on a Layer to be able to maintain its
position correctly during composition when asynchronously panning and zooming.
Introduce a new display-list item 'nsDisplayFixedPosition' that represents
fixed-position elements. This item cannot be merged, which forces fixed
position elements to have their own layer, and has a BuildLayer implementation
that sets the necessary metadata on a Layer to be able to maintain its
position correctly during composition when asynchronously panning and zooming.
* * *
Bug 539356 - Part 9a - Add new display list invalidation API to nsDisplayItem and implement it. r=roc
* * *
Bug 539356 - Part 9b - Add new frame invalidation API. r=roc
* * *
Bug 539356 - Part 9c - Remove old invalidation code. r=bz
* * *
Bug 539356 - Part 9d - Make SVG support the new invalidation model. r=jwatt
* * *
Bug 539356 - Part 9e - FrameLayerBuilder changes for display list invalidation. r=roc
* * *
Bug 539356 - Part 9f - Compute the invalid area of the layer tree and pass this to the widget. r=roc
* * *
Bug 539356 - Part 9g - Modify MozAfterPaint code to work with the new invalidation model. r=roc
Currently we return an extra out parameter on GetOpaqueRegion. This is ugly and it's also going to be inefficient
because in a followup patch I'm going to avoid calls to GetOpaqueRegion, but we still need to know whether the item
needs a transparent surface. So this patch removes that out parameter. Instead, we rely on the fact that only
Windows' glass-window-background display item needs to force a transparent surface, and there can only be one
of those per window. So we store a reference to it in the nsDisplayListBuilder if there is one, and then we can
efficiently tell if any leaf display item is the one that forces a transparent surface. For display items that
wrap a list, we continue to store whether they need to force a transparent surface in a boolean in the list.
It turns out that calling HasBorder() is especially expensive for themed frames since we call into the theme engine to compute the border, so avoiding it is a nice win.
It turns out that calling HasBorder() is especially expensive for themed frames since we call into the theme engine to compute the border, so avoiding it is a nice win.
Previously we snapped the results of nsDisplayItem::GetBounds and
nsDisplayItem::GetOpaqueRegion internally. By tracking which display items were
inside transforms, we disabled snapping quite conservatively whenever an ancestor
had a transform, which is undesirable.
With this patch, we don't snap inside GetBounds or GetOpaqueRegion, but just return
a boolean flag indicating whether the item will draw with snapping or not. This flag
is conservative so that "true" means we will snap (if the graphics context has a transform
that allows snapping), but "false" means we might or might not snap (so it's always safe
to return false).
FrameLayerBuilder takes over responsibility for snapping item bounds. When it converts
display item bounds to layer pixel coordinates, it checks the snap flag returned from
the display item and checks whether the transform when we draw into the layer will be
a known scale (the ContainerParameters scale factors) plus integer translation. If both
are true, we snap the item bounds when converting to layer pixel coordinates. With
this approach, we can snap item bounds even when the items have ancestors with active
transforms.