| 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 |