Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: sky/engine/core/rendering/RenderBox.cpp

Issue 950553002: Address TODOs in the new layer painting and hit testing. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: remove shouldClip Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 475
476 LayoutRect localHitTestRect = hitTestRect; 476 LayoutRect localHitTestRect = hitTestRect;
477 HitTestLocation localHitTestLocation = hitTestLocation; 477 HitTestLocation localHitTestLocation = hitTestLocation;
478 478
479 // We need transform state for the first time, or to offset the container st ate, or to accumulate the new transform. 479 // We need transform state for the first time, or to offset the container st ate, or to accumulate the new transform.
480 if (layer()->transform() || transformState || layer()->has3DTransformedDesce ndant() || layer()->preserves3D()) 480 if (layer()->transform() || transformState || layer()->has3DTransformedDesce ndant() || layer()->preserves3D())
481 localTransformState = createLocalTransformState(rootLayer, containerLaye r, localHitTestRect, localHitTestLocation, transformState); 481 localTransformState = createLocalTransformState(rootLayer, containerLaye r, localHitTestRect, localHitTestLocation, transformState);
482 482
483 // Apply a transform if we have one. 483 // Apply a transform if we have one.
484 if (layer()->transform()) { 484 if (layer()->transform()) {
485 // The RenderView cannot have transforms.
486 ASSERT(parent());
485 // Make sure the parent's clip rects have been calculated. 487 // Make sure the parent's clip rects have been calculated.
486 if (parent()) { 488 ClipRect clipRect = layer()->clipper().backgroundClipRect(ClipRectsConte xt(rootLayer, RootRelativeClipRects));
487 ClipRect clipRect = layer()->clipper().backgroundClipRect(ClipRectsC ontext(rootLayer, RootRelativeClipRects)); 489 // Go ahead and test the enclosing clip now.
488 // Go ahead and test the enclosing clip now. 490 if (!clipRect.intersects(localHitTestLocation))
489 if (!clipRect.intersects(localHitTestLocation)) 491 return 0;
490 return 0;
491 }
492 492
493 // If the transform can't be inverted, then don't hit test this layer at all. 493 // If the transform can't be inverted, then don't hit test this layer at all.
494 if (!localTransformState->m_accumulatedTransform.isInvertible()) 494 if (!localTransformState->m_accumulatedTransform.isInvertible())
495 return 0; 495 return 0;
496 496
497 // Compute the point and the hit test rect in the coords of this layer b y using the values 497 // Compute the point and the hit test rect in the coords of this layer b y using the values
498 // from the transformState, which store the point and quad in the coords of the last flattened 498 // from the transformState, which store the point and quad in the coords of the last flattened
499 // layer, and the accumulated transform which lets up map through preser ve-3d layers. 499 // layer, and the accumulated transform which lets up map through preser ve-3d layers.
500 // 500 //
501 // We can't just map hitTestLocation and hitTestRect because they may ha ve been flattened (losing z) 501 // We can't just map hitTestLocation and hitTestRect because they may ha ve been flattened (losing z)
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 if (!opacity()) 649 if (!opacity())
650 return; 650 return;
651 651
652 LayerPaintingInfo paintingInfo(rootLayer, rect, LayoutSize()); 652 LayerPaintingInfo paintingInfo(rootLayer, rect, LayoutSize());
653 653
654 if (!layer()->paintsWithTransform()) { 654 if (!layer()->paintsWithTransform()) {
655 paintLayerContents(context, paintingInfo, rect); 655 paintLayerContents(context, paintingInfo, rect);
656 return; 656 return;
657 } 657 }
658 658
659 // The RenderView can't be transformed in Sky.
660 ASSERT(layer()->parent());
661
659 TransformationMatrix layerTransform = layer()->renderableTransform(); 662 TransformationMatrix layerTransform = layer()->renderableTransform();
660 // If the transform can't be inverted, then don't paint anything. 663 // If the transform can't be inverted, then don't paint anything.
661 if (!layerTransform.isInvertible()) 664 if (!layerTransform.isInvertible())
662 return; 665 return;
663 666
664 // If we have a transparency layer enclosing us and we are the root of a tra nsform, then we need to establish the transparency 667 // If we have a transparency layer enclosing us and we are the root of a tra nsform, then we need to establish the transparency
665 // layer from the parent now, assuming there is a parent 668 // layer from the parent now, assuming there is a parent
666 if (layer()->isTransparent()) { 669 if (layer()->isTransparent()) {
667 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branchin g since the 670 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branchin g since the
668 // RenderView can't be transformed in sky. 671 // RenderView can't be transformed in sky.
669 if (layer()->parent()) 672 if (layer()->parent())
670 layer()->parent()->beginTransparencyLayers(context, paintingInfo.roo tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); 673 layer()->parent()->beginTransparencyLayers(context, paintingInfo.roo tLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation);
671 else 674 else
672 layer()->beginTransparencyLayers(context, paintingInfo.rootLayer, pa intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation); 675 layer()->beginTransparencyLayers(context, paintingInfo.rootLayer, pa intingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation);
673 } 676 }
674 677
675 // Make sure the parent's clip rects have been calculated. 678 // Make sure the parent's clip rects have been calculated.
676 ClipRect clipRect; 679 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, PaintingClipRects) ;
677 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branching si nce the 680 ClipRect clipRect = layer()->clipper().backgroundClipRect(clipRectsContext);
678 // RenderView can't be transformed in sky. 681 clipRect.intersect(paintingInfo.paintDirtyRect);
679 if (layer()->parent()) {
680 ClipRectsContext clipRectsContext(paintingInfo.rootLayer, PaintingClipRe cts);
681 clipRect = layer()->clipper().backgroundClipRect(clipRectsContext);
682 clipRect.intersect(paintingInfo.paintDirtyRect);
683 682
684 // Push the parent coordinate space's clip. 683 // Push the parent coordinate space's clip.
685 layer()->parent()->clipToRect(paintingInfo, context, clipRect); 684 layer()->parent()->clipToRect(paintingInfo, context, clipRect);
686 }
687 685
688 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving 686 // This involves subtracting out the position of the layer in our current co ordinate space, but preserving
689 // the accumulated error for sub-pixel layout. 687 // the accumulated error for sub-pixel layout.
690 LayoutPoint delta; 688 LayoutPoint delta;
691 layer()->convertToLayerCoords(paintingInfo.rootLayer, delta); 689 layer()->convertToLayerCoords(paintingInfo.rootLayer, delta);
692 TransformationMatrix transform(layer()->renderableTransform()); 690 TransformationMatrix transform(layer()->renderableTransform());
693 IntPoint roundedDelta = roundedIntPoint(delta); 691 IntPoint roundedDelta = roundedIntPoint(delta);
694 transform.translateRight(roundedDelta.x(), roundedDelta.y()); 692 transform.translateRight(roundedDelta.x(), roundedDelta.y());
695 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta); 693 LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
696 694
697 // Apply the transform. 695 // Apply the transform.
698 GraphicsContextStateSaver stateSaver(*context, false); 696 GraphicsContextStateSaver stateSaver(*context, false);
699 if (!transform.isIdentity()) { 697 if (!transform.isIdentity()) {
700 stateSaver.save(); 698 stateSaver.save();
701 context->concatCTM(transform.toAffineTransform()); 699 context->concatCTM(transform.toAffineTransform());
702 } 700 }
703 701
704 // Now do a paint with the root layer shifted to be us. 702 // Now do a paint with the root layer shifted to be us.
705 LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(transfor m.inverse().mapRect(paintingInfo.paintDirtyRect)), 703 LayerPaintingInfo transformedPaintingInfo(layer(), enclosingIntRect(transfor m.inverse().mapRect(paintingInfo.paintDirtyRect)),
706 adjustedSubPixelAccumulation); 704 adjustedSubPixelAccumulation);
707 paintLayerContents(context, transformedPaintingInfo, rect); 705 paintLayerContents(context, transformedPaintingInfo, rect);
708 706
709 // Restore the clip. 707 // Restore the clip.
710 // TODO(ojan): This should ASSERT(layer()->parent()) instead of branching si nce the 708 layer()->parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRec t);
711 // RenderView can't be transformed in sky.
712 if (layer()->parent())
713 layer()->parent()->restoreClip(context, paintingInfo.paintDirtyRect, cli pRect);
714 } 709 }
715 710
716 void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPainting Info& paintingInfo, const IntRect& rect) 711 void RenderBox::paintLayerContents(GraphicsContext* context, const LayerPainting Info& paintingInfo, const IntRect& rect)
717 { 712 {
718 float deviceScaleFactor = blink::deviceScaleFactor(frame()); 713 float deviceScaleFactor = blink::deviceScaleFactor(frame());
719 context->setDeviceScaleFactor(deviceScaleFactor); 714 context->setDeviceScaleFactor(deviceScaleFactor);
720 715
721 GraphicsContext* transparencyLayerContext = context; 716 GraphicsContext* transparencyLayerContext = context;
722 717
723 LayoutPoint offsetFromRoot; 718 LayoutPoint offsetFromRoot;
724 layer()->convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot); 719 layer()->convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
725 720
721 LayerPaintingInfo localPaintingInfo(paintingInfo);
722
723 LayoutRect layerBounds;
724 // FIXME(sky): Remove foregroundRect. It's unused.
725 ClipRect contentRect, foregroundRect;
726 ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipR ects, localPaintingInfo.subPixelAccumulation);
727 layer()->clipper().calculateRects(clipRectsContext, localPaintingInfo.paintD irtyRect,
728 layerBounds, contentRect, foregroundRect,
729 &offsetFromRoot);
730
731 if (!layer()->intersectsDamageRect(layerBounds, contentRect.rect(), localPai ntingInfo.rootLayer, &offsetFromRoot))
732 return;
733
726 LayoutRect rootRelativeBounds; 734 LayoutRect rootRelativeBounds;
727 bool rootRelativeBoundsComputed = false; 735 bool rootRelativeBoundsComputed = false;
728 736
729 // Apply clip-path to context. 737 // Apply clip-path to context.
730 GraphicsContextStateSaver clipStateSaver(*context, false); 738 GraphicsContextStateSaver clipStateSaver(*context, false);
731 739
732 // Clip-path, like border radius, must not be applied to the contents of a c omposited-scrolling container. 740 // Clip-path, like border radius, must not be applied to the contents of a c omposited-scrolling container.
733 // It must, however, still be applied to the mask layer, so that the composi tor can properly mask the 741 // It must, however, still be applied to the mask layer, so that the composi tor can properly mask the
734 // scrolling contents and scrollbars. 742 // scrolling contents and scrollbars.
735 // TODO(ojan): This style null check doesn't make sense. We should always ha ve a style. 743 if (hasClipPath()) {
736 if (hasClipPath() && style()) {
737 ASSERT(style()->clipPath()); 744 ASSERT(style()->clipPath());
738 if (style()->clipPath()->type() == ClipPathOperation::SHAPE) { 745 if (style()->clipPath()->type() == ClipPathOperation::SHAPE) {
739 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()- >clipPath()); 746 ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style()- >clipPath());
740 if (clipPath->isValid()) { 747 if (clipPath->isValid()) {
741 clipStateSaver.save(); 748 clipStateSaver.save();
742 749
743 if (!rootRelativeBoundsComputed) { 750 if (!rootRelativeBoundsComputed) {
744 rootRelativeBounds = layer()->physicalBoundingBoxIncludingRe flectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); 751 rootRelativeBounds = layer()->physicalBoundingBoxIncludingRe flectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
745 rootRelativeBoundsComputed = true; 752 rootRelativeBoundsComputed = true;
746 } 753 }
747 754
748 context->clipPath(clipPath->path(rootRelativeBounds), clipPath-> windRule()); 755 context->clipPath(clipPath->path(rootRelativeBounds), clipPath-> windRule());
749 } 756 }
750 } 757 }
751 } 758 }
752 759
753 LayerPaintingInfo localPaintingInfo(paintingInfo); 760 bool haveTransparency = layer()->isTransparent();
761
754 FilterEffectRendererHelper filterPainter(layer()->filterRenderer() && layer( )->paintsWithFilters()); 762 FilterEffectRendererHelper filterPainter(layer()->filterRenderer() && layer( )->paintsWithFilters());
755 763
756 LayoutRect layerBounds;
757 // FIXME(sky): Remove foregroundRect. It's unused.
758 ClipRect contentRect, foregroundRect;
759 ClipRectsContext clipRectsContext(localPaintingInfo.rootLayer, PaintingClipR ects, localPaintingInfo.subPixelAccumulation);
760 layer()->clipper().calculateRects(clipRectsContext, localPaintingInfo.paintD irtyRect,
761 layerBounds, contentRect, foregroundRect,
762 &offsetFromRoot);
763
764 bool shouldPaintContent = layer()->intersectsDamageRect(layerBounds, content Rect.rect(), localPaintingInfo.rootLayer, &offsetFromRoot);
765
766 bool haveTransparency = layer()->isTransparent();
767
768 if (filterPainter.haveFilterEffect()) { 764 if (filterPainter.haveFilterEffect()) {
769 ASSERT(layer()->filterInfo()); 765 ASSERT(layer()->filterInfo());
770 766
771 if (!rootRelativeBoundsComputed) 767 if (!rootRelativeBoundsComputed)
772 rootRelativeBounds = layer()->physicalBoundingBoxIncludingReflection AndStackingChildren(paintingInfo.rootLayer, offsetFromRoot); 768 rootRelativeBounds = layer()->physicalBoundingBoxIncludingReflection AndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
773 769
774 if (filterPainter.prepareFilterEffect(layer(), rootRelativeBounds, paint ingInfo.paintDirtyRect)) { 770 if (filterPainter.prepareFilterEffect(layer(), rootRelativeBounds, paint ingInfo.paintDirtyRect)) {
775 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer. 771 // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
776 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer 772 // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
777 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that 773 // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that
(...skipping 12 matching lines...) Expand all
790 // Subsequent code should not clip to the dirty rect, since we've al ready 786 // Subsequent code should not clip to the dirty rect, since we've al ready
791 // done it above, and doing it later will defeat the outsets. 787 // done it above, and doing it later will defeat the outsets.
792 localPaintingInfo.clipToDirtyRect = false; 788 localPaintingInfo.clipToDirtyRect = false;
793 789
794 context = filterPainter.beginFilterEffect(context); 790 context = filterPainter.beginFilterEffect(context);
795 } 791 }
796 } 792 }
797 793
798 LayoutPoint layerLocation = toPoint(layerBounds.location() - location() + lo calPaintingInfo.subPixelAccumulation); 794 LayoutPoint layerLocation = toPoint(layerBounds.location() - location() + lo calPaintingInfo.subPixelAccumulation);
799 795
800 if (shouldPaintContent) { 796 // Begin transparency if we have something to paint.
801 bool contentRectIsEmpty = contentRect.isEmpty(); 797 if (haveTransparency)
798 layer()->beginTransparencyLayers(transparencyLayerContext, localPainting Info.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.subPixelAccumulat ion);
802 799
803 // Begin transparency if we have something to paint. 800 if (localPaintingInfo.clipToDirtyRect)
804 if (haveTransparency && !contentRectIsEmpty) 801 layer()->clipToRect(localPaintingInfo, context, contentRect);
805 layer()->beginTransparencyLayers(transparencyLayerContext, localPain tingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.subPixelAccum ulation);
806 802
807 // Optimize clipping for the single fragment case. 803 Vector<RenderBox*> layers;
808 bool shouldClip = localPaintingInfo.clipToDirtyRect && !contentRectIsEmp ty; 804 PaintInfo paintInfo(context, pixelSnappedIntRect(contentRect.rect()), localP aintingInfo.rootLayer->renderer());
809 if (shouldClip) 805 paint(paintInfo, layerLocation, layers);
810 layer()->clipToRect(localPaintingInfo, context, contentRect);
811 806
812 // TODO(ojan): We probably should have already set shouldPaintContent to false if the rect is empty. 807 std::stable_sort(layers.begin(), layers.end(), forwardCompareZIndex);
813 if (!contentRectIsEmpty) { 808 for (auto& box : layers) {
814 Vector<RenderBox*> layers; 809 box->paintLayer(context, paintingInfo.rootLayer, rect);
810 }
815 811
816 PaintInfo paintInfo(context, pixelSnappedIntRect(contentRect.rect()) , localPaintingInfo.rootLayer->renderer()); 812 if (localPaintingInfo.clipToDirtyRect)
817 paint(paintInfo, layerLocation, layers); 813 layer()->restoreClip(context, localPaintingInfo.paintDirtyRect, contentR ect);
818
819 std::stable_sort(layers.begin(), layers.end(), forwardCompareZIndex) ;
820 for (auto& box : layers) {
821 box->paintLayer(context, paintingInfo.rootLayer, rect);
822 }
823 }
824
825 if (shouldClip)
826 layer()->restoreClip(context, localPaintingInfo.paintDirtyRect, cont entRect);
827 }
828 814
829 if (filterPainter.hasStartedFilterEffect()) { 815 if (filterPainter.hasStartedFilterEffect()) {
830 context = filterPainter.applyFilterEffect(); 816 context = filterPainter.applyFilterEffect();
831 layer()->restoreClip(transparencyLayerContext, localPaintingInfo.paintDi rtyRect, contentRect); 817 layer()->restoreClip(transparencyLayerContext, localPaintingInfo.paintDi rtyRect, contentRect);
832 } 818 }
833 819
834 // Make sure that we now use the original transparency context. 820 // Make sure that we now use the original transparency context.
835 ASSERT(transparencyLayerContext == context); 821 ASSERT(transparencyLayerContext == context);
836 822
837 // End our transparency layer 823 // End our transparency layer
(...skipping 2197 matching lines...) Expand 10 before | Expand all | Expand 10 after
3035 3021
3036 RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style) 3022 RenderBox::BoxDecorationData::BoxDecorationData(const RenderStyle& style)
3037 { 3023 {
3038 backgroundColor = style.colorIncludingFallback(CSSPropertyBackgroundColor); 3024 backgroundColor = style.colorIncludingFallback(CSSPropertyBackgroundColor);
3039 hasBackground = backgroundColor.alpha() || style.hasBackgroundImage(); 3025 hasBackground = backgroundColor.alpha() || style.hasBackgroundImage();
3040 ASSERT(hasBackground == style.hasBackground()); 3026 ASSERT(hasBackground == style.hasBackground());
3041 hasBorder = style.hasBorder(); 3027 hasBorder = style.hasBorder();
3042 } 3028 }
3043 3029
3044 } // namespace blink 3030 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698