diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc index d502d06679e6a..f2d0e38d372c4 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_image.cc @@ -25,7 +25,9 @@ #include "third_party/blink/renderer/core/layout/svg/layout_svg_image.h" +#include "base/logging.h" #include "third_party/blink/renderer/core/layout/hit_test_location.h" +#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/layout/hit_test_result.h" #include "third_party/blink/renderer/core/layout/layout_image_resource.h" #include "third_party/blink/renderer/core/layout/layout_object_inlines.h" @@ -249,6 +251,15 @@ bool LayoutSVGImage::NodeAtPoint(HitTestResult& result, void LayoutSVGImage::ImageChanged(WrappedImagePtr, CanDeferInvalidation defer) { NOT_DESTROYED(); + if (!GetDocument().GetPage() || + !GetDocument().GetPage()->IsOrdinary()) { + LOG(ERROR) << "[POC] LayoutSVGImage::ImageChanged in isolated doc " + << "url=" << GetDocument().Url().GetString().Utf8() + << " new_size=" << CalculateObjectSize().ToString() + << " old_size=" << object_bounding_box_.size().ToString() + << " will_SetNeedsLayout=" + << (CalculateObjectSize() != object_bounding_box_.size()); + } // Notify parent resources that we've changed. This also invalidates // references from resources (filters) that may have a cached // representation of this image/layout object. diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc index 85e5ccb1d0494..cfdfd4328429f 100644 --- a/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc +++ b/third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc @@ -23,6 +23,8 @@ #include +#include "base/debug/dump_without_crashing.h" +#include "base/logging.h" #include "base/memory/ptr_util.h" #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h" #include "third_party/blink/renderer/core/layout/svg/svg_layout_support.h" @@ -235,6 +237,13 @@ PaintRecord LayoutSVGResourcePattern::AsPaintRecord( const auto* pattern_layout_object = To( pattern_content_element->GetLayoutObject()); DCHECK(pattern_layout_object); + // [POC] Diagnostic: log if the pattern subtree is dirty at paint time. + if (pattern_layout_object->NeedsLayout()) { + LOG(ERROR) << "[POC][HIT] LayoutSVGResourcePattern::AsPaintRecord: pattern " + << "subtree NeedsLayout()! obj=" << pattern_layout_object + << " in doc=" << &pattern_layout_object->GetDocument(); + base::debug::DumpWithoutCrashing(); + } DCHECK(!pattern_layout_object->NeedsLayout()); SubtreeContentTransformScope content_transform_scope(tile_transform); diff --git a/third_party/blink/renderer/core/paint/clip_path_clipper.cc b/third_party/blink/renderer/core/paint/clip_path_clipper.cc index bd3bc38351daa..777152d1c7a0f 100644 --- a/third_party/blink/renderer/core/paint/clip_path_clipper.cc +++ b/third_party/blink/renderer/core/paint/clip_path_clipper.cc @@ -37,6 +37,8 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/transforms/affine_transform.h" #include "third_party/skia/include/pathops/SkPathOps.h" +#include "base/debug/dump_without_crashing.h" +#include "base/logging.h" #include "ui/gfx/geometry/rect_conversions.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -76,6 +78,14 @@ LayoutSVGResourceClipper* ResolveElementReference( if (DisplayLockUtilities::LockedAncestorPreventingLayout(*resource_clipper)) return nullptr; + // [POC] Diagnostic: SECURITY_DCHECK is debug-only and only checks the + // container itself, not the subtree. Log if the subtree is dirty. + if (resource_clipper->NeedsLayout()) { + LOG(ERROR) << "[POC][HIT] ResolveElementReference: clip-path subtree " + << "NeedsLayout()! clipper=" << resource_clipper << " in doc=" + << &resource_clipper->GetDocument(); + base::debug::DumpWithoutCrashing(); + } SECURITY_DCHECK(!resource_clipper->SelfNeedsFullLayout()); return resource_clipper; } diff --git a/third_party/blink/renderer/core/paint/svg_shape_painter.cc b/third_party/blink/renderer/core/paint/svg_shape_painter.cc index ea10cbf775b73..e84d754be4898 100644 --- a/third_party/blink/renderer/core/paint/svg_shape_painter.cc +++ b/third_party/blink/renderer/core/paint/svg_shape_painter.cc @@ -4,6 +4,8 @@ #include "third_party/blink/renderer/core/paint/svg_shape_painter.h" +#include "base/debug/dump_without_crashing.h" +#include "base/logging.h" #include "base/types/optional_util.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_resource_marker.h" #include "third_party/blink/renderer/core/layout/svg/layout_svg_shape.h" @@ -285,6 +287,23 @@ void SVGShapePainter::PaintMarker(const PaintInfo& paint_info, float stroke_width) { marker.ClearInvalidationMask(); + static int paint_count = 0; + if (++paint_count <= 5) { + LOG(ERROR) << "[POC] PaintMarker called (#" << paint_count + << "), marker NeedsLayout=" << marker.NeedsLayout() + << " doc=" << marker.GetDocument().Url().GetString().Utf8(); + } + // [POC] Diagnostic: external resource markers are painted without re-running + // the resource document's lifecycle. If anything dirtied the marker subtree + // after SVGResourceDocumentContent::LoadingFinished(), we'd be painting a + // dirty NG layout subtree here. + if (marker.NeedsLayout()) { + LOG(ERROR) << "[POC][HIT] PaintMarker: marker subtree NeedsLayout()! " + << "marker=" << &marker << " in doc=" + << &marker.GetDocument(); + base::debug::DumpWithoutCrashing(); + } + if (!marker.ShouldPaint()) return; diff --git a/third_party/blink/renderer/core/svg/svg_fe_image_element.cc b/third_party/blink/renderer/core/svg/svg_fe_image_element.cc index 3434520ff6e28..f5f212d888a87 100644 --- a/third_party/blink/renderer/core/svg/svg_fe_image_element.cc +++ b/third_party/blink/renderer/core/svg/svg_fe_image_element.cc @@ -21,6 +21,7 @@ #include "third_party/blink/renderer/core/svg/svg_fe_image_element.h" +#include "base/logging.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/id_target_observer.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" @@ -149,6 +150,10 @@ void SVGFEImageElement::RemovedFrom(ContainerNode& root_parent) { } void SVGFEImageElement::ImageNotifyFinished(ImageResourceContent*) { + LOG(ERROR) << "[POC] SVGFEImageElement::ImageNotifyFinished doc=" + << GetDocument().Url().GetString().Utf8() + << " load_event_finished=" + << GetDocument().LoadEventFinished(); if (!isConnected()) return; diff --git a/third_party/blink/renderer/core/svg/svg_resource_document_content.cc b/third_party/blink/renderer/core/svg/svg_resource_document_content.cc index fef101ebe80b7..eb55386ca8abe 100644 --- a/third_party/blink/renderer/core/svg/svg_resource_document_content.cc +++ b/third_party/blink/renderer/core/svg/svg_resource_document_content.cc @@ -22,9 +22,11 @@ #include "third_party/blink/renderer/core/svg/svg_resource_document_content.h" +#include "base/logging.h" #include "base/notreached.h" #include "base/task/single_thread_task_runner.h" #include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/local_frame_view.h" #include "third_party/blink/renderer/core/loader/resource/svg_document_resource.h" #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/svg/graphics/isolated_svg_document_host.h" @@ -146,14 +148,22 @@ SVGResourceDocumentContent::UpdateDocument(scoped_refptr data, // so we can check if we have a usable document and notify our listeners. If // not, then we need to wait for the async load completion callback. if (!document_host_->IsLoaded()) { + LOG(ERROR) << "[POC] SVGResourceDocumentContent::UpdateDocument: " + << "going ASYNC, request_url=" + << request_url.GetString().Utf8(); return UpdateResult::kAsync; } + LOG(ERROR) << "[POC] SVGResourceDocumentContent::UpdateDocument: " + << "completed SYNC, request_url=" + << request_url.GetString().Utf8(); LoadingFinished(); return UpdateResult::kCompleted; } void SVGResourceDocumentContent::LoadingFinished() { LocalFrame* frame = document_host_->GetFrame(); + LOG(ERROR) << "[POC] SVGResourceDocumentContent::LoadingFinished url=" + << url_.GetString().Utf8() << " (single lifecycle pass)"; frame->View()->UpdateAllLifecyclePhasesExceptPaint( DocumentUpdateReason::kSVGImage); UpdateStatus(ResourceStatus::kCached); @@ -241,6 +251,14 @@ SVGResourceTarget* SVGResourceDocumentContent::GetResourceTarget( } void SVGResourceDocumentContent::ContentChanged() { + if (status_ == ResourceStatus::kCached) { + LocalFrame* frame = + document_host_ ? document_host_->GetFrame() : nullptr; + bool dirty = frame && frame->View() && frame->View()->NeedsLayout(); + LOG(ERROR) << "[POC] SVGResourceDocumentContent::ContentChanged " + << "POST-LOAD url=" << url_.GetString().Utf8() + << " inner_view_needs_layout=" << dirty; + } for (auto& observer : observers_) { observer->ResourceContentChanged(this); }