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

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

Issue 2732573003: Skip paint property update and visual rect update if no geometry change (Closed)
Patch Set: - Created 3 years, 9 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/FindPaintOffsetAndVisualRectNeedingUpdate.h
diff --git a/third_party/WebKit/Source/core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h b/third_party/WebKit/Source/core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h
new file mode 100644
index 0000000000000000000000000000000000000000..711bd68ba5e372168c2a953a14bc57bac4f20224
--- /dev/null
+++ b/third_party/WebKit/Source/core/paint/FindPaintOffsetAndVisualRectNeedingUpdate.h
@@ -0,0 +1,181 @@
+// Copyright 2017 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 FindPaintOffsetAndVisualRectNeedingUpdate_h
+#define FindPaintOffsetAndVisualRectNeedingUpdate_h
+
+#if DCHECK_IS_ON()
+
+#include "core/layout/LayoutObject.h"
+#include "core/paint/FindPropertiesNeedingUpdate.h"
+#include "core/paint/ObjectPaintInvalidator.h"
+#include "core/paint/PaintInvalidator.h"
+#include "core/paint/PaintLayer.h"
+#include "core/paint/PaintPropertyTreeBuilder.h"
+
+namespace blink {
+
+// This file contains scope classes for catching cases where paint offset or
+// visual rect needed an update but were not marked as such. If paint offset or
+// any visual rect (including visual rect of the object itself, scroll controls,
+// caret, selection, etc.) will change, the object must be marked as such by
+// LayoutObject::setNeedsPaintOffsetAndVisualRectUpdate() (which is a private
+// function called by several public paint-invalidation-flag setting functions).
+
+class FindPaintOffsetNeedingUpdateScope {
+ public:
+ FindPaintOffsetNeedingUpdateScope(
+ const LayoutObject& object,
+ const PaintPropertyTreeBuilderContext& context)
+ : m_object(object),
+ m_context(context),
+ m_oldPaintOffset(object.paintOffset()) {
+ if (object.paintProperties() &&
+ object.paintProperties()->paintOffsetTranslation()) {
+ m_oldPaintOffsetTranslation =
+ object.paintProperties()->paintOffsetTranslation()->clone();
+ }
+ }
+
+ ~FindPaintOffsetNeedingUpdateScope() {
+ if (m_context.isActuallyNeeded)
+ return;
+ DCHECK_OBJECT_PROPERTY_EQ(m_object, &m_oldPaintOffset,
+ &m_object.paintOffset());
+ const auto* paintOffsetTranslation =
+ m_object.paintProperties()
+ ? m_object.paintProperties()->paintOffsetTranslation()
+ : nullptr;
+ DCHECK_OBJECT_PROPERTY_EQ(m_object, m_oldPaintOffsetTranslation.get(),
+ paintOffsetTranslation);
+ }
+
+ private:
+ const LayoutObject& m_object;
+ const PaintPropertyTreeBuilderContext& m_context;
+ LayoutPoint m_oldPaintOffset;
+ RefPtr<const TransformPaintPropertyNode> m_oldPaintOffsetTranslation;
+};
+
+class FindVisualRectNeedingUpdateScopeBase {
+ protected:
+ FindVisualRectNeedingUpdateScopeBase(const LayoutObject& object,
+ const PaintInvalidatorContext& context,
+ const LayoutRect& oldVisualRect)
+ : m_object(object),
+ m_context(context),
+ m_oldVisualRect(oldVisualRect),
+ m_neededVisualRectUpdate(context.needsVisualRectUpdate(object)) {
+ if (m_neededVisualRectUpdate) {
+ DCHECK(!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() ||
+ (context.m_treeBuilderContext &&
+ context.m_treeBuilderContext->isActuallyNeeded));
+ return;
+ }
+ context.m_forceVisualRectUpdateForChecking = true;
+ DCHECK(context.needsVisualRectUpdate(object));
+ }
+
+ ~FindVisualRectNeedingUpdateScopeBase() {
+ m_context.m_forceVisualRectUpdateForChecking = false;
+ DCHECK_EQ(m_neededVisualRectUpdate,
+ m_context.needsVisualRectUpdate(m_object));
+ }
+
+ static LayoutRect inflatedRect(const LayoutRect& r) {
+ LayoutRect result = r;
+ result.inflate(1);
+ return result;
+ }
+
+ void checkVisualRect(const LayoutRect& newVisualRect) {
+ if (m_neededVisualRectUpdate)
+ return;
+ DCHECK((m_oldVisualRect.isEmpty() && newVisualRect.isEmpty()) ||
+ m_object.enclosingLayer()->subtreeIsInvisible() ||
+ m_oldVisualRect == newVisualRect ||
+ // The following check is to tolerate the differences caused by
+ // pixel snapping that may happen for one rect but not for another
+ // while we need neither paint invalidation nor raster invalidation
+ // for the change. This may miss some real subpixel changes of visual
+ // rects. TODO(wangxianzhu): Look into whether we can tighten this
+ // for SPv2.
+ inflatedRect(m_oldVisualRect).contains(newVisualRect) ||
+ inflatedRect(newVisualRect).contains(m_oldVisualRect))
+ << "Visual rect changed without needing update"
+ << " object=" << m_object.debugName()
+ << " old=" << m_oldVisualRect.toString()
+ << " new=" << newVisualRect.toString();
+ }
+
+ const LayoutObject& m_object;
+ const PaintInvalidatorContext& m_context;
+ LayoutRect m_oldVisualRect;
+ bool m_neededVisualRectUpdate;
+};
+
+// For updates of visual rects (e.g. of scroll controls, caret, selection,etc.)
+// contained by an object.
+class FindVisualRectNeedingUpdateScope : FindVisualRectNeedingUpdateScopeBase {
+ public:
+ FindVisualRectNeedingUpdateScope(const LayoutObject& object,
+ const PaintInvalidatorContext& context,
+ const LayoutRect& oldVisualRect,
+ // Must be a reference to a rect that
+ // outlives this scope.
+ const LayoutRect& newVisualRect)
+ : FindVisualRectNeedingUpdateScopeBase(object, context, oldVisualRect),
+ m_newVisualRectRef(newVisualRect) {}
+
+ ~FindVisualRectNeedingUpdateScope() { checkVisualRect(m_newVisualRectRef); }
+
+ private:
+ const LayoutRect& m_newVisualRectRef;
+};
+
+// For updates of object visual rect and location.
+class FindObjectVisualRectNeedingUpdateScope
+ : FindVisualRectNeedingUpdateScopeBase {
+ public:
+ FindObjectVisualRectNeedingUpdateScope(const LayoutObject& object,
+ const PaintInvalidatorContext& context)
+ : FindVisualRectNeedingUpdateScopeBase(object,
+ context,
+ object.visualRect()),
+ m_oldLocation(ObjectPaintInvalidator(object).locationInBacking()) {}
+
+ ~FindObjectVisualRectNeedingUpdateScope() {
+ checkVisualRect(m_object.visualRect());
+ checkLocation();
+ }
+
+ void checkLocation() {
+ if (m_neededVisualRectUpdate)
+ return;
+ LayoutPoint newLocation =
+ ObjectPaintInvalidator(m_object).locationInBacking();
+ // Location of LayoutText and non-root SVG is location of the visual rect
+ // which have been checked above.
+ DCHECK(m_object.isText() || m_object.isSVGChild() ||
+ newLocation == m_oldLocation ||
+ m_object.enclosingLayer()->subtreeIsInvisible() ||
+ // See checkVisualRect for the issue of approximation.
+ LayoutRect(-1, -1, 2, 2)
+ .contains(LayoutRect(LayoutPoint(newLocation - m_oldLocation),
+ LayoutSize())))
+ << "Location changed without needing update"
+ << " object=" << m_object.debugName()
+ << " old=" << m_oldLocation.toString()
+ << " new=" << newLocation.toString();
+ }
+
+ private:
+ LayoutPoint m_oldLocation;
+};
+
+} // namespace blink
+
+#endif // DCHECK_IS_ON()
+
+#endif // FindPaintOffsetAndVisualRectNeedingUpdate_h

Powered by Google App Engine
This is Rietveld 408576698