PL_ARENA_ALLOCATE(NS_REINTERPRET_CAST(void*,newPop), &aPool, sizeof(DisplayListElement2)); PL_ARENA_ALLOCATE(NS_REINTERPRET_CAST(void*,newPush), &aPool, sizeof(DisplayListElement2));
ARENA_ALLOCATE(newPop, &aPool, DisplayListElement2); ARENA_ALLOCATE(newPush, &aPool, DisplayListElement2);
static void SortByZOrder(DisplayZTreeNode *aNode, nsVoidArray &aBuffer, nsVoidArray &aMergeTmp,                         PRBool aForceSort, PLArenaPool &aPool){  PRBool autoZIndex = PR_TRUE;  nsInt64 explicitZIndex = 0;  if (nsnull != aNode->mView) {    // Hixie says only non-translucent elements can have z-index:auto    autoZIndex = aNode->mView->GetZIndexIsAuto() && aNode->mView->GetOpacity() == 1.0f;    explicitZIndex = BuildExtendedZIndex(aNode->mView);  }  if (nsnull == aNode->mZChild) {    if (nsnull != aNode->mDisplayElement) {      aBuffer.AppendElement(aNode->mDisplayElement);      aNode->mDisplayElement->mZIndex = explicitZIndex;      aNode->mDisplayElement = nsnull;    }    return;  }  DisplayZTreeNode *child;  PRInt32 childStartIndex = aBuffer.Count();  for (child = aNode->mZChild; nsnull != child; child = child->mZSibling) {    SortByZOrder(child, aBuffer, aMergeTmp, PR_FALSE, aPool);  }  PRInt32 childEndIndex = aBuffer.Count();  PRInt32 sortStartIndex = childStartIndex;  PRInt32 sortEndIndex = childEndIndex;  PRBool hasClip = PR_FALSE;  DisplayListElement2* ePush = nsnull;  DisplayListElement2* ePop = nsnull;  // When we sort the children by z-index, don't sort any PUSH_ or POP_ instructions  // which are bracketing the children.  while (sortEndIndex - sortStartIndex >= 2) {    DisplayListElement2* childElem =      NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(sortStartIndex));    if (childElem->mView == aNode->mView) {      if (childElem->mFlags & PUSH_CLIP) {        hasClip = PR_TRUE;        // remember where the push and pop instructions are so we can        // duplicate them later, if necessary        ePush = NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(sortStartIndex));        ePop = NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(sortEndIndex - 1));        sortStartIndex++;        sortEndIndex--;      } else if (childElem->mFlags & PUSH_FILTER) {        NS_ASSERTION(!autoZIndex, "FILTER cannot apply to z-index:auto view");        sortStartIndex++;        sortEndIndex--;      } else {        break;      }    } else {      break;    }  }  if (hasClip) {    ApplyZOrderStableSort(aBuffer, aMergeTmp, sortStartIndex, sortEndIndex);        if (autoZIndex && sortEndIndex - sortStartIndex >= 1) {      // If we're an auto-z-index, then we have to worry about the possibility that some of      // our children may be moved by the z-sorter beyond the bounds of the PUSH...POP clip      // instructions. So basically, we ensure that around every group of children of      // equal z-index, there is a PUSH...POP element pair with the same z-index. The stable      // z-sorter will not break up such a group.      // Note that if we're not an auto-z-index set, then our children will never be broken      // up so we don't need to do this.      // We also don't have to worry if we have no real children.      // We don't have to do the same thing for PUSH_FILTER/POP_FILTER because      // a filter always corresponds to non-auto z-index; there is no way children      // can be sorted beyond the PUSH/POP instructions.      DisplayListElement2* eFirstChild = NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(sortStartIndex));      ePush->mZIndex = eFirstChild->mZIndex;      DisplayListElement2* eLastChild = NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(sortEndIndex - 1));      ePop->mZIndex = eLastChild->mZIndex;      DisplayListElement2* e = eFirstChild;      for (PRInt32 i = sortStartIndex; i < sortEndIndex - 1; i++) {        DisplayListElement2* eNext = NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(i + 1));        NS_ASSERTION(e->mZIndex <= eNext->mZIndex, "Display Z-list is not sorted!!");        if (e->mZIndex != eNext->mZIndex) {          // need to insert a POP for the last sequence and a PUSH for the next sequence          DisplayListElement2 *newPop, *newPush;          PL_ARENA_ALLOCATE(NS_REINTERPRET_CAST(void*,newPop), &aPool, sizeof(DisplayListElement2));          PL_ARENA_ALLOCATE(NS_REINTERPRET_CAST(void*,newPush), &aPool, sizeof(DisplayListElement2));          *newPop = *ePop;          newPop->mZIndex = e->mZIndex;          *newPush = *ePush;          newPush->mZIndex = eNext->mZIndex;          aBuffer.InsertElementAt(newPop, i + 1);          aBuffer.InsertElementAt(newPush, i + 2);          i += 2;          childEndIndex += 2;          sortEndIndex += 2;        }        e = eNext;      }    }  } else if (aForceSort || !autoZIndex) {    ApplyZOrderStableSort(aBuffer, aMergeTmp, sortStartIndex, sortEndIndex);  }  for (PRInt32 i = childStartIndex; i < childEndIndex; i++) {    DisplayListElement2* element = NS_STATIC_CAST(DisplayListElement2*, aBuffer.ElementAt(i));    if (!autoZIndex) {      element->mZIndex = explicitZIndex;    } else if (aNode->mView->IsTopMost()) {      // promote children to topmost if this view is topmost      element->mZIndex |= nsInt64(1);    }  }}