Bug 942483 - Port paint-dumping to android/b2g. r=gal
authorBenoit Girard <b56girard@gmail.com>
Sat, 23 Nov 2013 17:44:18 -0500
changeset 171939 b6a8c9ded5b06211bc86d9b7bee5aff0ab80bde1
parent 171938 c3226714968f287d7b7f469c7e63f6f9f6a6dac2
child 171940 d280a1c64f762159c0f3dcd334f6b8f784ed2d3b
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgal
bugs942483
milestone28.0a1
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 942483 - Port paint-dumping to android/b2g. r=gal
gfx/layers/Layers.cpp
gfx/layers/composite/ContentHost.cpp
gfx/layers/composite/ImageHost.cpp
gfx/layers/composite/TiledContentHost.cpp
gfx/layers/ipc/CompositorParent.cpp
gfx/thebes/gfxASurface.h
layout/base/FrameLayerBuilder.cpp
layout/base/nsDisplayList.cpp
layout/base/nsDisplayList.h
layout/base/nsLayoutDebugger.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsRefreshDriver.cpp
view/src/nsViewManager.cpp
xpcom/glue/nsCRTGlue.cpp
xpcom/glue/nsDebug.h
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1134,30 +1134,32 @@ template <typename T>
 void WriteSnapshotLinkToDumpFile(T* aObj, FILE* aFile)
 {
   if (!aObj) {
     return;
   }
   nsCString string(aObj->Name());
   string.Append("-");
   string.AppendInt((uint64_t)aObj);
-  fprintf(aFile, "href=\"javascript:ViewImage('%s')\"", string.BeginReading());
+  fprintf_stderr(aFile, "href=\"javascript:ViewImage('%s')\"", string.BeginReading());
 }
 
 template <typename T>
 void WriteSnapshotToDumpFile_internal(T* aObj, gfxASurface* aSurf)
 {
   nsCString string(aObj->Name());
   string.Append("-");
   string.AppendInt((uint64_t)aObj);
-  if (gfxUtils::sDumpPaintFile)
-    fprintf(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
+  if (gfxUtils::sDumpPaintFile) {
+    fprintf_stderr(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
+  }
   aSurf->DumpAsDataURL(gfxUtils::sDumpPaintFile);
-  if (gfxUtils::sDumpPaintFile)
-    fprintf(gfxUtils::sDumpPaintFile, "\";");
+  if (gfxUtils::sDumpPaintFile) {
+    fprintf_stderr(gfxUtils::sDumpPaintFile, "\";");
+  }
 }
 
 void WriteSnapshotToDumpFile(Layer* aLayer, gfxASurface* aSurf)
 {
   WriteSnapshotToDumpFile_internal(aLayer, aSurf);
 }
 
 void WriteSnapshotToDumpFile(LayerManager* aManager, gfxASurface* aSurf)
@@ -1171,71 +1173,67 @@ void WriteSnapshotToDumpFile(Compositor*
   WriteSnapshotToDumpFile_internal(aCompositor, surf);
 }
 #endif
 
 void
 Layer::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
 {
   if (aDumpHtml) {
-    fprintf(aFile, "<li><a id=\"%p\" ", this);
+    fprintf_stderr(aFile, "<li><a id=\"%p\" ", this);
 #ifdef MOZ_DUMP_PAINTING
     if (GetType() == TYPE_CONTAINER || GetType() == TYPE_THEBES) {
       WriteSnapshotLinkToDumpFile(this, aFile);
     }
 #endif
-    fprintf(aFile, ">");
+    fprintf_stderr(aFile, ">");
   }
   DumpSelf(aFile, aPrefix);
 
 #ifdef MOZ_DUMP_PAINTING
   if (AsLayerComposite() && AsLayerComposite()->GetCompositableHost()) {
     AsLayerComposite()->GetCompositableHost()->Dump(aFile, aPrefix, aDumpHtml);
   }
 #endif
 
   if (aDumpHtml) {
-    fprintf(aFile, "</a>");
+    fprintf_stderr(aFile, "</a>");
   }
 
   if (Layer* mask = GetMaskLayer()) {
     nsAutoCString pfx(aPrefix);
     pfx += "  Mask layer: ";
     mask->Dump(aFile, pfx.get(), aDumpHtml);
   }
 
   if (Layer* kid = GetFirstChild()) {
     nsAutoCString pfx(aPrefix);
     pfx += "  ";
     if (aDumpHtml) {
-      fprintf(aFile, "<ul>");
+      fprintf_stderr(aFile, "<ul>");
     }
     kid->Dump(aFile, pfx.get(), aDumpHtml);
     if (aDumpHtml) {
-      fprintf(aFile, "</ul>");
+      fprintf_stderr(aFile, "</ul>");
     }
   }
 
   if (aDumpHtml) {
-    fprintf(aFile, "</li>");
+    fprintf_stderr(aFile, "</li>");
   }
   if (Layer* next = GetNextSibling())
     next->Dump(aFile, aPrefix, aDumpHtml);
 }
 
 void
 Layer::DumpSelf(FILE* aFile, const char* aPrefix)
 {
   nsAutoCString str;
   PrintInfo(str, aPrefix);
-  if (!aFile || aFile == stderr) {
-    printf_stderr("%s\n", str.get());
-  } else {
-    fprintf(aFile, "%s\n", str.get());
-  }
+  fprintf_stderr(aFile, "%s\n", str.get());
 }
 
 void
 Layer::Log(const char* aPrefix)
 {
   if (!IsLogEnabled())
     return;
 
@@ -1402,54 +1400,54 @@ ReadbackLayer::PrintInfo(nsACString& aTo
 
 void
 LayerManager::Dump(FILE* aFile, const char* aPrefix, bool aDumpHtml)
 {
   FILE* file = FILEOrDefault(aFile);
 
 #ifdef MOZ_DUMP_PAINTING
   if (aDumpHtml) {
-    fprintf(file, "<ul><li><a ");
+    fprintf_stderr(file, "<ul><li><a ");
     WriteSnapshotLinkToDumpFile(this, file);
-    fprintf(file, ">");
+    fprintf_stderr(file, ">");
   }
 #endif
   DumpSelf(file, aPrefix);
 #ifdef MOZ_DUMP_PAINTING
   if (aDumpHtml) {
-    fprintf(file, "</a>");
+    fprintf_stderr(file, "</a>");
   }
 #endif
 
   nsAutoCString pfx(aPrefix);
   pfx += "  ";
   if (!GetRoot()) {
-    fprintf(file, "%s(null)", pfx.get());
+    fprintf_stderr(file, "%s(null)", pfx.get());
     if (aDumpHtml) {
-      fprintf(file, "</li></ul>");
+      fprintf_stderr(file, "</li></ul>");
     }
     return;
   }
 
   if (aDumpHtml) {
-    fprintf(file, "<ul>");
+    fprintf_stderr(file, "<ul>");
   }
   GetRoot()->Dump(file, pfx.get(), aDumpHtml);
   if (aDumpHtml) {
-    fprintf(file, "</ul></li></ul>");
+    fprintf_stderr(file, "</ul></li></ul>");
   }
   fputc('\n', file);
 }
 
 void
 LayerManager::DumpSelf(FILE* aFile, const char* aPrefix)
 {
   nsAutoCString str;
   PrintInfo(str, aPrefix);
-  fprintf(FILEOrDefault(aFile), "%s\n", str.get());
+  fprintf_stderr(FILEOrDefault(aFile), "%s\n", str.get());
 }
 
 void
 LayerManager::Log(const char* aPrefix)
 {
   if (!IsLogEnabled())
     return;
 
--- a/gfx/layers/composite/ContentHost.cpp
+++ b/gfx/layers/composite/ContentHost.cpp
@@ -255,30 +255,30 @@ ContentHostBase::Dump(FILE* aFile,
                       bool aDumpHtml)
 {
   if (!aDumpHtml) {
     return;
   }
   if (!aFile) {
     aFile = stderr;
   }
-  fprintf(aFile, "<ul>");
+  fprintf_stderr(aFile, "<ul>");
   if (mDeprecatedTextureHost) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, "<li> <a href=");
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, "<li> <a href=");
     DumpDeprecatedTextureHost(aFile, mDeprecatedTextureHost);
-    fprintf(aFile, "> Front buffer </a></li> ");
+    fprintf_stderr(aFile, "> Front buffer </a></li> ");
   }
   if (mDeprecatedTextureHostOnWhite) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, "<li> <a href=");
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, "<li> <a href=");
     DumpDeprecatedTextureHost(aFile, mDeprecatedTextureHostOnWhite);
-    fprintf(aFile, "> Front buffer on white </a> </li> ");
+    fprintf_stderr(aFile, "> Front buffer on white </a> </li> ");
   }
