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/LayerPainter.h" | 6 #include "core/paint/LayerPainter.h" |
| 7 | 7 |
| 8 #include "core/frame/Settings.h" | 8 #include "core/frame/Settings.h" |
| 9 #include "core/page/Page.h" | 9 #include "core/page/Page.h" |
| 10 #include "core/paint/FilterPainter.h" | 10 #include "core/paint/FilterPainter.h" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 151 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform) ; | 151 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform) ; |
| 152 | 152 |
| 153 // Paint the reflection first if we have one. | 153 // Paint the reflection first if we have one. |
| 154 if (m_renderLayer.reflectionInfo()) | 154 if (m_renderLayer.reflectionInfo()) |
| 155 m_renderLayer.reflectionInfo()->paint(context, paintingInfo, localPaintF lags | PaintLayerPaintingReflection); | 155 m_renderLayer.reflectionInfo()->paint(context, paintingInfo, localPaintF lags | PaintLayerPaintingReflection); |
| 156 | 156 |
| 157 localPaintFlags |= PaintLayerPaintingCompositingAllPhases; | 157 localPaintFlags |= PaintLayerPaintingCompositingAllPhases; |
| 158 paintLayerContents(context, paintingInfo, localPaintFlags); | 158 paintLayerContents(context, paintingInfo, localPaintFlags); |
| 159 } | 159 } |
| 160 | 160 |
| 161 class ClipPathPainter { | |
|
mstensho (USE GERRIT)
2014/11/12 21:00:27
Does this class actually paint anything at all? Co
chrishtr
2014/11/12 21:41:45
Done.
| |
| 162 public: | |
| 163 ClipPathPainter(GraphicsContext* context, const RenderLayer& renderLayer, co nst LayerPaintingInfo& paintingInfo, LayoutRect& rootRelativeBounds, bool& rootR elativeBoundsComputed, | |
| 164 const LayoutPoint& offsetFromRoot, PaintLayerFlags paintFlags) | |
| 165 : m_resourceClipper(0), m_clipStateSaver(*context, false), m_renderLayer(ren derLayer), m_context(context) | |
|
mstensho (USE GERRIT)
2014/11/12 21:00:27
Strange indentation.
chrishtr
2014/11/12 21:41:45
Done.
| |
| 166 { | |
| 167 RenderStyle* style = renderLayer.renderer()->style(); | |
| 168 | |
| 169 // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container. | |
| 170 // It must, however, still be applied to the mask layer, so that the com positor can properly mask the | |
| 171 // scrolling contents and scrollbars. | |
| 172 if (!renderLayer.renderer()->hasClipPath() || !style || (renderLayer.nee dsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPha se))) | |
| 173 return; | |
| 174 | |
| 175 m_clipperState = RenderSVGResourceClipper::ClipperNotApplied; | |
| 176 | |
| 177 ASSERT(style->clipPath()); | |
| 178 if (style->clipPath()->type() == ClipPathOperation::SHAPE) { | |
| 179 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->c lipPath()); | |
| 180 if (clipPath->isValid()) { | |
| 181 m_clipStateSaver.save(); | |
| 182 | |
| 183 if (!rootRelativeBoundsComputed) { | |
|
mstensho (USE GERRIT)
2014/11/12 21:00:27
It's tempting to create a getter for this (LayoutR
chrishtr
2014/11/12 21:41:45
I almost pulled the trigger on this in earlier rev
| |
| 184 rootRelativeBounds = renderLayer.physicalBoundingBoxIncludin gReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | |
| 185 rootRelativeBoundsComputed = true; | |
| 186 } | |
| 187 | |
| 188 context->clipPath(clipPath->path(rootRelativeBounds), clipPath-> windRule()); | |
| 189 } | |
| 190 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { | |
| 191 ReferenceClipPathOperation* referenceClipPathOperation = toReference ClipPathOperation(style->clipPath()); | |
| 192 Document& document = renderLayer.renderer()->document(); | |
| 193 // FIXME: It doesn't work with forward or external SVG references (h ttps://bugs.webkit.org/show_bug.cgi?id=90405) | |
| 194 Element* element = document.getElementById(referenceClipPathOperatio n->fragment()); | |
| 195 if (isSVGClipPathElement(element) && element->renderer()) { | |
| 196 // FIXME: Saving at this point is not required in the 'mask'- | |
| 197 // case, or if the clip ends up empty. | |
| 198 m_clipStateSaver.save(); | |
| 199 if (!rootRelativeBoundsComputed) { | |
| 200 rootRelativeBounds = renderLayer.physicalBoundingBoxIncludin gReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | |
| 201 rootRelativeBoundsComputed = true; | |
| 202 } | |
| 203 | |
| 204 m_resourceClipper = toRenderSVGResourceClipper(toRenderSVGResour ceContainer(element->renderer())); | |
| 205 if (!m_resourceClipper->applyClippingToContext(renderLayer.rende rer(), rootRelativeBounds, | |
| 206 paintingInfo.paintDirtyRect, context, m_clipperState)) { | |
| 207 // No need to post-apply the clipper if this failed. | |
| 208 m_resourceClipper = 0; | |
| 209 } | |
| 210 } | |
| 211 } | |
| 212 } | |
| 213 | |
| 214 ~ClipPathPainter() | |
| 215 { | |
| 216 if (m_resourceClipper) | |
| 217 m_resourceClipper->postApplyStatefulResource(m_renderLayer.renderer( ), m_context, m_clipperState); | |
| 218 } | |
| 219 private: | |
| 220 RenderSVGResourceClipper* m_resourceClipper; | |
| 221 GraphicsContextStateSaver m_clipStateSaver; | |
| 222 RenderSVGResourceClipper::ClipperState m_clipperState; | |
| 223 const RenderLayer& m_renderLayer; | |
| 224 GraphicsContext* m_context; | |
| 225 }; | |
| 226 | |
| 161 void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint ingInfo& paintingInfo, PaintLayerFlags paintFlags) | 227 void LayerPainter::paintLayerContents(GraphicsContext* context, const LayerPaint ingInfo& paintingInfo, PaintLayerFlags paintFlags) |
| 162 { | 228 { |
| 163 ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingL ayerDescendant()); | 229 ASSERT(m_renderLayer.isSelfPaintingLayer() || m_renderLayer.hasSelfPaintingL ayerDescendant()); |
| 164 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); | 230 ASSERT(!(paintFlags & PaintLayerAppliedTransform)); |
| 165 | 231 |
| 166 bool haveTransparency = paintFlags & PaintLayerHaveTransparency; | 232 bool haveTransparency = paintFlags & PaintLayerHaveTransparency; |
| 167 bool isSelfPaintingLayer = m_renderLayer.isSelfPaintingLayer(); | 233 bool isSelfPaintingLayer = m_renderLayer.isSelfPaintingLayer(); |
| 168 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScr ollbars; | 234 bool isPaintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScr ollbars; |
| 169 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositing ScrollingPhase; | 235 bool isPaintingScrollingContent = paintFlags & PaintLayerPaintingCompositing ScrollingPhase; |
| 170 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingComposi tingForegroundPhase; | 236 bool isPaintingCompositedForeground = paintFlags & PaintLayerPaintingComposi tingForegroundPhase; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 192 | 258 |
| 193 LayoutPoint offsetFromRoot; | 259 LayoutPoint offsetFromRoot; |
| 194 m_renderLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); | 260 m_renderLayer.convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); |
| 195 | 261 |
| 196 if (m_renderLayer.compositingState() == PaintsIntoOwnBacking) | 262 if (m_renderLayer.compositingState() == PaintsIntoOwnBacking) |
| 197 offsetFromRoot.move(m_renderLayer.subpixelAccumulation()); | 263 offsetFromRoot.move(m_renderLayer.subpixelAccumulation()); |
| 198 | 264 |
| 199 LayoutRect rootRelativeBounds; | 265 LayoutRect rootRelativeBounds; |
| 200 bool rootRelativeBoundsComputed = false; | 266 bool rootRelativeBoundsComputed = false; |
| 201 | 267 |
| 202 // Apply clip-path to context. | 268 ClipPathPainter clipPathPainter(context, m_renderLayer, paintingInfo, rootRe lativeBounds, rootRelativeBoundsComputed, offsetFromRoot, paintFlags); |
| 203 GraphicsContextStateSaver clipStateSaver(*context, false); | |
| 204 RenderStyle* style = m_renderLayer.renderer()->style(); | |
| 205 RenderSVGResourceClipper* resourceClipper = 0; | |
| 206 RenderSVGResourceClipper::ClipperState clipperState = RenderSVGResourceClipp er::ClipperNotApplied; | |
| 207 | |
| 208 // Clip-path, like border radius, must not be applied to the contents of a c omposited-scrolling container. | |
| 209 // It must, however, still be applied to the mask layer, so that the composi tor can properly mask the | |
| 210 // scrolling contents and scrollbars. | |
| 211 if (m_renderLayer.renderer()->hasClipPath() && style && (!m_renderLayer.need sCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase) ) { | |
| 212 ASSERT(style->clipPath()); | |
| 213 if (style->clipPath()->type() == ClipPathOperation::SHAPE) { | |
| 214 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->c lipPath()); | |
| 215 if (clipPath->isValid()) { | |
| 216 clipStateSaver.save(); | |
| 217 | |
| 218 if (!rootRelativeBoundsComputed) { | |
| 219 rootRelativeBounds = m_renderLayer.physicalBoundingBoxInclud ingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | |
| 220 rootRelativeBoundsComputed = true; | |
| 221 } | |
| 222 | |
| 223 context->clipPath(clipPath->path(rootRelativeBounds), clipPath-> windRule()); | |
| 224 } | |
| 225 } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) { | |
| 226 ReferenceClipPathOperation* referenceClipPathOperation = toReference ClipPathOperation(style->clipPath()); | |
| 227 Document& document = m_renderLayer.renderer()->document(); | |
| 228 // FIXME: It doesn't work with forward or external SVG references (h ttps://bugs.webkit.org/show_bug.cgi?id=90405) | |
| 229 Element* element = document.getElementById(referenceClipPathOperatio n->fragment()); | |
| 230 if (isSVGClipPathElement(element) && element->renderer()) { | |
| 231 // FIXME: Saving at this point is not required in the 'mask'- | |
| 232 // case, or if the clip ends up empty. | |
| 233 clipStateSaver.save(); | |
| 234 if (!rootRelativeBoundsComputed) { | |
| 235 rootRelativeBounds = m_renderLayer.physicalBoundingBoxInclud ingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); | |
| 236 rootRelativeBoundsComputed = true; | |
| 237 } | |
| 238 | |
| 239 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResource Container(element->renderer())); | |
| 240 if (!resourceClipper->applyClippingToContext(m_renderLayer.rende rer(), rootRelativeBounds, | |
| 241 paintingInfo.paintDirtyRect, context, clipperState)) { | |
| 242 // No need to post-apply the clipper if this failed. | |
| 243 resourceClipper = 0; | |
| 244 } | |
| 245 } | |
| 246 } | |
| 247 } | |
| 248 | 269 |
| 249 // Blending operations must be performed only with the nearest ancestor stac king context. | 270 // Blending operations must be performed only with the nearest ancestor stac king context. |
| 250 // Note that there is no need to create a transparency layer if we're painti ng the root. | 271 // Note that there is no need to create a transparency layer if we're painti ng the root. |
| 251 bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocu mentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLa yer.hasNonIsolatedDescendantWithBlendMode(); | 272 bool createTransparencyLayerForBlendMode = !m_renderLayer.renderer()->isDocu mentElement() && m_renderLayer.stackingNode()->isStackingContext() && m_renderLa yer.hasNonIsolatedDescendantWithBlendMode(); |
| 252 | 273 |
| 253 if (createTransparencyLayerForBlendMode) | 274 if (createTransparencyLayerForBlendMode) |
| 254 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa intDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); | 275 beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.pa intDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior); |
| 255 | 276 |
| 256 LayerPaintingInfo localPaintingInfo(paintingInfo); | 277 LayerPaintingInfo localPaintingInfo(paintingInfo); |
| 257 | 278 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 paintChildClippingMaskForFragments(layerFragments, context, localPaintin gInfo, paintingRootForRenderer, paintFlags); | 368 paintChildClippingMaskForFragments(layerFragments, context, localPaintin gInfo, paintingRootForRenderer, paintFlags); |
| 348 } | 369 } |
| 349 | 370 |
| 350 // End our transparency layer | 371 // End our transparency layer |
| 351 if ((haveTransparency || createTransparencyLayerForBlendMode) && m_renderLay er.usedTransparency() | 372 if ((haveTransparency || createTransparencyLayerForBlendMode) && m_renderLay er.usedTransparency() |
| 352 && !(m_renderLayer.reflectionInfo() && m_renderLayer.reflectionInfo()->i sPaintingInsideReflection())) { | 373 && !(m_renderLayer.reflectionInfo() && m_renderLayer.reflectionInfo()->i sPaintingInsideReflection())) { |
| 353 context->endLayer(); | 374 context->endLayer(); |
| 354 context->restore(); | 375 context->restore(); |
| 355 m_renderLayer.setUsedTransparency(false); | 376 m_renderLayer.setUsedTransparency(false); |
| 356 } | 377 } |
| 357 | |
| 358 if (resourceClipper) | |
| 359 resourceClipper->postApplyStatefulResource(m_renderLayer.renderer(), con text, clipperState); | |
| 360 } | 378 } |
| 361 | 379 |
| 362 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye r) | 380 static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye r) |
| 363 { | 381 { |
| 364 if (startLayer == endLayer) | 382 if (startLayer == endLayer) |
| 365 return true; | 383 return true; |
| 366 | 384 |
| 367 RenderView* view = startLayer->renderer()->view(); | 385 RenderView* view = startLayer->renderer()->view(); |
| 368 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlo ck()) { | 386 for (RenderBlock* currentBlock = startLayer->renderer()->containingBlock(); currentBlock && currentBlock != view; currentBlock = currentBlock->containingBlo ck()) { |
| 369 if (currentBlock->layer() == endLayer) | 387 if (currentBlock->layer() == endLayer) |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 | 846 |
| 829 OwnPtr<ClipRecorder> clipRecorder; | 847 OwnPtr<ClipRecorder> clipRecorder; |
| 830 if (needsToClip(paintingInfo, clipRect)) | 848 if (needsToClip(paintingInfo, clipRect)) |
| 831 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con text, DisplayItem::ClipLayerFragmentParent, clipRect)); | 849 clipRecorder = adoptPtr(new ClipRecorder(m_renderLayer.parent(), con text, DisplayItem::ClipLayerFragmentParent, clipRect)); |
| 832 | 850 |
| 833 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen t.paginationOffset); | 851 paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragmen t.paginationOffset); |
| 834 } | 852 } |
| 835 } | 853 } |
| 836 | 854 |
| 837 } // namespace blink | 855 } // namespace blink |
| OLD | NEW |