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 |