-  fprintf(aFile, "</ul>");
+  fprintf_stderr(aFile, "</ul>");
 }
 
 #endif
 
 ContentHostSingleBuffered::~ContentHostSingleBuffered()
 {
   DestroyTextures();
   DestroyFrontHost();
@@ -811,30 +811,30 @@ ContentHostDoubleBuffered::Dump(FILE* aF
 {
   ContentHostBase::Dump(aFile, aPrefix, aDumpHtml);
   if (!aDumpHtml) {
     return;
   }
   if (!aFile) {
     aFile = stderr;
   }
-  fprintf(aFile, "<ul>");
+  fprintf_stderr(aFile, "<ul>");
   if (mBackHost) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, "<li> <a href=");
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, "<li> <a href=");
     DumpDeprecatedTextureHost(aFile, mBackHost);
-    fprintf(aFile, " >Back buffer</a></li>");
+    fprintf_stderr(aFile, " >Back buffer</a></li>");
   }
   if (mBackHostOnWhite) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, "<li> <a href=");
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, "<li> <a href=");
     DumpDeprecatedTextureHost(aFile, mBackHostOnWhite);
-    fprintf(aFile, " >Back buffer on white</a> </li>");
+    fprintf_stderr(aFile, " >Back buffer on white</a> </li>");
   }
-  fprintf(aFile, "</ul>");
+  fprintf_stderr(aFile, "</ul>");
 }
 #endif
 
 LayerRenderState
 ContentHostBase::GetRenderState()
 {
   LayerRenderState result = mDeprecatedTextureHost->GetRenderState();
 
--- a/gfx/layers/composite/ImageHost.cpp
+++ b/gfx/layers/composite/ImageHost.cpp
@@ -176,21 +176,21 @@ void
 ImageHost::Dump(FILE* aFile,
                 const char* aPrefix,
                 bool aDumpHtml)
 {
   if (!aFile) {
     aFile = stderr;
   }
   if (mFrontBuffer) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, aDumpHtml ? "<ul><li>TextureHost: "
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, aDumpHtml ? "<ul><li>TextureHost: "
                              : "TextureHost: ");
     DumpTextureHost(aFile, mFrontBuffer);
-    fprintf(aFile, aDumpHtml ? " </li></ul> " : " ");
+    fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " ");
   }
 }
 #endif
 
 LayerRenderState
 ImageHost::GetRenderState()
 {
   if (mFrontBuffer) {
@@ -386,21 +386,21 @@ void
 DeprecatedImageHostSingle::Dump(FILE* aFile,
                                 const char* aPrefix,
                                 bool aDumpHtml)
 {
   if (!aFile) {
     aFile = stderr;
   }
   if (mDeprecatedTextureHost) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, aDumpHtml ? "<ul><li>DeprecatedTextureHost: "
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, aDumpHtml ? "<ul><li>DeprecatedTextureHost: "
                              : "DeprecatedTextureHost: ");
     DumpDeprecatedTextureHost(aFile, mDeprecatedTextureHost);
-    fprintf(aFile, aDumpHtml ? " </li></ul> " : " ");
+    fprintf_stderr(aFile, aDumpHtml ? " </li></ul> " : " ");
   }
 }
 
 already_AddRefed<gfxImageSurface>
 DeprecatedImageHostSingle::GetAsSurface()
 {
   return mDeprecatedTextureHost->GetAsSurface();
 }
