Changeset 200279 in webkit
- Timestamp:
- Apr 29, 2016, 7:55:01 PM (9 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r200276 r200279 1 2016-04-29 Simon Fraser <simon.fraser@apple.com> 2 3 Clean up GraphicsContext use in RenderLayer::paintLayerContents() 4 https://bugs.webkit.org/show_bug.cgi?id=157193 5 6 Reviewed by Zalan Bujtas. 7 8 Make the lifetime of the temporary GraphicsContext used to paint filters more explicit 9 by putting it in an inner scope. 10 11 Make currentContext a reference. 12 13 transparencyLayerContext was a confusing name (it doens't mean we've started a 14 transparency layer), so just use "context" to refer to the original context. When 15 passed to other functions, this is called "contextForTransparencyLayer". 16 17 No longer leaves "context" as a null pointer if filterPainter->filterContext() returns 18 a null pointer. It's unclear if this ever happened. 19 20 * rendering/FilterEffectRenderer.cpp: 21 (WebCore::FilterEffectRendererHelper::filterContext): 22 * rendering/RenderLayer.cpp: 23 (WebCore::RenderLayer::beginTransparencyLayers): 24 (WebCore::RenderLayer::applyFilters): 25 (WebCore::RenderLayer::paintLayerContents): 26 (WebCore::RenderLayer::paintBackgroundForFragments): 27 (WebCore::RenderLayer::paintForegroundForFragments): 28 * rendering/RenderLayer.h: 29 1 30 2016-04-29 Joseph Pecoraro <pecoraro@apple.com> 2 31 -
trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp
r192140 r200279 388 388 { 389 389 if (!m_haveFilterEffect) 390 return 0;390 return nullptr; 391 391 392 392 FilterEffectRenderer* filter = m_renderLayer->filterRenderer(); -
trunk/Source/WebCore/rendering/RenderLayer.cpp
r200261 r200279 1820 1820 1821 1821 #ifdef REVEAL_TRANSPARENCY_LAYERS 1822 context ->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));1823 context ->fillRect(pixelSnappedClipRect);1822 context.setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f)); 1823 context.fillRect(pixelSnappedClipRect); 1824 1824 #endif 1825 1825 } … … 4197 4197 } 4198 4198 4199 GraphicsContext&RenderLayer::applyFilters(FilterEffectRendererHelper* filterPainter, GraphicsContext& originalContext, LayerPaintingInfo& paintingInfo, LayerFragments& layerFragments)4199 void RenderLayer::applyFilters(FilterEffectRendererHelper* filterPainter, GraphicsContext& originalContext, LayerPaintingInfo& paintingInfo, LayerFragments& layerFragments) 4200 4200 { 4201 4201 ASSERT(filterPainter->hasStartedFilterEffect()); … … 4206 4206 filterPainter->applyFilterEffect(originalContext); 4207 4207 restoreClip(originalContext, paintingInfo.paintDirtyRect, backgroundRect); 4208 return originalContext;4209 4208 } 4210 4209 … … 4240 4239 } 4241 4240 4242 void RenderLayer::paintLayerContents(GraphicsContext& originalContext, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)4241 void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) 4243 4242 { 4244 4243 ASSERT(isSelfPaintingLayer() || hasSelfPaintingLayerDescendant()); … … 4282 4281 // things on the scrolling thread. 4283 4282 bool didQuantizeFonts = true; 4284 bool needToAdjustSubpixelQuantization = setupFontSubpixelQuantization( originalContext, didQuantizeFonts);4283 bool needToAdjustSubpixelQuantization = setupFontSubpixelQuantization(context, didQuantizeFonts); 4285 4284 4286 4285 // Apply clip-path to context. 4287 4286 LayoutSize columnAwareOffsetFromRoot = offsetFromRoot; 4288 if (renderer().flowThreadContainingBlock() && (renderer().hasClipPath() || hasFilterThatIsPainting( originalContext, paintFlags)))4287 if (renderer().flowThreadContainingBlock() && (renderer().hasClipPath() || hasFilterThatIsPainting(context, paintFlags))) 4289 4288 columnAwareOffsetFromRoot = toLayoutSize(convertToLayerCoords(paintingInfo.rootLayer, LayoutPoint(), AdjustForColumns)); 4290 4289 4291 4290 bool hasClipPath = false; 4292 4291 if (shouldApplyClipPath(paintingInfo.paintBehavior, localPaintFlags)) 4293 hasClipPath = setupClipPath( originalContext, paintingInfo, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);4292 hasClipPath = setupClipPath(context, paintingInfo, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed); 4294 4293 4295 4294 LayerPaintingInfo localPaintingInfo(paintingInfo); 4296 4297 GraphicsContext* context = &originalContext;4298 GraphicsContext& transparencyLayerContext = originalContext;4299 std::unique_ptr<FilterEffectRendererHelper> filterPainter = setupFilters(*context, localPaintingInfo, paintFlags, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);4300 if (filterPainter) {4301 context = filterPainter->filterContext();4302 if (context != &transparencyLayerContext && haveTransparency) {4303 // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.4304 beginTransparencyLayers(transparencyLayerContext, localPaintingInfo, paintingInfo.paintDirtyRect);4305 }4306 }4307 4308 // If this layer's renderer is a child of the subtreePaintRoot, we render unconditionally, which4309 // is done by passing a nil subtreePaintRoot down to our renderer (as if no subtreePaintRoot was ever set).4310 // Otherwise, our renderer tree may or may not contain the subtreePaintRoot root, so we pass that root along4311 // so it will be tested against as we descend through the renderers.4312 RenderObject* subtreePaintRootForRenderer = nullptr;4313 if (localPaintingInfo.subtreePaintRoot && !renderer().isDescendantOf(localPaintingInfo.subtreePaintRoot))4314 subtreePaintRootForRenderer = localPaintingInfo.subtreePaintRoot;4315 4316 if (localPaintingInfo.overlapTestRequests && isSelfPaintingLayer)4317 performOverlapTests(*localPaintingInfo.overlapTestRequests, localPaintingInfo.rootLayer, this);4318 4295 4319 4296 bool selectionAndBackgroundsOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionAndBackgroundsOnly; 4320 4297 bool selectionOnly = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly; 4321 4322 PaintBehavior paintBehavior = PaintBehaviorNormal;4323 if (localPaintFlags & PaintLayerPaintingSkipRootBackground)4324 paintBehavior |= PaintBehaviorSkipRootBackground;4325 else if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly)4326 paintBehavior |= PaintBehaviorRootBackgroundOnly;4327 4328 4298 LayerFragments layerFragments; 4329 LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect; 4330 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { 4331 // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each 4332 // fragment should paint. If the parent's filter dictates full repaint to ensure proper filter effect, 4333 // use the overflow clip as dirty rect, instead of no clipping. It maintains proper clipping for overflow::scroll. 4334 if (!paintingInfo.clipToDirtyRect && renderer().hasOverflowClip()) { 4335 // We can turn clipping back by requesting full repaint for the overflow area. 4336 localPaintingInfo.clipToDirtyRect = true; 4337 paintDirtyRect = selfClipRect(); 4338 } 4339 collectFragments(layerFragments, localPaintingInfo.rootLayer, paintDirtyRect, ExcludeCompositedPaginatedLayers, 4340 (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize, 4341 (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, offsetFromRoot); 4342 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, localPaintFlags, shouldPaintContent, offsetFromRoot); 4343 } 4344 4345 if (isPaintingCompositedBackground) { 4346 // Paint only the backgrounds for all of the fragments of the layer. 4347 if (shouldPaintContent && !selectionOnly) 4348 paintBackgroundForFragments(layerFragments, *context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency, 4349 localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); 4350 } 4351 4352 // Now walk the sorted list of children with negative z-indices. 4353 if ((isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground)) 4354 paintList(negZOrderList(), *context, localPaintingInfo, localPaintFlags); 4355 4356 if (isPaintingCompositedForeground) { 4357 if (shouldPaintContent) 4358 paintForegroundForFragments(layerFragments, *context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency, 4359 localPaintingInfo, paintBehavior, subtreePaintRootForRenderer, selectionOnly || selectionAndBackgroundsOnly); 4360 } 4361 4362 if (shouldPaintOutline) 4363 paintOutlineForFragments(layerFragments, *context, localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); 4364 4365 if (isPaintingCompositedForeground) { 4366 // Paint any child layers that have overflow. 4367 paintList(m_normalFlowList.get(), *context, localPaintingInfo, localPaintFlags); 4368 4369 // Now walk the sorted list of children with positive z-indices. 4370 paintList(posZOrderList(), *context, localPaintingInfo, localPaintFlags); 4371 4372 // Paint the fixed elements from flow threads. 4373 paintFixedLayersInNamedFlows(*context, localPaintingInfo, localPaintFlags); 4299 RenderObject* subtreePaintRootForRenderer = nullptr; 4300 4301 { // Scope for currentContext. 4302 std::unique_ptr<FilterEffectRendererHelper> filterPainter = setupFilters(context, localPaintingInfo, paintFlags, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed); 4303 4304 GraphicsContext* filterContext = filterPainter ? filterPainter->filterContext() : nullptr; 4305 if (filterContext && haveTransparency) { 4306 // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context. 4307 beginTransparencyLayers(context, localPaintingInfo, paintingInfo.paintDirtyRect); 4308 } 4309 GraphicsContext& currentContext = filterContext ? *filterContext : context; 4310 4311 // If this layer's renderer is a child of the subtreePaintRoot, we render unconditionally, which 4312 // is done by passing a nil subtreePaintRoot down to our renderer (as if no subtreePaintRoot was ever set). 4313 // Otherwise, our renderer tree may or may not contain the subtreePaintRoot root, so we pass that root along 4314 // so it will be tested against as we descend through the renderers. 4315 if (localPaintingInfo.subtreePaintRoot && !renderer().isDescendantOf(localPaintingInfo.subtreePaintRoot)) 4316 subtreePaintRootForRenderer = localPaintingInfo.subtreePaintRoot; 4317 4318 if (localPaintingInfo.overlapTestRequests && isSelfPaintingLayer) 4319 performOverlapTests(*localPaintingInfo.overlapTestRequests, localPaintingInfo.rootLayer, this); 4320 4321 PaintBehavior paintBehavior = PaintBehaviorNormal; 4322 if (localPaintFlags & PaintLayerPaintingSkipRootBackground) 4323 paintBehavior |= PaintBehaviorSkipRootBackground; 4324 else if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly) 4325 paintBehavior |= PaintBehaviorRootBackgroundOnly; 4326 4327 LayoutRect paintDirtyRect = localPaintingInfo.paintDirtyRect; 4328 if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) { 4329 // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each 4330 // fragment should paint. If the parent's filter dictates full repaint to ensure proper filter effect, 4331 // use the overflow clip as dirty rect, instead of no clipping. It maintains proper clipping for overflow::scroll. 4332 if (!paintingInfo.clipToDirtyRect && renderer().hasOverflowClip()) { 4333 // We can turn clipping back by requesting full repaint for the overflow area. 4334 localPaintingInfo.clipToDirtyRect = true; 4335 paintDirtyRect = selfClipRect(); 4336 } 4337 collectFragments(layerFragments, localPaintingInfo.rootLayer, paintDirtyRect, ExcludeCompositedPaginatedLayers, 4338 (localPaintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize, 4339 (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, offsetFromRoot); 4340 updatePaintingInfoForFragments(layerFragments, localPaintingInfo, localPaintFlags, shouldPaintContent, offsetFromRoot); 4341 } 4374 4342 4375 // If this is a region, paint its contents via the flow thread's layer. 4376 if (shouldPaintContent) 4377 paintFlowThreadIfRegionForFragments(layerFragments, *context, localPaintingInfo, localPaintFlags); 4378 } 4379 4380 if (isPaintingOverlayScrollbars && hasScrollbars()) 4381 paintOverflowControlsForFragments(layerFragments, *context, localPaintingInfo); 4382 4383 if (filterPainter) { 4384 context = &applyFilters(filterPainter.get(), transparencyLayerContext, localPaintingInfo, layerFragments); 4385 filterPainter = nullptr; 4386 } 4387 4388 // Make sure that we now use the original transparency context. 4389 ASSERT(&transparencyLayerContext == context); 4390 4343 if (isPaintingCompositedBackground) { 4344 // Paint only the backgrounds for all of the fragments of the layer. 4345 if (shouldPaintContent && !selectionOnly) { 4346 paintBackgroundForFragments(layerFragments, currentContext, context, paintingInfo.paintDirtyRect, haveTransparency, 4347 localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); 4348 } 4349 } 4350 4351 // Now walk the sorted list of children with negative z-indices. 4352 if ((isPaintingScrollingContent && isPaintingOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackground)) 4353 paintList(negZOrderList(), currentContext, localPaintingInfo, localPaintFlags); 4354 4355 if (isPaintingCompositedForeground) { 4356 if (shouldPaintContent) { 4357 paintForegroundForFragments(layerFragments, currentContext, context, paintingInfo.paintDirtyRect, haveTransparency, 4358 localPaintingInfo, paintBehavior, subtreePaintRootForRenderer, selectionOnly || selectionAndBackgroundsOnly); 4359 } 4360 } 4361 4362 if (shouldPaintOutline) 4363 paintOutlineForFragments(layerFragments, currentContext, localPaintingInfo, paintBehavior, subtreePaintRootForRenderer); 4364 4365 if (isPaintingCompositedForeground) { 4366 // Paint any child layers that have overflow. 4367 paintList(m_normalFlowList.get(), currentContext, localPaintingInfo, localPaintFlags); 4368 4369 // Now walk the sorted list of children with positive z-indices. 4370 paintList(posZOrderList(), currentContext, localPaintingInfo, localPaintFlags); 4371 4372 // Paint the fixed elements from flow threads. 4373 paintFixedLayersInNamedFlows(currentContext, localPaintingInfo, localPaintFlags); 4374 4375 // If this is a region, paint its contents via the flow thread's layer. 4376 if (shouldPaintContent) 4377 paintFlowThreadIfRegionForFragments(layerFragments, currentContext, localPaintingInfo, localPaintFlags); 4378 } 4379 4380 if (isPaintingOverlayScrollbars && hasScrollbars()) 4381 paintOverflowControlsForFragments(layerFragments, currentContext, localPaintingInfo); 4382 4383 if (filterContext) { 4384 applyFilters(filterPainter.get(), context, localPaintingInfo, layerFragments); 4385 filterPainter = nullptr; 4386 } 4387 } 4388 4391 4389 if (shouldPaintContent && !(selectionOnly || selectionAndBackgroundsOnly)) { 4392 4390 if (shouldPaintMask(paintingInfo.paintBehavior, localPaintFlags)) { 4393 4391 // Paint the mask for the fragments. 4394 paintMaskForFragments(layerFragments, *context, localPaintingInfo, subtreePaintRootForRenderer);4392 paintMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer); 4395 4393 } 4396 4394 4397 4395 if (!(paintFlags & PaintLayerPaintingCompositingMaskPhase) && (paintFlags & PaintLayerPaintingCompositingClipPathPhase)) { 4398 4396 // Re-use paintChildClippingMaskForFragments to paint black for the compositing clipping mask. 4399 paintChildClippingMaskForFragments(layerFragments, *context, localPaintingInfo, subtreePaintRootForRenderer);4397 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer); 4400 4398 } 4401 4399 4402 4400 if ((localPaintFlags & PaintLayerPaintingChildClippingMaskPhase)) { 4403 4401 // Paint the border radius mask for the fragments. 4404 paintChildClippingMaskForFragments(layerFragments, *context, localPaintingInfo, subtreePaintRootForRenderer);4402 paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer); 4405 4403 } 4406 4404 } … … 4408 4406 // End our transparency layer 4409 4407 if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) { 4410 context ->endTransparencyLayer();4411 context ->restore();4408 context.endTransparencyLayer(); 4409 context.restore(); 4412 4410 m_usedTransparency = false; 4413 4411 } … … 4415 4413 // Re-set this to whatever it was before we painted the layer. 4416 4414 if (needToAdjustSubpixelQuantization) 4417 context ->setShouldSubpixelQuantizeFonts(didQuantizeFonts);4415 context.setShouldSubpixelQuantizeFonts(didQuantizeFonts); 4418 4416 4419 4417 if (hasClipPath) 4420 context ->restore();4418 context.restore(); 4421 4419 } 4422 4420 … … 4664 4662 } 4665 4663 4666 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext& context, GraphicsContext& transparencyLayerContext,4664 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext& context, GraphicsContext& contextForTransparencyLayer, 4667 4665 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 4668 4666 RenderObject* subtreePaintRootForRenderer) … … 4674 4672 // Begin transparency layers lazily now that we know we have to paint something. 4675 4673 if (haveTransparency) 4676 beginTransparencyLayers( transparencyLayerContext, localPaintingInfo, transparencyPaintDirtyRect);4674 beginTransparencyLayers(contextForTransparencyLayer, localPaintingInfo, transparencyPaintDirtyRect); 4677 4675 4678 4676 if (localPaintingInfo.clipToDirtyRect) { … … 4692 4690 } 4693 4691 4694 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext& context, GraphicsContext& transparencyLayerContext,4692 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext& context, GraphicsContext& contextForTransparencyLayer, 4695 4693 const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, 4696 4694 RenderObject* subtreePaintRootForRenderer, bool selectionOnly) … … 4700 4698 for (const auto& fragment : layerFragments) { 4701 4699 if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) { 4702 beginTransparencyLayers( transparencyLayerContext, localPaintingInfo, transparencyPaintDirtyRect);4700 beginTransparencyLayers(contextForTransparencyLayer, localPaintingInfo, transparencyPaintDirtyRect); 4703 4701 break; 4704 4702 } -
trunk/Source/WebCore/rendering/RenderLayer.h
r200116 r200279 787 787 bool hasFilterThatIsPainting(GraphicsContext&, PaintLayerFlags) const; 788 788 std::unique_ptr<FilterEffectRendererHelper> setupFilters(GraphicsContext&, LayerPaintingInfo&, PaintLayerFlags, const LayoutSize& offsetFromRoot, LayoutRect& rootRelativeBounds, bool& rootRelativeBoundsComputed); 789 GraphicsContext&applyFilters(FilterEffectRendererHelper*, GraphicsContext& originalContext, LayerPaintingInfo&, LayerFragments&);789 void applyFilters(FilterEffectRendererHelper*, GraphicsContext& originalContext, LayerPaintingInfo&, LayerFragments&); 790 790 791 791 void paintLayer(GraphicsContext&, const LayerPaintingInfo&, PaintLayerFlags);
Note:
See TracChangeset
for help on using the changeset viewer.