Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(549)

Unified Diff: third_party/WebKit/Source/core/paint/PaintPropertyUnderInvalidationChecks.h

Issue 2404213004: Implement incremental paint property tree rebuilding (Closed)
Patch Set: Fix bug in how svg local to border box was updated, no longer crash in tests Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/paint/PaintPropertyUnderInvalidationChecks.h
diff --git a/third_party/WebKit/Source/core/paint/PaintPropertyUnderInvalidationChecks.h b/third_party/WebKit/Source/core/paint/PaintPropertyUnderInvalidationChecks.h
new file mode 100644
index 0000000000000000000000000000000000000000..ecf18d31b339276bdc678d77e1c0026360c530f2
--- /dev/null
+++ b/third_party/WebKit/Source/core/paint/PaintPropertyUnderInvalidationChecks.h
@@ -0,0 +1,143 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PaintPropertyUnderInvalidationChecks_h
+#define PaintPropertyUnderInvalidationChecks_h
+
+// Only check for property underInvalidation in debug builds.
+// TODO(pdr): Consider a runtime enabled feature for under-invalidation.
+#ifndef NDEBUG
+
+namespace blink {
+
+#define DCHECK_PTR_VAL_EQ(ptrA, ptrB) \
+ DCHECK((!!ptrA == !!ptrB) && ((!ptrA && !ptrB) || (*ptrA == *ptrB)));
+
+// This file contains two scope classes for catching paint property under-
+// invalidation of FrameViews and LayoutObjects. UnderInvalidation occurs when
+// paint-property-affecting state on an object changes without invalidating the
+// paint properties (see: {FrameView, LayoutObject}::setPaintPropertiesInvalid).
+//
+// Both scope classes work by recording the paint property state before
+// rebuilding the properties of an object. The object is then artifically
+// marked as invalid and the properties are rebuilt. When the checker goes out
+// of scope, any changes to the properties are detected with DCHECKs.
+
+class FrameViewUnderInvalidationCheckScope {
+ public:
+ static std::unique_ptr<FrameViewUnderInvalidationCheckScope> createIfNeeded(
+ FrameView* frameView) {
+ if (frameView->paintPropertiesValid())
+ return wrapUnique(new FrameViewUnderInvalidationCheckScope(frameView));
+ return nullptr;
+ }
+
+ FrameViewUnderInvalidationCheckScope(FrameView* frameView)
+ : m_frameView(frameView) {
+ // Mark the properties as invalid to ensure they are rebuilt.
+ m_frameView->setPaintPropertiesInvalid();
+ if (auto* preTranslation = m_frameView->preTranslation())
+ m_preTranslation = preTranslation->clone();
+ if (auto* contentClip = m_frameView->contentClip())
+ m_contentClip = contentClip->clone();
+ if (auto* scrollTranslation = m_frameView->scrollTranslation())
+ m_scrollTranslation = scrollTranslation;
+ if (auto* scroll = m_frameView->scroll())
+ m_scroll = scroll;
+ }
+
+ ~FrameViewUnderInvalidationCheckScope() {
+ // If paint properties are not marked as invalid but still change, we are
+ // missing a call to FrameView::setPaintPropertiesInvalid();
+ DCHECK_PTR_VAL_EQ(m_preTranslation, m_frameView->preTranslation());
+ DCHECK_PTR_VAL_EQ(m_contentClip, m_frameView->contentClip());
+ DCHECK_PTR_VAL_EQ(m_scrollTranslation, m_frameView->scrollTranslation());
+ DCHECK_PTR_VAL_EQ(m_scroll, m_frameView->scroll());
+ // Restore original clean properties bit.
+ m_frameView->setPaintPropertiesValid();
+ }
+
+ private:
+ Persistent<FrameView> m_frameView;
+ RefPtr<TransformPaintPropertyNode> m_preTranslation;
+ RefPtr<ClipPaintPropertyNode> m_contentClip;
+ RefPtr<TransformPaintPropertyNode> m_scrollTranslation;
+ RefPtr<ScrollPaintPropertyNode> m_scroll;
+};
+
+class ObjectUnderInvalidationCheckScope {
+ public:
+ static std::unique_ptr<ObjectUnderInvalidationCheckScope> createIfNeeded(
+ const LayoutObject& object) {
+ if (object.paintPropertiesValid())
+ return wrapUnique(new ObjectUnderInvalidationCheckScope(object));
+ return nullptr;
+ }
+
+ ObjectUnderInvalidationCheckScope(const LayoutObject& object)
+ : m_object(object) {
+ // Mark the properties as invalid to ensure they are rebuilt.
+ const_cast<LayoutObject&>(m_object).setPaintPropertiesInvalid();
+ if (const auto* properties = m_object.paintProperties())
+ m_properties = properties->clone();
+ }
+
+ ~ObjectUnderInvalidationCheckScope() {
+ // If paint properties are not marked as invalid but still change, we are
+ // missing a call to LayoutObject::setPaintPropertiesInvalid();
+ const auto* objectProperties = m_object.paintProperties();
+ if (m_properties && objectProperties) {
+ DCHECK_PTR_VAL_EQ(m_properties->paintOffsetTranslation(),
+ objectProperties->paintOffsetTranslation());
+ DCHECK_PTR_VAL_EQ(m_properties->transform(),
+ objectProperties->transform());
+ DCHECK_PTR_VAL_EQ(m_properties->effect(), objectProperties->effect());
+ DCHECK_PTR_VAL_EQ(m_properties->cssClip(), objectProperties->cssClip());
+ DCHECK_PTR_VAL_EQ(m_properties->cssClipFixedPosition(),
+ objectProperties->cssClipFixedPosition());
+ DCHECK_PTR_VAL_EQ(m_properties->innerBorderRadiusClip(),
+ objectProperties->innerBorderRadiusClip());
+ DCHECK_PTR_VAL_EQ(m_properties->overflowClip(),
+ objectProperties->overflowClip());
+ DCHECK_PTR_VAL_EQ(m_properties->perspective(),
+ objectProperties->perspective());
+ DCHECK_PTR_VAL_EQ(m_properties->svgLocalToBorderBoxTransform(),
+ objectProperties->svgLocalToBorderBoxTransform());
+ DCHECK_PTR_VAL_EQ(m_properties->scrollTranslation(),
+ objectProperties->scrollTranslation());
+ DCHECK_PTR_VAL_EQ(m_properties->scrollbarPaintOffset(),
+ objectProperties->scrollbarPaintOffset());
+ const auto* borderBox = m_properties->localBorderBoxProperties();
+ const auto* objectBorderBox =
+ objectProperties->localBorderBoxProperties();
+ if (borderBox && objectBorderBox) {
+ DCHECK(borderBox->paintOffset == objectBorderBox->paintOffset);
+ DCHECK_EQ(borderBox->propertyTreeState.transform(),
+ objectBorderBox->propertyTreeState.transform());
+ DCHECK_EQ(borderBox->propertyTreeState.clip(),
+ objectBorderBox->propertyTreeState.clip());
+ DCHECK_EQ(borderBox->propertyTreeState.effect(),
+ objectBorderBox->propertyTreeState.effect());
+ DCHECK_EQ(borderBox->propertyTreeState.scroll(),
+ objectBorderBox->propertyTreeState.scroll());
+ } else {
+ DCHECK_EQ(!!borderBox, !!objectBorderBox);
+ }
+ } else {
+ DCHECK_EQ(!!m_properties, !!objectProperties);
+ }
+ // Restore original clean properties bit.
+ const_cast<LayoutObject&>(m_object).setPaintPropertiesValid();
+ }
+
+ private:
+ const LayoutObject& m_object;
+ std::unique_ptr<const ObjectPaintProperties> m_properties;
+};
+
+} // namespace blink
+
+#endif // NDEBUG
+
+#endif // PaintPropertyUnderInvalidationChecks_h

Powered by Google App Engine
This is Rietveld 408576698