--- a/gfx/layers/composite/TiledContentHost.cpp
+++ b/gfx/layers/composite/TiledContentHost.cpp
@@ -326,24 +326,24 @@ TiledContentHost::Dump(FILE* aFile,
 {
   if (!aFile) {
     aFile = stderr;
   }
 
   TiledLayerBufferComposite::Iterator it = mVideoMemoryTiledBuffer.TilesBegin();
   TiledLayerBufferComposite::Iterator stop = mVideoMemoryTiledBuffer.TilesEnd();
   if (aDumpHtml) {
-    fprintf(aFile, "<ul>");
+    fprintf_stderr(aFile, "<ul>");
   }
   for (;it != stop; ++it) {
-    fprintf(aFile, "%s", aPrefix);
-    fprintf(aFile, aDumpHtml ? "<li> <a href=" : "Tile ");
+    fprintf_stderr(aFile, "%s", aPrefix);
+    fprintf_stderr(aFile, aDumpHtml ? "<li> <a href=" : "Tile ");
     DumpDeprecatedTextureHost(aFile, it->mDeprecatedTextureHost);
-    fprintf(aFile, aDumpHtml ? " >Tile</a></li>" : " ");
+    fprintf_stderr(aFile, aDumpHtml ? " >Tile</a></li>" : " ");
   }
     if (aDumpHtml) {
-    fprintf(aFile, "</ul>");
+    fprintf_stderr(aFile, "</ul>");
   }
 }
 #endif
 
 } // namespace
 } // namespace
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -549,18 +549,18 @@ CompositorParent::CompositeInTransaction
 
   RenderTraceLayers(mLayerManager->GetRoot(), "0000");
 
   mCompositionManager->ComputeRotation();
 
 #ifdef MOZ_DUMP_PAINTING
   static bool gDumpCompositorTree = false;
   if (gDumpCompositorTree) {
-    fprintf(stdout, "Painting --- compositing layer tree:\n");
-    mLayerManager->Dump(stdout, "", false);
+    printf_stderr("Painting --- compositing layer tree:\n");
+    mLayerManager->Dump();
   }
 #endif
   mLayerManager->EndEmptyTransaction();
 
 #ifdef COMPOSITOR_PERFORMANCE_WARNING
   if (mExpectedComposeTime + TimeDuration::FromMilliseconds(15) < TimeStamp::Now()) {
     printf_stderr("Compositor: Composite took %i ms.\n",
                   15 + (int)(TimeStamp::Now() - mExpectedComposeTime).ToMilliseconds());
--- a/gfx/thebes/gfxASurface.h
+++ b/gfx/thebes/gfxASurface.h
@@ -1,20 +1,16 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_ASURFACE_H
 #define GFX_ASURFACE_H
 
-#ifdef MOZ_DUMP_PAINTING
- #define MOZ_DUMP_IMAGES
-#endif
-
 #include "mozilla/MemoryReporting.h"
 #include "gfxTypes.h"
 #include "mozilla/Scoped.h"
 #include "nscore.h"
 
 #ifdef MOZILLA_INTERNAL_API
 #include "nsStringFwd.h"
 #else
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -175,17 +175,17 @@ public:
     MOZ_COUNT_CTOR(LayerManagerData);
   }
   ~LayerManagerData() {
     MOZ_COUNT_DTOR(LayerManagerData);
   }
  
 #ifdef DEBUG_DISPLAY_ITEM_DATA
   void Dump(const char *aPrefix = "") {
-    printf("%sLayerManagerData %p\n", aPrefix, this);
+    printf_stderr("%sLayerManagerData %p\n", aPrefix, this);
     nsAutoCString prefix;
     prefix += aPrefix;
     prefix += "  ";
     mDisplayItems.EnumerateEntries(
         FrameLayerBuilder::DumpDisplayItemDataForFrame, (void*)prefix.get());
   }
 #endif
 
@@ -894,17 +894,17 @@ InvalidatePostTransformRegion(ThebesLaye
   // to the ThebesLayer's own coordinates
   nsIntRegion rgn = aRegion;
   rgn.MoveBy(-aTranslation);
   aLayer->InvalidateRegion(rgn);
 #ifdef MOZ_DUMP_PAINTING
   if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
     nsAutoCString str;
     AppendToString(str, rgn);
-    printf("Invalidating layer %p: %s\n", aLayer, str.get());
+    printf_stderr("Invalidating layer %p: %s\n", aLayer, str.get());
   }
 #endif
 }
 
 static void
 InvalidatePostTransformRegion(ThebesLayer* aLayer, const nsRect& aRect, 
                               const DisplayItemClip& aClip,
                               const nsIntPoint& aTranslation)
@@ -962,17 +962,17 @@ FrameLayerBuilder::RemoveFrameFromLayerM
   }
 
 #ifdef DEBUG_DISPLAY_ITEM_DATA
   if (array->Length()) {
     LayerManagerData *rootData = array->ElementAt(0)->mParent;
     while (rootData->mParent) {
       rootData = rootData->mParent;
     }
-    printf("Removing frame %p - dumping display data\n", aFrame);
+    printf_stderr("Removing frame %p - dumping display data\n", aFrame);
     rootData->Dump();
   }
 #endif
 
   for (uint32_t i = 0; i < array->Length(); ++i) {
     DisplayItemData* data = array->ElementAt(i);
 
     ThebesLayer* t = data->mLayer->AsThebesLayer();
@@ -1052,17 +1052,17 @@ FrameLayerBuilder::ProcessRemovedDisplay
   if (!data->mUsed) {
     // This item was visible, but isn't anymore.
     FrameLayerBuilder* layerBuilder = static_cast<FrameLayerBuilder*>(aUserArg);
 
     ThebesLayer* t = data->mLayer->AsThebesLayer();
     if (t) {
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", data->mDisplayItemKey, data->mFrameList[0], t);
+        printf_stderr("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", data->mDisplayItemKey, data->mFrameList[0], t);
       }
 #endif
       InvalidatePostTransformRegion(t,
                                     data->mGeometry->ComputeInvalidationRegion(),
                                     data->mClip,
                                     layerBuilder->GetLastPaintOffset(t));
     }
     return PL_DHASH_REMOVE;
@@ -1111,21 +1111,21 @@ FrameLayerBuilder::DumpDisplayItemDataFo
   if (data->mOptLayer) {
     str += nsPrintfCString(", OptLayer %p", data->mOptLayer.get());
   }
   if (data->mInactiveManager) {
     str += nsPrintfCString(", InactiveLayerManager %p", data->mInactiveManager.get());
   }
   str += "\n";
 
-  printf("%s", str.get());
+  printf_stderr("%s", str.get());
     
   if (data->mInactiveManager) {
     prefix += "  ";
-    printf("%sDumping inactive layer info:\n", prefix.get());
+    printf_stderr("%sDumping inactive layer info:\n", prefix.get());
     LayerManagerData* lmd = static_cast<LayerManagerData*>
       (data->mInactiveManager->GetUserData(&gLayerManagerUserData));
     lmd->Dump(prefix.get());
   }
 #endif
   return PL_DHASH_NEXT;
 }
 
