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

Side by Side Diff: Source/core/layout/LayoutBox.cpp

Issue 1145993002: Refactor root element background painting (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebase Created 5 years, 6 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 static OverrideSizeMap* gOverrideContainingBlockLogicalWidthMap = nullptr; 82 static OverrideSizeMap* gOverrideContainingBlockLogicalWidthMap = nullptr;
83 static OverrideSizeMap* gExtraInlineOffsetMap = nullptr; 83 static OverrideSizeMap* gExtraInlineOffsetMap = nullptr;
84 static OverrideSizeMap* gExtraBlockOffsetMap = nullptr; 84 static OverrideSizeMap* gExtraBlockOffsetMap = nullptr;
85 85
86 86
87 // Size of border belt for autoscroll. When mouse pointer in border belt, 87 // Size of border belt for autoscroll. When mouse pointer in border belt,
88 // autoscroll is started. 88 // autoscroll is started.
89 static const int autoscrollBeltSize = 20; 89 static const int autoscrollBeltSize = 20;
90 static const unsigned backgroundObscurationTestMaxDepth = 4; 90 static const unsigned backgroundObscurationTestMaxDepth = 4;
91 91
92 static bool skipBodyBackground(const LayoutBox* bodyElementLayoutObject)
93 {
94 ASSERT(bodyElementLayoutObject->isBody());
95 // The <body> only paints its background if the root element has defined a b ackground independent of the body,
96 // or if the <body>'s parent is not the document element's layoutObject (e.g . inside SVG foreignObject).
97 LayoutObject* documentElementLayoutObject = bodyElementLayoutObject->documen t().documentElement()->layoutObject();
98 return documentElementLayoutObject
99 && !documentElementLayoutObject->hasBackground()
100 && (documentElementLayoutObject == bodyElementLayoutObject->parent());
101 }
102
103 LayoutBox::LayoutBox(ContainerNode* node) 92 LayoutBox::LayoutBox(ContainerNode* node)
104 : LayoutBoxModelObject(node) 93 : LayoutBoxModelObject(node)
105 , m_intrinsicContentLogicalHeight(-1) 94 , m_intrinsicContentLogicalHeight(-1)
106 , m_minPreferredLogicalWidth(-1) 95 , m_minPreferredLogicalWidth(-1)
107 , m_maxPreferredLogicalWidth(-1) 96 , m_maxPreferredLogicalWidth(-1)
108 { 97 {
109 setIsBox(); 98 setIsBox();
110 } 99 }
111 100
112 DeprecatedPaintLayerType LayoutBox::layerTypeRequired() const 101 DeprecatedPaintLayerType LayoutBox::layerTypeRequired() const
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 // It should be possible to not dirty the grid in some cases (like moving an explicitly placed grid item). 286 // It should be possible to not dirty the grid in some cases (like moving an explicitly placed grid item).
298 // For now, it's more simple to just always recompute the grid. 287 // For now, it's more simple to just always recompute the grid.
299 toLayoutGrid(parent())->dirtyGrid(); 288 toLayoutGrid(parent())->dirtyGrid();
300 } 289 }
301 290
302 void LayoutBox::updateFromStyle() 291 void LayoutBox::updateFromStyle()
303 { 292 {
304 LayoutBoxModelObject::updateFromStyle(); 293 LayoutBoxModelObject::updateFromStyle();
305 294
306 const ComputedStyle& styleToUse = styleRef(); 295 const ComputedStyle& styleToUse = styleRef();
307 bool isRootObject = isDocumentElement();
308 bool isViewObject = isLayoutView(); 296 bool isViewObject = isLayoutView();
309 bool rootLayerScrolls = document().settings() && document().settings()->root LayerScrolls(); 297 bool rootLayerScrolls = document().settings() && document().settings()->root LayerScrolls();
310 298
311 // The root and the LayoutView always paint their backgrounds/borders. 299 // LayoutView of the main frame is resposible from painting base background.
312 if (isRootObject || isViewObject) 300 if (isViewObject && !document().ownerElement())
313 setHasBoxDecorationBackground(true); 301 setHasBoxDecorationBackground(true);
314 302
315 setFloating(!isOutOfFlowPositioned() && styleToUse.isFloating()); 303 setFloating(!isOutOfFlowPositioned() && styleToUse.isFloating());
316 304
317 bool boxHasOverflowClip = false; 305 bool boxHasOverflowClip = false;
318 if (!styleToUse.isOverflowVisible() && isLayoutBlock() && (rootLayerScrolls || !isViewObject)) { 306 if (!styleToUse.isOverflowVisible() && isLayoutBlock() && (rootLayerScrolls || !isViewObject)) {
319 // If overflow has been propagated to the viewport, it has no effect her e. 307 // If overflow has been propagated to the viewport, it has no effect her e.
320 if (node() != document().viewportDefiningElement()) 308 if (node() != document().viewportDefiningElement())
321 boxHasOverflowClip = true; 309 boxHasOverflowClip = true;
322 } 310 }
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 BackgroundImageGeometry geometry; 1161 BackgroundImageGeometry geometry;
1174 BoxPainter::calculateBackgroundImageGeometry(*this, 0, style()->backgroundLa yers(), backgroundRect, geometry); 1162 BoxPainter::calculateBackgroundImageGeometry(*this, 0, style()->backgroundLa yers(), backgroundRect, geometry);
1175 if (geometry.hasNonLocalGeometry()) 1163 if (geometry.hasNonLocalGeometry())
1176 return false; 1164 return false;
1177 paintedExtent = LayoutRect(geometry.destRect()); 1165 paintedExtent = LayoutRect(geometry.destRect());
1178 return true; 1166 return true;
1179 } 1167 }
1180 1168
1181 bool LayoutBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c onst 1169 bool LayoutBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c onst
1182 { 1170 {
1183 if (isBody() && skipBodyBackground(this)) 1171 if (isDocumentElement() || backgroundStolenForBeingBody())
1184 return false; 1172 return false;
1185 1173
1186 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor); 1174 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor);
1187 if (backgroundColor.hasAlpha()) 1175 if (backgroundColor.hasAlpha())
1188 return false; 1176 return false;
1189 1177
1190 // If the element has appearance, it might be painted by theme. 1178 // If the element has appearance, it might be painted by theme.
1191 // We cannot be sure if theme paints the background opaque. 1179 // We cannot be sure if theme paints the background opaque.
1192 // In this case it is safe to not assume opaqueness. 1180 // In this case it is safe to not assume opaqueness.
1193 // FIXME: May be ask theme if it paints opaque. 1181 // FIXME: May be ask theme if it paints opaque.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 return false; 1302 return false;
1315 } 1303 }
1316 1304
1317 void LayoutBox::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintOf fset) 1305 void LayoutBox::paintMask(const PaintInfo& paintInfo, const LayoutPoint& paintOf fset)
1318 { 1306 {
1319 BoxPainter(*this).paintMask(paintInfo, paintOffset); 1307 BoxPainter(*this).paintMask(paintInfo, paintOffset);
1320 } 1308 }
1321 1309
1322 void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*) 1310 void LayoutBox::imageChanged(WrappedImagePtr image, const IntRect*)
1323 { 1311 {
1324 if (!parent())
1325 return;
1326
1327 // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border images. 1312 // TODO(chrishtr): support PaintInvalidationDelayedFull for animated border images.
1328 if ((style()->borderImage().image() && style()->borderImage().image()->data( ) == image) 1313 if ((style()->borderImage().image() && style()->borderImage().image()->data( ) == image)
1329 || (style()->maskBoxImage().image() && style()->maskBoxImage().image()-> data() == image)) { 1314 || (style()->maskBoxImage().image() && style()->maskBoxImage().image()-> data() == image)) {
1330 setShouldDoFullPaintInvalidation(); 1315 setShouldDoFullPaintInvalidation();
1331 return; 1316 return;
1332 } 1317 }
1333 1318
1334 ShapeValue* shapeOutsideValue = style()->shapeOutside(); 1319 ShapeValue* shapeOutsideValue = style()->shapeOutside();
1335 if (!frameView()->isInPerformLayout() && isFloating() && shapeOutsideValue & & shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image) { 1320 if (!frameView()->isInPerformLayout() && isFloating() && shapeOutsideValue & & shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image) {
1336 ShapeOutsideInfo& info = ShapeOutsideInfo::ensureInfo(*this); 1321 ShapeOutsideInfo& info = ShapeOutsideInfo::ensureInfo(*this);
1337 if (!info.isComputingShape()) { 1322 if (!info.isComputingShape()) {
1338 info.markShapeAsDirty(); 1323 info.markShapeAsDirty();
1339 markShapeOutsideDependentsForLayout(); 1324 markShapeOutsideDependentsForLayout();
1340 } 1325 }
1341 } 1326 }
1342 1327
1343 if (!paintInvalidationLayerRectsForImage(image, style()->backgroundLayers(), true)) 1328 if (!invalidatePaintOfLayerRectsForImage(image, style()->backgroundLayers(), true))
1344 paintInvalidationLayerRectsForImage(image, style()->maskLayers(), false) ; 1329 invalidatePaintOfLayerRectsForImage(image, style()->maskLayers(), false) ;
1345 } 1330 }
1346 1331
1347 bool LayoutBox::paintInvalidationLayerRectsForImage(WrappedImagePtr image, const FillLayer& layers, bool drawingBackground) 1332 bool LayoutBox::invalidatePaintOfLayerRectsForImage(WrappedImagePtr image, const FillLayer& layers, bool drawingBackground)
1348 { 1333 {
1349 Vector<LayoutObject*> layerLayoutObjects; 1334 if (drawingBackground && (isDocumentElement() || backgroundStolenForBeingBod y()))
1350 1335 return false;
1351 // A background of the body or document must extend to the total visible siz e of the document. This means the union of the
1352 // view and document bounds, since it can be the case that the view is large r than the document and vice-versa.
1353 // http://dev.w3.org/csswg/css-backgrounds/#the-background
1354 if (drawingBackground && (isDocumentElement() || (isBody() && !document().do cumentElement()->layoutObject()->hasBackground()))) {
1355 layerLayoutObjects.append(document().documentElement()->layoutObject());
1356 layerLayoutObjects.append(view());
1357 if (view()->frameView())
1358 view()->frameView()->setNeedsFullPaintInvalidation();
1359 } else {
1360 layerLayoutObjects.append(this);
1361 }
1362 for (const FillLayer* curLayer = &layers; curLayer; curLayer = curLayer->nex t()) { 1336 for (const FillLayer* curLayer = &layers; curLayer; curLayer = curLayer->nex t()) {
1363 if (curLayer->image() && image == curLayer->image()->data() && curLayer- >image()->canRender(*this, style()->effectiveZoom())) { 1337 if (curLayer->image() && image == curLayer->image()->data()) {
1364 for (LayoutObject* layerLayoutObject : layerLayoutObjects) { 1338 bool maybeAnimated = curLayer->image()->cachedImage() && curLayer->i mage()->cachedImage()->image() && curLayer->image()->cachedImage()->image()->may beAnimated();
1365 // For now, only support delayed paint invalidation for animated background images. 1339 if (maybeAnimated && drawingBackground)
1366 bool maybeAnimated = curLayer->image()->cachedImage() && curLaye r->image()->cachedImage()->image() && curLayer->image()->cachedImage()->image()- >maybeAnimated(); 1340 setShouldDoFullPaintInvalidation(PaintInvalidationDelayedFull);
1367 if (maybeAnimated && drawingBackground) 1341 else
1368 layerLayoutObject->setShouldDoFullPaintInvalidation(PaintInv alidationDelayedFull); 1342 setShouldDoFullPaintInvalidation();
1369 else
1370 layerLayoutObject->setShouldDoFullPaintInvalidation(PaintInv alidationFull);
1371 }
1372 return true; 1343 return true;
1373 } 1344 }
1374 } 1345 }
1375 return false; 1346 return false;
1376 } 1347 }
1377 1348
1378 bool LayoutBox::intersectsVisibleViewport() 1349 bool LayoutBox::intersectsVisibleViewport()
1379 { 1350 {
1380 LayoutRect rect = visualOverflowRect(); 1351 LayoutRect rect = visualOverflowRect();
1381 LayoutView* layoutView = view(); 1352 LayoutView* layoutView = view();
(...skipping 2554 matching lines...) Expand 10 before | Expand all | Expand 10 after
3936 return false; 3907 return false;
3937 } 3908 }
3938 3909
3939 PaintInvalidationReason LayoutBox::paintInvalidationReason(const LayoutBoxModelO bject& paintInvalidationContainer, 3910 PaintInvalidationReason LayoutBox::paintInvalidationReason(const LayoutBoxModelO bject& paintInvalidationContainer,
3940 const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRec t& newBounds, const LayoutPoint& newLocation) const 3911 const LayoutRect& oldBounds, const LayoutPoint& oldLocation, const LayoutRec t& newBounds, const LayoutPoint& newLocation) const
3941 { 3912 {
3942 PaintInvalidationReason invalidationReason = LayoutBoxModelObject::paintInva lidationReason(paintInvalidationContainer, oldBounds, oldLocation, newBounds, ne wLocation); 3913 PaintInvalidationReason invalidationReason = LayoutBoxModelObject::paintInva lidationReason(paintInvalidationContainer, oldBounds, oldLocation, newBounds, ne wLocation);
3943 if (isFullPaintInvalidationReason(invalidationReason)) 3914 if (isFullPaintInvalidationReason(invalidationReason))
3944 return invalidationReason; 3915 return invalidationReason;
3945 3916
3917 if (isLayoutView()) {
3918 const LayoutView* layoutView = toLayoutView(this);
3919 // In normal compositing mode, root background doesn't need to be invali dated for
3920 // box changes, because the background always covers the whole document rect
3921 // and clipping is done by compositor()->m_containerLayer. Also the scro llbars
3922 // are always composited. There are no other box decoration on the Layou tView thus
3923 // we can safely exit here.
3924 if (layoutView->usesCompositing() && (!document().settings() || !documen t().settings()->rootLayerScrolls()))
chrishtr 2015/06/09 21:07:53 Is this just an optional optimization?
trchen 2015/06/09 23:36:07 I'm not sure if this optional. I think having this
3925 return invalidationReason;
3926 }
3927
3946 // If the transform is not identity or translation, incremental invalidation is not applicable 3928 // If the transform is not identity or translation, incremental invalidation is not applicable
3947 // because the difference between oldBounds and newBounds doesn't cover all area needing invalidation. 3929 // because the difference between oldBounds and newBounds doesn't cover all area needing invalidation.
3948 // FIXME: Should also consider ancestor transforms since paintInvalidationCo ntainer. crbug.com/426111. 3930 // FIXME: Should also consider ancestor transforms since paintInvalidationCo ntainer. crbug.com/426111.
3949 if (invalidationReason == PaintInvalidationIncremental 3931 if (invalidationReason == PaintInvalidationIncremental
3950 && paintInvalidationContainer != this 3932 && paintInvalidationContainer != this
3951 && hasLayer() && layer()->transform() && !layer()->transform()->isIdenti tyOrTranslation()) 3933 && hasLayer() && layer()->transform() && !layer()->transform()->isIdenti tyOrTranslation())
3952 return PaintInvalidationBoundsChange; 3934 return PaintInvalidationBoundsChange;
3953 3935
3954 if (!style()->hasBackground() && !style()->hasBoxDecorations()) { 3936 if (!style()->hasBackground() && !style()->hasBoxDecorations()) {
3955 // We could let incremental invalidation cover non-composited scrollbars , but just 3937 // We could let incremental invalidation cover non-composited scrollbars , but just
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
4640 if (m_rareData) 4622 if (m_rareData)
4641 return true; 4623 return true;
4642 4624
4643 LayoutSize paintInvalidationSize = previousPaintInvalidationRect().size(); 4625 LayoutSize paintInvalidationSize = previousPaintInvalidationRect().size();
4644 // Don't save old box sizes if the paint rect is empty because we'll 4626 // Don't save old box sizes if the paint rect is empty because we'll
4645 // full invalidate once the paint rect becomes non-empty. 4627 // full invalidate once the paint rect becomes non-empty.
4646 if (paintInvalidationSize.isEmpty()) 4628 if (paintInvalidationSize.isEmpty())
4647 return false; 4629 return false;
4648 4630
4649 // We need the old box sizes only when the box has background, decorations, or masks. 4631 // We need the old box sizes only when the box has background, decorations, or masks.
4650 if (!style()->hasBackground() && !style()->hasBoxDecorations() && !style()-> hasMask()) 4632 // Main LayoutView paints base background, thus interested in box size.
4633 if (!isLayoutView() && !style()->hasBackground() && !style()->hasBoxDecorati ons() && !style()->hasMask())
4651 return false; 4634 return false;
4652 4635
4653 // No need to save old border box size if we can use size of the old paint 4636 // No need to save old border box size if we can use size of the old paint
4654 // rect as the old border box size in the next invalidation. 4637 // rect as the old border box size in the next invalidation.
4655 if (paintInvalidationSize != size()) 4638 if (paintInvalidationSize != size())
4656 return true; 4639 return true;
4657 4640
4658 // Background and mask layers can depend on other boxes than border box. See crbug.com/490533 4641 // Background and mask layers can depend on other boxes than border box. See crbug.com/490533
4659 if (style()->backgroundLayers().thisOrNextLayersUseContentBox() || style()-> backgroundLayers().thisOrNextLayersHaveLocalAttachment() 4642 if (style()->backgroundLayers().thisOrNextLayersUseContentBox() || style()-> backgroundLayers().thisOrNextLayersHaveLocalAttachment()
4660 || style()->maskLayers().thisOrNextLayersUseContentBox()) 4643 || style()->maskLayers().thisOrNextLayersUseContentBox())
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4790 bool LayoutBox::canRenderBorderImage() const 4773 bool LayoutBox::canRenderBorderImage() const
4791 { 4774 {
4792 if (!style()->hasBorderDecoration()) 4775 if (!style()->hasBorderDecoration())
4793 return false; 4776 return false;
4794 4777
4795 StyleImage* borderImage = style()->borderImage().image(); 4778 StyleImage* borderImage = style()->borderImage().image();
4796 return borderImage && borderImage->canRender(*this, style()->effectiveZoom() ) && borderImage->isLoaded(); 4779 return borderImage && borderImage->canRender(*this, style()->effectiveZoom() ) && borderImage->isLoaded();
4797 } 4780 }
4798 4781
4799 } // namespace blink 4782 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698