| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef PaintPropertyUnderInvalidationChecks_h |
| 6 #define PaintPropertyUnderInvalidationChecks_h |
| 7 |
| 8 // Only check for property underInvalidation in debug builds. |
| 9 // TODO(pdr): Consider a runtime enabled feature for under-invalidation. |
| 10 #ifndef NDEBUG |
| 11 |
| 12 namespace blink { |
| 13 |
| 14 #define DCHECK_PTR_VAL_EQ(ptrA, ptrB) \ |
| 15 DCHECK((!!ptrA == !!ptrB) && ((!ptrA && !ptrB) || (*ptrA == *ptrB))); |
| 16 |
| 17 // This file contains two scope classes for catching paint property under- |
| 18 // invalidation of FrameViews and LayoutObjects. UnderInvalidation occurs when |
| 19 // paint-property-affecting state on an object changes without invalidating the |
| 20 // paint properties (see: {FrameView, LayoutObject}::setPaintPropertiesInvalid). |
| 21 // |
| 22 // Both scope classes work by recording the paint property state before |
| 23 // rebuilding the properties of an object. The object is then artifically |
| 24 // marked as invalid and the properties are rebuilt. When the checker goes out |
| 25 // of scope, any changes to the properties are detected with DCHECKs. |
| 26 |
| 27 class FrameViewUnderInvalidationCheckScope { |
| 28 public: |
| 29 static std::unique_ptr<FrameViewUnderInvalidationCheckScope> createIfNeeded( |
| 30 FrameView* frameView) { |
| 31 if (frameView->paintPropertiesValid()) |
| 32 return wrapUnique(new FrameViewUnderInvalidationCheckScope(frameView)); |
| 33 return nullptr; |
| 34 } |
| 35 |
| 36 FrameViewUnderInvalidationCheckScope(FrameView* frameView) |
| 37 : m_frameView(frameView) { |
| 38 // Mark the properties as invalid to ensure they are rebuilt. |
| 39 m_frameView->setPaintPropertiesInvalid(); |
| 40 if (auto* preTranslation = m_frameView->preTranslation()) |
| 41 m_preTranslation = preTranslation->clone(); |
| 42 if (auto* contentClip = m_frameView->contentClip()) |
| 43 m_contentClip = contentClip->clone(); |
| 44 if (auto* scrollTranslation = m_frameView->scrollTranslation()) |
| 45 m_scrollTranslation = scrollTranslation; |
| 46 if (auto* scroll = m_frameView->scroll()) |
| 47 m_scroll = scroll; |
| 48 } |
| 49 |
| 50 ~FrameViewUnderInvalidationCheckScope() { |
| 51 // If paint properties are not marked as invalid but still change, we are |
| 52 // missing a call to FrameView::setPaintPropertiesInvalid(); |
| 53 DCHECK_PTR_VAL_EQ(m_preTranslation, m_frameView->preTranslation()); |
| 54 DCHECK_PTR_VAL_EQ(m_contentClip, m_frameView->contentClip()); |
| 55 DCHECK_PTR_VAL_EQ(m_scrollTranslation, m_frameView->scrollTranslation()); |
| 56 DCHECK_PTR_VAL_EQ(m_scroll, m_frameView->scroll()); |
| 57 // Restore original clean properties bit. |
| 58 m_frameView->setPaintPropertiesValid(); |
| 59 } |
| 60 |
| 61 private: |
| 62 Persistent<FrameView> m_frameView; |
| 63 RefPtr<TransformPaintPropertyNode> m_preTranslation; |
| 64 RefPtr<ClipPaintPropertyNode> m_contentClip; |
| 65 RefPtr<TransformPaintPropertyNode> m_scrollTranslation; |
| 66 RefPtr<ScrollPaintPropertyNode> m_scroll; |
| 67 }; |
| 68 |
| 69 class ObjectUnderInvalidationCheckScope { |
| 70 public: |
| 71 static std::unique_ptr<ObjectUnderInvalidationCheckScope> createIfNeeded( |
| 72 const LayoutObject& object) { |
| 73 if (object.paintPropertiesValid()) |
| 74 return wrapUnique(new ObjectUnderInvalidationCheckScope(object)); |
| 75 return nullptr; |
| 76 } |
| 77 |
| 78 ObjectUnderInvalidationCheckScope(const LayoutObject& object) |
| 79 : m_object(object) { |
| 80 // Mark the properties as invalid to ensure they are rebuilt. |
| 81 const_cast<LayoutObject&>(m_object).setPaintPropertiesInvalid(); |
| 82 if (const auto* properties = m_object.paintProperties()) |
| 83 m_properties = properties->clone(); |
| 84 } |
| 85 |
| 86 ~ObjectUnderInvalidationCheckScope() { |
| 87 // If paint properties are not marked as invalid but still change, we are |
| 88 // missing a call to LayoutObject::setPaintPropertiesInvalid(); |
| 89 const auto* objectProperties = m_object.paintProperties(); |
| 90 if (m_properties && objectProperties) { |
| 91 DCHECK_PTR_VAL_EQ(m_properties->paintOffsetTranslation(), |
| 92 objectProperties->paintOffsetTranslation()); |
| 93 DCHECK_PTR_VAL_EQ(m_properties->transform(), |
| 94 objectProperties->transform()); |
| 95 DCHECK_PTR_VAL_EQ(m_properties->effect(), objectProperties->effect()); |
| 96 DCHECK_PTR_VAL_EQ(m_properties->cssClip(), objectProperties->cssClip()); |
| 97 DCHECK_PTR_VAL_EQ(m_properties->cssClipFixedPosition(), |
| 98 objectProperties->cssClipFixedPosition()); |
| 99 DCHECK_PTR_VAL_EQ(m_properties->innerBorderRadiusClip(), |
| 100 objectProperties->innerBorderRadiusClip()); |
| 101 DCHECK_PTR_VAL_EQ(m_properties->overflowClip(), |
| 102 objectProperties->overflowClip()); |
| 103 DCHECK_PTR_VAL_EQ(m_properties->perspective(), |
| 104 objectProperties->perspective()); |
| 105 DCHECK_PTR_VAL_EQ(m_properties->svgLocalToBorderBoxTransform(), |
| 106 objectProperties->svgLocalToBorderBoxTransform()); |
| 107 DCHECK_PTR_VAL_EQ(m_properties->scrollTranslation(), |
| 108 objectProperties->scrollTranslation()); |
| 109 DCHECK_PTR_VAL_EQ(m_properties->scrollbarPaintOffset(), |
| 110 objectProperties->scrollbarPaintOffset()); |
| 111 const auto* borderBox = m_properties->localBorderBoxProperties(); |
| 112 const auto* objectBorderBox = |
| 113 objectProperties->localBorderBoxProperties(); |
| 114 if (borderBox && objectBorderBox) { |
| 115 DCHECK(borderBox->paintOffset == objectBorderBox->paintOffset); |
| 116 DCHECK_EQ(borderBox->propertyTreeState.transform(), |
| 117 objectBorderBox->propertyTreeState.transform()); |
| 118 DCHECK_EQ(borderBox->propertyTreeState.clip(), |
| 119 objectBorderBox->propertyTreeState.clip()); |
| 120 DCHECK_EQ(borderBox->propertyTreeState.effect(), |
| 121 objectBorderBox->propertyTreeState.effect()); |
| 122 DCHECK_EQ(borderBox->propertyTreeState.scroll(), |
| 123 objectBorderBox->propertyTreeState.scroll()); |
| 124 } else { |
| 125 DCHECK_EQ(!!borderBox, !!objectBorderBox); |
| 126 } |
| 127 } else { |
| 128 DCHECK_EQ(!!m_properties, !!objectProperties); |
| 129 } |
| 130 // Restore original clean properties bit. |
| 131 const_cast<LayoutObject&>(m_object).setPaintPropertiesValid(); |
| 132 } |
| 133 |
| 134 private: |
| 135 const LayoutObject& m_object; |
| 136 std::unique_ptr<const ObjectPaintProperties> m_properties; |
| 137 }; |
| 138 |
| 139 } // namespace blink |
| 140 |
| 141 #endif // NDEBUG |
| 142 |
| 143 #endif // PaintPropertyUnderInvalidationChecks_h |
| OLD | NEW |