Bug 795674 - Add DisplayItemData debugging code. r=roc
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 12 Oct 2012 12:38:25 +1300
changeset 110126 b1c3b7ae35719a30ce1e129bb0bfc6c14766a8a8
parent 110125 0586d2a97c52295b6667f6caaf2e5fd4a9c3a4f0
child 110127 f283941dbf752aa8a1a8fa39ea857a644b387cdf
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersroc
bugs795674
milestone19.0a1
Bug 795674 - Add DisplayItemData debugging code. r=roc
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/Makefile.in
layout/base/nsDisplayItemTypes.h
layout/base/nsDisplayItemTypesList.h
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -26,16 +26,17 @@
 #include "mozilla/gfx/Tools.h"
 
 #include "nsAnimationManager.h"
 #include "nsTransitionManager.h"
 
 #ifdef DEBUG
 #include <stdio.h>
 //#define DEBUG_INVALIDATIONS
+//#define DEBUG_DISPLAY_ITEM_DATA
 #endif
 
 using namespace mozilla::layers;
 using namespace mozilla::gfx;
 
 namespace mozilla {
 
 FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, nsIFrame* aFrame, uint32_t aKey, 
@@ -171,16 +172,27 @@ public:
   }
   ~LayerManagerData() {
     MOZ_COUNT_DTOR(LayerManagerData);
     // Remove display item data properties now, since we won't be able
     // to find these frames again without mFramesWithLayers.
     mDisplayItems.EnumerateEntries(
         FrameLayerBuilder::RemoveDisplayItemDataForFrame, nullptr);
   }
+ 
+#ifdef DEBUG_DISPLAY_ITEM_DATA
+  void Dump(const char *aPrefix = "") {
+    printf("%sLayerManagerData %p\n", aPrefix, this);
+    nsAutoCString prefix;
+    prefix += aPrefix;
+    prefix += "  ";
+    mDisplayItems.EnumerateEntries(
+        FrameLayerBuilder::DumpDisplayItemDataForFrame, (void*)prefix.get());
+  }
+#endif
 
   /**
    * Tracks which frames have layers associated with them.
    */
   LayerManager *mLayerManager;
   LayerManagerData *mParent;
   nsTHashtable<nsRefPtrHashKey<FrameLayerBuilder::DisplayItemData> > mDisplayItems;
   bool mInvalidateAllLayers;
@@ -852,16 +864,27 @@ FrameLayerBuilder::RemoveFrameFromLayerM
 
   // Hold a reference to all the items so that they don't get
   // deleted from under us.
   nsTArray<nsRefPtr<DisplayItemData> > arrayCopy;
   for (uint32_t i = 0; i < array->Length(); ++i) {
     arrayCopy.AppendElement(array->ElementAt(i));
   }
 
