Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/paint/PaintPropertyTreePrinter.h" | 5 #include "core/paint/PaintPropertyTreePrinter.h" |
| 6 | 6 |
| 7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
| 8 #include "core/frame/LocalFrame.h" | 8 #include "core/frame/LocalFrame.h" |
| 9 #include "core/layout/LayoutView.h" | 9 #include "core/layout/LayoutView.h" |
| 10 #include "core/paint/ObjectPaintProperties.h" | 10 #include "core/paint/ObjectPaintProperties.h" |
| 11 | 11 |
| 12 #include <iomanip> | |
| 13 #include <sstream> | |
| 14 | |
| 12 #ifndef NDEBUG | 15 #ifndef NDEBUG |
| 13 | 16 |
| 14 namespace blink { | 17 namespace blink { |
| 15 namespace { | 18 namespace { |
| 16 | 19 |
| 17 template <typename PropertyTreeNode> | 20 template <typename PropertyTreeNode> |
| 18 class PropertyTreePrinterTraits; | 21 class PropertyTreePrinterTraits; |
| 19 | 22 |
| 20 template <typename PropertyTreeNode> | 23 template <typename PropertyTreeNode> |
| 21 class PropertyTreePrinter { | 24 class PropertyTreePrinter { |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 if (const EffectPaintPropertyNode* effect = paintProperties.effect()) | 185 if (const EffectPaintPropertyNode* effect = paintProperties.effect()) |
| 183 printer.addPropertyNode(effect, "Effect (" + object.debugName() + ") "); | 186 printer.addPropertyNode(effect, "Effect (" + object.debugName() + ") "); |
| 184 } | 187 } |
| 185 | 188 |
| 186 static void printNodeAsString(const EffectPaintPropertyNode* node, StringBui lder& stringBuilder) | 189 static void printNodeAsString(const EffectPaintPropertyNode* node, StringBui lder& stringBuilder) |
| 187 { | 190 { |
| 188 stringBuilder.append(String::format(" opacity=%f", node->opacity())); | 191 stringBuilder.append(String::format(" opacity=%f", node->opacity())); |
| 189 } | 192 } |
| 190 }; | 193 }; |
| 191 | 194 |
| 192 } // anonymous namespace | 195 class PaintPropertyTreeGraphBuilder { |
| 196 public: | |
| 197 PaintPropertyTreeGraphBuilder() { } | |
| 198 | |
| 199 void generateTreeGraph(const FrameView& frameView, StringBuilder& stringBuil der) | |
| 200 { | |
| 201 m_layout.str(""); | |
| 202 m_properties.str(""); | |
| 203 m_ownerEdges.str(""); | |
| 204 m_properties << std::setprecision(2) << std::setiosflags(std::ios_base:: fixed); | |
| 205 | |
| 206 writeFrameViewNode(frameView, nullptr); | |
| 207 | |
| 208 stringBuilder.append("digraph {\n"); | |
| 209 stringBuilder.append("graph [rankdir=BT];\n"); | |
| 210 stringBuilder.append("subgraph cluster_layout {\n"); | |
| 211 std::string layoutStr = m_layout.str(); | |
| 212 stringBuilder.append(layoutStr.c_str(), layoutStr.length()); | |
| 213 stringBuilder.append("}\n"); | |
| 214 stringBuilder.append("subgraph cluster_properties {\n"); | |
| 215 std::string propertiesStr = m_properties.str(); | |
| 216 stringBuilder.append(propertiesStr.c_str(), propertiesStr.length()); | |
| 217 stringBuilder.append("}\n"); | |
| 218 std::string ownersStr = m_ownerEdges.str(); | |
| 219 stringBuilder.append(ownersStr.c_str(), ownersStr.length()); | |
| 220 stringBuilder.append("}\n"); | |
| 221 } | |
| 222 | |
| 223 private: | |
| 224 static String getTagName(Node* n) | |
| 225 { | |
| 226 if (n->isDocumentNode()) | |
| 227 return ""; | |
| 228 if (n->getNodeType() == Node::kCommentNode) | |
| 229 return "COMMENT"; | |
| 230 return n->nodeName(); | |
| 231 } | |
| 232 | |
| 233 static void writeParentEdge(const void* node, const void* parent, const char * color, std::ostream& os) | |
| 234 { | |
| 235 os << "n" << node << " -> " << "n" << parent; | |
| 236 if (color) | |
| 237 os << " [color=" << color << "]"; | |
| 238 os << ";" << std::endl; | |
| 239 } | |
| 240 | |
| 241 void writeOwnerEdge(const void* node, const void* owner) | |
| 242 { | |
| 243 std::ostream& os = m_ownerEdges; | |
| 244 os << "n" << owner << " -> " << "n" << node << " [color=" << s_layoutNod eColor << ", arrowhead=dot, constraint=false];" << std::endl; | |
| 245 } | |
| 246 | |
| 247 void writeTransformEdge(const void* node, const void* transform) | |
| 248 { | |
| 249 std::ostream& os = m_properties; | |
| 250 os << "n" << node << " -> " << "n" << transform << " [color=" << s_trans formNodeColor << "];" << std::endl; | |
| 251 } | |
| 252 | |
| 253 void writePaintPropertyNode(const TransformPaintPropertyNode& node, const vo id* owner, const char* label) | |
| 254 { | |
| 255 std::ostream& os = m_properties; | |
| 256 os << "n" << &node | |
| 257 << " [color=" << s_transformNodeColor | |
| 258 << ", fontcolor=" << s_transformNodeColor | |
| 259 << ", shape=box, label=\"" << label << "\\n"; | |
| 260 | |
| 261 const FloatPoint3D& origin = node.origin(); | |
| 262 os << "origin=("; | |
| 263 os << origin.x() << "," << origin.y() << "," << origin.z() << ")\\n"; | |
| 264 | |
| 265 os << "flattensInheritedTransform=" << (node.flattensInheritedTransform( ) ? "true" : "false") << "\\n"; | |
| 266 os << "renderingContextID=" << node.renderingContextID() << "\\n"; | |
| 267 | |
| 268 const TransformationMatrix& matrix = node.matrix(); | |
| 269 os << "[" << std::setw(8) << matrix.m11() << "," << std::setw(8) << matr ix.m12() << "," << std::setw(8) << matrix.m13() << "," << std::setw(8) << matrix .m14() << "\\n"; | |
| 270 os << std::setw(9) << matrix.m21() << "," << std::setw(8) << matrix.m22( ) << "," << std::setw(8) << matrix.m23() << "," << std::setw(8) << matrix.m24() << "\\n"; | |
| 271 os << std::setw(9) << matrix.m31() << "," << std::setw(8) << matrix.m32( ) << "," << std::setw(8) << matrix.m33() << "," << std::setw(8) << matrix.m34() << "\\n"; | |
| 272 os << std::setw(9) << matrix.m41() << "," << std::setw(8) << matrix.m42( ) << "," << std::setw(8) << matrix.m43() << "," << std::setw(8) << matrix.m44() << "]"; | |
| 273 | |
| 274 TransformationMatrix::DecomposedType decomposition; | |
| 275 if (!node.matrix().decompose(decomposition)) { | |
| 276 os << "\\ndegenerate\"];" << std::endl; | |
| 277 return; | |
| 278 } | |
| 279 | |
| 280 os << "\"];" << std::endl; | |
| 281 | |
| 282 if (owner) | |
| 283 writeOwnerEdge(&node, owner); | |
| 284 if (node.parent()) | |
| 285 writeParentEdge(&node, node.parent(), s_transformNodeColor, os); | |
| 286 } | |
| 287 | |
| 288 void writePaintPropertyNode(const ClipPaintPropertyNode& node, const void* o wner, const char* label) | |
| 289 { | |
| 290 std::ostream& os = m_properties; | |
| 291 os << "n" << &node | |
| 292 << " [color=" << s_clipNodeColor | |
| 293 << ", fontcolor=" << s_clipNodeColor | |
| 294 << ", shape=box, label=\"" << label << "\\n"; | |
| 295 | |
| 296 LayoutRect rect(node.clipRect().rect()); | |
| 297 if (IntRect(rect) == LayoutRect::infiniteIntRect()) | |
| 298 os << "(infinite)"; | |
| 299 else | |
| 300 os << "(" << rect.x() << ", " << rect.y() << ", " << rect.width() << ", " << rect.height() << ")"; | |
| 301 os << "\"];" << std::endl; | |
| 302 | |
| 303 if (owner) | |
| 304 writeOwnerEdge(&node, owner); | |
| 305 if (node.parent()) | |
| 306 writeParentEdge(&node, node.parent(), s_clipNodeColor, os); | |
| 307 if (node.localTransformSpace()) | |
| 308 writeTransformEdge(&node, node.localTransformSpace()); | |
| 309 } | |
| 310 | |
| 311 void writePaintPropertyNode(const EffectPaintPropertyNode& node, const void* owner, const char* label) | |
| 312 { | |
| 313 std::ostream& os = m_properties; | |
| 314 os << "n" << &node << " [shape=diamond, label=\"" << label << "\\n"; | |
| 315 os << "opacity=" << node.opacity() << "\"];" << std::endl; | |
| 316 | |
| 317 if (owner) | |
| 318 writeOwnerEdge(&node, owner); | |
| 319 if (node.parent()) | |
| 320 writeParentEdge(&node, node.parent(), s_effectNodeColor, os); | |
| 321 } | |
| 322 | |
| 323 void writeObjectPaintPropertyNodes(const LayoutObject& object) | |
| 324 { | |
| 325 const ObjectPaintProperties* properties = object.objectPaintProperties() ; | |
| 326 if (!properties) | |
| 327 return; | |
| 328 const TransformPaintPropertyNode* paintOffset = properties->paintOffsetT ranslation(); | |
| 329 if (paintOffset) | |
| 330 writePaintPropertyNode(*paintOffset, &object, "paintOffset"); | |
| 331 const TransformPaintPropertyNode* transform = properties->transform(); | |
| 332 if (transform) | |
| 333 writePaintPropertyNode(*transform, &object, "transform"); | |
| 334 const TransformPaintPropertyNode* perspective = properties->perspective( ); | |
| 335 if (perspective) | |
| 336 writePaintPropertyNode(*perspective, &object, "perspective"); | |
| 337 const TransformPaintPropertyNode* svgLocalToBorderBox = properties->svgL ocalToBorderBoxTransform(); | |
| 338 if (svgLocalToBorderBox) | |
| 339 writePaintPropertyNode(*svgLocalToBorderBox, &object, "svgLocalToBor derBox"); | |
| 340 const TransformPaintPropertyNode* scrollTranslation = properties->scroll Translation(); | |
| 341 if (scrollTranslation) | |
| 342 writePaintPropertyNode(*scrollTranslation, &object, "scrollTranslati on"); | |
| 343 const TransformPaintPropertyNode* scrollbarPaintOffset = properties->scr ollbarPaintOffset(); | |
| 344 if (scrollbarPaintOffset) | |
| 345 writePaintPropertyNode(*scrollbarPaintOffset, &object, "scrollbarPai ntOffset"); | |
| 346 const EffectPaintPropertyNode* effect = properties->effect(); | |
| 347 if (effect) | |
| 348 writePaintPropertyNode(*effect, &object, "effect"); | |
| 349 const ClipPaintPropertyNode* cssClip = properties->cssClip(); | |
| 350 if (cssClip) | |
| 351 writePaintPropertyNode(*cssClip, &object, "cssClip"); | |
| 352 const ClipPaintPropertyNode* cssClipFixedPosition = properties->cssClipF ixedPosition(); | |
| 353 if (cssClipFixedPosition) | |
| 354 writePaintPropertyNode(*cssClipFixedPosition, &object, "cssClipFixed Position"); | |
| 355 const ClipPaintPropertyNode* overflowClip = properties->overflowClip(); | |
| 356 if (overflowClip) | |
| 357 writePaintPropertyNode(*overflowClip, &object, "overflowClip"); | |
| 358 } | |
| 359 | |
| 360 void writeFrameViewPaintPropertyNodes(const FrameView& frameView) | |
| 361 { | |
| 362 TransformPaintPropertyNode* rootTransform = frameView.rootTransform(); | |
| 363 if (rootTransform) | |
| 364 writePaintPropertyNode(*rootTransform, &frameView, "rootTransform"); | |
| 365 ClipPaintPropertyNode* rootClip = frameView.rootClip(); | |
| 366 if (rootClip) | |
| 367 writePaintPropertyNode(*rootClip, &frameView, "rootClip"); | |
| 368 EffectPaintPropertyNode* rootEffect = frameView.rootEffect(); | |
| 369 if (rootEffect) | |
| 370 writePaintPropertyNode(*rootEffect, &frameView, "rootEffect"); | |
| 371 TransformPaintPropertyNode* preTranslation = frameView.preTranslation(); | |
| 372 if (preTranslation) | |
| 373 writePaintPropertyNode(*preTranslation, &frameView, "preTranslation" ); | |
| 374 TransformPaintPropertyNode* scrollTranslation = frameView.scrollTranslat ion(); | |
| 375 if (scrollTranslation) | |
| 376 writePaintPropertyNode(*scrollTranslation, &frameView, "scrollTransl ation"); | |
| 377 ClipPaintPropertyNode* contentClip = frameView.contentClip(); | |
| 378 if (contentClip) | |
| 379 writePaintPropertyNode(*contentClip, &frameView, "contentClip"); | |
| 380 } | |
| 381 | |
| 382 void writeLayoutObjectNode(const LayoutObject& object) | |
| 383 { | |
| 384 std::ostream& os = m_layout; | |
| 385 os << "n" << &object | |
| 386 << " [color=" << s_layoutNodeColor | |
| 387 << ", fontcolor=" << s_layoutNodeColor | |
| 388 << ", label=\"" << object.name(); | |
| 389 Node* node = object.node(); | |
| 390 if (node) { | |
| 391 os << "\\n" << getTagName(node).utf8().data(); | |
| 392 if (node->isElementNode() && toElement(node)->hasID()) | |
| 393 os << "\\nid=" << toElement(node)->getIdAttribute().utf8().data( ); | |
| 394 } | |
| 395 os << "\"];" << std::endl; | |
| 396 const void* parent = object.isLayoutView() ? (const void*) toLayoutView( object).frameView() : (const void*) object.parent(); | |
| 397 writeParentEdge(&object, parent, s_layoutNodeColor, os); | |
| 398 writeObjectPaintPropertyNodes(object); | |
| 399 for (const LayoutObject* child = object.slowFirstChild(); child; child = child->nextSibling()) { | |
| 400 if (child->isColumnSpanAll()) | |
| 401 continue; | |
|
Xianzhu
2016/08/19 04:08:17
It looks fragile to depend on the tree walk order
szager1
2016/08/19 04:52:31
collectPropertyNodes has a few incompatibilities:
Xianzhu
2016/08/20 23:06:48
OK. What if you remove the above two lines? If the
szager1
2016/08/31 00:40:12
Yes, you're right, these two lines are unnecessary
| |
| 402 writeLayoutObjectNode(*child); | |
| 403 } | |
| 404 if (object.isLayoutPart() && toLayoutPart(object).widget() && toLayoutPa rt(object).widget()->isFrameView()) { | |
| 405 FrameView* frameView = static_cast<FrameView*>(toLayoutPart(object). widget()); | |
| 406 writeFrameViewNode(*frameView, &object); | |
| 407 } | |
| 408 } | |
| 409 | |
| 410 void writeFrameViewNode(const FrameView& frameView, const void* parent) | |
| 411 { | |
| 412 std::ostream& os = m_layout; | |
| 413 os << "n" << &frameView | |
| 414 << " [color=" << s_layoutNodeColor | |
| 415 << ", fontcolor=" << s_layoutNodeColor | |
| 416 << ", shape=doublecircle" | |
| 417 << ", label=FrameView];" << std::endl; | |
| 418 | |
| 419 writeFrameViewPaintPropertyNodes(frameView); | |
| 420 if (parent) | |
| 421 writeParentEdge(&frameView, parent, s_layoutNodeColor, os); | |
| 422 LayoutView* layoutView = frameView.layoutView(); | |
| 423 if (layoutView) | |
| 424 writeLayoutObjectNode(*layoutView); | |
| 425 } | |
| 426 | |
| 427 private: | |
| 428 static const char* s_layoutNodeColor; | |
| 429 static const char* s_transformNodeColor; | |
| 430 static const char* s_clipNodeColor; | |
| 431 static const char* s_effectNodeColor; | |
| 432 | |
| 433 std::ostringstream m_layout; | |
| 434 std::ostringstream m_properties; | |
| 435 std::ostringstream m_ownerEdges; | |
| 436 }; | |
| 437 | |
| 438 const char* PaintPropertyTreeGraphBuilder::s_layoutNodeColor = "black"; | |
| 439 const char* PaintPropertyTreeGraphBuilder::s_transformNodeColor = "green"; | |
| 440 const char* PaintPropertyTreeGraphBuilder::s_clipNodeColor = "blue"; | |
| 441 const char* PaintPropertyTreeGraphBuilder::s_effectNodeColor = "black"; | |
| 442 | |
| 443 } // namespace { | |
| 193 } // namespace blink | 444 } // namespace blink |
| 194 | 445 |
| 195 void showTransformPropertyTree(const blink::FrameView& rootFrame) | 446 void showTransformPropertyTree(const blink::FrameView& rootFrame) |
| 196 { | 447 { |
| 197 blink::PropertyTreePrinter<blink::TransformPaintPropertyNode>().showTree(roo tFrame); | 448 blink::PropertyTreePrinter<blink::TransformPaintPropertyNode>().showTree(roo tFrame); |
| 198 } | 449 } |
| 199 | 450 |
| 200 void showClipPropertyTree(const blink::FrameView& rootFrame) | 451 void showClipPropertyTree(const blink::FrameView& rootFrame) |
| 201 { | 452 { |
| 202 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showTree(rootFram e); | 453 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showTree(rootFram e); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 215 void showPaintPropertyPath(const blink::ClipPaintPropertyNode* node) | 466 void showPaintPropertyPath(const blink::ClipPaintPropertyNode* node) |
| 216 { | 467 { |
| 217 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showPath(node); | 468 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showPath(node); |
| 218 } | 469 } |
| 219 | 470 |
| 220 void showPaintPropertyPath(const blink::EffectPaintPropertyNode* node) | 471 void showPaintPropertyPath(const blink::EffectPaintPropertyNode* node) |
| 221 { | 472 { |
| 222 blink::PropertyTreePrinter<blink::EffectPaintPropertyNode>().showPath(node); | 473 blink::PropertyTreePrinter<blink::EffectPaintPropertyNode>().showPath(node); |
| 223 } | 474 } |
| 224 | 475 |
| 476 String paintPropertyTreeGraph(const blink::FrameView& frameView) | |
| 477 { | |
| 478 blink::PaintPropertyTreeGraphBuilder builder; | |
| 479 StringBuilder stringBuilder; | |
| 480 builder.generateTreeGraph(frameView, stringBuilder); | |
| 481 return stringBuilder.toString(); | |
| 482 } | |
| 483 | |
| 225 #endif | 484 #endif |
| OLD | NEW |