| 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 << "\\n(degenerate)"; |
| 277 |
| 278 os << "\"];" << std::endl; |
| 279 |
| 280 if (owner) |
| 281 writeOwnerEdge(&node, owner); |
| 282 if (node.parent()) |
| 283 writeParentEdge(&node, node.parent(), s_transformNodeColor, os); |
| 284 } |
| 285 |
| 286 void writePaintPropertyNode(const ClipPaintPropertyNode& node, const void* o
wner, const char* label) |
| 287 { |
| 288 std::ostream& os = m_properties; |
| 289 os << "n" << &node |
| 290 << " [color=" << s_clipNodeColor |
| 291 << ", fontcolor=" << s_clipNodeColor |
| 292 << ", shape=box, label=\"" << label << "\\n"; |
| 293 |
| 294 LayoutRect rect(node.clipRect().rect()); |
| 295 if (IntRect(rect) == LayoutRect::infiniteIntRect()) |
| 296 os << "(infinite)"; |
| 297 else |
| 298 os << "(" << rect.x() << ", " << rect.y() << ", " << rect.width() <<
", " << rect.height() << ")"; |
| 299 os << "\"];" << std::endl; |
| 300 |
| 301 if (owner) |
| 302 writeOwnerEdge(&node, owner); |
| 303 if (node.parent()) |
| 304 writeParentEdge(&node, node.parent(), s_clipNodeColor, os); |
| 305 if (node.localTransformSpace()) |
| 306 writeTransformEdge(&node, node.localTransformSpace()); |
| 307 } |
| 308 |
| 309 void writePaintPropertyNode(const EffectPaintPropertyNode& node, const void*
owner, const char* label) |
| 310 { |
| 311 std::ostream& os = m_properties; |
| 312 os << "n" << &node << " [shape=diamond, label=\"" << label << "\\n"; |
| 313 os << "opacity=" << node.opacity() << "\"];" << std::endl; |
| 314 |
| 315 if (owner) |
| 316 writeOwnerEdge(&node, owner); |
| 317 if (node.parent()) |
| 318 writeParentEdge(&node, node.parent(), s_effectNodeColor, os); |
| 319 } |
| 320 |
| 321 void writeObjectPaintPropertyNodes(const LayoutObject& object) |
| 322 { |
| 323 const ObjectPaintProperties* properties = object.objectPaintProperties()
; |
| 324 if (!properties) |
| 325 return; |
| 326 const TransformPaintPropertyNode* paintOffset = properties->paintOffsetT
ranslation(); |
| 327 if (paintOffset) |
| 328 writePaintPropertyNode(*paintOffset, &object, "paintOffset"); |
| 329 const TransformPaintPropertyNode* transform = properties->transform(); |
| 330 if (transform) |
| 331 writePaintPropertyNode(*transform, &object, "transform"); |
| 332 const TransformPaintPropertyNode* perspective = properties->perspective(
); |
| 333 if (perspective) |
| 334 writePaintPropertyNode(*perspective, &object, "perspective"); |
| 335 const TransformPaintPropertyNode* svgLocalToBorderBox = properties->svgL
ocalToBorderBoxTransform(); |
| 336 if (svgLocalToBorderBox) |
| 337 writePaintPropertyNode(*svgLocalToBorderBox, &object, "svgLocalToBor
derBox"); |
| 338 const TransformPaintPropertyNode* scrollTranslation = properties->scroll
Translation(); |
| 339 if (scrollTranslation) |
| 340 writePaintPropertyNode(*scrollTranslation, &object, "scrollTranslati
on"); |
| 341 const TransformPaintPropertyNode* scrollbarPaintOffset = properties->scr
ollbarPaintOffset(); |
| 342 if (scrollbarPaintOffset) |
| 343 writePaintPropertyNode(*scrollbarPaintOffset, &object, "scrollbarPai
ntOffset"); |
| 344 const EffectPaintPropertyNode* effect = properties->effect(); |
| 345 if (effect) |
| 346 writePaintPropertyNode(*effect, &object, "effect"); |
| 347 const ClipPaintPropertyNode* cssClip = properties->cssClip(); |
| 348 if (cssClip) |
| 349 writePaintPropertyNode(*cssClip, &object, "cssClip"); |
| 350 const ClipPaintPropertyNode* cssClipFixedPosition = properties->cssClipF
ixedPosition(); |
| 351 if (cssClipFixedPosition) |
| 352 writePaintPropertyNode(*cssClipFixedPosition, &object, "cssClipFixed
Position"); |
| 353 const ClipPaintPropertyNode* overflowClip = properties->overflowClip(); |
| 354 if (overflowClip) { |
| 355 writePaintPropertyNode(*overflowClip, &object, "overflowClip"); |
| 356 if (object.isLayoutView() && overflowClip->parent()) |
| 357 writePaintPropertyNode(*overflowClip->parent(), nullptr, "rootCl
ip"); |
| 358 } |
| 359 } |
| 360 |
| 361 void writeFrameViewPaintPropertyNodes(const FrameView& frameView) |
| 362 { |
| 363 TransformPaintPropertyNode* rootTransform = frameView.rootTransform(); |
| 364 if (rootTransform) |
| 365 writePaintPropertyNode(*rootTransform, &frameView, "rootTransform"); |
| 366 ClipPaintPropertyNode* rootClip = frameView.rootClip(); |
| 367 if (rootClip) |
| 368 writePaintPropertyNode(*rootClip, &frameView, "rootClip"); |
| 369 EffectPaintPropertyNode* rootEffect = frameView.rootEffect(); |
| 370 if (rootEffect) |
| 371 writePaintPropertyNode(*rootEffect, &frameView, "rootEffect"); |
| 372 TransformPaintPropertyNode* preTranslation = frameView.preTranslation(); |
| 373 if (preTranslation) |
| 374 writePaintPropertyNode(*preTranslation, &frameView, "preTranslation"
); |
| 375 TransformPaintPropertyNode* scrollTranslation = frameView.scrollTranslat
ion(); |
| 376 if (scrollTranslation) |
| 377 writePaintPropertyNode(*scrollTranslation, &frameView, "scrollTransl
ation"); |
| 378 ClipPaintPropertyNode* contentClip = frameView.contentClip(); |
| 379 if (contentClip) |
| 380 writePaintPropertyNode(*contentClip, &frameView, "contentClip"); |
| 381 } |
| 382 |
| 383 void writeLayoutObjectNode(const LayoutObject& object) |
| 384 { |
| 385 std::ostream& os = m_layout; |
| 386 os << "n" << &object |
| 387 << " [color=" << s_layoutNodeColor |
| 388 << ", fontcolor=" << s_layoutNodeColor |
| 389 << ", label=\"" << object.name(); |
| 390 Node* node = object.node(); |
| 391 if (node) { |
| 392 os << "\\n" << getTagName(node).utf8().data(); |
| 393 if (node->isElementNode() && toElement(node)->hasID()) |
| 394 os << "\\nid=" << toElement(node)->getIdAttribute().utf8().data(
); |
| 395 } |
| 396 os << "\"];" << std::endl; |
| 397 const void* parent = object.isLayoutView() ? (const void*) toLayoutView(
object).frameView() : (const void*) object.parent(); |
| 398 writeParentEdge(&object, parent, s_layoutNodeColor, os); |
| 399 writeObjectPaintPropertyNodes(object); |
| 400 for (const LayoutObject* child = object.slowFirstChild(); child; child =
child->nextSibling()) |
| 401 writeLayoutObjectNode(*child); |
| 402 if (object.isLayoutPart() && toLayoutPart(object).widget() && toLayoutPa
rt(object).widget()->isFrameView()) { |
| 403 FrameView* frameView = static_cast<FrameView*>(toLayoutPart(object).
widget()); |
| 404 writeFrameViewNode(*frameView, &object); |
| 405 } |
| 406 } |
| 407 |
| 408 void writeFrameViewNode(const FrameView& frameView, const void* parent) |
| 409 { |
| 410 std::ostream& os = m_layout; |
| 411 os << "n" << &frameView |
| 412 << " [color=" << s_layoutNodeColor |
| 413 << ", fontcolor=" << s_layoutNodeColor |
| 414 << ", shape=doublecircle" |
| 415 << ", label=FrameView];" << std::endl; |
| 416 |
| 417 writeFrameViewPaintPropertyNodes(frameView); |
| 418 if (parent) |
| 419 writeParentEdge(&frameView, parent, s_layoutNodeColor, os); |
| 420 LayoutView* layoutView = frameView.layoutView(); |
| 421 if (layoutView) |
| 422 writeLayoutObjectNode(*layoutView); |
| 423 } |
| 424 |
| 425 private: |
| 426 static const char* s_layoutNodeColor; |
| 427 static const char* s_transformNodeColor; |
| 428 static const char* s_clipNodeColor; |
| 429 static const char* s_effectNodeColor; |
| 430 |
| 431 std::ostringstream m_layout; |
| 432 std::ostringstream m_properties; |
| 433 std::ostringstream m_ownerEdges; |
| 434 }; |
| 435 |
| 436 const char* PaintPropertyTreeGraphBuilder::s_layoutNodeColor = "black"; |
| 437 const char* PaintPropertyTreeGraphBuilder::s_transformNodeColor = "green"; |
| 438 const char* PaintPropertyTreeGraphBuilder::s_clipNodeColor = "blue"; |
| 439 const char* PaintPropertyTreeGraphBuilder::s_effectNodeColor = "black"; |
| 440 |
| 441 } // namespace { |
| 193 } // namespace blink | 442 } // namespace blink |
| 194 | 443 |
| 195 void showTransformPropertyTree(const blink::FrameView& rootFrame) | 444 void showTransformPropertyTree(const blink::FrameView& rootFrame) |
| 196 { | 445 { |
| 197 blink::PropertyTreePrinter<blink::TransformPaintPropertyNode>().showTree(roo
tFrame); | 446 blink::PropertyTreePrinter<blink::TransformPaintPropertyNode>().showTree(roo
tFrame); |
| 198 } | 447 } |
| 199 | 448 |
| 200 void showClipPropertyTree(const blink::FrameView& rootFrame) | 449 void showClipPropertyTree(const blink::FrameView& rootFrame) |
| 201 { | 450 { |
| 202 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showTree(rootFram
e); | 451 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showTree(rootFram
e); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 215 void showPaintPropertyPath(const blink::ClipPaintPropertyNode* node) | 464 void showPaintPropertyPath(const blink::ClipPaintPropertyNode* node) |
| 216 { | 465 { |
| 217 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showPath(node); | 466 blink::PropertyTreePrinter<blink::ClipPaintPropertyNode>().showPath(node); |
| 218 } | 467 } |
| 219 | 468 |
| 220 void showPaintPropertyPath(const blink::EffectPaintPropertyNode* node) | 469 void showPaintPropertyPath(const blink::EffectPaintPropertyNode* node) |
| 221 { | 470 { |
| 222 blink::PropertyTreePrinter<blink::EffectPaintPropertyNode>().showPath(node); | 471 blink::PropertyTreePrinter<blink::EffectPaintPropertyNode>().showPath(node); |
| 223 } | 472 } |
| 224 | 473 |
| 474 String paintPropertyTreeGraph(const blink::FrameView& frameView) |
| 475 { |
| 476 blink::PaintPropertyTreeGraphBuilder builder; |
| 477 StringBuilder stringBuilder; |
| 478 builder.generateTreeGraph(frameView, stringBuilder); |
| 479 return stringBuilder.toString(); |
| 480 } |
| 481 |
| 225 #endif | 482 #endif |
| OLD | NEW |