Chromium Code Reviews| 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 "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 m_layoutView.paintObject(paintInfo, paintOffset); | 28 m_layoutView.paintObject(paintInfo, paintOffset); |
| 26 BlockPainter(m_layoutView).paintOverflowControlsIfNeeded(paintInfo, paintOff set); | 29 BlockPainter(m_layoutView).paintOverflowControlsIfNeeded(paintInfo, paintOff set); |
| 27 } | 30 } |
| 28 | 31 |
| 29 static inline bool layoutObjectObscuresBackground(LayoutBox* rootBox) | |
| 30 { | |
| 31 ASSERT(rootBox); | |
| 32 const ComputedStyle& style = rootBox->styleRef(); | |
| 33 if (style.visibility() != VISIBLE | |
| 34 || style.opacity() != 1 | |
| 35 || style.hasFilter() | |
| 36 || style.hasTransform()) | |
| 37 return false; | |
| 38 | |
| 39 if (rootBox->compositingState() == PaintsIntoOwnBacking) | |
| 40 return false; | |
| 41 | |
| 42 const LayoutObject* rootLayoutObject = rootBox->layoutObjectForRootBackgroun d(); | |
| 43 if (rootLayoutObject->style()->backgroundClip() == TextFillBox) | |
| 44 return false; | |
| 45 | |
| 46 return true; | |
| 47 } | |
| 48 | |
| 49 void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) | 32 void ViewPainter::paintBoxDecorationBackground(const PaintInfo& paintInfo) |
|
chrishtr
2015/06/09 21:07:53
What prevents this from being called when the back
trchen
2015/06/09 23:36:08
LayoutView always steals backgrounds from the root
| |
| 50 { | 33 { |
| 51 if (m_layoutView.document().ownerElement() || !m_layoutView.view()) | |
| 52 return; | |
| 53 | |
| 54 if (paintInfo.skipRootBackground()) | 34 if (paintInfo.skipRootBackground()) |
| 55 return; | 35 return; |
| 56 | 36 |
| 57 bool shouldPaintBackground = true; | 37 GraphicsContext& context = *paintInfo.context; |
| 58 Node* documentElement = m_layoutView.document().documentElement(); | 38 IntRect documentRect = m_layoutView.unscaledDocumentRect(); |
| 59 if (LayoutBox* rootBox = documentElement ? toLayoutBox(documentElement->layo utObject()) : 0) | 39 const Document& document = m_layoutView.document(); |
| 60 shouldPaintBackground = !rootFillsViewportBackground(rootBox) || !layout ObjectObscuresBackground(rootBox); | 40 const FrameView& frameView = *m_layoutView.frameView(); |
| 41 bool isMainFrame = !document.ownerElement(); | |
| 42 bool paintsBaseBackground = isMainFrame && !frameView.isTransparent(); | |
| 43 bool shouldClearCanvas = paintsBaseBackground && (document.settings() && doc ument.settings()->shouldClearDocumentBackground()); | |
| 44 Color baseBackgroundColor = paintsBaseBackground ? frameView.baseBackgroundC olor() : Color(); | |
| 45 const LayoutObject* rootObject = document.documentElement() ? document.docum entElement()->layoutObject() : nullptr; | |
| 61 | 46 |
| 62 // If painting will entirely fill the view, no need to fill the background. | 47 LayoutObjectDrawingRecorder recorder(context, m_layoutView, DisplayItem::Box DecorationBackground, documentRect); |
| 63 if (!shouldPaintBackground) | 48 if (recorder.canUseCachedDrawing()) |
| 64 return; | 49 return; |
| 65 | 50 |
| 66 // This code typically only executes if the root element's visibility has be en set to hidden, | 51 bool backgroundRenderable = true; |
| 67 // if there is a transform on the <html>, or if there is a page scale factor less than 1. | 52 TransformationMatrix transform; |
| 68 // Only fill with the base background color (typically white) if we're the r oot document, | 53 IntRect paintRect = documentRect; |
| 69 // since iframes/frames with no background in the child document should show the parent's background. | 54 if (!rootObject || !rootObject->isBox()) { |
|
chrishtr
2015/06/09 21:07:53
Add comments explaining this code. Also comments e
trchen
2015/06/09 23:36:08
Acknowledged.
| |
| 70 if (!m_layoutView.frameView()->isTransparent()) { | 55 backgroundRenderable = false; |
| 71 LayoutRect paintRect(paintInfo.rect); | 56 } else if (rootObject->hasLayer()) { |
| 72 if (RuntimeEnabledFeatures::slimmingPaintEnabled()) | 57 const DeprecatedPaintLayer& rootLayer = *toLayoutBoxModelObject(rootObje ct)->layer(); |
| 73 paintRect = m_layoutView.viewRect(); | 58 LayoutPoint offset; |
| 59 rootLayer.convertToLayerCoords(nullptr, offset); | |
| 60 transform.translate(offset.x(), offset.y()); | |
| 61 transform.multiply(rootLayer.renderableTransform(paintInfo.paintBehavior )); | |
| 74 | 62 |
| 75 LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutView, D isplayItem::BoxDecorationBackground, m_layoutView.viewRect()); | 63 if (!transform.isInvertible()) { |
| 76 if (!recorder.canUseCachedDrawing()) { | 64 backgroundRenderable = false; |
| 77 Color baseColor = m_layoutView.frameView()->baseBackgroundColor(); | 65 } else { |
| 78 paintInfo.context->fillRect(paintRect, baseColor, baseColor.alpha() ? | 66 bool isClamped; |
| 79 SkXfermode::kSrc_Mode : SkXfermode::kClear_Mode); | 67 paintRect = transform.inverse().projectQuad(FloatQuad(documentRect), &isClamped).enclosingBoundingBox(); |
| 68 backgroundRenderable = !isClamped; | |
| 80 } | 69 } |
| 81 } | 70 } |
| 82 } | |
| 83 | 71 |
| 84 bool ViewPainter::rootFillsViewportBackground(LayoutBox* rootBox) const | 72 if (!backgroundRenderable) { |
| 85 { | 73 if (baseBackgroundColor.alpha()) |
| 86 ASSERT(rootBox); | 74 context.fillRect(documentRect, baseBackgroundColor, shouldClearCanva s ? SkXfermode::kSrc_Mode : SkXfermode::kSrcOver_Mode); |
| 87 // CSS Boxes always fill the viewport background (see paintRootBoxFillLayers ) | 75 else if (shouldClearCanvas) |
| 88 if (!rootBox->isSVG()) | 76 context.fillRect(documentRect, Color(), SkXfermode::kClear_Mode); |
| 89 return true; | 77 return; |
| 78 } | |
| 90 | 79 |
| 91 return rootBox->frameRect().contains(m_layoutView.frameRect()); | 80 BoxPainter::FillLayerOcclusionOutputList reversedPaintList; |
| 81 bool shouldDrawBackgroundInSeparateBuffer = BoxPainter(m_layoutView).calcula teFillLayerOcclusionCulling(reversedPaintList, m_layoutView.style()->backgroundL ayers()); | |
| 82 ASSERT(reversedPaintList.size()); | |
| 83 Color rootBackgroundColor = m_layoutView.style()->visitedDependentColor(CSSP ropertyBackgroundColor); | |
| 84 if (!rootBackgroundColor.hasAlpha()) | |
| 85 shouldDrawBackgroundInSeparateBuffer = false; | |
| 86 | |
| 87 if (!baseBackgroundColor.alpha() && shouldClearCanvas) | |
| 88 shouldDrawBackgroundInSeparateBuffer = false; | |
| 89 | |
| 90 if (shouldDrawBackgroundInSeparateBuffer) { | |
| 91 if (baseBackgroundColor.alpha()) | |
| 92 context.fillRect(documentRect, baseBackgroundColor, shouldClearCanva s ? SkXfermode::kSrc_Mode : SkXfermode::kSrcOver_Mode); | |
| 93 context.beginLayer(); | |
| 94 } | |
| 95 | |
| 96 Color combinedBackgroundColor = shouldDrawBackgroundInSeparateBuffer ? rootB ackgroundColor : baseBackgroundColor.blend(rootBackgroundColor); | |
| 97 if (combinedBackgroundColor.alpha()) | |
| 98 context.fillRect(documentRect, combinedBackgroundColor, (shouldDrawBackg roundInSeparateBuffer || shouldClearCanvas) ? SkXfermode::kSrc_Mode : SkXfermode ::kSrcOver_Mode); | |
| 99 else if (shouldClearCanvas && !shouldDrawBackgroundInSeparateBuffer) | |
| 100 context.fillRect(documentRect, Color(), SkXfermode::kClear_Mode); | |
| 101 | |
| 102 { | |
| 103 GraphicsContextStateSaver stateSaver(context); | |
|
chrishtr
2015/06/09 21:07:53
Don't use a state saver here, just use save and re
trchen
2015/06/09 23:36:08
Acknowledged.
| |
| 104 // TODO(trchen): We should be able to handle 3D-transformed root | |
| 105 // background with slimming paint by using transform display items. | |
| 106 context.concatCTM(transform.toAffineTransform()); | |
| 107 for (auto it = reversedPaintList.rbegin(); it != reversedPaintList.rend( ); ++it) { | |
| 108 ASSERT((*it)->clip() == BorderFillBox); | |
| 109 BoxPainter::paintFillLayerExtended(m_layoutView, paintInfo, Color(), **it, LayoutRect(paintRect), BackgroundBleedNone); | |
| 110 } | |
| 111 } | |
| 112 | |
| 113 if (shouldDrawBackgroundInSeparateBuffer) | |
| 114 context.endLayer(); | |
| 92 } | 115 } |
| 93 | 116 |
| 94 } // namespace blink | 117 } // namespace blink |
| OLD | NEW |