Chromium Code Reviews| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 #include "core/layout/LayoutPart.h" | 61 #include "core/layout/LayoutPart.h" |
| 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/page/AutoscrollController.h" | 69 #include "core/page/AutoscrollController.h" |
| 70 #include "core/page/Page.h" | 70 #include "core/page/Page.h" |
| 71 #include "core/paint/ObjectPaintInvalidator.h" | |
| 71 #include "core/paint/ObjectPaintProperties.h" | 72 #include "core/paint/ObjectPaintProperties.h" |
| 72 #include "core/paint/PaintLayer.h" | 73 #include "core/paint/PaintLayer.h" |
| 73 #include "core/style/ContentData.h" | 74 #include "core/style/ContentData.h" |
| 74 #include "core/style/CursorData.h" | 75 #include "core/style/CursorData.h" |
| 75 #include "platform/HostWindow.h" | 76 #include "platform/HostWindow.h" |
| 76 #include "platform/RuntimeEnabledFeatures.h" | 77 #include "platform/RuntimeEnabledFeatures.h" |
| 77 #include "platform/TracedValue.h" | 78 #include "platform/TracedValue.h" |
| 78 #include "platform/geometry/TransformState.h" | 79 #include "platform/geometry/TransformState.h" |
| 79 #include "wtf/allocator/Partitions.h" | 80 #include "wtf/allocator/Partitions.h" |
| 80 #include "wtf/text/StringBuilder.h" | 81 #include "wtf/text/StringBuilder.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 unsigned m_bitfields; | 126 unsigned m_bitfields; |
| 126 unsigned m_bitfields2; | 127 unsigned m_bitfields2; |
| 127 LayoutRect rect; // Stores the previous paint invalidation rect. | 128 LayoutRect rect; // Stores the previous paint invalidation rect. |
| 128 LayoutPoint position; // Stores the previous position from the paint invalid ation container. | 129 LayoutPoint position; // Stores the previous position from the paint invalid ation container. |
| 129 }; | 130 }; |
| 130 | 131 |
| 131 static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), "LayoutObj ect should stay small"); | 132 static_assert(sizeof(LayoutObject) == sizeof(SameSizeAsLayoutObject), "LayoutObj ect should stay small"); |
| 132 | 133 |
| 133 bool LayoutObject::s_affectsParentBlock = false; | 134 bool LayoutObject::s_affectsParentBlock = false; |
| 134 | 135 |
| 135 typedef HashMap<const LayoutObject*, LayoutRect> SelectionPaintInvalidationMap; | |
| 136 static SelectionPaintInvalidationMap* selectionPaintInvalidationMap = nullptr; | |
| 137 | |
| 138 // The pointer to paint properties is implemented as a global hash map temporari ly, | 136 // The pointer to paint properties is implemented as a global hash map temporari ly, |
| 139 // to avoid memory regression during the transition towards SPv2. | 137 // to avoid memory regression during the transition towards SPv2. |
| 140 typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> Obj ectPaintPropertiesMap; | 138 typedef HashMap<const LayoutObject*, std::unique_ptr<ObjectPaintProperties>> Obj ectPaintPropertiesMap; |
| 141 static ObjectPaintPropertiesMap& objectPaintPropertiesMap() | 139 static ObjectPaintPropertiesMap& objectPaintPropertiesMap() |
| 142 { | 140 { |
| 143 DEFINE_STATIC_LOCAL(ObjectPaintPropertiesMap, staticObjectPaintPropertiesMap , ()); | 141 DEFINE_STATIC_LOCAL(ObjectPaintPropertiesMap, staticObjectPaintPropertiesMap , ()); |
| 144 return staticObjectPaintPropertiesMap; | 142 return staticObjectPaintPropertiesMap; |
| 145 } | 143 } |
| 146 | 144 |
| 147 void* LayoutObject::operator new(size_t sz) | 145 void* LayoutObject::operator new(size_t sz) |
| (...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1093 void addJsonObjectForRect(TracedValue* value, const char* name, const T& rect) | 1091 void addJsonObjectForRect(TracedValue* value, const char* name, const T& rect) |
| 1094 { | 1092 { |
| 1095 value->beginDictionary(name); | 1093 value->beginDictionary(name); |
| 1096 value->setDouble("x", rect.x()); | 1094 value->setDouble("x", rect.x()); |
| 1097 value->setDouble("y", rect.y()); | 1095 value->setDouble("y", rect.y()); |
| 1098 value->setDouble("width", rect.width()); | 1096 value->setDouble("width", rect.width()); |
| 1099 value->setDouble("height", rect.height()); | 1097 value->setDouble("height", rect.height()); |
| 1100 value->endDictionary(); | 1098 value->endDictionary(); |
| 1101 } | 1099 } |
| 1102 | 1100 |
| 1103 template <typename T> | |
| 1104 void addJsonObjectForPoint(TracedValue* value, const char* name, const T& point) | |
| 1105 { | |
| 1106 value->beginDictionary(name); | |
| 1107 value->setDouble("x", point.x()); | |
| 1108 value->setDouble("y", point.y()); | |
| 1109 value->endDictionary(); | |
| 1110 } | |
| 1111 | |
| 1112 static std::unique_ptr<TracedValue> jsonObjectForPaintInvalidationInfo(const Lay outRect& rect, const String& invalidationReason) | 1101 static std::unique_ptr<TracedValue> jsonObjectForPaintInvalidationInfo(const Lay outRect& rect, const String& invalidationReason) |
| 1113 { | 1102 { |
| 1114 std::unique_ptr<TracedValue> value = TracedValue::create(); | 1103 std::unique_ptr<TracedValue> value = TracedValue::create(); |
| 1115 addJsonObjectForRect(value.get(), "rect", rect); | 1104 addJsonObjectForRect(value.get(), "rect", rect); |
| 1116 value->setString("invalidation_reason", invalidationReason); | 1105 value->setString("invalidation_reason", invalidationReason); |
| 1117 return value; | 1106 return value; |
| 1118 } | 1107 } |
| 1119 | 1108 |
| 1120 static void invalidatePaintRectangleOnWindow(const LayoutBoxModelObject& paintIn validationContainer, const IntRect& dirtyRect) | 1109 static void invalidatePaintRectangleOnWindow(const LayoutBoxModelObject& paintIn validationContainer, const IntRect& dirtyRect) |
| 1121 { | 1110 { |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1192 { | 1181 { |
| 1193 if (PaintLayer* paintingLayer = this->paintingLayer()) | 1182 if (PaintLayer* paintingLayer = this->paintingLayer()) |
| 1194 paintingLayer->setNeedsRepaint(); | 1183 paintingLayer->setNeedsRepaint(); |
| 1195 } | 1184 } |
| 1196 | 1185 |
| 1197 void LayoutObject::invalidateDisplayItemClients(PaintInvalidationReason reason) const | 1186 void LayoutObject::invalidateDisplayItemClients(PaintInvalidationReason reason) const |
| 1198 { | 1187 { |
| 1199 invalidateDisplayItemClient(*this, reason); | 1188 invalidateDisplayItemClient(*this, reason); |
| 1200 } | 1189 } |
| 1201 | 1190 |
| 1202 void LayoutObject::invalidateDisplayItemClientsWithPaintInvalidationState(const PaintInvalidationState& paintInvalidationState, PaintInvalidationReason reason) const | |
| 1203 { | |
| 1204 paintInvalidationState.paintingLayer().setNeedsRepaint(); | |
| 1205 invalidateDisplayItemClients(reason); | |
| 1206 } | |
| 1207 | |
| 1208 bool LayoutObject::compositedScrollsWithRespectTo(const LayoutBoxModelObject& pa intInvalidationContainer) const | 1191 bool LayoutObject::compositedScrollsWithRespectTo(const LayoutBoxModelObject& pa intInvalidationContainer) const |
| 1209 { | 1192 { |
| 1210 return paintInvalidationContainer.usesCompositedScrolling() && this != &pain tInvalidationContainer; | 1193 return paintInvalidationContainer.usesCompositedScrolling() && this != &pain tInvalidationContainer; |
| 1211 } | 1194 } |
| 1212 | 1195 |
| 1213 IntSize LayoutObject::scrollAdjustmentForPaintInvalidation(const LayoutBoxModelO bject& paintInvalidationContainer) const | 1196 IntSize LayoutObject::scrollAdjustmentForPaintInvalidation(const LayoutBoxModelO bject& paintInvalidationContainer) const |
| 1214 { | 1197 { |
| 1215 // Non-composited scrolling should be included in the bounds of scrolled ite ms. Since mapToVisualRectInAncestorSpace does not include | 1198 // Non-composited scrolling should be included in the bounds of scrolled ite ms. Since mapToVisualRectInAncestorSpace does not include |
| 1216 // scrolling of the ancestor, we need to add it back in after. | 1199 // scrolling of the ancestor, we need to add it back in after. |
| 1217 if (paintInvalidationContainer.isBox() && !paintInvalidationContainer.usesCo mpositedScrolling() && this != &paintInvalidationContainer) { | 1200 if (paintInvalidationContainer.isBox() && !paintInvalidationContainer.usesCo mpositedScrolling() && this != &paintInvalidationContainer) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1251 // Skip walking down the tree as everything should be fine below us. | 1234 // Skip walking down the tree as everything should be fine below us. |
| 1252 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) | 1235 if (!shouldCheckForPaintInvalidation(paintInvalidationState)) |
| 1253 return; | 1236 return; |
| 1254 | 1237 |
| 1255 PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *th is); | 1238 PaintInvalidationState newPaintInvalidationState(paintInvalidationState, *th is); |
| 1256 | 1239 |
| 1257 if (mayNeedPaintInvalidationSubtree()) | 1240 if (mayNeedPaintInvalidationSubtree()) |
| 1258 newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinConta iner(); | 1241 newPaintInvalidationState.setForceSubtreeInvalidationCheckingWithinConta iner(); |
| 1259 | 1242 |
| 1260 PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidatio nState); | 1243 PaintInvalidationReason reason = invalidatePaintIfNeeded(newPaintInvalidatio nState); |
| 1261 clearPaintInvalidationFlags(newPaintInvalidationState); | 1244 clearPaintInvalidationFlags(); |
| 1262 | 1245 |
| 1263 newPaintInvalidationState.updateForChildren(reason); | 1246 newPaintInvalidationState.updateForChildren(reason); |
| 1264 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); | 1247 invalidatePaintOfSubtreesIfNeeded(newPaintInvalidationState); |
| 1265 } | 1248 } |
| 1266 | 1249 |
| 1267 void LayoutObject::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationStat e& childPaintInvalidationState) | 1250 void LayoutObject::invalidatePaintOfSubtreesIfNeeded(const PaintInvalidationStat e& childPaintInvalidationState) |
| 1268 { | 1251 { |
| 1269 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli ng()) { | 1252 for (LayoutObject* child = slowFirstChild(); child; child = child->nextSibli ng()) { |
| 1270 // Column spanners are invalidated through their placeholders. | 1253 // Column spanners are invalidated through their placeholders. |
| 1271 // See LayoutMultiColumnSpannerPlaceholder::invalidatePaintOfSubtreesIfN eeded(). | 1254 // See LayoutMultiColumnSpannerPlaceholder::invalidatePaintOfSubtreesIfN eeded(). |
| 1272 if (child->isColumnSpanAll()) | 1255 if (child->isColumnSpanAll()) |
| 1273 continue; | 1256 continue; |
| 1274 child->invalidateTreeIfNeeded(childPaintInvalidationState); | 1257 child->invalidateTreeIfNeeded(childPaintInvalidationState); |
| 1275 } | 1258 } |
| 1276 } | 1259 } |
| 1277 | 1260 |
| 1278 static std::unique_ptr<TracedValue> jsonObjectForOldAndNewRects(const LayoutRect & oldRect, const LayoutPoint& oldLocation, const LayoutRect& newRect, const Layo utPoint& newLocation) | |
| 1279 { | |
| 1280 std::unique_ptr<TracedValue> value = TracedValue::create(); | |
| 1281 addJsonObjectForRect(value.get(), "oldRect", oldRect); | |
| 1282 addJsonObjectForPoint(value.get(), "oldLocation", oldLocation); | |
| 1283 addJsonObjectForRect(value.get(), "newRect", newRect); | |
| 1284 addJsonObjectForPoint(value.get(), "newLocation", newLocation); | |
| 1285 return value; | |
| 1286 } | |
| 1287 | |
| 1288 LayoutRect LayoutObject::selectionRectInViewCoordinates() const | 1261 LayoutRect LayoutObject::selectionRectInViewCoordinates() const |
| 1289 { | 1262 { |
| 1290 LayoutRect selectionRect = localSelectionRect(); | 1263 LayoutRect selectionRect = localSelectionRect(); |
| 1291 if (!selectionRect.isEmpty()) | 1264 if (!selectionRect.isEmpty()) |
| 1292 mapToVisualRectInAncestorSpace(view(), selectionRect); | 1265 mapToVisualRectInAncestorSpace(view(), selectionRect); |
| 1293 return selectionRect; | 1266 return selectionRect; |
| 1294 } | 1267 } |
| 1295 | 1268 |
| 1296 LayoutRect LayoutObject::previousSelectionRectForPaintInvalidation() const | |
| 1297 { | |
| 1298 if (!selectionPaintInvalidationMap) | |
| 1299 return LayoutRect(); | |
| 1300 | |
| 1301 return selectionPaintInvalidationMap->get(this); | |
| 1302 } | |
| 1303 | |
| 1304 void LayoutObject::setPreviousSelectionRectForPaintInvalidation(const LayoutRect & selectionRect) | |
| 1305 { | |
| 1306 if (!selectionPaintInvalidationMap) { | |
| 1307 if (selectionRect.isEmpty()) | |
| 1308 return; | |
| 1309 selectionPaintInvalidationMap = new SelectionPaintInvalidationMap(); | |
| 1310 } | |
| 1311 | |
| 1312 if (selectionRect.isEmpty()) | |
| 1313 selectionPaintInvalidationMap->remove(this); | |
| 1314 else | |
| 1315 selectionPaintInvalidationMap->set(this, selectionRect); | |
| 1316 } | |
| 1317 | |
| 1318 inline void LayoutObject::invalidateSelectionIfNeeded(const LayoutBoxModelObject & paintInvalidationContainer, const PaintInvalidationState& paintInvalidationSta te, PaintInvalidationReason invalidationReason) | |
| 1319 { | |
| 1320 // Update selection rect when we are doing full invalidation (in case that t he object is moved, composite status changed, etc.) | |
| 1321 // or shouldInvalidationSelection is set (in case that the selection itself changed). | |
| 1322 bool fullInvalidation = isFullPaintInvalidationReason(invalidationReason); | |
| 1323 if (!fullInvalidation && !shouldInvalidateSelection()) | |
| 1324 return; | |
| 1325 | |
| 1326 LayoutRect oldSelectionRect = previousSelectionRectForPaintInvalidation(); | |
| 1327 LayoutRect newSelectionRect = localSelectionRect(); | |
| 1328 if (!newSelectionRect.isEmpty()) | |
| 1329 paintInvalidationState.mapLocalRectToPaintInvalidationBacking(newSelecti onRect); | |
| 1330 | |
| 1331 newSelectionRect.move(scrollAdjustmentForPaintInvalidation(paintInvalidation Container)); | |
| 1332 | |
| 1333 setPreviousSelectionRectForPaintInvalidation(newSelectionRect); | |
| 1334 | |
| 1335 if (!fullInvalidation) { | |
| 1336 fullyInvalidatePaint(paintInvalidationContainer, PaintInvalidationSelect ion, oldSelectionRect, newSelectionRect); | |
| 1337 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidation State, PaintInvalidationSelection); | |
| 1338 } | |
| 1339 } | |
| 1340 | |
| 1341 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid ationState& paintInvalidationState) | 1269 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid ationState& paintInvalidationState) |
| 1342 { | 1270 { |
| 1343 ASSERT(&paintInvalidationState.currentObject() == this); | 1271 DCHECK(&paintInvalidationState.currentObject() == this); |
| 1344 | 1272 |
| 1345 if (styleRef().hasOutline()) { | 1273 if (styleRef().hasOutline()) { |
| 1346 PaintLayer& layer = paintInvalidationState.paintingLayer(); | 1274 PaintLayer& layer = paintInvalidationState.paintingLayer(); |
| 1347 if (layer.layoutObject() != this) | 1275 if (layer.layoutObject() != this) |
| 1348 layer.setNeedsPaintPhaseDescendantOutlines(); | 1276 layer.setNeedsPaintPhaseDescendantOutlines(); |
| 1349 } | 1277 } |
| 1350 | 1278 |
| 1351 LayoutView* v = view(); | 1279 LayoutView* v = view(); |
| 1352 if (v->document().printing()) | 1280 if (v->document().printing()) |
| 1353 return PaintInvalidationNone; // Don't invalidate paints if we're printi ng. | 1281 return PaintInvalidationNone; // Don't invalidate paints if we're printi ng. |
| 1354 | 1282 |
| 1283 PaintInvalidatorContextAdapter context(paintInvalidationState); | |
| 1284 | |
| 1355 const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationSt ate.paintInvalidationContainer(); | 1285 const LayoutBoxModelObject& paintInvalidationContainer = paintInvalidationSt ate.paintInvalidationContainer(); |
| 1356 ASSERT(paintInvalidationContainer == containerForPaintInvalidation()); | 1286 DCHECK(paintInvalidationContainer == containerForPaintInvalidation()); |
| 1357 | 1287 |
| 1358 const LayoutRect oldBounds = previousPaintInvalidationRect(); | 1288 context.oldBounds = previousPaintInvalidationRect(); |
| 1359 const LayoutPoint oldLocation = RuntimeEnabledFeatures::slimmingPaintInvalid ationEnabled() ? LayoutPoint() : previousPositionFromPaintInvalidationBacking(); | 1289 context.oldLocation = previousPositionFromPaintInvalidationBacking(); |
| 1360 LayoutRect newBounds = paintInvalidationState.computePaintInvalidationRectIn Backing(); | 1290 context.newBounds = paintInvalidationState.computePaintInvalidationRectInBac king(); |
| 1361 LayoutPoint newLocation = RuntimeEnabledFeatures::slimmingPaintInvalidationE nabled() ? LayoutPoint() : paintInvalidationState.computePositionFromPaintInvali dationBacking(); | 1291 context.newLocation = paintInvalidationState.computePositionFromPaintInvalid ationBacking(); |
| 1362 | 1292 |
| 1363 IntSize adjustment = scrollAdjustmentForPaintInvalidation(paintInvalidationC ontainer); | 1293 IntSize adjustment = scrollAdjustmentForPaintInvalidation(paintInvalidationC ontainer); |
| 1364 newLocation.move(adjustment); | 1294 context.newLocation.move(adjustment); |
| 1365 newBounds.move(adjustment); | 1295 context.newBounds.move(adjustment); |
| 1366 | 1296 |
| 1367 setPreviousPaintInvalidationRect(newBounds); | 1297 setPreviousPaintInvalidationRect(context.newBounds); |
| 1368 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled()) | 1298 setPreviousPositionFromPaintInvalidationBacking(context.newLocation); |
| 1369 setPreviousPositionFromPaintInvalidationBacking(newLocation); | |
| 1370 | 1299 |
| 1371 if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { | 1300 if (!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() && paintInvalidationState.forcedSubtreeInvalidationRectUpdateWithinContainerOnly()) { |
| 1372 // We are done updating the paint invalidation rect. No other paint inva lidation work to do for this object. | 1301 // We are done updating the paint invalidation rect. No other paint inva lidation work to do for this object. |
| 1373 return PaintInvalidationNone; | 1302 return PaintInvalidationNone; |
| 1374 } | 1303 } |
| 1375 | 1304 |
| 1376 PaintInvalidationReason invalidationReason = getPaintInvalidationReason(pain tInvalidationState, oldBounds, oldLocation, newBounds, newLocation); | 1305 return invalidatePaintIfNeeded(context); |
| 1377 | |
| 1378 // We need to invalidate the selection before checking for whether we are do ing a full invalidation. | |
| 1379 // This is because we need to update the old rect regardless. | |
| 1380 invalidateSelectionIfNeeded(paintInvalidationContainer, paintInvalidationSta te, invalidationReason); | |
| 1381 | |
| 1382 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("blink.invalidation"), "LayoutObject: :invalidatePaintIfNeeded()", | |
| 1383 "object", this->debugName().ascii(), | |
| 1384 "info", jsonObjectForOldAndNewRects(oldBounds, oldLocation, newBounds, n ewLocation)); | |
|
chrishtr
2016/08/09 23:47:31
I think this is actually used by the frame viewer
Xianzhu
2016/08/10 16:25:01
I think the frame viewer is using another trace ev
| |
| 1385 | |
| 1386 bool boxDecorationBackgroundObscured = boxDecorationBackgroundIsKnownToBeObs cured(); | |
| 1387 if (!isFullPaintInvalidationReason(invalidationReason) && boxDecorationBackg roundObscured != m_bitfields.lastBoxDecorationBackgroundObscured()) | |
| 1388 invalidationReason = PaintInvalidationBackgroundObscurationChange; | |
| 1389 m_bitfields.setLastBoxDecorationBackgroundObscured(boxDecorationBackgroundOb scured); | |
| 1390 | |
| 1391 if (invalidationReason == PaintInvalidationNone) { | |
| 1392 // TODO(trchen): Currently we don't keep track of paint offset of layout objects. | |
| 1393 // There are corner cases that the display items need to be invalidated for paint offset | |
| 1394 // mutation, but incurs no pixel difference (i.e. bounds stay the same) so no rect-based | |
| 1395 // invalidation is issued. See crbug.com/508383 and crbug.com/515977. | |
| 1396 // This is a workaround to force display items to update paint offset. | |
| 1397 if (!RuntimeEnabledFeatures::slimmingPaintInvalidationEnabled() && paint InvalidationState.forcedSubtreeInvalidationCheckingWithinContainer()) | |
| 1398 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalida tionState, PaintInvalidationLocationChange); | |
| 1399 | |
| 1400 return invalidationReason; | |
| 1401 } | |
| 1402 | |
| 1403 if (invalidationReason == PaintInvalidationIncremental) | |
| 1404 incrementallyInvalidatePaint(paintInvalidationContainer, oldBounds, newB ounds, newLocation); | |
| 1405 else | |
| 1406 fullyInvalidatePaint(paintInvalidationContainer, invalidationReason, old Bounds, newBounds); | |
| 1407 | |
| 1408 invalidateDisplayItemClientsWithPaintInvalidationState(paintInvalidationStat e, invalidationReason); | |
| 1409 return invalidationReason; | |
| 1410 } | 1306 } |
| 1411 | 1307 |
| 1412 PaintInvalidationReason LayoutObject::getPaintInvalidationReason(const PaintInva lidationState& paintInvalidationState, | 1308 PaintInvalidationReason LayoutObject::invalidatePaintIfNeeded(const PaintInvalid atorContext& context) const |
| 1413 const LayoutRect& oldBounds, const LayoutPoint& oldPositionFromPaintInvalida tionBacking, | |
| 1414 const LayoutRect& newBounds, const LayoutPoint& newPositionFromPaintInvalida tionBacking) const | |
| 1415 { | 1309 { |
| 1416 if (paintInvalidationState.forcedSubtreeFullInvalidationWithinContainer()) | 1310 return ObjectPaintInvalidator(*this, context).invalidatePaintIfNeeded(); |
| 1417 return PaintInvalidationSubtree; | |
| 1418 | |
| 1419 if (shouldDoFullPaintInvalidation()) | |
| 1420 return m_bitfields.fullPaintInvalidationReason(); | |
| 1421 | |
| 1422 if (paintedOutputOfObjectHasNoEffect()) | |
| 1423 return PaintInvalidationNone; | |
| 1424 | |
| 1425 // The outline may change shape because of position change of descendants. F or simplicity, | |
| 1426 // just force full paint invalidation if this object is marked for checking paint invalidation | |
| 1427 // for any reason. | |
| 1428 if (styleRef().hasOutline()) | |
| 1429 return PaintInvalidationOutline; | |
| 1430 | |
| 1431 bool locationChanged = newPositionFromPaintInvalidationBacking != oldPositio nFromPaintInvalidationBacking; | |
| 1432 | |
| 1433 // If the bounds are the same then we know that none of the statements below | |
| 1434 // can match, so we can early out. | |
| 1435 if (oldBounds == newBounds) | |
| 1436 return locationChanged && !oldBounds.isEmpty() ? PaintInvalidationLocati onChange : PaintInvalidationNone; | |
| 1437 | |
| 1438 // If we shifted, we don't know the exact reason so we are conservative and trigger a full invalidation. Shifting could | |
| 1439 // be caused by some layout property (left / top) or some in-flow layoutObje ct inserted / removed before us in the tree. | |
| 1440 if (newBounds.location() != oldBounds.location()) | |
| 1441 return PaintInvalidationBoundsChange; | |
| 1442 | |
| 1443 // If the size is zero on one of our bounds then we know we're going to have | |
| 1444 // to do a full invalidation of either old bounds or new bounds. If we fall | |
| 1445 // into the incremental invalidation we'll issue two invalidations instead | |
| 1446 // of one. | |
| 1447 if (oldBounds.isEmpty()) | |
| 1448 return PaintInvalidationBecameVisible; | |
| 1449 if (newBounds.isEmpty()) | |
| 1450 return PaintInvalidationBecameInvisible; | |
| 1451 | |
| 1452 if (locationChanged) | |
| 1453 return PaintInvalidationLocationChange; | |
| 1454 | |
| 1455 return PaintInvalidationIncremental; | |
| 1456 } | 1311 } |
| 1457 | 1312 |
| 1458 void LayoutObject::adjustInvalidationRectForCompositedScrolling(LayoutRect& rect , const LayoutBoxModelObject& paintInvalidationContainer) const | 1313 void LayoutObject::adjustInvalidationRectForCompositedScrolling(LayoutRect& rect , const LayoutBoxModelObject& paintInvalidationContainer) const |
| 1459 { | 1314 { |
| 1460 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { | 1315 if (compositedScrollsWithRespectTo(paintInvalidationContainer)) { |
| 1461 LayoutSize offset(-toLayoutBox(&paintInvalidationContainer)->scrolledCon tentOffset()); | 1316 LayoutSize offset(-toLayoutBox(&paintInvalidationContainer)->scrolledCon tentOffset()); |
| 1462 rect.move(offset); | 1317 rect.move(offset); |
| 1463 } | 1318 } |
| 1464 } | 1319 } |
| 1465 | 1320 |
| 1466 LayoutRect LayoutObject::previousPaintInvalidationRectIncludingCompositedScrolli ng(const LayoutBoxModelObject& paintInvalidationContainer) const | 1321 LayoutRect LayoutObject::previousPaintInvalidationRectIncludingCompositedScrolli ng(const LayoutBoxModelObject& paintInvalidationContainer) const |
| 1467 { | 1322 { |
| 1468 LayoutRect invalidationRect = previousPaintInvalidationRect(); | 1323 LayoutRect invalidationRect = previousPaintInvalidationRect(); |
| 1469 adjustInvalidationRectForCompositedScrolling(invalidationRect, paintInvalida tionContainer); | 1324 adjustInvalidationRectForCompositedScrolling(invalidationRect, paintInvalida tionContainer); |
| 1470 return invalidationRect; | 1325 return invalidationRect; |
| 1471 } | 1326 } |
| 1472 | 1327 |
| 1473 void LayoutObject::adjustPreviousPaintInvalidationForScrollIfNeeded(const Double Size& scrollDelta) | 1328 void LayoutObject::adjustPreviousPaintInvalidationForScrollIfNeeded(const Double Size& scrollDelta) |
| 1474 { | 1329 { |
| 1475 if (containerForPaintInvalidation().usesCompositedScrolling()) | 1330 if (containerForPaintInvalidation().usesCompositedScrolling()) |
| 1476 return; | 1331 return; |
| 1477 m_previousPaintInvalidationRect.move(LayoutSize(scrollDelta)); | 1332 m_previousPaintInvalidationRect.move(LayoutSize(scrollDelta)); |
| 1478 } | 1333 } |
| 1479 | 1334 |
| 1480 void LayoutObject::clearPreviousPaintInvalidationRects() | 1335 void LayoutObject::clearPreviousPaintInvalidationRects() |
| 1481 { | 1336 { |
| 1482 setPreviousPaintInvalidationRect(LayoutRect()); | 1337 setPreviousPaintInvalidationRect(LayoutRect()); |
| 1483 } | 1338 } |
| 1484 | 1339 |
| 1485 void LayoutObject::incrementallyInvalidatePaint(const LayoutBoxModelObject& pain tInvalidationContainer, const LayoutRect& oldBounds, const LayoutRect& newBounds , const LayoutPoint& positionFromPaintInvalidationBacking) | |
| 1486 { | |
| 1487 ASSERT(oldBounds.location() == newBounds.location()); | |
| 1488 | |
| 1489 LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX(); | |
| 1490 if (deltaRight > 0) { | |
| 1491 LayoutRect invalidationRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()); | |
| 1492 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe ct, PaintInvalidationIncremental); | |
| 1493 } else if (deltaRight < 0) { | |
| 1494 LayoutRect invalidationRect(newBounds.maxX(), oldBounds.y(), -deltaRight , oldBounds.height()); | |
| 1495 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe ct, PaintInvalidationIncremental); | |
| 1496 } | |
| 1497 | |
| 1498 LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY(); | |
| 1499 if (deltaBottom > 0) { | |
| 1500 LayoutRect invalidationRect(newBounds.x(), oldBounds.maxY(), newBounds.w idth(), deltaBottom); | |
| 1501 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe ct, PaintInvalidationIncremental); | |
| 1502 } else if (deltaBottom < 0) { | |
| 1503 LayoutRect invalidationRect(oldBounds.x(), newBounds.maxY(), oldBounds.w idth(), -deltaBottom); | |
| 1504 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe ct, PaintInvalidationIncremental); | |
| 1505 } | |
| 1506 } | |
| 1507 | |
| 1508 void LayoutObject::fullyInvalidatePaint(const LayoutBoxModelObject& paintInvalid ationContainer, PaintInvalidationReason invalidationReason, const LayoutRect& ol dBounds, const LayoutRect& newBounds) | |
| 1509 { | |
| 1510 // The following logic avoids invalidating twice if one set of bounds contai ns the other. | |
| 1511 if (!newBounds.contains(oldBounds)) { | |
| 1512 LayoutRect invalidationRect = oldBounds; | |
| 1513 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRe ct, invalidationReason); | |
| 1514 | |
| 1515 if (oldBounds.contains(newBounds)) | |
| 1516 return; | |
| 1517 } | |
| 1518 | |
| 1519 LayoutRect invalidationRect = newBounds; | |
| 1520 invalidatePaintUsingContainer(paintInvalidationContainer, invalidationRect, invalidationReason); | |
| 1521 } | |
| 1522 | |
| 1523 LayoutRect LayoutObject::absoluteClippedOverflowRect() const | 1340 LayoutRect LayoutObject::absoluteClippedOverflowRect() const |
| 1524 { | 1341 { |
| 1525 LayoutRect rect = localOverflowRectForPaintInvalidation(); | 1342 LayoutRect rect = localOverflowRectForPaintInvalidation(); |
| 1526 mapToVisualRectInAncestorSpace(view(), rect); | 1343 mapToVisualRectInAncestorSpace(view(), rect); |
| 1527 return rect; | 1344 return rect; |
| 1528 } | 1345 } |
| 1529 | 1346 |
| 1530 LayoutRect LayoutObject::localOverflowRectForPaintInvalidation() const | 1347 LayoutRect LayoutObject::localOverflowRectForPaintInvalidation() const |
| 1531 { | 1348 { |
| 1532 ASSERT_NOT_REACHED(); | 1349 ASSERT_NOT_REACHED(); |
| (...skipping 1065 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2598 // m_style is null in cases of partial construction. Any handler we added | 2415 // m_style is null in cases of partial construction. Any handler we added |
| 2599 // previously may have already been removed by the Document independently. | 2416 // previously may have already been removed by the Document independently. |
| 2600 if (node() && !node()->isTextNode() && m_style && m_style->getTouchAction() != TouchActionAuto) { | 2417 if (node() && !node()->isTextNode() && m_style && m_style->getTouchAction() != TouchActionAuto) { |
| 2601 EventHandlerRegistry& registry = document().frameHost()->eventHandlerReg istry(); | 2418 EventHandlerRegistry& registry = document().frameHost()->eventHandlerReg istry(); |
| 2602 if (registry.eventHandlerTargets(EventHandlerRegistry::TouchStartOrMoveE ventBlocking)->contains(node())) | 2419 if (registry.eventHandlerTargets(EventHandlerRegistry::TouchStartOrMoveE ventBlocking)->contains(node())) |
| 2603 registry.didRemoveEventHandler(*node(), EventHandlerRegistry::TouchS tartOrMoveEventBlocking); | 2420 registry.didRemoveEventHandler(*node(), EventHandlerRegistry::TouchS tartOrMoveEventBlocking); |
| 2604 } | 2421 } |
| 2605 | 2422 |
| 2606 setAncestorLineBoxDirty(false); | 2423 setAncestorLineBoxDirty(false); |
| 2607 | 2424 |
| 2608 if (selectionPaintInvalidationMap) | 2425 ObjectPaintInvalidator::objectWillBeDestroyed(*this); |
| 2609 selectionPaintInvalidationMap->remove(this); | |
| 2610 | 2426 |
| 2611 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) | 2427 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 2612 objectPaintPropertiesMap().remove(this); | 2428 objectPaintPropertiesMap().remove(this); |
| 2613 | 2429 |
| 2614 clearLayoutRootIfNeeded(); | 2430 clearLayoutRootIfNeeded(); |
| 2615 | 2431 |
| 2616 if (m_style) { | 2432 if (m_style) { |
| 2617 for (const FillLayer* bgLayer = &m_style->backgroundLayers(); bgLayer; b gLayer = bgLayer->next()) { | 2433 for (const FillLayer* bgLayer = &m_style->backgroundLayers(); bgLayer; b gLayer = bgLayer->next()) { |
| 2618 if (StyleImage* backgroundImage = bgLayer->image()) | 2434 if (StyleImage* backgroundImage = bgLayer->image()) |
| 2619 backgroundImage->removeClient(this); | 2435 backgroundImage->removeClient(this); |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3412 } | 3228 } |
| 3413 | 3229 |
| 3414 void LayoutObject::setMayNeedPaintInvalidationSubtree() | 3230 void LayoutObject::setMayNeedPaintInvalidationSubtree() |
| 3415 { | 3231 { |
| 3416 if (mayNeedPaintInvalidationSubtree()) | 3232 if (mayNeedPaintInvalidationSubtree()) |
| 3417 return; | 3233 return; |
| 3418 m_bitfields.setMayNeedPaintInvalidationSubtree(true); | 3234 m_bitfields.setMayNeedPaintInvalidationSubtree(true); |
| 3419 setMayNeedPaintInvalidation(); | 3235 setMayNeedPaintInvalidation(); |
| 3420 } | 3236 } |
| 3421 | 3237 |
| 3422 void LayoutObject::clearPaintInvalidationFlags(const PaintInvalidationState& pai ntInvalidationState) | 3238 void LayoutObject::clearPaintInvalidationFlags() |
| 3423 { | 3239 { |
| 3424 // paintInvalidationStateIsDirty should be kept in sync with the | 3240 // paintInvalidationStateIsDirty should be kept in sync with the |
| 3425 // booleans that are cleared below. | 3241 // booleans that are cleared below. |
| 3426 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() || paintInvalidationStateIsDirty()); | 3242 ASSERT(!shouldCheckForPaintInvalidationRegardlessOfPaintInvalidationState() || paintInvalidationStateIsDirty()); |
| 3427 clearShouldDoFullPaintInvalidation(); | 3243 clearShouldDoFullPaintInvalidation(); |
| 3428 m_bitfields.setChildShouldCheckForPaintInvalidation(false); | 3244 m_bitfields.setChildShouldCheckForPaintInvalidation(false); |
| 3429 m_bitfields.setMayNeedPaintInvalidation(false); | 3245 m_bitfields.setMayNeedPaintInvalidation(false); |
| 3430 m_bitfields.setMayNeedPaintInvalidationSubtree(false); | 3246 m_bitfields.setMayNeedPaintInvalidationSubtree(false); |
| 3431 m_bitfields.setShouldInvalidateSelection(false); | 3247 m_bitfields.setShouldInvalidateSelection(false); |
| 3432 } | 3248 } |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3645 const blink::LayoutObject* root = object1; | 3461 const blink::LayoutObject* root = object1; |
| 3646 while (root->parent()) | 3462 while (root->parent()) |
| 3647 root = root->parent(); | 3463 root = root->parent(); |
| 3648 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); | 3464 root->showLayoutTreeAndMark(object1, "*", object2, "-", 0); |
| 3649 } else { | 3465 } else { |
| 3650 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); | 3466 WTFLogAlways("%s", "Cannot showLayoutTree. Root is (nil)"); |
| 3651 } | 3467 } |
| 3652 } | 3468 } |
| 3653 | 3469 |
| 3654 #endif | 3470 #endif |
| OLD | NEW |