OLD | NEW |
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/ViewPainter.h" | 5 #include "core/paint/ViewPainter.h" |
6 | 6 |
7 #include "core/frame/FrameView.h" | 7 #include "core/frame/FrameView.h" |
8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
9 #include "core/layout/LayoutBox.h" | 9 #include "core/layout/LayoutBox.h" |
10 #include "core/layout/LayoutView.h" | 10 #include "core/layout/LayoutView.h" |
11 #include "core/paint/BlockPainter.h" | 11 #include "core/paint/BlockPainter.h" |
12 #include "core/paint/BoxPainter.h" | 12 #include "core/paint/BoxPainter.h" |
13 #include "core/paint/LayoutObjectDrawingRecorder.h" | 13 #include "core/paint/LayoutObjectDrawingRecorder.h" |
14 #include "core/paint/PaintInfo.h" | 14 #include "core/paint/PaintInfo.h" |
15 #include "core/paint/PaintLayer.h" | 15 #include "core/paint/PaintLayer.h" |
16 #include "platform/RuntimeEnabledFeatures.h" | 16 #include "platform/RuntimeEnabledFeatures.h" |
17 | 17 |
18 namespace blink { | 18 namespace blink { |
19 | 19 |
20 void ViewPainter::paint(const PaintInfo& paintInfo, | 20 void ViewPainter::paint(const PaintInfo& paintInfo, |
21 const LayoutPoint& paintOffset) { | 21 const LayoutPoint& paintOffset) { |
22 // If we ever require layout but receive a paint anyway, something has gone ho
rribly wrong. | 22 // If we ever require layout but receive a paint anyway, something has gone |
| 23 // horribly wrong. |
23 DCHECK(!m_layoutView.needsLayout()); | 24 DCHECK(!m_layoutView.needsLayout()); |
24 // LayoutViews should never be called to paint with an offset not on device pi
xels. | 25 // LayoutViews should never be called to paint with an offset not on device |
| 26 // pixels. |
25 DCHECK(LayoutPoint(IntPoint(paintOffset.x().toInt(), | 27 DCHECK(LayoutPoint(IntPoint(paintOffset.x().toInt(), |
26 paintOffset.y().toInt())) == paintOffset); | 28 paintOffset.y().toInt())) == paintOffset); |
27 | 29 |
28 const FrameView* frameView = m_layoutView.frameView(); | 30 const FrameView* frameView = m_layoutView.frameView(); |
29 if (frameView->shouldThrottleRendering()) | 31 if (frameView->shouldThrottleRendering()) |
30 return; | 32 return; |
31 | 33 |
32 m_layoutView.paintObject(paintInfo, paintOffset); | 34 m_layoutView.paintObject(paintInfo, paintOffset); |
33 BlockPainter(m_layoutView) | 35 BlockPainter(m_layoutView) |
34 .paintOverflowControlsIfNeeded(paintInfo, paintOffset); | 36 .paintOverflowControlsIfNeeded(paintInfo, paintOffset); |
35 } | 37 } |
36 | 38 |
37 void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) { | 39 void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) { |
38 if (paintInfo.skipRootBackground()) | 40 if (paintInfo.skipRootBackground()) |
39 return; | 41 return; |
40 | 42 |
41 // This function overrides background painting for the LayoutView. | 43 // This function overrides background painting for the LayoutView. |
42 // View background painting is special in the following ways: | 44 // View background painting is special in the following ways: |
43 // 1. The view paints background for the root element, the background position
ing respects | 45 // 1. The view paints background for the root element, the background |
44 // the positioning and transformation of the root element. | 46 // positioning respects the positioning and transformation of the root |
45 // 2. CSS background-clip is ignored, the background layers always expand to c
over the whole | 47 // element. |
46 // canvas. None of the stacking context effects (except transformation) on
the root element | 48 // 2. CSS background-clip is ignored, the background layers always expand to |
47 // affects the background. | 49 // cover the whole canvas. None of the stacking context effects (except |
48 // 3. The main frame is also responsible for painting the user-agent-defined b
ase background | 50 // transformation) on the root element affects the background. |
49 // color. Conceptually it should be painted by the embedder but painting it
here allows | 51 // 3. The main frame is also responsible for painting the user-agent-defined |
50 // culling and pre-blending optimization when possible. | 52 // base background color. Conceptually it should be painted by the embedder |
| 53 // but painting it here allows culling and pre-blending optimization when |
| 54 // possible. |
51 | 55 |
52 GraphicsContext& context = paintInfo.context; | 56 GraphicsContext& context = paintInfo.context; |
53 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( | 57 if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( |
54 context, m_layoutView, DisplayItem::kDocumentBackground)) | 58 context, m_layoutView, DisplayItem::kDocumentBackground)) |
55 return; | 59 return; |
56 | 60 |
57 // The background fill rect is the size of the LayoutView's main GraphicsLayer
. | 61 // The background fill rect is the size of the LayoutView's main |
| 62 // GraphicsLayer. |
58 IntRect backgroundRect = | 63 IntRect backgroundRect = |
59 pixelSnappedIntRect(m_layoutView.layer()->boundingBoxForCompositing()); | 64 pixelSnappedIntRect(m_layoutView.layer()->boundingBoxForCompositing()); |
60 const Document& document = m_layoutView.document(); | 65 const Document& document = m_layoutView.document(); |
61 const FrameView& frameView = *m_layoutView.frameView(); | 66 const FrameView& frameView = *m_layoutView.frameView(); |
62 bool isMainFrame = document.isInMainFrame(); | 67 bool isMainFrame = document.isInMainFrame(); |
63 bool paintsBaseBackground = isMainFrame && !frameView.isTransparent(); | 68 bool paintsBaseBackground = isMainFrame && !frameView.isTransparent(); |
64 bool shouldClearCanvas = | 69 bool shouldClearCanvas = |
65 paintsBaseBackground && | 70 paintsBaseBackground && |
66 (document.settings() && | 71 (document.settings() && |
67 document.settings()->shouldClearDocumentBackground()); | 72 document.settings()->shouldClearDocumentBackground()); |
68 Color baseBackgroundColor = | 73 Color baseBackgroundColor = |
69 paintsBaseBackground ? frameView.baseBackgroundColor() : Color(); | 74 paintsBaseBackground ? frameView.baseBackgroundColor() : Color(); |
70 Color rootBackgroundColor = | 75 Color rootBackgroundColor = |
71 m_layoutView.style()->visitedDependentColor(CSSPropertyBackgroundColor); | 76 m_layoutView.style()->visitedDependentColor(CSSPropertyBackgroundColor); |
72 const LayoutObject* rootObject = | 77 const LayoutObject* rootObject = |
73 document.documentElement() ? document.documentElement()->layoutObject() | 78 document.documentElement() ? document.documentElement()->layoutObject() |
74 : nullptr; | 79 : nullptr; |
75 | 80 |
76 LayoutObjectDrawingRecorder recorder( | 81 LayoutObjectDrawingRecorder recorder( |
77 context, m_layoutView, DisplayItem::kDocumentBackground, backgroundRect); | 82 context, m_layoutView, DisplayItem::kDocumentBackground, backgroundRect); |
78 | 83 |
79 // Special handling for print economy mode. | 84 // Special handling for print economy mode. |
80 bool forceBackgroundToWhite = | 85 bool forceBackgroundToWhite = |
81 BoxPainter::shouldForceWhiteBackgroundForPrintEconomy( | 86 BoxPainter::shouldForceWhiteBackgroundForPrintEconomy( |
82 m_layoutView.styleRef(), document); | 87 m_layoutView.styleRef(), document); |
83 if (forceBackgroundToWhite) { | 88 if (forceBackgroundToWhite) { |
84 // If for any reason the view background is not transparent, paint white ins
tead, otherwise keep transparent as is. | 89 // If for any reason the view background is not transparent, paint white |
| 90 // instead, otherwise keep transparent as is. |
85 if (paintsBaseBackground || rootBackgroundColor.alpha() || | 91 if (paintsBaseBackground || rootBackgroundColor.alpha() || |
86 m_layoutView.style()->backgroundLayers().image()) | 92 m_layoutView.style()->backgroundLayers().image()) |
87 context.fillRect(backgroundRect, Color::white, SkXfermode::kSrc_Mode); | 93 context.fillRect(backgroundRect, Color::white, SkXfermode::kSrc_Mode); |
88 return; | 94 return; |
89 } | 95 } |
90 | 96 |
91 // Compute the enclosing rect of the view, in root element space. | 97 // Compute the enclosing rect of the view, in root element space. |
92 // | 98 // |
93 // For background colors we can simply paint the document rect in the default
space. | 99 // For background colors we can simply paint the document rect in the default |
94 // However for background image, the root element transform applies. The strat
egy is to apply | 100 // space. However for background image, the root element transform applies. |
95 // root element transform on the context and issue draw commands in the local
space, therefore | 101 // The strategy is to apply root element transform on the context and issue |
96 // we need to apply inverse transform on the document rect to get to the root
element space. | 102 // draw commands in the local space, therefore we need to apply inverse |
| 103 // transform on the document rect to get to the root element space. |
97 bool backgroundRenderable = true; | 104 bool backgroundRenderable = true; |
98 TransformationMatrix transform; | 105 TransformationMatrix transform; |
99 IntRect paintRect = backgroundRect; | 106 IntRect paintRect = backgroundRect; |
100 if (!rootObject || !rootObject->isBox()) { | 107 if (!rootObject || !rootObject->isBox()) { |
101 backgroundRenderable = false; | 108 backgroundRenderable = false; |
102 } else if (rootObject->hasLayer()) { | 109 } else if (rootObject->hasLayer()) { |
103 const PaintLayer& rootLayer = *toLayoutBoxModelObject(rootObject)->layer(); | 110 const PaintLayer& rootLayer = *toLayoutBoxModelObject(rootObject)->layer(); |
104 LayoutPoint offset; | 111 LayoutPoint offset; |
105 rootLayer.convertToLayerCoords(nullptr, offset); | 112 rootLayer.convertToLayerCoords(nullptr, offset); |
106 transform.translate(offset.x(), offset.y()); | 113 transform.translate(offset.x(), offset.y()); |
(...skipping 21 matching lines...) Expand all Loading... |
128 return; | 135 return; |
129 } | 136 } |
130 | 137 |
131 BoxPainter::FillLayerOcclusionOutputList reversedPaintList; | 138 BoxPainter::FillLayerOcclusionOutputList reversedPaintList; |
132 bool shouldDrawBackgroundInSeparateBuffer = | 139 bool shouldDrawBackgroundInSeparateBuffer = |
133 BoxPainter(m_layoutView) | 140 BoxPainter(m_layoutView) |
134 .calculateFillLayerOcclusionCulling( | 141 .calculateFillLayerOcclusionCulling( |
135 reversedPaintList, m_layoutView.style()->backgroundLayers()); | 142 reversedPaintList, m_layoutView.style()->backgroundLayers()); |
136 ASSERT(reversedPaintList.size()); | 143 ASSERT(reversedPaintList.size()); |
137 | 144 |
138 // If the root background color is opaque, isolation group can be skipped beca
use the canvas | 145 // If the root background color is opaque, isolation group can be skipped |
| 146 // because the canvas |
139 // will be cleared by root background color. | 147 // will be cleared by root background color. |
140 if (!rootBackgroundColor.hasAlpha()) | 148 if (!rootBackgroundColor.hasAlpha()) |
141 shouldDrawBackgroundInSeparateBuffer = false; | 149 shouldDrawBackgroundInSeparateBuffer = false; |
142 | 150 |
143 // We are going to clear the canvas with transparent pixels, isolation group c
an be skipped. | 151 // We are going to clear the canvas with transparent pixels, isolation group |
| 152 // can be skipped. |
144 if (!baseBackgroundColor.alpha() && shouldClearCanvas) | 153 if (!baseBackgroundColor.alpha() && shouldClearCanvas) |
145 shouldDrawBackgroundInSeparateBuffer = false; | 154 shouldDrawBackgroundInSeparateBuffer = false; |
146 | 155 |
147 if (shouldDrawBackgroundInSeparateBuffer) { | 156 if (shouldDrawBackgroundInSeparateBuffer) { |
148 if (baseBackgroundColor.alpha()) | 157 if (baseBackgroundColor.alpha()) |
149 context.fillRect(backgroundRect, baseBackgroundColor, | 158 context.fillRect(backgroundRect, baseBackgroundColor, |
150 shouldClearCanvas ? SkXfermode::kSrc_Mode | 159 shouldClearCanvas ? SkXfermode::kSrc_Mode |
151 : SkXfermode::kSrcOver_Mode); | 160 : SkXfermode::kSrcOver_Mode); |
152 context.beginLayer(); | 161 context.beginLayer(); |
153 } | 162 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 LayoutRect(paintRect), BackgroundBleedNone); | 196 LayoutRect(paintRect), BackgroundBleedNone); |
188 context.restore(); | 197 context.restore(); |
189 } | 198 } |
190 } | 199 } |
191 | 200 |
192 if (shouldDrawBackgroundInSeparateBuffer) | 201 if (shouldDrawBackgroundInSeparateBuffer) |
193 context.endLayer(); | 202 context.endLayer(); |
194 } | 203 } |
195 | 204 |
196 } // namespace blink | 205 } // namespace blink |
OLD | NEW |