+#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);
+    rootData->Dump();
+  }
+#endif
+
   for (uint32_t i = 0; i < array->Length(); ++i) {
     DisplayItemData* data = array->ElementAt(i);
 
     ThebesLayer* t = data->mLayer->AsThebesLayer();
     if (t) {
       ThebesDisplayItemLayerUserData* thebesData =
           static_cast<ThebesDisplayItemLayerUserData*>(t->GetUserData(&gThebesDisplayItemLayerUserData));
       if (thebesData) {
@@ -1007,16 +1030,72 @@ FrameLayerBuilder::RemoveDisplayItemData
 {
   DisplayItemData* data = aEntry->GetKey();
   // If this was called from a frame destructor then the prop is definitely already gone,
   // and we could crash trying to check. See the definition of sDestroyedFrame.
   data->RemoveFrameData(sDestroyedFrame);
   return PL_DHASH_REMOVE;
 }
 
+/* static */ PLDHashOperator 
+FrameLayerBuilder::DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
+                                               void* aClosure)
+{
+#ifdef DEBUG_DISPLAY_ITEM_DATA
+  DisplayItemData *data = aEntry->GetKey();
+
+  nsAutoCString prefix;
+  prefix += static_cast<const char*>(aClosure);
+  
+  const char *layerState;
+  switch (data->mLayerState) {
+    case LAYER_NONE:
+      layerState = "LAYER_NONE"; break;
+    case LAYER_INACTIVE:
+      layerState = "LAYER_INACTIVE"; break;
+    case LAYER_ACTIVE:
+      layerState = "LAYER_ACTIVE"; break;
+    case LAYER_ACTIVE_FORCE:
+      layerState = "LAYER_ACTIVE_FORCE"; break;
+    case LAYER_ACTIVE_EMPTY:
+      layerState = "LAYER_ACTIVE_EMPTY"; break;
+    case LAYER_SVG_EFFECTS:
+      layerState = "LAYER_SVG_EFFECTS"; break;
+  }
+  uint32_t mask = (1 << nsDisplayItem::TYPE_BITS) - 1;
+
+  nsAutoCString str;
+  str += prefix;
+  str += nsPrintfCString("Frame %p ", data->mFrameList[0]);
+  str += nsDisplayItem::DisplayItemTypeName(static_cast<nsDisplayItem::Type>(data->mDisplayItemKey & mask));
+  if ((data->mDisplayItemKey >> nsDisplayItem::TYPE_BITS)) {
+    str += nsPrintfCString("(%i)", data->mDisplayItemKey >> nsDisplayItem::TYPE_BITS);
+  }
+  str += nsPrintfCString(", %s, Layer %p", layerState, data->mLayer.get());
+  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());
+    
+  if (data->mInactiveManager) {
+    prefix += "  ";
+    printf("%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;
+}
+
 /* static */ PLDHashOperator
 FrameLayerBuilder::StoreNewDisplayItemData(DisplayItemHashData* aEntry,
                                            void* aUserArg)
 {
   LayerManagerData* data = static_cast<LayerManagerData*>(aUserArg);
   const DisplayItemKey& key = aEntry->GetKey();
 
   // Remember that this frame has display items in retained layers
--- a/layout/base/FrameLayerBuilder.h
+++ b/layout/base/FrameLayerBuilder.h
@@ -640,16 +640,18 @@ protected:
   /**
    * A useful hashtable iteration function that removes the
    * DisplayItemData property for the frame and returns PL_DHASH_REMOVE.
    * aClosure is ignored.
    */
   static PLDHashOperator RemoveDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
                                                        void* aClosure);
 
+  static PLDHashOperator DumpDisplayItemDataForFrame(nsRefPtrHashKey<DisplayItemData>* aEntry,
+                                                     void* aClosure);
   /**
    * We store one of these for each display item associated with a
    * ThebesLayer, in a hashtable that maps each ThebesLayer to an array
    * of ClippedDisplayItems. (ThebesLayerItemsEntry is the hash entry
    * for that hashtable.)
    * These are only stored during the paint process, so that the
    * DrawThebesLayer callback can figure out which items to draw for the
    * ThebesLayer.
--- a/layout/base/Makefile.in
+++ b/layout/base/Makefile.in
@@ -32,16 +32,17 @@ EXPORTS		= \
 		nsArenaMemoryStats.h \
 		nsBidi.h \
 		nsBidiPresUtils.h \
 		nsCaret.h \
 		nsCSSFrameConstructor.h \
 		nsChangeHint.h \
 		nsCompatibility.h \
 		nsDisplayItemTypes.h \
+		nsDisplayItemTypesList.h \
 		nsDisplayList.h \
 		nsDisplayListInvalidation.h \
 		nsFrameManager.h \
 		nsFrameManagerBase.h \
 		nsFrameIterator.h \
 		nsILayoutDebugger.h \
 		nsILayoutHistoryState.h \
 		nsIPercentHeightObserver.h  \
--- a/layout/base/nsDisplayItemTypes.h
+++ b/layout/base/nsDisplayItemTypes.h
@@ -7,114 +7,35 @@
 
 /**
  * It's useful to be able to dynamically check the type of certain items.
  * Every subclass of nsDisplayItem must have a new type added here for the purposes
  * of easy comparison and matching of items in different display lists.
  * 
  * This is #included inside nsDisplayItem.
  */
+
+
 enum Type {
-  TYPE_ALT_FEEDBACK = 1,
-  TYPE_BACKGROUND,
-  TYPE_BORDER,
-  TYPE_BOX_SHADOW_OUTER,
-  TYPE_BOX_SHADOW_INNER,
-  TYPE_BULLET,
-  TYPE_BUTTON_BORDER_BACKGROUND,
-  TYPE_BUTTON_BOX_SHADOW_OUTER,
-  TYPE_BUTTON_FOREGROUND,
-  TYPE_CANVAS,
-  TYPE_CANVAS_BACKGROUND,
-  TYPE_CANVAS_FOCUS,
-  TYPE_CARET,
-  TYPE_CHECKED_CHECKBOX,
-  TYPE_CHECKED_RADIOBUTTON,
-  TYPE_CLIP,
-  TYPE_CLIP_ROUNDED_RECT,
-  TYPE_COLUMN_RULE,
-  TYPE_COMBOBOX_FOCUS,
-  TYPE_EVENT_RECEIVER,
-  TYPE_FIELDSET_BORDER_BACKGROUND,
-  TYPE_FIXED_POSITION,
-  TYPE_FORCEPAINTONSCROLL,
-  TYPE_FRAMESET_BORDER,
-  TYPE_FRAMESET_BLANK,
-  TYPE_HEADER_FOOTER,
-  TYPE_IMAGE,
-  TYPE_LIST_FOCUS,
-  TYPE_OPACITY,
-  TYPE_OPTION_EVENT_GRABBER,
-  TYPE_OUTLINE,
-  TYPE_OWN_LAYER,
-  TYPE_PAGE_CONTENT,
-  TYPE_PAGE_SEQUENCE,
-  TYPE_PLUGIN,
-  TYPE_PLUGIN_READBACK,
-  TYPE_PLUGIN_VIDEO,
-  TYPE_PRINT_PLUGIN,
-  TYPE_REMOTE,
-  TYPE_REMOTE_SHADOW,
-  TYPE_SCROLL_LAYER,
-  TYPE_SCROLL_INFO_LAYER,
-  TYPE_SELECTION_OVERLAY,
-  TYPE_SOLID_COLOR,
-  TYPE_SVG_EFFECTS,
-  TYPE_SVG_GLYPHS,
-  TYPE_SVG_OUTER_SVG,
-  TYPE_SVG_PATH_GEOMETRY,
-  TYPE_TABLE_CELL_BACKGROUND,
-  TYPE_TABLE_CELL_SELECTION,
-  TYPE_TABLE_ROW_BACKGROUND,
-  TYPE_TABLE_ROW_GROUP_BACKGROUND,
-  TYPE_TABLE_BORDER_BACKGROUND,
-  TYPE_TEXT,
-  TYPE_TEXT_DECORATION,
-  TYPE_TEXT_OVERFLOW,
-  TYPE_TEXT_SHADOW,
-  TYPE_TRANSFORM,
-  TYPE_VIDEO,
-  TYPE_WRAP_LIST,
-  TYPE_ZOOM,
-  TYPE_EXCLUDE_GLASS_FRAME,
+  TYPE_ZERO = 0, /** Spacer so that the first item starts at 1 */
 
-#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
-  TYPE_REFLOW_COUNT,
-#endif
-
-#ifdef MOZ_XUL
-  TYPE_XUL_EVENT_REDIRECTOR,
-  TYPE_XUL_GROUP_BACKGROUND,
-  TYPE_XUL_IMAGE,
-  TYPE_XUL_TEXT_BOX,
-  TYPE_XUL_TREE_BODY,
-  TYPE_XUL_TREE_COL_SPLITTER_TARGET,
-#ifdef DEBUG_LAYOUT
-  TYPE_XUL_DEBUG,
-#endif
-#endif
-
-  TYPE_MATHML_BAR,
-  TYPE_MATHML_CHAR_BACKGROUND,
-  TYPE_MATHML_CHAR_FOREGROUND,
-  TYPE_MATHML_ERROR,
-  TYPE_MATHML_MENCLOSE_NOTATION,
-  TYPE_MATHML_SELECTION_RECT,
-  TYPE_MATHML_SLASH,
-#ifdef DEBUG
-  TYPE_MATHML_BOUNDING_METRICS,
-  TYPE_MATHML_CHAR_DEBUG,
-#endif
-
-#ifdef DEBUG
-  TYPE_DEBUG_BORDER,
-  TYPE_DEBUG_IMAGE_MAP,
-  TYPE_DEBUG_PLACEHOLDER,
-  TYPE_EVENT_TARGET_BORDER,
-#endif
+#define DECLARE_DISPLAY_ITEM_TYPE(name) TYPE_##name,
+#include "nsDisplayItemTypesList.h"
+#undef DECLARE_DISPLAY_ITEM_TYPE
 
   TYPE_MAX
 };
 
 enum {
   // Number of bits needed to represent all types
   TYPE_BITS = 8
 };
+
+static const char* DisplayItemTypeName(Type aType)
+{
+  switch (aType) {
+#define DECLARE_DISPLAY_ITEM_TYPE(name) case TYPE_##name: return #name;
+#include "nsDisplayItemTypesList.h"
+#undef DECLARE_DISPLAY_ITEM_TYPE
+
+    default: return "TYPE_UNKNOWN";
+  }
+}
new file mode 100644
--- /dev/null
+++ b/layout/base/nsDisplayItemTypesList.h
@@ -0,0 +1,95 @@
+DECLARE_DISPLAY_ITEM_TYPE(ALT_FEEDBACK)
+DECLARE_DISPLAY_ITEM_TYPE(BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(BORDER)
+DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_OUTER)
+DECLARE_DISPLAY_ITEM_TYPE(BOX_SHADOW_INNER)
+DECLARE_DISPLAY_ITEM_TYPE(BULLET)
+DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BORDER_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BOX_SHADOW_OUTER)
+DECLARE_DISPLAY_ITEM_TYPE(BUTTON_FOREGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(CANVAS)
+DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(CANVAS_FOCUS)
+DECLARE_DISPLAY_ITEM_TYPE(CARET)
+DECLARE_DISPLAY_ITEM_TYPE(CHECKED_CHECKBOX)
+DECLARE_DISPLAY_ITEM_TYPE(CHECKED_RADIOBUTTON)
+DECLARE_DISPLAY_ITEM_TYPE(CLIP)
+DECLARE_DISPLAY_ITEM_TYPE(CLIP_ROUNDED_RECT)
+DECLARE_DISPLAY_ITEM_TYPE(COLUMN_RULE)
+DECLARE_DISPLAY_ITEM_TYPE(COMBOBOX_FOCUS)
+DECLARE_DISPLAY_ITEM_TYPE(EVENT_RECEIVER)
+DECLARE_DISPLAY_ITEM_TYPE(FIELDSET_BORDER_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(FIXED_POSITION)
+DECLARE_DISPLAY_ITEM_TYPE(FORCEPAINTONSCROLL)
+DECLARE_DISPLAY_ITEM_TYPE(FRAMESET_BORDER)
+DECLARE_DISPLAY_ITEM_TYPE(FRAMESET_BLANK)
+DECLARE_DISPLAY_ITEM_TYPE(HEADER_FOOTER)
+DECLARE_DISPLAY_ITEM_TYPE(IMAGE)
+DECLARE_DISPLAY_ITEM_TYPE(LIST_FOCUS)
+DECLARE_DISPLAY_ITEM_TYPE(OPACITY)
+DECLARE_DISPLAY_ITEM_TYPE(OPTION_EVENT_GRABBER)
+DECLARE_DISPLAY_ITEM_TYPE(OUTLINE)
+DECLARE_DISPLAY_ITEM_TYPE(OWN_LAYER)
+DECLARE_DISPLAY_ITEM_TYPE(PAGE_CONTENT)
+DECLARE_DISPLAY_ITEM_TYPE(PAGE_SEQUENCE)
+DECLARE_DISPLAY_ITEM_TYPE(PLUGIN)
+DECLARE_DISPLAY_ITEM_TYPE(PLUGIN_READBACK)
+DECLARE_DISPLAY_ITEM_TYPE(PLUGIN_VIDEO)
+DECLARE_DISPLAY_ITEM_TYPE(PRINT_PLUGIN)
+DECLARE_DISPLAY_ITEM_TYPE(REMOTE)
+DECLARE_DISPLAY_ITEM_TYPE(REMOTE_SHADOW)
+DECLARE_DISPLAY_ITEM_TYPE(SCROLL_LAYER)
+DECLARE_DISPLAY_ITEM_TYPE(SCROLL_INFO_LAYER)
+DECLARE_DISPLAY_ITEM_TYPE(SELECTION_OVERLAY)
+DECLARE_DISPLAY_ITEM_TYPE(SOLID_COLOR)
+DECLARE_DISPLAY_ITEM_TYPE(SVG_EFFECTS)
+DECLARE_DISPLAY_ITEM_TYPE(SVG_GLYPHS)
+DECLARE_DISPLAY_ITEM_TYPE(SVG_OUTER_SVG)
+DECLARE_DISPLAY_ITEM_TYPE(SVG_PATH_GEOMETRY)
+DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(TABLE_CELL_SELECTION)
+DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(TABLE_ROW_GROUP_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(TABLE_BORDER_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(TEXT)
+DECLARE_DISPLAY_ITEM_TYPE(TEXT_DECORATION)
+DECLARE_DISPLAY_ITEM_TYPE(TEXT_OVERFLOW)
+DECLARE_DISPLAY_ITEM_TYPE(TEXT_SHADOW)
+DECLARE_DISPLAY_ITEM_TYPE(TRANSFORM)
+DECLARE_DISPLAY_ITEM_TYPE(VIDEO)
+DECLARE_DISPLAY_ITEM_TYPE(WRAP_LIST)
+DECLARE_DISPLAY_ITEM_TYPE(ZOOM)
+DECLARE_DISPLAY_ITEM_TYPE(EXCLUDE_GLASS_FRAME)
+
+#if defined(MOZ_REFLOW_PERF_DSP) && defined(MOZ_REFLOW_PERF)
+DECLARE_DISPLAY_ITEM_TYPE(REFLOW_COUNT)
+#endif
+
+#ifdef MOZ_XUL
+DECLARE_DISPLAY_ITEM_TYPE(XUL_EVENT_REDIRECTOR)
+DECLARE_DISPLAY_ITEM_TYPE(XUL_GROUP_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(XUL_IMAGE)
+DECLARE_DISPLAY_ITEM_TYPE(XUL_TEXT_BOX)
+DECLARE_DISPLAY_ITEM_TYPE(XUL_TREE_BODY)
+DECLARE_DISPLAY_ITEM_TYPE(XUL_TREE_COL_SPLITTER_TARGET)
+#ifdef DEBUG_LAYOUT
+DECLARE_DISPLAY_ITEM_TYPE(XUL_DEBUG)
+#endif
+#endif
+
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_BAR)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_CHAR_BACKGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_CHAR_FOREGROUND)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_ERROR)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_MENCLOSE_NOTATION)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_SELECTION_RECT)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_SLASH)
+#ifdef DEBUG
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_BOUNDING_METRICS)
+DECLARE_DISPLAY_ITEM_TYPE(MATHML_CHAR_DEBUG)
+
+DECLARE_DISPLAY_ITEM_TYPE(DEBUG_BORDER)
+DECLARE_DISPLAY_ITEM_TYPE(DEBUG_IMAGE_MAP)
+DECLARE_DISPLAY_ITEM_TYPE(DEBUG_PLACEHOLDER)
+DECLARE_DISPLAY_ITEM_TYPE(EVENT_TARGET_BORDER)
+#endif