@@ -1347,17 +1347,17 @@ ResetScrollPositionForLayerPixelAlignmen
   }
 }
 
 static void
 InvalidateEntireThebesLayer(ThebesLayer* aLayer, const nsIFrame* aAnimatedGeometryRoot)
 {
 #ifdef MOZ_DUMP_PAINTING
   if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-    printf("Invalidating entire layer %p\n", aLayer);
+    printf_stderr("Invalidating entire layer %p\n", aLayer);
   }
 #endif
   nsIntRect invalidate = aLayer->GetValidRegion().GetBounds();
   aLayer->InvalidateRegion(invalidate);
   ResetScrollPositionForLayerPixelAlignment(aAnimatedGeometryRoot);
 }
 
 already_AddRefed<ThebesLayer>
@@ -1397,25 +1397,25 @@ ContainerState::CreateOrRecycleThebesLay
       InvalidateEntireThebesLayer(layer, aAnimatedGeometryRoot);
 #ifndef MOZ_ANDROID_OMTC
       didResetScrollPositionForLayerPixelAlignment = true;
 #endif
     }
     if (!data->mRegionToInvalidate.IsEmpty()) {
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("Invalidating deleted frame content from layer %p\n", layer.get());
+        printf_stderr("Invalidating deleted frame content from layer %p\n", layer.get());
       }
 #endif
       layer->InvalidateRegion(data->mRegionToInvalidate);
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
         nsAutoCString str;
         AppendToString(str, data->mRegionToInvalidate);
-        printf("Invalidating layer %p: %s\n", layer.get(), str.get());
+        printf_stderr("Invalidating layer %p: %s\n", layer.get(), str.get());
       }
 #endif
       data->mRegionToInvalidate.SetEmpty();
     }
 
     // We do not need to Invalidate these areas in the widget because we
     // assume the caller of InvalidateThebesLayerContents has ensured
     // the area is invalidated in the widget.
