Bug 1283236 - don't use ForEachNode() in ApplyDoubleBuffering()
We found that the use of TreeTraversal.h library here (where the root
node is treated as a special case) does not help readability, so revert
to the previous plain implementation
MozReview-Commit-ID: Dp7isl4lNvL
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -482,81 +482,66 @@ MarkLayersHidden(Layer* aLayer, const In
* all layers to the same coordinate system (the "root coordinate system").
* MarkLayersHidden must be called before calling this.
* @param aVisibleRect the rectangle of aLayer that is visible (i.e. not
* clipped and in the dirty rect), in the root coordinate system.
*/
static void
ApplyDoubleBuffering(Layer* aLayer, const IntRect& aVisibleRect)
{
- std::stack<IntRect> visibleRectStack;
- visibleRectStack.push(aVisibleRect);
+ BasicImplData* data = ToData(aLayer);
+ if (data->IsHidden())
+ return;
- ForEachNode<ForwardIterator>(
- aLayer,
- [&aLayer, &visibleRectStack](Layer* layer) {
- BasicImplData* data = ToData(layer);
- if (layer != aLayer) {
- data->SetClipToVisibleRegion(true);
- }
- if (data->IsHidden()) {
- return TraversalFlag::Skip;
- }
-
- IntRect newVisibleRect(visibleRectStack.top());
+ IntRect newVisibleRect(aVisibleRect);
- {
- const Maybe<ParentLayerIntRect>& clipRect = layer->GetLocalClipRect();
- if (clipRect) {
- IntRect cr = clipRect->ToUnknownRect();
- // clipRect is in the container's coordinate system. Get it into the
- // global coordinate system.
- if (layer->GetParent()) {
- Matrix tr;
- if (layer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
- NS_ASSERTION(!ThebesMatrix(tr).HasNonIntegerTranslation(),
- "Parent can only have an integer translation");
- cr += nsIntPoint(int32_t(tr._31), int32_t(tr._32));
- } else {
- NS_ERROR("Parent can only have an integer translation");
- }
- }
- newVisibleRect.IntersectRect(newVisibleRect, cr);
- }
+ {
+ const Maybe<ParentLayerIntRect>& clipRect = aLayer->GetLocalClipRect();
+ if (clipRect) {
+ IntRect cr = clipRect->ToUnknownRect();
+ // clipRect is in the container's coordinate system. Get it into the
+ // global coordinate system.
+ if (aLayer->GetParent()) {
+ Matrix tr;
+ if (aLayer->GetParent()->GetEffectiveTransform().CanDraw2D(&tr)) {
+ NS_ASSERTION(!ThebesMatrix(tr).HasNonIntegerTranslation(),
+ "Parent can only have an integer translation");
+ cr += nsIntPoint(int32_t(tr._31), int32_t(tr._32));
+ } else {
+ NS_ERROR("Parent can only have an integer translation");
}
+ }
+ newVisibleRect.IntersectRect(newVisibleRect, cr);
+ }
+ }
- BasicContainerLayer* container =
- static_cast<BasicContainerLayer*>(layer->AsContainerLayer());
- // Layers that act as their own backbuffers should be drawn to the destination
- // using OP_SOURCE to ensure that alpha values in a transparent window are
- // cleared. This can also be faster than OP_OVER.
- if (!container) {
- data->SetOperator(CompositionOp::OP_SOURCE);
- data->SetDrawAtomically(true);
- return TraversalFlag::Skip;
- } else {
- if (container->UseIntermediateSurface() ||
- !container->ChildrenPartitionVisibleRegion(newVisibleRect)) {
- // We need to double-buffer this container.
- data->SetOperator(CompositionOp::OP_SOURCE);
- container->ForceIntermediateSurface();
- return TraversalFlag::Skip;
- } else {
- visibleRectStack.push(newVisibleRect);
- return TraversalFlag::Continue;
- }
- }
-
- },
- [&visibleRectStack](Layer* layer)
- {
- visibleRectStack.pop();
- return TraversalFlag::Continue;
+ BasicContainerLayer* container =
+ static_cast<BasicContainerLayer*>(aLayer->AsContainerLayer());
+ // Layers that act as their own backbuffers should be drawn to the destination
+ // using OP_SOURCE to ensure that alpha values in a transparent window are
+ // cleared. This can also be faster than OP_OVER.
+ if (!container) {
+ data->SetOperator(CompositionOp::OP_SOURCE);
+ data->SetDrawAtomically(true);
+ } else {
+ if (container->UseIntermediateSurface() ||
+ !container->ChildrenPartitionVisibleRegion(newVisibleRect)) {
+ // We need to double-buffer this container.
+ data->SetOperator(CompositionOp::OP_SOURCE);
+ container->ForceIntermediateSurface();
+ } else {
+ // Tell the children to clip to their visible regions so our assumption
+ // that they don't paint outside their visible regions is valid!
+ for (Layer* child = aLayer->GetFirstChild(); child;
+ child = child->GetNextSibling()) {
+ ToData(child)->SetClipToVisibleRegion(true);
+ ApplyDoubleBuffering(child, newVisibleRect);
}
- );
+ }
+ }
}
void
BasicLayerManager::EndTransaction(DrawPaintedLayerCallback aCallback,
void* aCallbackData,
EndTransactionFlags aFlags)
{
mInTransaction = false;