Bug 626962. Part 0: Don't do empty transactions when painting to a widget's non-retaining layer manager. r=tnikkel,a=blocker
authorRobert O'Callahan <robert@ocallahan.org>
Thu, 03 Feb 2011 21:45:23 +1300
changeset 61835 b4e9a17e7fe2f98f46c528af4ead056527e1d7b7
parent 61834 e1d2e090c9a6aa796f2bc4aff97a8e497ee81d4d
child 61836 2a13f323dfa05b3a249110a06e0ff219c795c982
push id1
push userroot
push dateTue, 10 Dec 2013 15:46:25 +0000
reviewerstnikkel, blocker
bugs626962
milestone2.0b12pre
Bug 626962. Part 0: Don't do empty transactions when painting to a widget's non-retaining layer manager. r=tnikkel,a=blocker
layout/base/nsLayoutUtils.cpp
layout/base/nsPresShell.cpp
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -1382,17 +1382,17 @@ nsLayoutUtils::PaintFrame(nsIRenderingCo
 		                       !(aFlags & PAINT_HIDE_CARET));
   nsDisplayList list;
   if (aFlags & PAINT_IN_TRANSFORM) {
     builder.SetInTransform(PR_TRUE);
   }
   if (aFlags & PAINT_SYNC_DECODE_IMAGES) {
     builder.SetSyncDecodeImages(PR_TRUE);
   }
-  if (aFlags & PAINT_WIDGET_LAYERS || aFlags & PAINT_TO_WINDOW) {
+  if (aFlags & (PAINT_WIDGET_LAYERS | PAINT_TO_WINDOW)) {
     builder.SetPaintingToWindow(PR_TRUE);
   }
   if (aFlags & PAINT_IGNORE_SUPPRESSION) {
     builder.IgnorePaintSuppression();
   }
   if (aRenderingContext &&
       aRenderingContext->ThebesContext()->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING) {
     builder.SetSnappingEnabled(PR_FALSE);
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6133,32 +6133,43 @@ PresShell::Paint(nsIView*           aDis
   NS_ASSERTION(aWidgetToPaint, "Can't paint without a widget");
 
   nsPresContext* presContext = GetPresContext();
   AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
 
   nsIFrame* frame = aPaintDefaultBackground
       ? nsnull : static_cast<nsIFrame*>(aDisplayRoot->GetClientData());
 
-  LayerManager* layerManager = aWidgetToPaint->GetLayerManager();
+  bool isRetainingManager;
+  LayerManager* layerManager =
+    aWidgetToPaint->GetLayerManager(&isRetainingManager);
   NS_ASSERTION(layerManager, "Must be in paint event");
   layerManager->BeginTransaction();
 
-  if (frame) {
+  if (frame && isRetainingManager) {
+    // Try to do an empty transaction, if the frame tree does not
+    // need to be updated. Do not try to do an empty transaction on
+    // a non-retained layer manager (like the BasicLayerManager that
+    // draws the window title bar on Mac), because a) it won't work
+    // and b) below we don't want to clear NS_FRAME_UPDATE_LAYER_TREE,
+    // that will cause us to forget to update the real layer manager!
     if (!(frame->GetStateBits() & NS_FRAME_UPDATE_LAYER_TREE)) {
       if (layerManager->EndEmptyTransaction()) {
         frame->UpdatePaintCountForPaintedPresShells();
         presContext->NotifyDidPaintForSubtree();
         
         return NS_OK;
       }
     }
     
+
+    frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
+  }
+  if (frame) {
     frame->ClearPresShellsFromLastPaint();
-    frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
   }
 
   nscolor bgcolor = ComputeBackstopColor(aDisplayRoot);
 
   if (frame && aViewToPaint == aDisplayRoot) {
     // Defer invalidates that are triggered during painting, and discard
     // invalidates of areas that are already being repainted.
     // The layer system can trigger invalidates during painting