LCOV - code coverage report
Current view: top level - layout/base - nsLayoutDebugger.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 150 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 19 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : /*
       7             :  * implementation of interface that allows layout-debug extension access
       8             :  * to some internals of layout
       9             :  */
      10             : 
      11             : #include "nsILayoutDebugger.h"
      12             : 
      13             : #include "nsAttrValue.h"
      14             : #include "nsFrame.h"
      15             : #include "nsDisplayList.h"
      16             : #include "FrameLayerBuilder.h"
      17             : #include "nsPrintfCString.h"
      18             : 
      19             : #include <iostream>
      20             : #include <stdio.h>
      21             : 
      22             : using namespace mozilla;
      23             : using namespace mozilla::layers;
      24             : 
      25             : #ifdef DEBUG
      26             : class nsLayoutDebugger : public nsILayoutDebugger {
      27             : public:
      28             :   nsLayoutDebugger();
      29             : 
      30             :   NS_DECL_ISUPPORTS
      31             : 
      32             :   NS_IMETHOD SetShowFrameBorders(bool aEnable) override;
      33             : 
      34             :   NS_IMETHOD GetShowFrameBorders(bool* aResult) override;
      35             : 
      36             :   NS_IMETHOD SetShowEventTargetFrameBorder(bool aEnable) override;
      37             : 
      38             :   NS_IMETHOD GetShowEventTargetFrameBorder(bool* aResult) override;
      39             : 
      40             : protected:
      41             :   virtual ~nsLayoutDebugger();
      42             : };
      43             : 
      44             : nsresult
      45           0 : NS_NewLayoutDebugger(nsILayoutDebugger** aResult)
      46             : {
      47           0 :   NS_PRECONDITION(aResult, "null OUT ptr");
      48           0 :   if (!aResult) {
      49           0 :     return NS_ERROR_NULL_POINTER;
      50             :   }
      51           0 :   nsLayoutDebugger* it = new nsLayoutDebugger();
      52           0 :   return it->QueryInterface(NS_GET_IID(nsILayoutDebugger), (void**)aResult);
      53             : }
      54             : 
      55           0 : nsLayoutDebugger::nsLayoutDebugger()
      56             : {
      57           0 : }
      58             : 
      59           0 : nsLayoutDebugger::~nsLayoutDebugger()
      60             : {
      61           0 : }
      62             : 
      63           0 : NS_IMPL_ISUPPORTS(nsLayoutDebugger, nsILayoutDebugger)
      64             : 
      65             : NS_IMETHODIMP
      66           0 : nsLayoutDebugger::SetShowFrameBorders(bool aEnable)
      67             : {
      68           0 :   nsFrame::ShowFrameBorders(aEnable);
      69           0 :   return NS_OK;
      70             : }
      71             : 
      72             : NS_IMETHODIMP
      73           0 : nsLayoutDebugger::GetShowFrameBorders(bool* aResult)
      74             : {
      75           0 :   *aResult = nsFrame::GetShowFrameBorders();
      76           0 :   return NS_OK;
      77             : }
      78             : 
      79             : NS_IMETHODIMP
      80           0 : nsLayoutDebugger::SetShowEventTargetFrameBorder(bool aEnable)
      81             : {
      82           0 :   nsFrame::ShowEventTargetFrameBorder(aEnable);
      83           0 :   return NS_OK;
      84             : }
      85             : 
      86             : NS_IMETHODIMP
      87           0 : nsLayoutDebugger::GetShowEventTargetFrameBorder(bool* aResult)
      88             : {
      89           0 :   *aResult = nsFrame::GetShowEventTargetFrameBorder();
      90           0 :   return NS_OK;
      91             : }
      92             : 
      93             : #endif
      94             : 
      95           0 : std::ostream& operator<<(std::ostream& os, const nsPrintfCString& rhs) {
      96           0 :   os << rhs.get();
      97           0 :   return os;
      98             : }
      99             : 
     100             : static void
     101             : PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
     102             :                    std::stringstream& aStream, uint32_t aIndent, bool aDumpHtml);
     103             : 
     104             : static void
     105           0 : PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem,
     106             :                    std::stringstream& aStream, uint32_t aIndent, bool aDumpSublist, bool aDumpHtml)
     107             : {
     108           0 :   std::stringstream ss;
     109             : 
     110           0 :   if (!aDumpHtml) {
     111           0 :     for (uint32_t indent = 0; indent < aIndent; indent++) {
     112           0 :       aStream << "  ";
     113             :     }
     114             :   }
     115           0 :   nsAutoString contentData;
     116           0 :   nsIFrame* f = aItem->Frame();
     117             : #ifdef DEBUG_FRAME_DUMP
     118           0 :   f->GetFrameName(contentData);
     119             : #endif
     120           0 :   nsIContent* content = f->GetContent();
     121           0 :   if (content) {
     122           0 :     nsString tmp;
     123           0 :     if (content->GetID()) {
     124           0 :       content->GetID()->ToString(tmp);
     125           0 :       contentData.AppendLiteral(" id:");
     126           0 :       contentData.Append(tmp);
     127             :     }
     128           0 :     const nsAttrValue* classes = content->IsElement() ?
     129           0 :       content->AsElement()->GetClasses() : nullptr;
     130           0 :     if (classes) {
     131           0 :       classes->ToString(tmp);
     132           0 :       contentData.AppendLiteral(" class:");
     133           0 :       contentData.Append(tmp);
     134             :     }
     135             :   }
     136             :   bool snap;
     137           0 :   nsRect rect = aItem->GetBounds(aBuilder, &snap);
     138           0 :   nsRect layerRect = rect - (*aItem->GetAnimatedGeometryRoot())->GetOffsetToCrossDoc(aItem->ReferenceFrame());
     139           0 :   nsRect vis = aItem->GetVisibleRect();
     140           0 :   nsRect component = aItem->GetComponentAlphaBounds(aBuilder);
     141           0 :   nsDisplayList* list = aItem->GetChildren();
     142           0 :   const DisplayItemClip& clip = aItem->GetClip();
     143           0 :   nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap);
     144             : 
     145             : #ifdef MOZ_DUMP_PAINTING
     146           0 :   if (aDumpHtml && aItem->Painted()) {
     147           0 :     nsCString string(aItem->Name());
     148           0 :     string.Append('-');
     149           0 :     string.AppendInt((uint64_t)aItem);
     150           0 :     aStream << nsPrintfCString("<a href=\"javascript:ViewImage('%s')\">", string.BeginReading());
     151             :   }
     152             : #endif
     153             : 
     154           0 :   aStream << nsPrintfCString("%s p=0x%p f=0x%p(%s) %sbounds(%d,%d,%d,%d) layerBounds(%d,%d,%d,%d) visible(%d,%d,%d,%d) componentAlpha(%d,%d,%d,%d) clip(%s) asr(%s) clipChain(%s)%s ref=0x%p agr=0x%p",
     155           0 :           aItem->Name(), aItem, (void*)f, NS_ConvertUTF16toUTF8(contentData).get(),
     156           0 :           (aItem->ZIndex() ? nsPrintfCString("z=%d ", aItem->ZIndex()).get() : ""),
     157             :           rect.x, rect.y, rect.width, rect.height,
     158             :           layerRect.x, layerRect.y, layerRect.width, layerRect.height,
     159             :           vis.x, vis.y, vis.width, vis.height,
     160             :           component.x, component.y, component.width, component.height,
     161           0 :           clip.ToString().get(),
     162           0 :           ActiveScrolledRoot::ToString(aItem->GetActiveScrolledRoot()).get(),
     163           0 :           DisplayItemClipChain::ToString(aItem->GetClipChain()).get(),
     164           0 :           aItem->IsUniform(aBuilder) ? " uniform" : "",
     165           0 :           aItem->ReferenceFrame(), aItem->GetAnimatedGeometryRoot()->mFrame);
     166             : 
     167           0 :   for (auto iter = opaque.RectIter(); !iter.Done(); iter.Next()) {
     168           0 :     const nsRect& r = iter.Get();
     169           0 :     aStream << nsPrintfCString(" (opaque %d,%d,%d,%d)", r.x, r.y, r.width, r.height);
     170             :   }
     171             : 
     172           0 :   const auto& willChange = aItem->Frame()->StyleDisplay()->mWillChange;
     173           0 :   if (!willChange.IsEmpty()) {
     174           0 :     aStream << " (will-change=";
     175           0 :     for (size_t i = 0; i < willChange.Length(); i++) {
     176           0 :       if (i > 0) {
     177           0 :         aStream << ",";
     178             :       }
     179           0 :       nsDependentAtomString buffer(willChange[i]);
     180           0 :       aStream << NS_LossyConvertUTF16toASCII(buffer).get();
     181             :     }
     182           0 :     aStream << ")";
     183             :   }
     184             : 
     185             :   // Display item specific debug info
     186           0 :   aItem->WriteDebugInfo(aStream);
     187             : 
     188             : #ifdef MOZ_DUMP_PAINTING
     189           0 :   if (aDumpHtml && aItem->Painted()) {
     190           0 :     aStream << "</a>";
     191             :   }
     192             : #endif
     193           0 :   uint32_t key = aItem->GetPerFrameKey();
     194           0 :   Layer* layer = mozilla::FrameLayerBuilder::GetDebugOldLayerFor(f, key);
     195           0 :   if (layer) {
     196           0 :     if (aDumpHtml) {
     197           0 :       aStream << nsPrintfCString(" <a href=\"#%p\">layer=%p</a>", layer, layer);
     198             :     } else {
     199           0 :       aStream << nsPrintfCString(" layer=0x%p", layer);
     200             :     }
     201             :   }
     202             : #ifdef MOZ_DUMP_PAINTING
     203           0 :   if (aItem->GetType() == nsDisplayItem::TYPE_MASK) {
     204           0 :     nsCString str;
     205           0 :     (static_cast<nsDisplayMask*>(aItem))->PrintEffects(str);
     206           0 :     aStream << str.get();
     207             :   }
     208             : 
     209           0 :   if (aItem->GetType() == nsDisplayItem::TYPE_FILTER) {
     210           0 :     nsCString str;
     211           0 :     (static_cast<nsDisplayFilter*>(aItem))->PrintEffects(str);
     212           0 :     aStream << str.get();
     213             :   }
     214             : #endif
     215           0 :   aStream << "\n";
     216             : #ifdef MOZ_DUMP_PAINTING
     217           0 :   if (aDumpHtml && aItem->Painted()) {
     218           0 :     nsCString string(aItem->Name());
     219           0 :     string.Append('-');
     220           0 :     string.AppendInt((uint64_t)aItem);
     221           0 :     aStream << nsPrintfCString("<br><img id=\"%s\">\n", string.BeginReading());
     222             :   }
     223             : #endif
     224             : 
     225           0 :   if (aDumpSublist && list) {
     226           0 :     PrintDisplayListTo(aBuilder, *list, aStream, aIndent+1, aDumpHtml);
     227             :   }
     228           0 : }
     229             : 
     230             : static void
     231           0 : PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
     232             :                    std::stringstream& aStream, uint32_t aIndent, bool aDumpHtml)
     233             : {
     234           0 :   if (aDumpHtml) {
     235           0 :     aStream << "<ul>";
     236             :   }
     237             : 
     238           0 :   for (nsDisplayItem* i = aList.GetBottom(); i != nullptr; i = i->GetAbove()) {
     239           0 :     if (aDumpHtml) {
     240           0 :       aStream << "<li>";
     241             :     }
     242           0 :     PrintDisplayItemTo(aBuilder, i, aStream, aIndent, true, aDumpHtml);
     243           0 :     if (aDumpHtml) {
     244           0 :       aStream << "</li>";
     245             :     }
     246             :   }
     247             : 
     248           0 :   if (aDumpHtml) {
     249           0 :     aStream << "</ul>";
     250             :   }
     251           0 : }
     252             : 
     253             : void
     254           0 : nsFrame::PrintDisplayList(nsDisplayListBuilder* aBuilder,
     255             :                           const nsDisplayList& aList,
     256             :                           std::stringstream& aStream,
     257             :                           bool aDumpHtml)
     258             : {
     259           0 :   PrintDisplayListTo(aBuilder, aList, aStream, 0, aDumpHtml);
     260           0 : }
     261             : 
     262             : /**
     263             :  * The two functions below are intended to be called from a debugger.
     264             :  */
     265             : void
     266           0 : PrintDisplayItemToStdout(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem)
     267             : {
     268           0 :   std::stringstream stream;
     269           0 :   PrintDisplayItemTo(aBuilder, aItem, stream, 0, true, false);
     270           0 :   std::cout << stream.str() << std::endl;
     271           0 : }
     272             : 
     273             : void
     274           0 : PrintDisplayListToStdout(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList)
     275             : {
     276           0 :   std::stringstream stream;
     277           0 :   PrintDisplayListTo(aBuilder, aList, stream, 0, false);
     278           0 :   std::cout << stream.str() << std::endl;
     279           0 : }
     280             : 
     281             : #ifdef MOZ_DUMP_PAINTING
     282             : static void
     283           0 : PrintDisplayListSetItem(nsDisplayListBuilder* aBuilder,
     284             :                         const char* aItemName,
     285             :                         const nsDisplayList& aList,
     286             :                         std::stringstream& aStream,
     287             :                         bool aDumpHtml)
     288             : {
     289           0 :   if (aDumpHtml) {
     290           0 :     aStream << "<li>";
     291             :   }
     292           0 :   aStream << aItemName << "\n";
     293           0 :   PrintDisplayListTo(aBuilder, aList, aStream, 0, aDumpHtml);
     294           0 :   if (aDumpHtml) {
     295           0 :     aStream << "</li>";
     296             :   }
     297           0 : }
     298             : 
     299             : void
     300           0 : nsFrame::PrintDisplayListSet(nsDisplayListBuilder* aBuilder,
     301             :                              const nsDisplayListSet& aSet,
     302             :                              std::stringstream& aStream,
     303             :                              bool aDumpHtml)
     304             : {
     305           0 :   if (aDumpHtml) {
     306           0 :     aStream << "<ul>";
     307             :   }
     308           0 :   PrintDisplayListSetItem(aBuilder, "[BorderBackground]", *(aSet.BorderBackground()), aStream, aDumpHtml);
     309           0 :   PrintDisplayListSetItem(aBuilder, "[BlockBorderBackgrounds]", *(aSet.BlockBorderBackgrounds()), aStream, aDumpHtml);
     310           0 :   PrintDisplayListSetItem(aBuilder, "[Floats]", *(aSet.Floats()), aStream, aDumpHtml);
     311           0 :   PrintDisplayListSetItem(aBuilder, "[PositionedDescendants]", *(aSet.PositionedDescendants()), aStream, aDumpHtml);
     312           0 :   PrintDisplayListSetItem(aBuilder, "[Outlines]", *(aSet.Outlines()), aStream, aDumpHtml);
     313           0 :   PrintDisplayListSetItem(aBuilder, "[Content]", *(aSet.Content()), aStream, aDumpHtml);
     314           0 :   if (aDumpHtml) {
     315           0 :     aStream << "</ul>";
     316             :   }
     317           0 : }
     318             : 
     319             : #endif

Generated by: LCOV version 1.13