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 "core/paint/PaintLayerPainter.h" | 5 #include "core/paint/PaintLayerPainter.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/ClipPathOperation.h" | 9 #include "core/layout/ClipPathOperation.h" |
| 10 #include "core/layout/LayoutBlock.h" | 10 #include "core/layout/LayoutBlock.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 86 | 86 |
| 87 // If this layer is totally invisible then there is nothing to paint. | 87 // If this layer is totally invisible then there is nothing to paint. |
| 88 if (!m_paintLayer.layoutObject()->opacity() && !m_paintLayer.layoutObject()- >hasBackdropFilter()) | 88 if (!m_paintLayer.layoutObject()->opacity() && !m_paintLayer.layoutObject()- >hasBackdropFilter()) |
| 89 return FullyPainted; | 89 return FullyPainted; |
| 90 | 90 |
| 91 if (m_paintLayer.paintsWithTransparency(paintingInfo.globalPaintFlags())) | 91 if (m_paintLayer.paintsWithTransparency(paintingInfo.globalPaintFlags())) |
| 92 paintFlags |= PaintLayerHaveTransparency; | 92 paintFlags |= PaintLayerHaveTransparency; |
| 93 | 93 |
| 94 LayerFixedPositionRecorder fixedPositionRecorder(context, *m_paintLayer.layo utObject()); | 94 LayerFixedPositionRecorder fixedPositionRecorder(context, *m_paintLayer.layo utObject()); |
| 95 | 95 |
| 96 // Transforms will be applied by property nodes directly for SPv2. | |
| 96 // PaintLayerAppliedTransform is used in LayoutReplica, to avoid applying th e transform twice. | 97 // PaintLayerAppliedTransform is used in LayoutReplica, to avoid applying th e transform twice. |
| 97 if (m_paintLayer.paintsWithTransform(paintingInfo.globalPaintFlags()) && !(p aintFlags & PaintLayerAppliedTransform)) | 98 if (!RuntimeEnabledFeatures::slimmingPaintV2Enabled() && m_paintLayer.paints WithTransform(paintingInfo.globalPaintFlags()) && !(paintFlags & PaintLayerAppli edTransform)) |
| 98 return paintLayerWithTransform(context, paintingInfo, paintFlags); | 99 return paintLayerWithTransform(context, paintingInfo, paintFlags); |
| 99 | 100 |
| 100 return paintLayerContentsAndReflection(context, paintingInfo, paintFlags); | 101 return paintLayerContentsAndReflection(context, paintingInfo, paintFlags); |
| 101 } | 102 } |
| 102 | 103 |
| 103 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContentsAndReflectio n(GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLay erFlags paintFlags, FragmentPolicy fragmentPolicy) | 104 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerContentsAndReflectio n(GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLay erFlags paintFlags, FragmentPolicy fragmentPolicy) |
| 104 { | 105 { |
| 105 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay erDescendant()); | 106 ASSERT(m_paintLayer.isSelfPaintingLayer() || m_paintLayer.hasSelfPaintingLay erDescendant()); |
| 106 | 107 |
| 107 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform) ; | 108 PaintLayerFlags localPaintFlags = paintFlags & ~(PaintLayerAppliedTransform) ; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 m_paintLayer.layoutObject()->opacity(), &compositingBounds); | 320 m_paintLayer.layoutObject()->opacity(), &compositingBounds); |
| 320 } | 321 } |
| 321 | 322 |
| 322 PaintLayerPaintingInfo localPaintingInfo(paintingInfo); | 323 PaintLayerPaintingInfo localPaintingInfo(paintingInfo); |
| 323 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; | 324 localPaintingInfo.subPixelAccumulation = subpixelAccumulation; |
| 324 | 325 |
| 325 PaintLayerFragments layerFragments; | 326 PaintLayerFragments layerFragments; |
| 326 if (shouldPaintContent || shouldPaintSelfOutline || isPaintingOverlayScrollb ars) { | 327 if (shouldPaintContent || shouldPaintSelfOutline || isPaintingOverlayScrollb ars) { |
| 327 // Collect the fragments. This will compute the clip rectangles and pain t offsets for each layer fragment. | 328 // Collect the fragments. This will compute the clip rectangles and pain t offsets for each layer fragment. |
| 328 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects ) ? UncachedClipRects : PaintingClipRects; | 329 ClipRectsCacheSlot cacheSlot = (paintFlags & PaintLayerUncachedClipRects ) ? UncachedClipRects : PaintingClipRects; |
| 329 if (fragmentPolicy == ForceSingleFragment) | 330 // TODO(trchen): We haven't decided how to handle visual fragmentation w ith SPv2. |
| 331 // Related thread https://groups.google.com/a/chromium.org/forum/#!topic /graphics-dev/81XuWFf-mxM | |
|
chrishtr
2016/02/02 19:41:10
Following up on this now in the google group, we n
trchen
2016/02/02 21:54:51
This CL will unblock many other things, and I don'
chrishtr
2016/02/02 23:31:59
Sure, of course.
| |
| 332 if (fragmentPolicy == ForceSingleFragment || RuntimeEnabledFeatures::sli mmingPaintV2Enabled()) | |
| 330 m_paintLayer.appendSingleFragmentIgnoringPagination(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, cacheSlot, Ignore OverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.su bPixelAccumulation); | 333 m_paintLayer.appendSingleFragmentIgnoringPagination(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect, cacheSlot, Ignore OverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.su bPixelAccumulation); |
| 331 else | 334 else |
| 332 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.root Layer, localPaintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation); | 335 m_paintLayer.collectFragments(layerFragments, localPaintingInfo.root Layer, localPaintingInfo.paintDirtyRect, cacheSlot, IgnoreOverlayScrollbarSize, respectOverflowClip, &offsetFromRoot, localPaintingInfo.subPixelAccumulation); |
| 333 if (shouldPaintContent) { | 336 if (shouldPaintContent) { |
| 334 // TODO(wangxianzhu): This is for old slow scrolling. Implement simi lar optimization for slimming paint v2. | 337 // TODO(wangxianzhu): This is for old slow scrolling. Implement simi lar optimization for slimming paint v2. |
| 335 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFra gments, localPaintingInfo, paintFlags, offsetFromRoot); | 338 shouldPaintContent = atLeastOneFragmentIntersectsDamageRect(layerFra gments, localPaintingInfo, paintFlags, offsetFromRoot); |
| 336 if (!shouldPaintContent) | 339 if (!shouldPaintContent) |
| 337 result = MayBeClippedByPaintDirtyRect; | 340 result = MayBeClippedByPaintDirtyRect; |
| 338 } | 341 } |
| 339 } | 342 } |
| 340 | 343 |
| 341 bool selectionOnly = localPaintingInfo.globalPaintFlags() & GlobalPaintSelec tionOnly; | 344 bool selectionOnly = localPaintingInfo.globalPaintFlags() & GlobalPaintSelec tionOnly; |
| 342 | 345 |
| 343 { // Begin block for the lifetime of any filter. | 346 { // Begin block for the lifetime of any filter. |
| 344 FilterPainter filterPainter(m_paintLayer, context, offsetFromRoot, layer Fragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect, localPainti ngInfo, paintFlags, | 347 FilterPainter filterPainter(m_paintLayer, context, offsetFromRoot, layer Fragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect, localPainti ngInfo, paintFlags, |
| 345 rootRelativeBounds, rootRelativeBoundsComputed); | 348 rootRelativeBounds, rootRelativeBoundsComputed); |
| 346 | 349 |
| 347 Optional<ScopedPaintChunkProperties> scopedPaintChunkProperties; | 350 Optional<ScopedPaintChunkProperties> scopedPaintChunkProperties; |
| 348 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { | 351 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) |
| 349 if (const auto* objectProperties = m_paintLayer.layoutObject()->obje ctPaintProperties()) { | 352 scopedPaintChunkProperties.emplace(context.paintController(), m_pain tLayer.cachedSPv2PaintParameters().properties); |
|
chrishtr
2016/02/02 19:43:31
Is it true that this is a pure cache? i.e. the old
trchen
2016/02/02 21:54:51
Nope, the old code won't work for non-trivial case
chrishtr
2016/02/02 23:31:59
It's still not clear what you are trying to achiev
trchen
2016/02/02 23:48:26
ObjectPaintProperties hold references to the prope
| |
| 350 PaintChunkProperties properties(context.paintController().curren tPaintChunkProperties()); | |
| 351 if (TransformPaintPropertyNode* transform = objectProperties->tr ansformForLayerContents()) | |
| 352 properties.transform = transform; | |
| 353 if (EffectPaintPropertyNode* effect = objectProperties->effect() ) | |
| 354 properties.effect = effect; | |
| 355 scopedPaintChunkProperties.emplace(context.paintController(), pr operties); | |
| 356 } | |
| 357 } | |
| 358 | 353 |
| 359 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPai ntContent && !selectionOnly; | 354 bool shouldPaintBackground = isPaintingCompositedBackground && shouldPai ntContent && !selectionOnly; |
| 360 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintin gOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackgr ound); | 355 bool shouldPaintNegZOrderList = (isPaintingScrollingContent && isPaintin gOverflowContents) || (!isPaintingScrollingContent && isPaintingCompositedBackgr ound); |
| 361 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPa intContent; | 356 bool shouldPaintOwnContents = isPaintingCompositedForeground && shouldPa intContent; |
| 362 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForegr ound; | 357 bool shouldPaintNormalFlowAndPosZOrderLists = isPaintingCompositedForegr ound; |
| 363 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; | 358 bool shouldPaintOverlayScrollbars = isPaintingOverlayScrollbars; |
| 364 | 359 |
| 365 if (shouldPaintBackground) { | 360 if (shouldPaintBackground) { |
| 366 paintBackgroundForFragments(layerFragments, context, paintingInfo.pa intDirtyRect, | 361 paintBackgroundForFragments(layerFragments, context, paintingInfo.pa intDirtyRect, |
| 367 localPaintingInfo, paintFlags); | 362 localPaintingInfo, paintFlags); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 // for this is that fragment.layerBounds is set to the border box, not t he bounding box, of | 420 // for this is that fragment.layerBounds is set to the border box, not t he bounding box, of |
| 426 // the layer. | 421 // the layer. |
| 427 if (m_paintLayer.intersectsDamageRect(fragment.layerBounds, fragment.bac kgroundRect.rect(), newOffsetFromRoot)) | 422 if (m_paintLayer.intersectsDamageRect(fragment.layerBounds, fragment.bac kgroundRect.rect(), newOffsetFromRoot)) |
| 428 return true; | 423 return true; |
| 429 } | 424 } |
| 430 return false; | 425 return false; |
| 431 } | 426 } |
| 432 | 427 |
| 433 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerWithTransform(Graphi csContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) | 428 PaintLayerPainter::PaintResult PaintLayerPainter::paintLayerWithTransform(Graphi csContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags) |
| 434 { | 429 { |
| 430 // Transforms will be applied by property nodes directly for SPv2. | |
| 431 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
| 432 | |
| 435 TransformationMatrix layerTransform = m_paintLayer.renderableTransform(paint ingInfo.globalPaintFlags()); | 433 TransformationMatrix layerTransform = m_paintLayer.renderableTransform(paint ingInfo.globalPaintFlags()); |
| 436 // If the transform can't be inverted, then don't paint anything. | 434 // If the transform can't be inverted, then don't paint anything. |
| 437 if (!layerTransform.isInvertible()) | 435 if (!layerTransform.isInvertible()) |
| 438 return FullyPainted; | 436 return FullyPainted; |
| 439 | 437 |
| 440 // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer here. | 438 // FIXME: We should make sure that we don't walk past paintingInfo.rootLayer here. |
| 441 // m_paintLayer may be the "root", and then we should avoid looking at its p arent. | 439 // m_paintLayer may be the "root", and then we should avoid looking at its p arent. |
| 442 PaintLayer* parentLayer = m_paintLayer.parent(); | 440 PaintLayer* parentLayer = m_paintLayer.parent(); |
| 443 | 441 |
| 444 ClipRect ancestorBackgroundClipRect; | 442 ClipRect ancestorBackgroundClipRect; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 493 } | 491 } |
| 494 } | 492 } |
| 495 if (paintFragmentByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset) == MayBeClippedByPaintDirtyRect) | 493 if (paintFragmentByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset) == MayBeClippedByPaintDirtyRect) |
| 496 result = MayBeClippedByPaintDirtyRect; | 494 result = MayBeClippedByPaintDirtyRect; |
| 497 } | 495 } |
| 498 return result; | 496 return result; |
| 499 } | 497 } |
| 500 | 498 |
| 501 PaintLayerPainter::PaintResult PaintLayerPainter::paintFragmentByApplyingTransfo rm(GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLa yerFlags paintFlags, const LayoutPoint& fragmentTranslation) | 499 PaintLayerPainter::PaintResult PaintLayerPainter::paintFragmentByApplyingTransfo rm(GraphicsContext& context, const PaintLayerPaintingInfo& paintingInfo, PaintLa yerFlags paintFlags, const LayoutPoint& fragmentTranslation) |
| 502 { | 500 { |
| 501 // Transforms will be applied by property nodes directly for SPv2. | |
| 502 ASSERT(!RuntimeEnabledFeatures::slimmingPaintV2Enabled()); | |
| 503 | |
| 503 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving | 504 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving |
| 504 // the accumulated error for sub-pixel layout. | 505 // the accumulated error for sub-pixel layout. |
| 505 LayoutPoint delta; | 506 LayoutPoint delta; |
| 506 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, delta); | 507 m_paintLayer.convertToLayerCoords(paintingInfo.rootLayer, delta); |
| 507 delta.moveBy(fragmentTranslation); | 508 delta.moveBy(fragmentTranslation); |
| 508 TransformationMatrix transform(m_paintLayer.renderableTransform(paintingInfo .globalPaintFlags())); | 509 TransformationMatrix transform(m_paintLayer.renderableTransform(paintingInfo .globalPaintFlags())); |
| 509 IntPoint roundedDelta = roundedIntPoint(delta); | 510 IntPoint roundedDelta = roundedIntPoint(delta); |
| 510 transform.translateRight(roundedDelta.x(), roundedDelta.y()); | 511 transform.translateRight(roundedDelta.x(), roundedDelta.y()); |
| 511 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta); | 512 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta); |
| 512 | 513 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 615 default: | 616 default: |
| 616 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; | 617 clippingRule = LayerClipRecorder::IncludeSelfForBorderRadius; |
| 617 break; | 618 break; |
| 618 } | 619 } |
| 619 | 620 |
| 620 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, cl ipRect, &paintingInfo, fragment.paginationOffset, paintFlags, clippingRule); | 621 clipRecorder.emplace(context, *m_paintLayer.layoutObject(), clipType, cl ipRect, &paintingInfo, fragment.paginationOffset, paintFlags, clippingRule); |
| 621 } | 622 } |
| 622 | 623 |
| 623 LayoutRect newCullRect(clipRect.rect()); | 624 LayoutRect newCullRect(clipRect.rect()); |
| 624 Optional<ScrollRecorder> scrollRecorder; | 625 Optional<ScrollRecorder> scrollRecorder; |
| 625 LayoutPoint paintOffset = toPoint(fragment.layerBounds.location() - m_paintL ayer.layoutBoxLocation()); | 626 LayoutPoint paintOffset; |
| 626 if (!paintingInfo.scrollOffsetAccumulation.isZero()) { | 627 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) { |
| 627 // As a descendant of the root layer, m_paintLayer's painting is not con trolled by the ScrollRecorders | 628 paintOffset = toPoint(m_paintLayer.cachedSPv2PaintParameters().paintOffs et - m_paintLayer.layoutBoxLocation()); |
| 628 // created by BlockPainter of the ancestor layers up to the root layer, so we need to issue ScrollRecorder | 629 } else { |
| 629 // for this layer seperately, with the scroll offset accumulated from th e root layer to the parent of this | 630 paintOffset = toPoint(fragment.layerBounds.location() - m_paintLayer.lay outBoxLocation()); |
| 630 // layer, to get the same result as ScrollRecorder in BlockPainter. | 631 if (!paintingInfo.scrollOffsetAccumulation.isZero()) { |
| 631 paintOffset += paintingInfo.scrollOffsetAccumulation; | 632 // As a descendant of the root layer, m_paintLayer's painting is not controlled by the ScrollRecorders |
| 633 // created by BlockPainter of the ancestor layers up to the root lay er, so we need to issue ScrollRecorder | |
| 634 // for this layer seperately, with the scroll offset accumulated fro m the root layer to the parent of this | |
| 635 // layer, to get the same result as ScrollRecorder in BlockPainter. | |
| 636 paintOffset += paintingInfo.scrollOffsetAccumulation; | |
| 632 | 637 |
| 633 newCullRect.move(paintingInfo.scrollOffsetAccumulation); | 638 newCullRect.move(paintingInfo.scrollOffsetAccumulation); |
| 634 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, pai ntingInfo.scrollOffsetAccumulation); | 639 scrollRecorder.emplace(context, *m_paintLayer.layoutObject(), phase, paintingInfo.scrollOffsetAccumulation); |
| 640 } | |
| 635 } | 641 } |
| 636 PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, | 642 PaintInfo paintInfo(context, pixelSnappedIntRect(newCullRect), phase, |
| 637 paintingInfo.globalPaintFlags(), paintFlags, paintingInfo.rootLayer->lay outObject()); | 643 paintingInfo.globalPaintFlags(), paintFlags, paintingInfo.rootLayer->lay outObject()); |
| 638 | 644 |
| 639 m_paintLayer.layoutObject()->paint(paintInfo, paintOffset); | 645 m_paintLayer.layoutObject()->paint(paintInfo, paintOffset); |
| 640 } | 646 } |
| 641 | 647 |
| 642 void PaintLayerPainter::paintBackgroundForFragments(const PaintLayerFragments& l ayerFragments, | 648 void PaintLayerPainter::paintBackgroundForFragments(const PaintLayerFragments& l ayerFragments, |
| 643 GraphicsContext& context, const LayoutRect& transparencyPaintDirtyRect, | 649 GraphicsContext& context, const LayoutRect& transparencyPaintDirtyRect, |
| 644 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags) | 650 const PaintLayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags) |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 738 if (!m_paintLayer.containsDirtyOverlayScrollbars()) | 744 if (!m_paintLayer.containsDirtyOverlayScrollbars()) |
| 739 return; | 745 return; |
| 740 | 746 |
| 741 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe ct(damageRect)), paintFlags, LayoutSize()); | 747 PaintLayerPaintingInfo paintingInfo(&m_paintLayer, LayoutRect(enclosingIntRe ct(damageRect)), paintFlags, LayoutSize()); |
| 742 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); | 748 paintLayer(context, paintingInfo, PaintLayerPaintingOverlayScrollbars); |
| 743 | 749 |
| 744 m_paintLayer.setContainsDirtyOverlayScrollbars(false); | 750 m_paintLayer.setContainsDirtyOverlayScrollbars(false); |
| 745 } | 751 } |
| 746 | 752 |
| 747 } // namespace blink | 753 } // namespace blink |
| OLD | NEW |