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

Side by Side Diff: third_party/WebKit/Source/core/paint/BlockPainter.cpp

Issue 1584903002: Improvement handling of background and outline paint phases (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@PaintPhaseRename
Patch Set: Created 4 years, 11 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
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 "core/paint/BlockPainter.h" 5 #include "core/paint/BlockPainter.h"
6 6
7 #include "core/editing/DragCaretController.h" 7 #include "core/editing/DragCaretController.h"
8 #include "core/editing/FrameSelection.h" 8 #include "core/editing/FrameSelection.h"
9 #include "core/frame/Settings.h" 9 #include "core/frame/Settings.h"
10 #include "core/layout/LayoutBlockFlow.h" 10 #include "core/layout/LayoutBlockFlow.h"
(...skipping 24 matching lines...) Expand all
35 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location(); 35 LayoutPoint adjustedPaintOffset = paintOffset + m_layoutBlock.location();
36 PaintInfo localPaintInfo(paintInfo); 36 PaintInfo localPaintInfo(paintInfo);
37 PaintPhase originalPhase = localPaintInfo.phase; 37 PaintPhase originalPhase = localPaintInfo.phase;
38 38
39 // There are some cases where not all clipped visual overflow is accounted f or. 39 // There are some cases where not all clipped visual overflow is accounted f or.
40 // FIXME: reduce the number of such cases. 40 // FIXME: reduce the number of such cases.
41 ContentsClipBehavior contentsClipBehavior = ForceContentsClip; 41 ContentsClipBehavior contentsClipBehavior = ForceContentsClip;
42 if (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() && !( m_layoutBlock.shouldPaintSelectionGaps() && originalPhase == PaintPhaseForegroun d) && !m_layoutBlock.hasCaret()) 42 if (m_layoutBlock.hasOverflowClip() && !m_layoutBlock.hasControlClip() && !( m_layoutBlock.shouldPaintSelectionGaps() && originalPhase == PaintPhaseForegroun d) && !m_layoutBlock.hasCaret())
43 contentsClipBehavior = SkipContentsClipIfPossible; 43 contentsClipBehavior = SkipContentsClipIfPossible;
44 44
45 if (localPaintInfo.phase == PaintPhaseOutline) { 45 if (originalPhase == PaintPhaseOutline) {
46 localPaintInfo.phase = PaintPhaseDescendantOutlines; 46 localPaintInfo.phase = PaintPhaseDescendantOutlinesOnly;
47 } else if (localPaintInfo.phase == PaintPhaseBlockBackground) { 47 } else if (shouldPaintSelfBlockBackground(originalPhase)) {
48 localPaintInfo.phase = PaintPhaseSelfBlockBackground; 48 localPaintInfo.phase = PaintPhaseSelfBlockBackgroundOnly;
49 m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset); 49 m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
50 localPaintInfo.phase = PaintPhaseDescendantBlockBackgrounds; 50 if (shouldPaintDescendantBlockBackgrounds(originalPhase))
51 localPaintInfo.phase = PaintPhaseDescendantBlockBackgroundsOnly;
51 } 52 }
52 53
53 { 54 if (originalPhase != PaintPhaseSelfBlockBackgroundOnly && originalPhase != P aintPhaseSelfOutlineOnly) {
54 BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset , contentsClipBehavior); 55 BoxClipper boxClipper(m_layoutBlock, localPaintInfo, adjustedPaintOffset , contentsClipBehavior);
55 m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset); 56 m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
56 } 57 }
57 58
58 if (originalPhase == PaintPhaseOutline) { 59 if (shouldPaintSelfOutline(originalPhase)) {
59 localPaintInfo.phase = PaintPhaseSelfOutline; 60 localPaintInfo.phase = PaintPhaseSelfOutlineOnly;
60 m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset); 61 m_layoutBlock.paintObject(localPaintInfo, adjustedPaintOffset);
61 localPaintInfo.phase = originalPhase;
62 } else if (originalPhase == PaintPhaseBlockBackground) {
63 localPaintInfo.phase = originalPhase;
64 } 62 }
65 63
66 // Our scrollbar widgets paint exactly when we tell them to, so that they wo rk properly with 64 // Our scrollbar widgets paint exactly when we tell them to, so that they wo rk properly with
67 // z-index. We paint after we painted the background/border, so that the scr ollbars will 65 // z-index. We paint after we painted the background/border, so that the scr ollbars will
68 // sit above the background/border. 66 // sit above the background/border.
67 localPaintInfo.phase = originalPhase;
69 paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset); 68 paintOverflowControlsIfNeeded(localPaintInfo, adjustedPaintOffset);
70 } 69 }
71 70
72 void BlockPainter::paintOverflowControlsIfNeeded(const PaintInfo& paintInfo, con st LayoutPoint& paintOffset) 71 void BlockPainter::paintOverflowControlsIfNeeded(const PaintInfo& paintInfo, con st LayoutPoint& paintOffset)
73 { 72 {
74 PaintPhase phase = paintInfo.phase; 73 if (m_layoutBlock.hasOverflowClip()
75 if (m_layoutBlock.hasOverflowClip() && m_layoutBlock.style()->visibility() = = VISIBLE && (phase == PaintPhaseSelfBlockBackground || phase == PaintPhaseBlock Background) && paintInfo.shouldPaintWithinRoot(&m_layoutBlock) && !paintInfo.pai ntRootBackgroundOnly()) { 74 && m_layoutBlock.style()->visibility() == VISIBLE
75 && shouldPaintSelfBlockBackground(paintInfo.phase)
76 && paintInfo.shouldPaintWithinRoot(&m_layoutBlock)
77 && !paintInfo.paintRootBackgroundOnly()) {
76 Optional<ClipRecorder> clipRecorder; 78 Optional<ClipRecorder> clipRecorder;
77 if (!m_layoutBlock.layer()->isSelfPaintingLayer()) { 79 if (!m_layoutBlock.layer()->isSelfPaintingLayer()) {
78 LayoutRect clipRect = m_layoutBlock.borderBoxRect(); 80 LayoutRect clipRect = m_layoutBlock.borderBoxRect();
79 clipRect.moveBy(paintOffset); 81 clipRect.moveBy(paintOffset);
80 clipRecorder.emplace(paintInfo.context, m_layoutBlock, DisplayItem:: ClipScrollbarsToBoxBounds, clipRect); 82 clipRecorder.emplace(paintInfo.context, m_layoutBlock, DisplayItem:: ClipScrollbarsToBoxBounds, clipRect);
81 } 83 }
82 ScrollableAreaPainter(*m_layoutBlock.layer()->scrollableArea()).paintOve rflowControls(paintInfo.context, roundedIntPoint(paintOffset), paintInfo.cullRec t(), false /* paintingOverlayControls */); 84 ScrollableAreaPainter(*m_layoutBlock.layer()->scrollableArea()).paintOve rflowControls(paintInfo.context, roundedIntPoint(paintOffset), paintInfo.cullRec t(), false /* paintingOverlayControls */);
83 } 85 }
84 } 86 }
85 87
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 paintInfo.context.paintController().invalidatePaintOffset(m_layoutBl ock); 131 paintInfo.context.paintController().invalidatePaintOffset(m_layoutBl ock);
130 } 132 }
131 // Set previousPaintOffset here in case that m_layoutBlock paints nothin g and no 133 // Set previousPaintOffset here in case that m_layoutBlock paints nothin g and no
132 // LayoutObjectDrawingRecorder updates its previousPaintOffset. 134 // LayoutObjectDrawingRecorder updates its previousPaintOffset.
133 // TODO(wangxianzhu): Integrate paint offset checking into new paint inv alidation. 135 // TODO(wangxianzhu): Integrate paint offset checking into new paint inv alidation.
134 m_layoutBlock.mutableForPainting().setPreviousPaintOffset(paintOffset); 136 m_layoutBlock.mutableForPainting().setPreviousPaintOffset(paintOffset);
135 } 137 }
136 138
137 const PaintPhase paintPhase = paintInfo.phase; 139 const PaintPhase paintPhase = paintInfo.phase;
138 140
139 if ((paintPhase == PaintPhaseSelfBlockBackground || paintPhase == PaintPhase BlockBackground) 141 if (shouldPaintSelfBlockBackground(paintPhase)) {
140 && m_layoutBlock.style()->visibility() == VISIBLE 142 if (m_layoutBlock.style()->visibility() == VISIBLE && m_layoutBlock.hasB oxDecorationBackground())
141 && m_layoutBlock.hasBoxDecorationBackground()) 143 m_layoutBlock.paintBoxDecorationBackground(paintInfo, paintOffset);
142 m_layoutBlock.paintBoxDecorationBackground(paintInfo, paintOffset); 144 // We're done. We don't bother painting any children.
145 if (paintPhase == PaintPhaseSelfBlockBackgroundOnly)
146 return;
147 }
148
149 if (paintInfo.paintRootBackgroundOnly())
150 return;
143 151
144 if (paintPhase == PaintPhaseMask && m_layoutBlock.style()->visibility() == V ISIBLE) { 152 if (paintPhase == PaintPhaseMask && m_layoutBlock.style()->visibility() == V ISIBLE) {
145 m_layoutBlock.paintMask(paintInfo, paintOffset); 153 m_layoutBlock.paintMask(paintInfo, paintOffset);
146 return; 154 return;
147 } 155 }
148 156
149 if (paintPhase == PaintPhaseClippingMask && m_layoutBlock.style()->visibilit y() == VISIBLE) { 157 if (paintPhase == PaintPhaseClippingMask && m_layoutBlock.style()->visibilit y() == VISIBLE) {
150 BoxPainter(m_layoutBlock).paintClippingMask(paintInfo, paintOffset); 158 BoxPainter(m_layoutBlock).paintClippingMask(paintInfo, paintOffset);
151 return; 159 return;
152 } 160 }
153 161
154 // FIXME: When Skia supports annotation rect covering (https://code.google.c om/p/skia/issues/detail?id=3872), 162 // FIXME: When Skia supports annotation rect covering (https://code.google.c om/p/skia/issues/detail?id=3872),
155 // this rect may be covered by foreground and descendant drawings. Then we m ay need a dedicated paint phase. 163 // this rect may be covered by foreground and descendant drawings. Then we m ay need a dedicated paint phase.
156 if (paintPhase == PaintPhaseForeground && paintInfo.isPrinting()) 164 if (paintPhase == PaintPhaseForeground && paintInfo.isPrinting())
157 ObjectPainter(m_layoutBlock).addPDFURLRectIfNeeded(paintInfo, paintOffse t); 165 ObjectPainter(m_layoutBlock).addPDFURLRectIfNeeded(paintInfo, paintOffse t);
158 166
159 { 167 if (paintPhase != PaintPhaseSelfOutlineOnly) {
160 Optional<ScrollRecorder> scrollRecorder; 168 Optional<ScrollRecorder> scrollRecorder;
161 Optional<PaintInfo> scrolledPaintInfo; 169 Optional<PaintInfo> scrolledPaintInfo;
162 if (m_layoutBlock.hasOverflowClip()) { 170 if (m_layoutBlock.hasOverflowClip()) {
163 IntSize scrollOffset = m_layoutBlock.scrolledContentOffset(); 171 IntSize scrollOffset = m_layoutBlock.scrolledContentOffset();
164 if (m_layoutBlock.layer()->scrollsOverflow() || !scrollOffset.isZero ()) { 172 if (m_layoutBlock.layer()->scrollsOverflow() || !scrollOffset.isZero ()) {
165 scrollRecorder.emplace(paintInfo.context, m_layoutBlock, paintPh ase, scrollOffset); 173 scrollRecorder.emplace(paintInfo.context, m_layoutBlock, paintPh ase, scrollOffset);
166 scrolledPaintInfo.emplace(paintInfo); 174 scrolledPaintInfo.emplace(paintInfo);
167 AffineTransform transform; 175 AffineTransform transform;
168 transform.translate(-scrollOffset.width(), -scrollOffset.height( )); 176 transform.translate(-scrollOffset.width(), -scrollOffset.height( ));
169 scrolledPaintInfo->updateCullRect(transform); 177 scrolledPaintInfo->updateCullRect(transform);
170 } 178 }
171 } 179 }
172 180
173 // We're done. We don't bother painting any children.
174 if (paintPhase == PaintPhaseSelfBlockBackground || paintInfo.paintRootBa ckgroundOnly())
175 return;
176
177 const PaintInfo& contentsPaintInfo = scrolledPaintInfo ? *scrolledPaintI nfo : paintInfo; 181 const PaintInfo& contentsPaintInfo = scrolledPaintInfo ? *scrolledPaintI nfo : paintInfo;
178 182
179 if (paintPhase != PaintPhaseSelfOutline) 183 paintContents(contentsPaintInfo, paintOffset);
180 paintContents(contentsPaintInfo, paintOffset);
181 184
182 if (paintPhase == PaintPhaseForeground && !paintInfo.isPrinting()) 185 if (paintPhase == PaintPhaseForeground && !paintInfo.isPrinting())
183 m_layoutBlock.paintSelection(contentsPaintInfo, paintOffset); // Fil l in gaps in selection on lines and between blocks. 186 m_layoutBlock.paintSelection(contentsPaintInfo, paintOffset); // Fil l in gaps in selection on lines and between blocks.
184 187
185 if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection | | paintPhase == PaintPhaseTextClip) 188 if (paintPhase == PaintPhaseFloat || paintPhase == PaintPhaseSelection | | paintPhase == PaintPhaseTextClip)
186 m_layoutBlock.paintFloats(contentsPaintInfo, paintOffset); 189 m_layoutBlock.paintFloats(contentsPaintInfo, paintOffset);
187 } 190 }
188 191
189 if ((paintPhase == PaintPhaseOutline || paintPhase == PaintPhaseSelfOutline) && m_layoutBlock.style()->hasOutline() && m_layoutBlock.style()->visibility() = = VISIBLE) 192 if (shouldPaintSelfOutline(paintPhase))
190 ObjectPainter(m_layoutBlock).paintOutline(paintInfo, paintOffset); 193 ObjectPainter(m_layoutBlock).paintOutline(paintInfo, paintOffset);
191 194
192 // If the caret's node's layout object's containing block is this block, and the paint action is PaintPhaseForeground, 195 // If the caret's node's layout object's containing block is this block, and the paint action is PaintPhaseForeground,
193 // then paint the caret. 196 // then paint the caret.
194 if (paintPhase == PaintPhaseForeground && m_layoutBlock.hasCaret() && !Layou tObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutBl ock, DisplayItem::Caret, paintOffset)) { 197 if (paintPhase == PaintPhaseForeground && m_layoutBlock.hasCaret() && !Layou tObjectDrawingRecorder::useCachedDrawingIfPossible(paintInfo.context, m_layoutBl ock, DisplayItem::Caret, paintOffset)) {
195 LayoutRect bounds = m_layoutBlock.visualOverflowRect(); 198 LayoutRect bounds = m_layoutBlock.visualOverflowRect();
196 bounds.moveBy(paintOffset); 199 bounds.moveBy(paintOffset);
197 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutBlock, D isplayItem::Caret, bounds, paintOffset); 200 LayoutObjectDrawingRecorder recorder(paintInfo.context, m_layoutBlock, D isplayItem::Caret, bounds, paintOffset);
198 paintCarets(paintInfo, paintOffset); 201 paintCarets(paintInfo, paintOffset);
199 } 202 }
(...skipping 24 matching lines...) Expand all
224 227
225 void BlockPainter::paintContents(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) 228 void BlockPainter::paintContents(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
226 { 229 {
227 // Avoid painting descendants of the root element when stylesheets haven't l oaded. This eliminates FOUC. 230 // Avoid painting descendants of the root element when stylesheets haven't l oaded. This eliminates FOUC.
228 // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document 231 // It's ok not to draw, because later on, when all the stylesheets do load, styleResolverChanged() on the Document
229 // will do a full paint invalidation. 232 // will do a full paint invalidation.
230 if (m_layoutBlock.document().didLayoutWithPendingStylesheets() && !m_layoutB lock.isLayoutView()) 233 if (m_layoutBlock.document().didLayoutWithPendingStylesheets() && !m_layoutB lock.isLayoutView())
231 return; 234 return;
232 235
233 if (m_layoutBlock.childrenInline()) { 236 if (m_layoutBlock.childrenInline()) {
234 if (paintInfo.phase == PaintPhaseDescendantOutlines) 237 if (shouldPaintDescendantOutlines(paintInfo.phase))
235 ObjectPainter(m_layoutBlock).paintInlineChildrenOutlines(paintInfo, paintOffset); 238 ObjectPainter(m_layoutBlock).paintInlineChildrenOutlines(paintInfo, paintOffset);
236 else 239 else
237 LineBoxListPainter(m_layoutBlock.lineBoxes()).paint(m_layoutBlock, p aintInfo, paintOffset); 240 LineBoxListPainter(m_layoutBlock.lineBoxes()).paint(m_layoutBlock, p aintInfo, paintOffset);
238 } else { 241 } else {
239 PaintPhase newPhase = (paintInfo.phase == PaintPhaseDescendantOutlines) ? PaintPhaseOutline : paintInfo.phase; 242 PaintInfo paintInfoForDescendants = paintInfo.forDescendants();
240 newPhase = (newPhase == PaintPhaseDescendantBlockBackgrounds) ? PaintPha seBlockBackground : newPhase; 243 paintInfoForDescendants.updatePaintingRootForChildren(&m_layoutBlock);
241 244 m_layoutBlock.paintChildren(paintInfoForDescendants, paintOffset);
242 // We don't paint our own background, but we do let the kids paint their backgrounds.
243 PaintInfo paintInfoForChild(paintInfo);
244 paintInfoForChild.phase = newPhase;
245 paintInfoForChild.updatePaintingRootForChildren(&m_layoutBlock);
246 m_layoutBlock.paintChildren(paintInfoForChild, paintOffset);
247 } 245 }
248 } 246 }
249 247
250 } // namespace blink 248 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698