@@ -2048,19 +2048,19 @@ ContainerState::FindThebesLayerFor(nsDis
 
 #ifdef MOZ_DUMP_PAINTING
 static void
 DumpPaintedImage(nsDisplayItem* aItem, gfxASurface* aSurf)
 {
   nsCString string(aItem->Name());
   string.Append("-");
   string.AppendInt((uint64_t)aItem);
-  fprintf(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
+  fprintf_stderr(gfxUtils::sDumpPaintFile, "array[\"%s\"]=\"", string.BeginReading());
   aSurf->DumpAsDataURL(gfxUtils::sDumpPaintFile);
-  fprintf(gfxUtils::sDumpPaintFile, "\";");
+  fprintf_stderr(gfxUtils::sDumpPaintFile, "\";");
 }
 #endif
 
 static void
 PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
                    LayerManager* aManager,
                    nsDisplayItem* aItem,
                    gfxContext* aContext,
@@ -2391,17 +2391,17 @@ ContainerState::InvalidateForLayerChange
     // Invalidate the old bounds in the old layer and new bounds in the new layer.
     ThebesLayer* t = oldLayer->AsThebesLayer();
     if (t) {
       // Note that whenever the layer's scale changes, we invalidate the whole thing,
       // so it doesn't matter whether we are using the old scale at last paint
       // or a new scale here
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("Display item type %s(%p) changed layers %p to %p!\n", aItem->Name(), aItem->Frame(), t, aNewLayer);
+        printf_stderr("Display item type %s(%p) changed layers %p to %p!\n", aItem->Name(), aItem->Frame(), t, aNewLayer);
       }
 #endif
       InvalidatePostTransformRegion(t,
           oldGeometry->ComputeInvalidationRegion(),
           *oldClip,
           mLayerBuilder->GetLastPaintOffset(t));
     }
     if (aNewLayer) {
@@ -2434,27 +2434,27 @@ ContainerState::InvalidateForLayerChange
   nsRegion combined;
   nsPoint shift = aTopLeft - data->mLastAnimatedGeometryRootOrigin;
   if (!oldLayer) {
     // This item is being added for the first time, invalidate its entire area.
     //TODO: We call GetGeometry again in AddThebesDisplayItem, we should reuse this.
     combined = aClip.ApplyNonRoundedIntersection(aGeometry->ComputeInvalidationRegion());
 #ifdef MOZ_DUMP_PAINTING
     if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-      printf("Display item type %s(%p) added to layer %p!\n", aItem->Name(), aItem->Frame(), aNewLayer);
+      printf_stderr("Display item type %s(%p) added to layer %p!\n", aItem->Name(), aItem->Frame(), aNewLayer);
     }
 #endif
   } else if (isInvalid || (aItem->IsInvalid(invalid) && invalid.IsEmpty())) {
     // Either layout marked item as needing repainting, invalidate the entire old and new areas.
     combined = oldClip->ApplyNonRoundedIntersection(oldGeometry->ComputeInvalidationRegion());
     combined.MoveBy(shift);
     combined.Or(combined, aClip.ApplyNonRoundedIntersection(aGeometry->ComputeInvalidationRegion()));
 #ifdef MOZ_DUMP_PAINTING
     if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-      printf("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n", aItem->Name(), aItem->Frame(), aNewLayer);
+      printf_stderr("Display item type %s(%p) (in layer %p) belongs to an invalidated frame!\n", aItem->Name(), aItem->Frame(), aNewLayer);
     }
 #endif
   } else {
     // Let the display item check for geometry changes and decide what needs to be
     // repainted.
     oldGeometry->MoveBy(shift);
     aItem->ComputeInvalidationRegion(mBuilder, oldGeometry, &combined);
     oldClip->AddOffsetAndComputeDifference(shift, oldGeometry->ComputeInvalidationRegion(),
@@ -2471,17 +2471,17 @@ ContainerState::InvalidateForLayerChange
     // Restrict invalidation to the clipped region
     nsRegion clip;
     if (aClip.ComputeRegionInClips(oldClip, shift, &clip)) {
       combined.And(combined, clip);
     }
 #ifdef MOZ_DUMP_PAINTING
     if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
       if (!combined.IsEmpty()) {
-        printf("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), aItem->Frame(), aNewLayer);
+        printf_stderr("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), aItem->Frame(), aNewLayer);
       }
     }
 #endif
   }
   if (!combined.IsEmpty()) {
     aItem->NotifyRenderingChanged();
     InvalidatePostTransformRegion(newThebesLayer,
         combined.ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
@@ -2578,17 +2578,17 @@ FrameLayerBuilder::AddThebesDisplayItem(
       if (aLayerState == LAYER_SVG_EFFECTS) {
         invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem->Frame(),
                                                                         aItem->ToReferenceFrame(),
                                                                         invalid.GetBounds());
       }
       if (!invalid.IsEmpty()) {
 #ifdef MOZ_DUMP_PAINTING
         if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-          printf("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->Frame(), aLayer);
+          printf_stderr("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->Frame(), aLayer);
         }
 #endif
         if (hasClip) {
           invalid.And(invalid, intClip);
         }
 
         invalid.ScaleRoundOut(thebesData->mXScale, thebesData->mYScale);
         InvalidatePostTransformRegion(aLayer, invalid,
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -2229,17 +2229,17 @@ nsDisplayThemedBackground::~nsDisplayThe
   MOZ_COUNT_DTOR(nsDisplayThemedBackground);
 #endif
 }
 
 #ifdef MOZ_DUMP_PAINTING
 void
 nsDisplayThemedBackground::WriteDebugInfo(FILE *aOutput)
 {
-  fprintf(aOutput, "(themed, appearance:%d) ", mAppearance);
+  fprintf_stderr(aOutput, "(themed, appearance:%d) ", mAppearance);
 }
 #endif
 
 void
 nsDisplayThemedBackground::HitTest(nsDisplayListBuilder* aBuilder,
                                   const nsRect& aRect,
                                   HitTestState* aState,
                                   nsTArray<nsIFrame*> *aOutFrames)
@@ -4708,37 +4708,37 @@ nsDisplaySVGEffects::PrintEffects(FILE* 
 {
   nsIFrame* firstFrame =
     nsLayoutUtils::FirstContinuationOrSpecialSibling(mFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
   bool isOK = true;
   nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
   bool first = true;
-  fprintf(aOutput, " effects=(");
+  fprintf_stderr(aOutput, " effects=(");
   if (mFrame->StyleDisplay()->mOpacity != 1.0f) {
     first = false;
-    fprintf(aOutput, "opacity(%f)", mFrame->StyleDisplay()->mOpacity);
+    fprintf_stderr(aOutput, "opacity(%f)", mFrame->StyleDisplay()->mOpacity);
   }
   if (clipPathFrame) {
     if (!first) {
-      fprintf(aOutput, ", ");
+      fprintf_stderr(aOutput, ", ");
     }
-    fprintf(aOutput, "clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
+    fprintf_stderr(aOutput, "clip(%s)", clipPathFrame->IsTrivial() ? "trivial" : "non-trivial");
     first = false;
   }
   if (effectProperties.GetFilterFrame(&isOK)) {
     if (!first) {
-      fprintf(aOutput, ", ");
+      fprintf_stderr(aOutput, ", ");
     }
-    fprintf(aOutput, "filter");
+    fprintf_stderr(aOutput, "filter");
     first = false;
   }
   if (effectProperties.GetMaskFrame(&isOK)) {
     if (!first) {
-      fprintf(aOutput, ", ");
+      fprintf_stderr(aOutput, ", ");
     }
-    fprintf(aOutput, "mask");
+    fprintf_stderr(aOutput, "mask");
   }
-  fprintf(aOutput, ")");
+  fprintf_stderr(aOutput, ")");
 }
 #endif
 
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -2150,17 +2150,17 @@ public:
   {
     const nsDisplayItemBoundsGeometry* geometry = static_cast<const nsDisplayItemBoundsGeometry*>(aGeometry);
     ComputeInvalidationRegionDifference(aBuilder, geometry, aInvalidRegion);
   }
 
   NS_DISPLAY_DECL_NAME("BackgroundColor", TYPE_BACKGROUND_COLOR)
 #ifdef MOZ_DUMP_PAINTING
   virtual void WriteDebugInfo(FILE *aOutput) MOZ_OVERRIDE {
-    fprintf(aOutput, "(rgba %d,%d,%d,%d)", 
+    fprintf_stderr(aOutput, "(rgba %d,%d,%d,%d)", 
             NS_GET_R(mColor), NS_GET_G(mColor),
             NS_GET_B(mColor), NS_GET_A(mColor));
 
   }
 #endif
 
 protected:
   const nsStyleBackground* mBackgroundStyle;
@@ -2484,17 +2484,17 @@ public:
   {
     // We don't need to compute an invalidation region since we have LayerTreeInvalidation
   }
   virtual bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
   bool NeedsActiveLayer();
   NS_DISPLAY_DECL_NAME("Opacity", TYPE_OPACITY)
 #ifdef MOZ_DUMP_PAINTING
   virtual void WriteDebugInfo(FILE *aOutput) MOZ_OVERRIDE {
-    fprintf(aOutput, "(opacity %f)", mFrame->StyleDisplay()->mOpacity);
+    fprintf_stderr(aOutput, "(opacity %f)", mFrame->StyleDisplay()->mOpacity);
   }
 #endif
 
   bool CanUseAsyncAnimations(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
 };
 
 class nsDisplayMixBlendMode : public nsDisplayWrapList {
 public:
--- a/layout/base/nsLayoutDebugger.cpp
+++ b/layout/base/nsLayoutDebugger.cpp
@@ -122,26 +122,26 @@ nsLayoutDebugger::GetStyleSize(nsIPresSh
 #ifdef MOZ_DUMP_PAINTING
 static int sPrintDisplayListIndent = 0;
 
 static void
 PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
                    FILE* aOutput, bool aDumpHtml)
 {
   if (aDumpHtml) {
-    fprintf(aOutput, "<ul>");
+    fprintf_stderr(aOutput, "<ul>");
   }
 
   for (nsDisplayItem* i = aList.GetBottom(); i != nullptr; i = i->GetAbove()) {
     if (aDumpHtml) {
-      fprintf(aOutput, "<li>");
+      fprintf_stderr(aOutput, "<li>");
     } else {
       sPrintDisplayListIndent ++;
       for (int indent = 0; indent < sPrintDisplayListIndent; indent++) {
-        fprintf(aOutput, "  ");
+        fprintf_stderr(aOutput, "  ");
       }
     }
     nsIFrame* f = i->Frame();
     nsAutoString fName;
 #ifdef DEBUG
     f->GetFrameName(fName);
 #endif
     bool snap;
@@ -156,58 +156,58 @@ PrintDisplayListTo(nsDisplayListBuilder*
     if (!list || list->DidComputeVisibility()) {
       opaque = i->GetOpaqueRegion(aBuilder, &snap);
     }
 #endif
     if (aDumpHtml && i->Painted()) {
       nsCString string(i->Name());
       string.Append("-");
       string.AppendInt((uint64_t)i);
-      fprintf(aOutput, "<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
+      fprintf_stderr(aOutput, "<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
     }
-    fprintf(aOutput, "%s %p(%s) bounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
+    fprintf_stderr(aOutput, "%s %p(%s) bounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) %s",
             i->Name(), (void*)f, NS_ConvertUTF16toUTF8(fName).get(),
             rect.x, rect.y, rect.width, rect.height,
             vis.x, vis.y, vis.width, vis.height,
             component.x, component.y, component.width, component.height,
             clip.ToString().get(),
             i->IsUniform(aBuilder, &color) ? " uniform" : "");
     nsRegionRectIterator iter(opaque);
     for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
-      fprintf(aOutput, " (opaque %d,%d,%d,%d)", r->x, r->y, r->width, r->height);
+      fprintf_stderr(aOutput, " (opaque %d,%d,%d,%d)", r->x, r->y, r->width, r->height);
     }
     i->WriteDebugInfo(aOutput);
     if (aDumpHtml && i->Painted()) {
-      fprintf(aOutput, "</a>");
+      fprintf_stderr(aOutput, "</a>");
     }
     uint32_t key = i->GetPerFrameKey();
     Layer* layer = mozilla::FrameLayerBuilder::GetDebugOldLayerFor(f, key);
     if (layer) {
       if (aDumpHtml) {
-        fprintf(aOutput, " <a href=\"#%p\">layer=%p</a>", layer, layer);
+        fprintf_stderr(aOutput, " <a href=\"#%p\">layer=%p</a>", layer, layer);
       } else {
-        fprintf(aOutput, " layer=%p", layer);
+        fprintf_stderr(aOutput, " layer=%p", layer);
       }
     }
     if (i->GetType() == nsDisplayItem::TYPE_SVG_EFFECTS) {
       (static_cast<nsDisplaySVGEffects*>(i))->PrintEffects(aOutput);
     }
     fputc('\n', aOutput);
     if (list) {
       PrintDisplayListTo(aBuilder, *list, aOutput, aDumpHtml);
     }
     if (aDumpHtml) {
-      fprintf(aOutput, "</li>");
+      fprintf_stderr(aOutput, "</li>");
     } else {
       sPrintDisplayListIndent --;
     }
   }
 
   if (aDumpHtml) {
-    fprintf(aOutput, "</ul>");
+    fprintf_stderr(aOutput, "</ul>");
   }
 }
 
 void
 nsFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
                           const nsDisplayList& aList,
                           FILE* aFile,
                           bool aDumpHtml)
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2081,17 +2081,17 @@ nsLayoutUtils::GetFramesForArea(nsIFrame
   }
 
   builder.EnterPresShell(aFrame, target);
   aFrame->BuildDisplayListForStackingContext(&builder, target, &list);
   builder.LeavePresShell(aFrame, target);
 
 #ifdef MOZ_DUMP_PAINTING
   if (gDumpEventList) {
-    fprintf(stdout, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
+    fprintf_stderr(stderr, "Event handling --- (%d,%d):\n", aRect.x, aRect.y);
     nsFrame::PrintDisplayList(&builder, list);
   }
 #endif
 
   nsDisplayItem::HitTestState hitTestState;
   list.HitTest(&builder, target, &hitTestState, &aOutFrames);
   list.DeleteAll();
   return NS_OK;
@@ -2272,26 +2272,26 @@ nsLayoutUtils::PaintFrame(nsRenderingCon
   FILE* savedDumpFile = gfxUtils::sDumpPaintFile;
   if (gfxUtils::sDumpPaintList || gfxUtils::sDumpPainting) {
     if (gfxUtils::sDumpPaintingToFile) {
       nsCString string("dump-");
       string.AppendInt(gPaintCount);
       string.Append(".html");
       gfxUtils::sDumpPaintFile = fopen(string.BeginReading(), "w");
     } else {
-      gfxUtils::sDumpPaintFile = stdout;
+      gfxUtils::sDumpPaintFile = stderr;
     }
     if (gfxUtils::sDumpPaintingToFile) {
-      fprintf(gfxUtils::sDumpPaintFile, "<html><head><script>var array = {}; function ViewImage(index) { window.location = array[index]; }</script></head><body>");
+      fprintf_stderr(gfxUtils::sDumpPaintFile, "<html><head><script>var array = {}; function ViewImage(index) { window.location = array[index]; }</script></head><body>");
     }
-    fprintf(gfxUtils::sDumpPaintFile, "Painting --- before optimization (dirty %d,%d,%d,%d):\n",
+    fprintf_stderr(gfxUtils::sDumpPaintFile, "Painting --- before optimization (dirty %d,%d,%d,%d):\n",
             dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height);
     nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile, gfxUtils::sDumpPaintingToFile);
     if (gfxUtils::sDumpPaintingToFile) {
-      fprintf(gfxUtils::sDumpPaintFile, "<script>");
+      fprintf_stderr(gfxUtils::sDumpPaintFile, "<script>");
     }
   }
 #endif
 
   list.ComputeVisibilityForRoot(&builder, &visibleRegion);
 
   uint32_t flags = nsDisplayList::PAINT_DEFAULT;
   if (aFlags & PAINT_WIDGET_LAYERS) {
@@ -2322,22 +2322,22 @@ nsLayoutUtils::PaintFrame(nsRenderingCon
     flags |= nsDisplayList::PAINT_NO_COMPOSITE;
   }
 
   list.PaintRoot(&builder, aRenderingContext, flags);
 
 #ifdef MOZ_DUMP_PAINTING
   if (gfxUtils::sDumpPaintList || gfxUtils::sDumpPainting) {
     if (gfxUtils::sDumpPaintingToFile) {
-      fprintf(gfxUtils::sDumpPaintFile, "</script>");
+      fprintf_stderr(gfxUtils::sDumpPaintFile, "</script>");
     }
-    fprintf(gfxUtils::sDumpPaintFile, "Painting --- after optimization:\n");
+    fprintf_stderr(gfxUtils::sDumpPaintFile, "Painting --- after optimization:\n");
     nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile, gfxUtils::sDumpPaintingToFile);
 
-    fprintf(gfxUtils::sDumpPaintFile, "Painting --- retained layer tree:\n");
+    fprintf_stderr(gfxUtils::sDumpPaintFile, "Painting --- retained layer tree:\n");
     nsIWidget* widget = aFrame->GetNearestWidget();
     if (widget) {
       nsRefPtr<LayerManager> layerManager = widget->GetLayerManager();
       if (layerManager) {
         FrameLayerBuilder::DumpRetainedLayerTree(layerManager, gfxUtils::sDumpPaintFile,
                                                  gfxUtils::sDumpPaintingToFile);
       }
     }
@@ -2942,19 +2942,19 @@ nsLayoutUtils::IntrinsicForContainer(nsR
                                      nsIFrame *aFrame,
                                      IntrinsicWidthType aType,
                                      uint32_t aFlags)
 {
   NS_PRECONDITION(aFrame, "null frame");
   NS_PRECONDITION(aType == MIN_WIDTH || aType == PREF_WIDTH, "bad type");
 
 #ifdef DEBUG_INTRINSIC_WIDTH
-  nsFrame::IndentBy(stdout, gNoiseIndent);
-  static_cast<nsFrame*>(aFrame)->ListTag(stdout);
-  printf(" %s intrinsic width for container:\n",
+  nsFrame::IndentBy(stderr, gNoiseIndent);
+  static_cast<nsFrame*>(aFrame)->ListTag(stderr);
+  printf_stderr(" %s intrinsic width for container:\n",
          aType == MIN_WIDTH ? "min" : "pref");
 #endif
 
   // If aFrame is a container for font size inflation, then shrink
   // wrapping inside of it should not apply font size inflation.
   AutoMaybeDisableFontInflation an(aFrame);
 
   nsIFrame::IntrinsicWidthOffsetData offsets =
@@ -3002,19 +3002,19 @@ nsLayoutUtils::IntrinsicForContainer(nsR
     ++gNoiseIndent;
 #endif
     if (aType == MIN_WIDTH)
       result = aFrame->GetMinWidth(aRenderingContext);
     else
       result = aFrame->GetPrefWidth(aRenderingContext);
 #ifdef DEBUG_INTRINSIC_WIDTH
     --gNoiseIndent;
-    nsFrame::IndentBy(stdout, gNoiseIndent);
-    static_cast<nsFrame*>(aFrame)->ListTag(stdout);
-    printf(" %s intrinsic width from frame is %d.\n",
+    nsFrame::IndentBy(stderr, gNoiseIndent);
+    static_cast<nsFrame*>(aFrame)->ListTag(stderr);
+    printf_stderr(" %s intrinsic width from frame is %d.\n",
            aType == MIN_WIDTH ? "min" : "pref", result);
 #endif
 
     // Handle elements with an intrinsic ratio (or size) and a specified
     // height, min-height, or max-height.
     const nsStyleCoord &styleHeight = stylePos->mHeight;
     const nsStyleCoord &styleMinHeight = stylePos->mMinHeight;
     const nsStyleCoord &styleMaxHeight = stylePos->mMaxHeight;
@@ -3191,19 +3191,19 @@ nsLayoutUtils::IntrinsicForContainer(nsR
     themeWidth += offsets.hMargin;
     themeWidth = AddPercents(aType, themeWidth, offsets.hPctMargin);
 
     if (themeWidth > result || !canOverride)
       result = themeWidth;
   }
 
 #ifdef DEBUG_INTRINSIC_WIDTH
-  nsFrame::IndentBy(stdout, gNoiseIndent);
-  static_cast<nsFrame*>(aFrame)->ListTag(stdout);
-  printf(" %s intrinsic width for container is %d twips.\n",
+  nsFrame::IndentBy(stderr, gNoiseIndent);
+  static_cast<nsFrame*>(aFrame)->ListTag(stderr);
+  printf_stderr(" %s intrinsic width for container is %d twips.\n",
          aType == MIN_WIDTH ? "min" : "pref", result);
 #endif
 
   return result;
 }
 
 /* static */ nscoord
 nsLayoutUtils::ComputeCBDependentValue(nscoord aPercentBasis,
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1194,33 +1194,33 @@ nsRefreshDriver::Tick(int64_t aNowEpoch,
   for (uint32_t i = 0; i < mPresShellsToInvalidateIfHidden.Length(); i++) {
     mPresShellsToInvalidateIfHidden[i]->InvalidatePresShellIfHidden();
   }
   mPresShellsToInvalidateIfHidden.Clear();
 
   if (mViewManagerFlushIsPending) {
 #ifdef MOZ_DUMP_PAINTING
     if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-      printf("Starting ProcessPendingUpdates\n");
+      printf_stderr("Starting ProcessPendingUpdates\n");
     }
 #endif
 #ifndef MOZ_WIDGET_GONK
     // Waiting for bug 830475 to work on B2G.
     nsRefPtr<layers::LayerManager> mgr = mPresContext->GetPresShell()->GetLayerManager();
     if (mgr) {
       mgr->SetPaintStartTime(mMostRecentRefresh);
     }
 #endif
 
     mViewManagerFlushIsPending = false;
     nsRefPtr<nsViewManager> vm = mPresContext->GetPresShell()->GetViewManager();
     vm->ProcessPendingUpdates();
 #ifdef MOZ_DUMP_PAINTING
     if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-      printf("Ending ProcessPendingUpdates\n");
+      printf_stderr("Ending ProcessPendingUpdates\n");
     }
 #endif
   }
 
   for (uint32_t i = 0; i < mPostRefreshObservers.Length(); ++i) {
     mPostRefreshObservers[i]->DidRefresh();
   }
   profiler_tracing("Paint", "RD", TRACING_INTERVAL_END);
--- a/view/src/nsViewManager.cpp
+++ b/view/src/nsViewManager.cpp
@@ -304,17 +304,17 @@ void nsViewManager::Refresh(nsView *aVie
   nsRegion damageRegion = aRegion.ToAppUnits(AppUnitsPerDevPixel());
   // move region from widget coordinates into view coordinates
   damageRegion.MoveBy(-aView->ViewToWidgetOffset());
 
   if (damageRegion.IsEmpty()) {
 #ifdef DEBUG_roc
     nsRect viewRect = aView->GetDimensions();
     nsRect damageRect = damageRegion.GetBounds();
-    printf("XXX Damage rectangle (%d,%d,%d,%d) does not intersect the widget's view (%d,%d,%d,%d)!\n",
+    printf_stderr("XXX Damage rectangle (%d,%d,%d,%d) does not intersect the widget's view (%d,%d,%d,%d)!\n",
            damageRect.x, damageRect.y, damageRect.width, damageRect.height,
            viewRect.x, viewRect.y, viewRect.width, viewRect.height);
 #endif
     return;
   }
   
   nsIWidget *widget = aView->GetWidget();
   if (!widget) {
@@ -332,30 +332,30 @@ void nsViewManager::Refresh(nsView *aVie
     SetPainting(true);
 
     NS_ASSERTION(GetDisplayRootFor(aView) == aView,
                  "Widgets that we paint must all be display roots");
 
     if (mPresShell) {
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("--COMPOSITE-- %p\n", mPresShell);
+        printf_stderr("--COMPOSITE-- %p\n", mPresShell);
       }
 #endif
       uint32_t paintFlags = nsIPresShell::PAINT_COMPOSITE;
       LayerManager *manager = widget->GetLayerManager();
       if (!manager->NeedsWidgetInvalidation()) {
         manager->FlushRendering();
       } else {
         mPresShell->Paint(aView, damageRegion,
                           paintFlags);
       }
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("--ENDCOMPOSITE--\n");
+        printf_stderr("--ENDCOMPOSITE--\n");
       }
 #endif
       mozilla::StartupTimeline::RecordOnce(mozilla::StartupTimeline::FIRST_PAINT);
     }
 
     SetPainting(false);
   }
 
@@ -406,27 +406,27 @@ void nsViewManager::ProcessPendingUpdate
           vm->FlushDelayedResize(true);
         }
       }
 
       NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
 
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
+        printf_stderr("---- PAINT START ----PresShell(%p), nsView(%p), nsIWidget(%p)\n", mPresShell, aView, widget);
       }
 #endif
       nsAutoScriptBlocker scriptBlocker;
       NS_ASSERTION(aView->HasWidget(), "Must have a widget!");
       SetPainting(true);
       mPresShell->Paint(aView, nsRegion(),
                         nsIPresShell::PAINT_LAYERS);
 #ifdef MOZ_DUMP_PAINTING
       if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
-        printf("---- PAINT END ----\n");
+        printf_stderr("---- PAINT END ----\n");
       }
 #endif
 
       aView->SetForcedRepaint(false);
       SetPainting(false);
       FlushDirtyRegionToWidget(aView);
     } else {
       FlushDirtyRegionToWidget(aView);
--- a/xpcom/glue/nsCRTGlue.cpp
+++ b/xpcom/glue/nsCRTGlue.cpp
@@ -263,51 +263,72 @@ void NS_MakeRandomString(char *aBuf, int
   for (i=0;i<aBufLen;i++) {
     *aBuf++ = table[rand()%TABLE_SIZE];
   }
   *aBuf = 0;
 }
 
 #endif
 #if defined(XP_WIN)
+
+#define va_copy(dest, src) (dest = src)
+
 void
-printf_stderr(const char *fmt, ...)
+vprintf_stderr(const char *fmt, va_list args)
 {
   if (IsDebuggerPresent()) {
     char buf[2048];
-    va_list args;
-    va_start(args, fmt);
-    vsnprintf(buf, sizeof(buf), fmt, args);
+    va_list argsCpy;
+    va_copy(argsCpy, args);
+    vsnprintf(buf, sizeof(buf), fmt, argsCpy);
     buf[sizeof(buf) - 1] = '\0';
-    va_end(args);
+    va_end(argsCpy);
     OutputDebugStringA(buf);
   }
 
   FILE *fp = _fdopen(_dup(2), "a");
   if (!fp)
       return;
 
-  va_list args;
-  va_start(args, fmt);
   vfprintf(fp, fmt, args);
-  va_end(args);
 
   fclose(fp);
 }
+
+#undef va_copy
+
 #elif defined(ANDROID)
 void
+vprintf_stderr(const char *fmt, va_list args)
+{
+  __android_log_vprint(ANDROID_LOG_INFO, "Gecko", fmt, args);
+}
+#else
+void
+vprintf_stderr(const char *fmt, va_list args)
+{
+  vfprintf(stderr, fmt, args);
+}
+#endif
+
+void
 printf_stderr(const char *fmt, ...)
 {
   va_list args;
   va_start(args, fmt);
-  __android_log_vprint(ANDROID_LOG_INFO, "Gecko", fmt, args);
+  vprintf_stderr(fmt, args);
   va_end(args);
 }
-#else
+
 void
-printf_stderr(const char *fmt, ...)
+fprintf_stderr(FILE* aFile, const char *fmt, ...)
 {
   va_list args;
   va_start(args, fmt);
-  vfprintf(stderr, fmt, args);
+  if (aFile == stderr) {
+    vprintf_stderr(fmt, args);
+  } else {
+    vfprintf(aFile, fmt, args);
+  }
   va_end(args);
 }
-#endif
+
+
--- a/xpcom/glue/nsDebug.h
+++ b/xpcom/glue/nsDebug.h
@@ -393,13 +393,20 @@ inline bool NS_warn_if_impl(bool conditi
  */
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 NS_COM_GLUE void
 printf_stderr(const char *fmt, ...);
 
+NS_COM_GLUE void
+vprintf_stderr(const char *fmt, va_list args);
+
+// fprintf with special handling for stderr to print to the console
+NS_COM_GLUE void
+fprintf_stderr(FILE* aFile, const char *fmt, ...);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif /* nsDebug_h___ */