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

Side by Side Diff: Source/core/paint/ViewPainter.cpp

Issue 1145993002: Refactor root element background painting (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: revise for xianzhu's comment 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 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "config.h" 5 #include "config.h"
6 #include "core/paint/ViewPainter.h" 6 #include "core/paint/ViewPainter.h"
7 7
8 #include "core/frame/FrameView.h" 8 #include "core/frame/FrameView.h"
9 #include "core/frame/Settings.h"
9 #include "core/layout/LayoutBox.h" 10 #include "core/layout/LayoutBox.h"
10 #include "core/layout/LayoutView.h" 11 #include "core/layout/LayoutView.h"
11 #include "core/paint/BlockPainter.h" 12 #include "core/paint/BlockPainter.h"
13 #include "core/paint/BoxPainter.h"
14 #include "core/paint/DeprecatedPaintLayer.h"
12 #include "core/paint/LayoutObjectDrawingRecorder.h" 15 #include "core/paint/LayoutObjectDrawingRecorder.h"
13 #include "core/paint/PaintInfo.h" 16 #include "core/paint/PaintInfo.h"
14 #include "platform/RuntimeEnabledFeatures.h" 17 #include "platform/RuntimeEnabledFeatures.h"
15 18
16 namespace blink { 19 namespace blink {
17 20
18 void ViewPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffs et) 21 void ViewPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffs et)
19 { 22 {
20 // If we ever require layout but receive a paint anyway, something has gone horribly wrong. 23 // If we ever require layout but receive a paint anyway, something has gone horribly wrong.
21 ASSERT(!m_layoutView.needsLayout()); 24 ASSERT(!m_layoutView.needsLayout());
22 // LayoutViews should never be called to paint with an offset not on device pixels. 25 // LayoutViews should never be called to paint with an offset not on device pixels.
23 ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffse t); 26 ASSERT(LayoutPoint(IntPoint(paintOffset.x(), paintOffset.y())) == paintOffse t);
24 27
25 // This avoids painting garbage between columns if there is a column gap. 28 // This avoids painting garbage between columns if there is a column gap.
26 // This is legacy WebKit behavior and doesn't work with slimmingpaint. We ca n remove it once region-based columns are launched. 29 // This is legacy WebKit behavior and doesn't work with slimmingpaint. We ca n remove it once region-based columns are launched.
27 if (!RuntimeEnabledFeatures::regionBasedColumnsEnabled() && m_layoutView.fra meView() && m_layoutView.style()->isOverflowPaged()) { 30 if (!RuntimeEnabledFeatures::regionBasedColumnsEnabled() && m_layoutView.fra meView() && m_layoutView.style()->isOverflowPaged()) {
28 ASSERT(!RuntimeEnabledFeatures::slimmingPaintEnabled()); 31 ASSERT(!RuntimeEnabledFeatures::slimmingPaintEnabled());
29 LayoutRect paintRect(paintInfo.rect); 32 LayoutRect paintRect(paintInfo.rect);
30 paintInfo.context->fillRect(paintRect, m_layoutView.frameView()->baseBac kgroundColor()); 33 paintInfo.context->fillRect(paintRect, m_layoutView.frameView()->baseBac kgroundColor());
31 } 34 }
32 35
33 m_layoutView.paintObject(paintInfo, paintOffset); 36 m_layoutView.paintObject(paintInfo, paintOffset);
34 BlockPainter(m_layoutView).paintOverflowControlsIfNeeded(paintInfo, paintOff set); 37 BlockPainter(m_layoutView).paintOverflowControlsIfNeeded(paintInfo, paintOff set);
35 } 38 }
36 39
37 static inline bool layoutObjectObscuresBackground(LayoutBox* rootBox)
38 {
39 ASSERT(rootBox);
40 const ComputedStyle& style = rootBox->styleRef();
41 if (style.visibility() != VISIBLE
42 || style.opacity() != 1
43 || style.hasFilter()
44 || style.hasTransform())
45 return false;
46
47 if (rootBox->compositingState() == PaintsIntoOwnBacking)
48 return false;
49
50 const LayoutObject* rootLayoutObject = rootBox->layoutObjectForRootBackgroun d();
51 if (rootLayoutObject->style()->backgroundClip() == TextFillBox)
52 return false;
53
54 return true;
55 }
56
57 void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) 40 void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo)
58 { 41 {
59 if (m_layoutView.document().ownerElement() || !m_layoutView.view())
60 return;
61
62 if (paintInfo.skipRootBackground()) 42 if (paintInfo.skipRootBackground())
63 return; 43 return;
64 44
65 bool shouldPaintBackground = true; 45 GraphicsContext& context = *paintInfo.context;
66 Node* documentElement = m_layoutView.document().documentElement(); 46 IntRect documentRect = m_layoutView.unscaledDocumentRect();
67 if (LayoutBox* rootBox = documentElement ? toLayoutBox(documentElement->layo utObject()) : 0) 47 const Document& document = m_layoutView.document();
68 shouldPaintBackground = !rootFillsViewportBackground(rootBox) || !layout ObjectObscuresBackground(rootBox); 48 const FrameView& frameView = *m_layoutView.frameView();
49 bool isMainFrame = !document.ownerElement();
50 bool paintsBaseBackground = isMainFrame && !frameView.isTransparent();
51 bool shouldClearCanvas = paintsBaseBackground && (document.settings() && doc ument.settings()->shouldClearDocumentBackground());
52 Color baseBackgroundColor = paintsBaseBackground ? frameView.baseBackgroundC olor() : Color();
53 const LayoutObject* rootObject = document.documentElement() ? document.docum entElement()->layoutObject() : nullptr;
69 54
70 // If painting will entirely fill the view, no need to fill the background. 55 LayoutObjectDrawingRecorder recorder(context, m_layoutView, DisplayItem::Box DecorationBackground, documentRect);
71 if (!shouldPaintBackground) 56 if (recorder.canUseCachedDrawing())
72 return; 57 return;
73 58
74 // This code typically only executes if the root element's visibility has be en set to hidden, 59 bool backgroundRenderable = true;
75 // if there is a transform on the <html>, or if there is a page scale factor less than 1. 60 TransformationMatrix transform;
76 // Only fill with the base background color (typically white) if we're the r oot document, 61 IntRect paintRect = documentRect;
77 // since iframes/frames with no background in the child document should show the parent's background. 62 if (!rootObject || !rootObject->isBox()) {
78 if (!m_layoutView.frameView()->isTransparent()) { 63 backgroundRenderable = false;
79 LayoutRect paintRect(paintInfo.rect); 64 } else if (rootObject->hasLayer()) {
80 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) 65 const DeprecatedPaintLayer& rootLayer = *toLayoutBoxModelObject(rootObje ct)->layer();
81 paintRect = m_layoutView.viewRect(); 66 LayoutPoint offset;
67 rootLayer.convertToLayerCoords(nullptr, offset);
68 transform.translate(offset.x(), offset.y());
69 transform.multiply(rootLayer.renderableTransform(paintInfo.paintBehavior ));
Xianzhu 2015/06/03 04:40:34 Do we need to invalidate / have we invalidated the
trchen 2015/06/03 23:15:24 Yes we do. Tried with the inspector we are already
Xianzhu 2015/06/03 23:24:19 The paint invalidation rect shown by inspector doe
82 70
83 LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutView, D isplayItem::BoxDecorationBackground, m_layoutView.viewRect()); 71 if (!transform.isInvertible()) {
84 if (!recorder.canUseCachedDrawing()) { 72 backgroundRenderable = false;
85 Color baseColor = m_layoutView.frameView()->baseBackgroundColor(); 73 } else {
86 paintInfo.context->fillRect(paintRect, baseColor, baseColor.alpha() ? 74 bool isClamped;
87 SkXfermode::kSrc_Mode : SkXfermode::kClear_Mode); 75 paintRect = transform.inverse().projectQuad(FloatQuad(documentRect), &isClamped).enclosingBoundingBox();
76 backgroundRenderable = !isClamped;
88 } 77 }
89 } 78 }
90 }
91 79
92 bool ViewPainter::rootFillsViewportBackground(LayoutBox* rootBox) const 80 if (!backgroundRenderable) {
93 { 81 if (baseBackgroundColor.alpha())
94 ASSERT(rootBox); 82 context.fillRect(documentRect, baseBackgroundColor, shouldClearCanva s ? SkXfermode::kSrc_Mode : SkXfermode::kSrcOver_Mode);
95 // CSS Boxes always fill the viewport background (see paintRootBoxFillLayers ) 83 else if (shouldClearCanvas)
96 if (!rootBox->isSVG()) 84 context.fillRect(documentRect, Color(), SkXfermode::kClear_Mode);
97 return true; 85 return;
86 }
98 87
99 return rootBox->frameRect().contains(m_layoutView.frameRect()); 88 Vector<const FillLayer*, 8> reversedPaintList;
89 bool shouldDrawBackgroundInSeparateBuffer = BoxPainter(m_layoutView).calcula teFillLayerOcclusionCulling(reversedPaintList, m_layoutView.style()->backgroundL ayers());
90 ASSERT(reversedPaintList.size());
91 Color rootBackgroundColor = m_layoutView.style()->visitedDependentColor(CSSP ropertyBackgroundColor);
92 if (!rootBackgroundColor.hasAlpha())
93 shouldDrawBackgroundInSeparateBuffer = false;
94
95 if (!baseBackgroundColor.alpha() && shouldClearCanvas)
96 shouldDrawBackgroundInSeparateBuffer = false;
97
98 if (shouldDrawBackgroundInSeparateBuffer) {
99 if (baseBackgroundColor.alpha())
100 context.fillRect(documentRect, baseBackgroundColor, shouldClearCanva s ? SkXfermode::kSrc_Mode : SkXfermode::kSrcOver_Mode);
101 context.beginLayer();
102 }
103
104 Color combinedBackgroundColor = shouldDrawBackgroundInSeparateBuffer ? rootB ackgroundColor : baseBackgroundColor.blend(rootBackgroundColor);
105 if (combinedBackgroundColor.alpha())
106 context.fillRect(documentRect, combinedBackgroundColor, (shouldDrawBackg roundInSeparateBuffer || shouldClearCanvas) ? SkXfermode::kSrc_Mode : SkXfermode ::kSrcOver_Mode);
107 else if (shouldClearCanvas && !shouldDrawBackgroundInSeparateBuffer)
108 context.fillRect(documentRect, Color(), SkXfermode::kClear_Mode);
109
110 {
111 GraphicsContextStateSaver stateSaver(context);
112 // TODO(trchen): We should be able to handle 3D-transformed root
113 // background with slimming paint by using transform display items.
114 context.concatCTM(transform.toAffineTransform());
115 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend( ); ++it) {
116 ASSERT((*it)->clip() == BorderFillBox);
117 BoxPainter::paintFillLayerExtended(m_layoutView, paintInfo, Color(), **it, LayoutRect(paintRect), BackgroundBleedNone);
118 }
119 }
120
121 if (shouldDrawBackgroundInSeparateBuffer)
122 context.endLayer();
100 } 123 }
101 124
102 } // namespace blink 125 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698