Bug 641599. Completely flush all ThebesLayers whenever the appunits-per-dev-pixel ratio changes. r=tnikkel
authorRobert O'Callahan <robert@ocallahan.org>
Mon, 11 Apr 2011 16:57:29 -0400
changeset 67872 1a53dc7c5c20
parent 67846 f65b79eeabd4
child 67873 71fa806ffd26
push id19449
push usereakhgari@mozilla.com
push dateTue, 12 Apr 2011 00:25:08 +0000
treeherdermozilla-central@0cfe6840e0a4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs641599
milestone2.2a1pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 641599. Completely flush all ThebesLayers whenever the appunits-per-dev-pixel ratio changes. r=tnikkel
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -92,16 +92,17 @@
 #include "nsIAppShell.h"
 #include "prenv.h"
 #include "nsIPrivateDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsObjectFrame.h"
 #include "nsTransitionManager.h"
 #include "mozilla/dom/Element.h"
 #include "nsIFrameMessageManager.h"
+#include "FrameLayerBuilder.h"
 
 #ifdef MOZ_SMIL
 #include "nsSMILAnimationController.h"
 #endif // MOZ_SMIL
 
 #ifdef IBMBIDI
 #include "nsBidiPresUtils.h"
 #endif // IBMBIDI
@@ -111,18 +112,17 @@
 
 // Needed for Start/Stop of Image Animation
 #include "imgIContainer.h"
 #include "nsIImageLoadingContent.h"
 
 //needed for resetting of image service color
 #include "nsLayoutCID.h"
 
-using mozilla::TimeDuration;
-using mozilla::TimeStamp;
+using namespace mozilla;
 using namespace mozilla::dom;
 
 static nscolor
 MakeColorPref(const char *colstr)
 {
   PRUint32 red, green, blue;
   nscolor colorref;
 
@@ -767,39 +767,56 @@ nsPresContext::GetUserPreferences()
 
   // We don't need to force reflow: either we are initializing a new
   // prescontext or we are being called from UpdateAfterPreferencesChanged()
   // which triggers a reflow anyway.
   SetBidi(bidiOptions, PR_FALSE);
 }
 
 void
+nsPresContext::AppUnitsPerDevPixelChanged()
+{
+  nsIFrame* rootFrame = mShell->FrameManager()->GetRootFrame();
+  if (rootFrame) {
+    // FrameLayerBuilder caches invalidation-related values that depend on the
+    // appunits-per-dev-pixel ratio, so ensure that all ThebesLayer drawing
+    // is completely flushed.
+    FrameLayerBuilder::InvalidateThebesLayersInSubtree(rootFrame);
+  }
+
+  mDeviceContext->FlushFontCache();
+
+  // All cached style data must be recomputed.
+  if (HasCachedStyleData()) {
+    MediaFeatureValuesChanged(PR_TRUE);
+    RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
+  }
+}
+
+void
 nsPresContext::PreferenceChanged(const char* aPrefName)
 {
   nsDependentCString prefName(aPrefName);
   if (prefName.EqualsLiteral("layout.css.dpi") ||
       prefName.EqualsLiteral("layout.css.devPixelsPerPx")) {
     PRInt32 oldAppUnitsPerDevPixel = AppUnitsPerDevPixel();
     if (mDeviceContext->CheckDPIChange() && mShell) {
-      mDeviceContext->FlushFontCache();
-
       // Re-fetch the view manager's window dimensions in case there's a deferred
       // resize which hasn't affected our mVisibleArea yet
       nscoord oldWidthAppUnits, oldHeightAppUnits;
       nsIViewManager* vm = mShell->GetViewManager();
       vm->GetWindowDimensions(&oldWidthAppUnits, &oldHeightAppUnits);
       float oldWidthDevPixels = oldWidthAppUnits/oldAppUnitsPerDevPixel;
       float oldHeightDevPixels = oldHeightAppUnits/oldAppUnitsPerDevPixel;
 
       nscoord width = NSToCoordRound(oldWidthDevPixels*AppUnitsPerDevPixel());
       nscoord height = NSToCoordRound(oldHeightDevPixels*AppUnitsPerDevPixel());
       vm->SetWindowDimensions(width, height);
 
-      MediaFeatureValuesChanged(PR_TRUE);
-      RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
+      AppUnitsPerDevPixelChanged();
     }
     return;
   }
   if (StringBeginsWith(prefName, NS_LITERAL_CSTRING("font."))) {
     // Changes to font family preferences don't change anything in the
     // computed style data, so the style system won't generate a reflow
     // hint for us.  We need to do that manually.
 
@@ -1309,37 +1326,34 @@ nsPresContext::GetDefaultFont(PRUint8 aF
 }
 
 void
 nsPresContext::SetFullZoom(float aZoom)
 {
   if (!mShell || mFullZoom == aZoom) {
     return;
   }
+
   // Re-fetch the view manager's window dimensions in case there's a deferred
   // resize which hasn't affected our mVisibleArea yet
   nscoord oldWidthAppUnits, oldHeightAppUnits;
   mShell->GetViewManager()->GetWindowDimensions(&oldWidthAppUnits, &oldHeightAppUnits);
   float oldWidthDevPixels = oldWidthAppUnits / float(mCurAppUnitsPerDevPixel);
   float oldHeightDevPixels = oldHeightAppUnits / float(mCurAppUnitsPerDevPixel);
-  if (mDeviceContext->SetPixelScale(aZoom)) {
-    mDeviceContext->FlushFontCache();
-  }
+  mDeviceContext->SetPixelScale(aZoom);
 
   NS_ASSERTION(!mSupressResizeReflow, "two zooms happening at the same time? impossible!");
   mSupressResizeReflow = PR_TRUE;
 
   mFullZoom = aZoom;
   mShell->GetViewManager()->
     SetWindowDimensions(NSToCoordRound(oldWidthDevPixels * AppUnitsPerDevPixel()),
                         NSToCoordRound(oldHeightDevPixels * AppUnitsPerDevPixel()));
-  if (HasCachedStyleData()) {
-    MediaFeatureValuesChanged(PR_TRUE);
-    RebuildAllStyleData(NS_STYLE_HINT_REFLOW);
-  }
+
+  AppUnitsPerDevPixelChanged();
 
   mSupressResizeReflow = PR_FALSE;
 
   mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel();
 }
 
 void
 nsPresContext::SetImageLoaders(nsIFrame* aTargetFrame,
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -1024,16 +1024,18 @@ protected:
   NS_HIDDEN_(void) UpdateAfterPreferencesChanged();
   static NS_HIDDEN_(void) PrefChangedUpdateTimerCallback(nsITimer *aTimer, void *aClosure);
 
   NS_HIDDEN_(void) GetUserPreferences();
   NS_HIDDEN_(void) GetFontPreferences();
 
   NS_HIDDEN_(void) UpdateCharSet(const nsAFlatCString& aCharSet);
 
+  void AppUnitsPerDevPixelChanged();
+
   PRBool MayHavePaintEventListener();
 
   void HandleRebuildUserFontSet() {
     mPostedFlushUserFontSet = PR_FALSE;
     FlushUserFontSet();
   }
 
   PRBool HavePendingInputEvent();