| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
| 4 * (C) 2000 Dirk Mueller (mueller@kde.org) | 4 * (C) 2000 Dirk Mueller (mueller@kde.org) |
| 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) | 5 * (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com) |
| 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserv
ed. |
| 7 * Copyright (C) 2009 Google Inc. All rights reserved. | 7 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 8 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) |
| 9 * | 9 * |
| 10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 #include "core/layout/LayoutScrollbarPart.h" | 62 #include "core/layout/LayoutScrollbarPart.h" |
| 63 #include "core/layout/LayoutTableCaption.h" | 63 #include "core/layout/LayoutTableCaption.h" |
| 64 #include "core/layout/LayoutTableCell.h" | 64 #include "core/layout/LayoutTableCell.h" |
| 65 #include "core/layout/LayoutTableCol.h" | 65 #include "core/layout/LayoutTableCol.h" |
| 66 #include "core/layout/LayoutTableRow.h" | 66 #include "core/layout/LayoutTableRow.h" |
| 67 #include "core/layout/LayoutTheme.h" | 67 #include "core/layout/LayoutTheme.h" |
| 68 #include "core/layout/LayoutView.h" | 68 #include "core/layout/LayoutView.h" |
| 69 #include "core/layout/ng/layout_ng_block_flow.h" | 69 #include "core/layout/ng/layout_ng_block_flow.h" |
| 70 #include "core/page/AutoscrollController.h" | 70 #include "core/page/AutoscrollController.h" |
| 71 #include "core/page/Page.h" | 71 #include "core/page/Page.h" |
| 72 #include "core/paint/ObjectPaintInvalidator.h" |
| 72 #include "core/paint/ObjectPaintProperties.h" | 73 #include "core/paint/ObjectPaintProperties.h" |
| 73 #include "core/paint/PaintLayer.h" | 74 #include "core/paint/PaintLayer.h" |
| 74 #include "core/style/ContentData.h" | 75 #include "core/style/ContentData.h" |
| 75 #include "core/style/CursorData.h" | 76 #include "core/style/CursorData.h" |
| 76 #include "platform/HostWindow.h" | 77 #include "platform/HostWindow.h" |
| 77 #include "platform/RuntimeEnabledFeatures.h" | 78 #include "platform/RuntimeEnabledFeatures.h" |
| 78 #include "platform/TracedValue.h" | 79 #include "platform/TracedValue.h" |
| 79 #include "platform/geometry/TransformState.h" | 80 #include "platform/geometry/TransformState.h" |
| 80 #include "wtf/allocator/Partitions.h" | 81 #include "wtf/allocator/Partitions.h" |
| 81 #include "wtf/text/StringBuilder.h" | 82 #include "wtf/text/StringBuilder.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 unsigned m_bitfields; | 127 unsigned m_bitfields; |
| 127 unsigned m_bitfields2; | 128 unsigned m_bitfields2; |
| 128 LayoutRect rect; // Stores the previous paint invalidation rect. | 129 LayoutRect rect; // Stores the previous paint invalidation rect. |
| 129 LayoutPoint position; // Stores the previous position from the paint invalid
ation container. | 130 LayoutPoint position; // Stores the previous position from the paint invalid
ation container. |
| 130 }; | 131 }; |
| 131 | 132 |
| 132 static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), "LayoutObj
ect should stay small"); | 133 static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), "LayoutObj
ect should stay small"); |
| 133 | 134 |
| 134 bool LayoutObject::s_affectsParentBlock = false; | 135 bool LayoutObject::s_affectsParentBlock = false; |
| 135 | 136 |
| 136 typedef HashMap<const LayoutObject*, LayoutRect> SelectionPaintInvalidationMap; | |
| 137 static SelectionPaintInvalidationMap* selectionPaintInvalidationMap = nullptr; | |
| 138 | |
| 139 // The pointer to paint properties is implemented as a global hash map temporari
ly, | 137 // The pointer to paint properties is implemented as a global hash map temporari
ly, |
| 140 // to avoid memory regression during the transition towards SPv2. | 138 // to avoid memory regression during the transition towards SPv2. |
| 141 typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> Obj
ectPaintPropertiesMap; | 139 typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> Obj
ectPaintPropertiesMap; |
| 142 static ObjectPaintPropertiesMap& objectPaintPropertiesMap() | 140 static ObjectPaintPropertiesMap& objectPaintPropertiesMap() |
| 143 { | 141 { |
| 144 DEFINE_STATIC_LOCAL(ObjectPaintPropertiesMap, staticObjectPaintPropertiesMap
, ()); | 142 DEFINE_STATIC_LOCAL(ObjectPaintPropertiesMap, staticObjectPaintPropertiesMap
, ()); |
| 145 return staticObjectPaintPropertiesMap; | 143 return staticObjectPaintPropertiesMap; |
| 146 } | 144 } |
| 147 | 145 |
| 148 void* LayoutObject::operator new(size_t sz) | 146 void* LayoutObject::operator new(size_t sz) |
| (...skipping 952 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1101 void addJsonObjectForRect(TracedValue* value, const char* name, const T& rect) | 1099 void addJsonObjectForRect(TracedValue* value, const char* name, const T& rect) |
| 1102 { | 1100 { |
| 1103 value->beginDictionary(name); | 1101 value->beginDictionary(name); |
| 1104 value->setDouble("x", rect.x()); | 1102 value->setDouble("x", rect.x()); |
| 1105 value->setDouble("y", rect.y()); | 1103 value->setDouble("y", rect.y()); |
| 1106 value->setDouble("width", rect.width()); | 1104 value->setDouble("width", rect.width()); |
| 1107 value->setDouble("height", rect.height()); | 1105 value->setDouble("height", rect.height()); |
| 1108 value->endDictionary(); | 1106 value->endDictionary(); |
| 1109 } | 1107 } |
| 1110 | 1108 |
| 1111 template <typename T> | |
| 1112 void addJsonObjectForPoint(TracedValue* value, const char* name, const T& point) | |
| 1113 { | |
| 1114 value->beginDictionary(name); | |
| 1115 value->setDouble("x", point.x()); | |
| 1116 value->setDouble("y", point.y()); | |
| 1117 value->endDictionary(); | |
| 1118 } | |
| 1119 | |
| 1120 static std::unique_ptr<TracedValue> jsonObjectForPaintInvalidationInfo(const Lay
outRect& rect, const String& invalidationReason) | 1109 static std::unique_ptr<TracedValue> jsonObjectForPaintInvalidationInfo(const Lay
outRect& rect, const String& invalidationReason) |
| 1121 { | 1110 { |
| 1122 std::unique_ptr<TracedValue> value = TracedValue::create(); | 1111 std::unique_ptr<TracedValue> value = TracedValue::create(); |
| 1123 addJsonObjectForRect(value.get(), "rect", rect); | 1112 addJsonObjectForRect(value.get(), "rect", rect); |
| 1124 value->setString("invalidation_reason", invalidationReason); | 1113 value->setString("invalidation_reason", invalidationReason); |
| 1125 return value; | 1114 return value; |
| 1126 } | 1115 } |
| 1127 | 1116 |
| 1128 static void invalidatePaintRectangleOnWindow(const LayoutBoxModelObject& paintIn
validationContainer, const IntRect& dirtyRect) | 1117 static void invalidatePaintRectangleOnWindow(const LayoutBoxModelObject& paintIn
validationContainer, const IntRect& dirtyRect) |
| 1129 { | 1118 { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1200 { | 1189 { |
| 1201 if (PaintLayer* paintingLayer = this->paintingLayer()) | 1190 if (PaintLayer* paintingLayer = this->paintingLayer()) |
| 1202 paintingLayer->setNeedsRepaint(); | 1191 paintingLayer->setNeedsRepaint(); |
| 1203 } | 1192 } |
| 1204 | 1193 |
| 1205 void LayoutObject::invalidateDisplayItemClients(PaintInvalidationReason reason)
const | 1194 void LayoutObject::invalidateDisplayItemClients(PaintInvalidationReason reason)
const |
| 1206 { | 1195 { |
| 1207 invalidateDisplayItemClient(*this, reason); | 1196 invalidateDisplayItemClient(*this, reason); |
| 1208 } | 1197 } |
| 1209 | 1198 |
| 1210 void LayoutObject::invalidateDisplayItemClientsWithPaintInvalidationState(const
PaintInvalidationState& paintInvalidationState, PaintInvalidationReason reason)
const | |
| 1211 { | |
| 1212 paintInvalidationState.paintingLayer().setNeedsRepaint(); | |
| 1213 invalidateDisplayItemClients(reason); | |
| 1214 } | |
| 1215 | |
| 1216 bool LayoutObject::compositedScrollsWithRespectTo(const LayoutBoxModelObject& pa
intInvalidationContainer) const | 1199 bool LayoutObject::compositedScrollsWithRespectTo(const LayoutBoxModelObject& pa
intInvalidationContainer) const |
| 1217 { | 1200 { |
| 1218 return paintInvalidationContainer.usesCompositedScrolling() && this != &pain
tInvalidationContainer; | 1201 return paintInvalidationContainer.usesCompositedScrolling() && this != &pain
tInvalidationContainer; |
| 1219 } | 1202 } |
| 1220 | 1203 |
| 1221 IntSize LayoutObject::scrollAdjustmentForPaintInvalidation(const LayoutBoxModelO
bject& paintInvalidationContainer) const | 1204 IntSize LayoutObject::scrollAdjustmentForPaintInvalidation(const LayoutBoxModelO
bject& paintInvalidationContainer) const |
| 1222 { | 1205 { |
| 1223 // Non-composited scrolling should be included in the bounds of scrolled ite
ms. Since mapToVisualRectInAncestorSpace does not include | 1206 // Non-composited scrolling should be included in the bounds of scrolled ite
ms. Since mapToVisualRectInAncestorSpace does not include |
| 1224 // scrolling of the ancestor, we need to add it back in after. | 1207 // scrolling of the ancestor, we need to add it back in after. |
| 1225 if (paintInvalidationContainer.isBox() && !paintInvalidationContainer.usesCo
mpositedScrolling() && this != &paintInvalidationContainer) { | 1208 if (paintInvalidationContainer.isBox() && !paintInvalidationContainer.usesCo
mpositedScrolling() && this != &paintInvalidationContainer) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1246 dirtyRectOnBacking.move(scrollAdjustmentForPaintInvalidation(paintInvalidati
onContainer)); | 1229 dirtyRectOnBacking.move(scrollAdjustmentForPaintInvalidation(paintInvalidati
onContainer)); |
| 1247 | 1230 |
| 1248 invalidatePaintUsingContainer(paintInvalidationContainer, dirtyRectOnBacking
, PaintInvalidationRectangle); | 1231 invalidatePaintUsingContainer(paintInvalidationContainer, dirtyRectOnBacking
, PaintInvalidationRectangle); |
| 1249 | 1232 |
| 1250 slowSetPaintingLayerNeedsRepaint(); | 1233 slowSetPaintingLayerNeedsRepaint(); |
| 1251 invalidateDisplayItemClients(PaintInvalidationRectangle); | 1234 invalidateDisplayItemClients(PaintInvalidationRectangle); |
| 1252 } | 1235 } |
| 1253 | 1236 |
| 1254 void LayoutObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInv
alidationState) | 1237 void LayoutObject::invalidateTreeIfNeeded(const PaintInvalidationState& paintInv
alidationState) |
| 1255 { | 1238 { |
| 1256 ASSERT(!needsLayout()); | 1239 ensureIsReadyForPaintInvalidation(); |
| 1257 | 1240 |
| 1258 // If we didn't need paint invalidation then our children don't need as well
. | 1241 // If we didn't need paint invalidation then our children don't need as well
. |
| 1259 // Skip walking down the tree as everything should be fine below us. | 1242 // Skip walking down the tree as everything should be fine below us. |
| 1260 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) | 1243 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) |
| 1261 return; | 1244 return; |
| 1262 | 1245 |
| 1263 PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *th
is); | 1246 PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *th
is); |
| 1264 | 1247 |
| 1265 if (mayNeedPaintInvalidationSubtree()) | 1248 if (mayNeedPaintInvalidationSubtree()) |
| 1266 newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinConta
iner(); | 1249 newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinConta
iner(); |
| 1267 | 1250 |
| 1268 PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidatio
nState); | 1251 PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidatio
nState); |
| 1269 clearPaintInvalidationFlags(newPaintInvalidationState); | 1252 clearPaintInvalidationFlags(); |
| 1270 | 1253 |
| 1271 newPaintInvalidationState.updateForChildren(reason); | 1254 newPaintInvalidationState.updateForChildren(reason); |
| 1272 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); | 1255 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); |
| 1273 } | 1256 } |
| 1274 | 1257 |
| 1275 void LayoutObject::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationStat
e& childPaintInvalidationState) | 1258 void LayoutObject::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationStat
e& childPaintInvalidationState) |
| 1276 { | 1259 { |
| 1277 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli
ng()) { | 1260 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli
ng()) { |
| 1278 // Column spanners are invalidated through their placeholders. | 1261 // Column spanners are invalidated through their placeholders. |
| 1279 // See LayoutMultiColumnSpannerPlaceholder::invalidatePaintOfSubtreesIfN
eeded(). | 1262 // See LayoutMultiColumnSpannerPlaceholder::invalidatePaintOfSubtreesIfN
eeded(). |
| 1280 if (child->isColumnSpanAll()) | 1263 if (child->isColumnSpanAll()) |
| 1281 continue; | 1264 continue; |
| 1282 child->invalidateTreeIfNeeded(childPaintInvalidationState); | 1265 child->invalidateTreeIfNeeded(childPaintInvalidationState); |
| 1283 } | 1266 } |
| 1284 } | 1267 } |
| 1285 | 1268 |
| 1286 static std::unique_ptr<TracedValue> jsonObjectForOldAndNewRects(const LayoutRect
& oldRect, const LayoutPoint& oldLocation, const LayoutRect& newRect, const Layo
utPoint& newLocation) | |
| 1287 { | |
| 1288 std::unique_ptr<TracedValue> value = TracedValue::create(); | |
| 1289 addJsonObjectForRect(value.get(), "oldRect", oldRect); | |
| 1290 addJsonObjectForPoint(value.get(), "oldLocation", oldLocation); | |
| 1291 addJsonObjectForRect(value.get(), "newRect", newRect); | |
| 1292 addJsonObjectForPoint(value.get(), "newLocation", newLocation); | |
| 1293 return value; | |
| 1294 } | |
| 1295 | |
| 1296 LayoutRect LayoutObject::selectionRectInViewCoordinates() const | 1269 LayoutRect LayoutObject::selectionRectInViewCoordinates() const |
| 1297 { | 1270 { |
| 1298 LayoutRect selectionRect = localSelectionRect(); | 1271 LayoutRect selectionRect = localSelectionRect(); |
| 1299 if (!selectionRect.isEmpty()) | 1272 if (!selectionRect.isEmpty()) |
| 1300 mapToVisualRectInAncestorSpace(view(), selectionRect); | 1273 mapToVisualRectInAncestorSpace(view(), selectionRect); |
| 1301 return selectionRect; | 1274 return selectionRect; |
| 1302 } | 1275 } |
| 1303 | 1276 |
| 1304 LayoutRect LayoutObject::previousSelectionRectForPaintInvalidation() const | |
| 1305 { | |
| 1306 if (!selectionPaintInvalidationMap) | |
| 1307 return LayoutRect(); | |
| 1308 | |
| 1309 return selectionPaintInvalidationMap->get(this); | |
| 1310 } | |
| 1311 | |
| 1312 void LayoutObject::setPreviousSelectionRectForPaintInvalidation(const LayoutRect
& selectionRect) | |
| 1313 { | |
| 1314 if (!selectionPaintInvalidationMap) { | |
| 1315 if (selectionRect.isEmpty()) | |
| 1316 return; | |
| 1317 selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); | |
| 1318 } | |
| 1319 | |
| 1320 if (selectionRect.isEmpty()) | |
| 1321 selectionPaintInvalidationMap->remove(this); | |
| 1322 else | |
| 1323 selectionPaintInvalidationMap->set(this, selectionRect); | |
| 1324 } | |
| 1325 | |
| 1326 inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject
& paintInvalidationContainer, const PaintInvalidationState& paintInvalidationSta
te, PaintInvalidationReason invalidationReason) | |
| 1327 { | |
| 1328 // Update selection rect when we are doing full invalidation (in case that t
he object is moved, composite status changed, etc.) | |
| 1329 // or shouldInvalidationSelection is set (in case that the selection itself
changed). | |
| 1330 bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); | |
| 1331 if (!fullInvalidation && !shouldInvalidateSelection()) | |
| 1332 return; | |
| 1333 | |
| 1334 LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); | |
| 1335 LayoutRect newSelectionRect = localSelectionRect(); | |
| 1336 if (!newSelectionRect.isEmpty()) | |
| 1337 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelecti
onRect); | |
| 1338 | |
| 1339 newSelectionRect.move(scrollAdjustmentForPaintInvalidation(paintInvalidation
Container)); | |
| 1340 | |
| 1341 setPreviousSelectionRectForPaintInvalidation(newSelectionRect); | |
| 1342 | |
| 1343 if (!fullInvalidation) { | |
| 1344 fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelect
ion, oldSelectionRect, newSelectionRect); | |
| 1345 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidation
State, PaintInvalidationSelection); | |
| 1346 } | |
| 1347 } | |
| 1348 | |
| 1349 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid
ationState& paintInvalidationState) | 1277 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid
ationState& paintInvalidationState) |
| 1350 { | 1278 { |
| 1351 ASSERT(&paintInvalidationState.currentObject() == this); | 1279 DCHECK(&paintInvalidationState.currentObject() == this); |
| 1352 | 1280 |
| 1353 if (styleRef().hasOutline()) { | 1281 if (styleRef().hasOutline()) { |
| 1354 PaintLayer& layer = paintInvalidationState.paintingLayer(); | 1282 PaintLayer& layer = paintInvalidationState.paintingLayer(); |
| 1355 if (layer.layoutObject() != this) | 1283 if (layer.layoutObject() != this) |
| 1356 layer.setNeedsPaintPhaseDescendantOutlines(); | 1284 layer.setNeedsPaintPhaseDescendantOutlines(); |
| 1357 } | 1285 } |
| 1358 | 1286 |
| 1359 LayoutView* v = view(); | 1287 LayoutView* v = view(); |
| 1360 if (v->document().printing()) | 1288 if (v->document().printing()) |
| 1361 return PaintInvalidationNone; // Don't invalidate paints if we're printi
ng. | 1289 return PaintInvalidationNone; // Don't invalidate paints if we're printi
ng. |
| 1362 | 1290 |
| 1291 PaintInvalidatorContextAdapter context(paintInvalidationState); |
| 1292 |
| 1363 const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationSt
ate.paintInvalidationContainer(); | 1293 const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationSt
ate.paintInvalidationContainer(); |
| 1364 ASSERT(paintInvalidationContainer == containerForPaintInvalidation()); | 1294 DCHECK(paintInvalidationContainer == containerForPaintInvalidation()); |
| 1365 | 1295 |
| 1366 const LayoutRect oldBounds = previousPaintInvalidationRect(); | 1296 context.oldBounds = previousPaintInvalidationRect(); |
| 1367 const LayoutPoint oldLocation = RuntimeEnabledFeatures::slimmingPaintInvalid
ationEnabled() ? LayoutPoint() : previousPositionFromPaintInvalidationBacking(); | 1297 context.oldLocation = previousPositionFromPaintInvalidationBacking(); |
| 1368 LayoutRect newBounds = paintInvalidationState.computePaintInvalidationRectIn
Backing(); | 1298 context.newBounds = paintInvalidationState.computePaintInvalidationRectInBac
king(); |
| 1369 LayoutPoint newLocation = RuntimeEnabledFeatures::slimmingPaintInvalidationE
nabled() ? LayoutPoint() : paintInvalidationState.computePositionFromPaintInvali
dationBacking(); | 1299 context.newLocation = paintInvalidationState.computePositionFromPaintInvalid
ationBacking(); |
| 1370 | 1300 |
| 1371 IntSize adjustment = scrollAdjustmentForPaintInvalidation(paintInvalidationC
ontainer); | 1301 IntSize adjustment = scrollAdjustmentForPaintInvalidation(paintInvalidationC
ontainer); |
| 1372 newLocation.move(adjustment); | 1302 context.newLocation.move(adjustment); |
| 1373 newBounds.move(adjustment); | 1303 context.newBounds.move(adjustment); |
| 1374 | 1304 |
| 1375 setPreviousPaintInvalidationRect(newBounds); | 1305 setPreviousPaintInvalidationRect(context.newBounds); |
| 1376 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) | 1306 setPreviousPositionFromPaintInvalidationBacking(context.newLocation); |
| 1377 setPreviousPositionFromPaintInvalidationBacking(newLocation); | |
| 1378 | 1307 |
| 1379 if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() &&
paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly())
{ | 1308 if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() &&
paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly())
{ |
| 1380 // We are done updating the paint invalidation rect. No other paint inva
lidation work to do for this object. | 1309 // We are done updating the paint invalidation rect. No other paint inva
lidation work to do for this object. |
| 1381 return PaintInvalidationNone; | 1310 return PaintInvalidationNone; |
| 1382 } | 1311 } |
| 1383 | 1312 |
| 1384 PaintInvalidationReason invalidationReason = getPaintInvalidationReason(pain
tInvalidationState, oldBounds, oldLocation, newBounds, newLocation); | 1313 return invalidatePaintIfNeeded(context); |
| 1385 | |
| 1386 // We need to invalidate the selection before checking for whether we are do
ing a full invalidation. | |
| 1387 // This is because we need to update the old rect regardless. | |
| 1388 invalidateSelectionIfNeeded(paintInvalidationContainer, paintInvalidationSta
te, invalidationReason); | |
| 1389 | |
| 1390 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "LayoutObject:
:invalidatePaintIfNeeded()", | |
| 1391 "object", this->debugName().ascii(), | |
| 1392 "info", jsonObjectForOldAndNewRects(oldBounds, oldLocation, newBounds, n
ewLocation)); | |
| 1393 | |
| 1394 bool backgroundObscured = backgroundIsKnownToBeObscured(); | |
| 1395 if (!isFullPaintInvalidationReason(invalidationReason) && backgroundObscured
!= m_bitfields.previousBackgroundObscured()) | |
| 1396 invalidationReason = PaintInvalidationBackgroundObscurationChange; | |
| 1397 m_bitfields.setPreviousBackgroundObscured(backgroundObscured); | |
| 1398 | |
| 1399 if (invalidationReason == PaintInvalidationNone || invalidationReason == Pai
ntInvalidationDelayedFull) { | |
| 1400 // TODO(trchen): Currently we don't keep track of paint offset of layout
objects. | |
| 1401 // There are corner cases that the display items need to be invalidated
for paint offset | |
| 1402 // mutation, but incurs no pixel difference (i.e. bounds stay the same)
so no rect-based | |
| 1403 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. | |
| 1404 // This is a workaround to force display items to update paint offset. | |
| 1405 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paint
InvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) | |
| 1406 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalida
tionState, PaintInvalidationLocationChange); | |
| 1407 | |
| 1408 return invalidationReason; | |
| 1409 } | |
| 1410 | |
| 1411 if (invalidationReason == PaintInvalidationIncremental) | |
| 1412 incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newB
ounds, newLocation); | |
| 1413 else | |
| 1414 fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, old
Bounds, newBounds); | |
| 1415 | |
| 1416 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationStat
e, invalidationReason); | |
| 1417 return invalidationReason; | |
| 1418 } | 1314 } |
| 1419 | 1315 |
| 1420 PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInva
lidationState& paintInvalidationState, | 1316 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid
atorContext& context) const |
| 1421 const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalida
tionBacking, | |
| 1422 const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalida
tionBacking) const | |
| 1423 { | 1317 { |
| 1424 if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) | 1318 return ObjectPaintInvalidator(*this, context).invalidatePaintIfNeeded(); |
| 1425 return PaintInvalidationSubtree; | |
| 1426 | |
| 1427 if (shouldDoFullPaintInvalidation()) | |
| 1428 return m_bitfields.fullPaintInvalidationReason(); | |
| 1429 | |
| 1430 if (paintedOutputOfObjectHasNoEffect()) | |
| 1431 return PaintInvalidationNone; | |
| 1432 | |
| 1433 // The outline may change shape because of position change of descendants. F
or simplicity, | |
| 1434 // just force full paint invalidation if this object is marked for checking
paint invalidation | |
| 1435 // for any reason. | |
| 1436 if (styleRef().hasOutline()) | |
| 1437 return PaintInvalidationOutline; | |
| 1438 | |
| 1439 bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositio
nFromPaintInvalidationBacking; | |
| 1440 | |
| 1441 // If the bounds are the same then we know that none of the statements below | |
| 1442 // can match, so we can early out. | |
| 1443 if (oldBounds == newBounds) | |
| 1444 return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocati
onChange : PaintInvalidationNone; | |
| 1445 | |
| 1446 // If we shifted, we don't know the exact reason so we are conservative and
trigger a full invalidation. Shifting could | |
| 1447 // be caused by some layout property (left / top) or some in-flow layoutObje
ct inserted / removed before us in the tree. | |
| 1448 if (newBounds.location() != oldBounds.location()) | |
| 1449 return PaintInvalidationBoundsChange; | |
| 1450 | |
| 1451 // If the size is zero on one of our bounds then we know we're going to have | |
| 1452 // to do a full invalidation of either old bounds or new bounds. If we fall | |
| 1453 // into the incremental invalidation we'll issue two invalidations instead | |
| 1454 // of one. | |
| 1455 if (oldBounds.isEmpty()) | |
| 1456 return PaintInvalidationBecameVisible; | |
| 1457 if (newBounds.isEmpty()) | |
| 1458 return PaintInvalidationBecameInvisible; | |
| 1459 | |
| 1460 if (locationChanged) | |
| 1461 return PaintInvalidationLocationChange; | |
| 1462 | |
| 1463 return PaintInvalidationIncremental; | |
| 1464 } | 1319 } |
| 1465 | 1320 |
| 1466 void LayoutObject::adjustInvalidationRectForCompositedScrolling(LayoutRect& rect
, const LayoutBoxModelObject& paintInvalidationContainer) const | 1321 void LayoutObject::adjustInvalidationRectForCompositedScrolling(LayoutRect& rect
, const LayoutBoxModelObject& paintInvalidationContainer) const |
| 1467 { | 1322 { |
| 1468 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { | 1323 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { |
| 1469 LayoutSize offset(-toLayoutBox(&paintInvalidationContainer)->scrolledCon
tentOffset()); | 1324 LayoutSize offset(-toLayoutBox(&paintInvalidationContainer)->scrolledCon
tentOffset()); |
| 1470 rect.move(offset); | 1325 rect.move(offset); |
| 1471 } | 1326 } |
| 1472 } | 1327 } |
| 1473 | 1328 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1485 m_previousPaintInvalidationRect.move(LayoutSize(scrollDelta)); | 1340 m_previousPaintInvalidationRect.move(LayoutSize(scrollDelta)); |
| 1486 } | 1341 } |
| 1487 | 1342 |
| 1488 void LayoutObject::clearPreviousPaintInvalidationRects() | 1343 void LayoutObject::clearPreviousPaintInvalidationRects() |
| 1489 { | 1344 { |
| 1490 setPreviousPaintInvalidationRect(LayoutRect()); | 1345 setPreviousPaintInvalidationRect(LayoutRect()); |
| 1491 // After clearing ("invalidating" the paint invalidation rects, mark this ob
ject as needing to re-compute them. | 1346 // After clearing ("invalidating" the paint invalidation rects, mark this ob
ject as needing to re-compute them. |
| 1492 setShouldDoFullPaintInvalidation(); | 1347 setShouldDoFullPaintInvalidation(); |
| 1493 } | 1348 } |
| 1494 | 1349 |
| 1495 void LayoutObject::incrementallyInvalidatePaint(const LayoutBoxModelObject& pain
tInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds
, const LayoutPoint& positionFromPaintInvalidationBacking) | |
| 1496 { | |
| 1497 ASSERT(oldBounds.location() == newBounds.location()); | |
| 1498 | |
| 1499 LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); | |
| 1500 if (deltaRight > 0) { | |
| 1501 LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight,
newBounds.height()); | |
| 1502 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe
ct, PaintInvalidationIncremental); | |
| 1503 } else if (deltaRight < 0) { | |
| 1504 LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight
, oldBounds.height()); | |
| 1505 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe
ct, PaintInvalidationIncremental); | |
| 1506 } | |
| 1507 | |
| 1508 LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); | |
| 1509 if (deltaBottom > 0) { | |
| 1510 LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.w
idth(), deltaBottom); | |
| 1511 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe
ct, PaintInvalidationIncremental); | |
| 1512 } else if (deltaBottom < 0) { | |
| 1513 LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.w
idth(), -deltaBottom); | |
| 1514 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe
ct, PaintInvalidationIncremental); | |
| 1515 } | |
| 1516 } | |
| 1517 | |
| 1518 void LayoutObject::fullyInvalidatePaint(const LayoutBoxModelObject& paintInvalid
ationContainer, PaintInvalidationReason invalidationReason, const LayoutRect& ol
dBounds, const LayoutRect& newBounds) | |
| 1519 { | |
| 1520 // The following logic avoids invalidating twice if one set of bounds contai
ns the other. | |
| 1521 if (!newBounds.contains(oldBounds)) { | |
| 1522 LayoutRect invalidationRect = oldBounds; | |
| 1523 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe
ct, invalidationReason); | |
| 1524 | |
| 1525 if (oldBounds.contains(newBounds)) | |
| 1526 return; | |
| 1527 } | |
| 1528 | |
| 1529 LayoutRect invalidationRect = newBounds; | |
| 1530 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect,
invalidationReason); | |
| 1531 } | |
| 1532 | |
| 1533 LayoutRect LayoutObject::absoluteClippedOverflowRect() const | 1350 LayoutRect LayoutObject::absoluteClippedOverflowRect() const |
| 1534 { | 1351 { |
| 1535 LayoutRect rect = localOverflowRectForPaintInvalidation(); | 1352 LayoutRect rect = localOverflowRectForPaintInvalidation(); |
| 1536 mapToVisualRectInAncestorSpace(view(), rect); | 1353 mapToVisualRectInAncestorSpace(view(), rect); |
| 1537 return rect; | 1354 return rect; |
| 1538 } | 1355 } |
| 1539 | 1356 |
| 1540 LayoutRect LayoutObject::localOverflowRectForPaintInvalidation() const | 1357 LayoutRect LayoutObject::localOverflowRectForPaintInvalidation() const |
| 1541 { | 1358 { |
| 1542 ASSERT_NOT_REACHED(); | 1359 ASSERT_NOT_REACHED(); |
| (...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2608 // m_style is null in cases of partial construction. Any handler we added | 2425 // m_style is null in cases of partial construction. Any handler we added |
| 2609 // previously may have already been removed by the Document independently. | 2426 // previously may have already been removed by the Document independently. |
| 2610 if (node() && !node()->isTextNode() && m_style && m_style->getTouchAction()
!= TouchActionAuto) { | 2427 if (node() && !node()->isTextNode() && m_style && m_style->getTouchAction()
!= TouchActionAuto) { |
| 2611 EventHandlerRegistry& registry = document().frameHost()->eventHandlerReg
istry(); | 2428 EventHandlerRegistry& registry = document().frameHost()->eventHandlerReg
istry(); |
| 2612 if (registry.eventHandlerTargets(EventHandlerRegistry::TouchStartOrMoveE
ventBlocking)->contains(node())) | 2429 if (registry.eventHandlerTargets(EventHandlerRegistry::TouchStartOrMoveE
ventBlocking)->contains(node())) |
| 2613 registry.didRemoveEventHandler(*node(), EventHandlerRegistry::TouchS
tartOrMoveEventBlocking); | 2430 registry.didRemoveEventHandler(*node(), EventHandlerRegistry::TouchS
tartOrMoveEventBlocking); |
| 2614 } | 2431 } |
| 2615 | 2432 |
| 2616 setAncestorLineBoxDirty(false); | 2433 setAncestorLineBoxDirty(false); |
| 2617 | 2434 |
| 2618 if (selectionPaintInvalidationMap) | 2435 ObjectPaintInvalidator::objectWillBeDestroyed(*this); |
| 2619 selectionPaintInvalidationMap->remove(this); | |
| 2620 | 2436 |
| 2621 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 2437 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 2622 objectPaintPropertiesMap().remove(this); | 2438 objectPaintPropertiesMap().remove(this); |
| 2623 | 2439 |
| 2624 clearLayoutRootIfNeeded(); | 2440 clearLayoutRootIfNeeded(); |
| 2625 | 2441 |
| 2626 if (m_style) { | 2442 if (m_style) { |
| 2627 for (const FillLayer* bgLayer = &m_style->backgroundLayers(); bgLayer; b
gLayer = bgLayer->next()) { | 2443 for (const FillLayer* bgLayer = &m_style->backgroundLayers(); bgLayer; b
gLayer = bgLayer->next()) { |
| 2628 if (StyleImage* backgroundImage = bgLayer->image()) | 2444 if (StyleImage* backgroundImage = bgLayer->image()) |
| 2629 backgroundImage->removeClient(this); | 2445 backgroundImage->removeClient(this); |
| (...skipping 800 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3430 } | 3246 } |
| 3431 | 3247 |
| 3432 void LayoutObject::setMayNeedPaintInvalidationAnimatgedBackgroundImage() | 3248 void LayoutObject::setMayNeedPaintInvalidationAnimatgedBackgroundImage() |
| 3433 { | 3249 { |
| 3434 if (mayNeedPaintInvalidationAnimatedBackgroundImage()) | 3250 if (mayNeedPaintInvalidationAnimatedBackgroundImage()) |
| 3435 return; | 3251 return; |
| 3436 m_bitfields.setMayNeedPaintInvalidationAnimatedBackgroundImage(true); | 3252 m_bitfields.setMayNeedPaintInvalidationAnimatedBackgroundImage(true); |
| 3437 setMayNeedPaintInvalidation(); | 3253 setMayNeedPaintInvalidation(); |
| 3438 } | 3254 } |
| 3439 | 3255 |
| 3440 void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai
ntInvalidationState) | 3256 void LayoutObject::clearPaintInvalidationFlags() |
| 3441 { | 3257 { |
| 3442 // paintInvalidationStateIsDirty should be kept in sync with the | 3258 // paintInvalidationStateIsDirty should be kept in sync with the |
| 3443 // booleans that are cleared below. | 3259 // booleans that are cleared below. |
| 3444 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
|| paintInvalidationStateIsDirty()); | 3260 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState()
|| paintInvalidationStateIsDirty()); |
| 3445 clearShouldDoFullPaintInvalidation(); | 3261 clearShouldDoFullPaintInvalidation(); |
| 3446 m_bitfields.setChildShouldCheckForPaintInvalidation(false); | 3262 m_bitfields.setChildShouldCheckForPaintInvalidation(false); |
| 3447 m_bitfields.setMayNeedPaintInvalidation(false); | 3263 m_bitfields.setMayNeedPaintInvalidation(false); |
| 3448 m_bitfields.setMayNeedPaintInvalidationSubtree(false); | 3264 m_bitfields.setMayNeedPaintInvalidationSubtree(false); |
| 3449 m_bitfields.setMayNeedPaintInvalidationAnimatedBackgroundImage(false); | 3265 m_bitfields.setMayNeedPaintInvalidationAnimatedBackgroundImage(false); |
| 3450 m_bitfields.setShouldInvalidateSelection(false); | 3266 m_bitfields.setShouldInvalidateSelection(false); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3664 const blink::LayoutObject* root = object1; | 3480 const blink::LayoutObject* root = object1; |
| 3665 while (root->parent()) | 3481 while (root->parent()) |
| 3666 root = root->parent(); | 3482 root = root->parent(); |
| 3667 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3483 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
| 3668 } else { | 3484 } else { |
| 3669 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); | 3485 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); |
| 3670 } | 3486 } |
| 3671 } | 3487 } |
| 3672 | 3488 |
| 3673 #endif | 3489 #endif |
| OLD | NEW |