Changeset 112049 in webkit
- Timestamp:
- Mar 25, 2012 11:02:56 PM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r112037 r112049 1 2012-03-25 Dana Jansens <danakj@chromium.org> 2 3 [chromium] Layers with animating transforms should prepaint even if they are not visible yet 4 https://bugs.webkit.org/show_bug.cgi?id=82117 5 6 Reviewed by Adrienne Walker. 7 8 For animating transforms, instead of early-outing when the layer's 9 visible rect is empty, let it prepaint regardless. 10 11 For now, we just only paint the outermost tiles, and only for small 12 layers, with at most 9 tiles. 13 14 This changes the behaviour of ContentLayerChromium's 15 idlePaintContentsIfDirty() so I've guarded the behaviour of the two 16 prepainting functions that it calls to ensure the old behaviour holds 17 without animations, and the new behaviour works with them. 18 19 Unit test: TiledLayerChromiumTest.idlePaintZeroSizedLayer 20 TiledLayerChromiumTest.idlePaintZeroSizedAnimatingLayer 21 TiledLayerChromiumTest.idlePaintNonVisibleLayers 22 TiledLayerChromiumTest.idlePaintNonVisibleAnimatingLayers 23 24 * platform/graphics/chromium/ContentLayerChromium.cpp: 25 (WebCore::ContentLayerChromium::idlePaintContentsIfDirty): 26 * platform/graphics/chromium/TiledLayerChromium.cpp: 27 (WebCore::TiledLayerChromium::prepareToUpdateIdle): 28 (WebCore::TiledLayerChromium::needsIdlePaint): 29 (WebCore::TiledLayerChromium::idlePaintRect): 30 * platform/graphics/chromium/TiledLayerChromium.h: 31 (WebCore::TiledLayerChromium::numPaintedTiles): 32 (TiledLayerChromium): 33 1 34 2012-03-25 Antti Koivisto <antti@apple.com> 2 35 -
trunk/Source/WebCore/platform/graphics/chromium/ContentLayerChromium.cpp
r110945 r112049 115 115 return; 116 116 117 const IntRect& layerRect = visibleLayerRect(); 118 if (layerRect.isEmpty()) 119 return; 120 117 const IntRect layerRect = visibleLayerRect(); 121 118 prepareToUpdateIdle(layerRect, occlusion); 122 119 if (needsIdlePaint(layerRect)) -
trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.cpp
r111978 r112049 629 629 updateBounds(); 630 630 631 if (m_tiler->isEmpty()) 632 return; 633 634 // Protect any textures in the pre-paint area so we don't end up just 635 // reclaiming them below. 631 if (!m_tiler->numTiles()) 632 return; 633 636 634 IntRect idlePaintLayerRect = idlePaintRect(layerRect); 635 if (idlePaintLayerRect.isEmpty()) 636 return; 637 638 // Protect any textures in the pre-paint area, as we would steal them from other layers 639 // over time anyhow. This ensures we don't lose tiles in the first rounds of idle painting 640 // that we have already painted. 637 641 protectTileTextures(idlePaintLayerRect); 642 643 int prepaintLeft, prepaintTop, prepaintRight, prepaintBottom; 644 m_tiler->layerRectToTileIndices(idlePaintLayerRect, prepaintLeft, prepaintTop, prepaintRight, prepaintBottom); 645 646 // If the layer is not visible, we have nothing to expand from, so instead we prepaint the outer-most set of tiles. 647 if (layerRect.isEmpty()) { 648 prepareToUpdateTiles(true, prepaintLeft, prepaintTop, prepaintRight, prepaintTop, 0); 649 if (!m_paintRect.isEmpty() || m_skipsIdlePaint) 650 return; 651 prepareToUpdateTiles(true, prepaintLeft, prepaintBottom, prepaintRight, prepaintBottom, 0); 652 if (!m_paintRect.isEmpty() || m_skipsIdlePaint) 653 return; 654 prepareToUpdateTiles(true, prepaintLeft, prepaintTop, prepaintLeft, prepaintBottom, 0); 655 if (!m_paintRect.isEmpty() || m_skipsIdlePaint) 656 return; 657 prepareToUpdateTiles(true, prepaintRight, prepaintTop, prepaintRight, prepaintBottom, 0); 658 659 return; 660 } 638 661 639 662 int left, top, right, bottom; 640 663 m_tiler->layerRectToTileIndices(layerRect, left, top, right, bottom); 641 664 642 // Prepaint anything that was occluded but inside the layer's visible region.665 // Otherwise, prepaint anything that was occluded but inside the layer's visible region. 643 666 prepareToUpdateTiles(true, left, top, right, bottom, 0); 644 667 if (!m_paintRect.isEmpty() || m_skipsIdlePaint) 645 668 return; 646 669 647 // Expand outwards until we find a dirty row or column to update. 648 int prepaintLeft, prepaintTop, prepaintRight, prepaintBottom; 649 m_tiler->layerRectToTileIndices(idlePaintLayerRect, prepaintLeft, prepaintTop, prepaintRight, prepaintBottom); 670 // Then expand outwards from the visible area until we find a dirty row or column to update. 650 671 while (!m_skipsIdlePaint && (left > prepaintLeft || top > prepaintTop || right < prepaintRight || bottom < prepaintBottom)) { 651 672 if (bottom < prepaintBottom) { … … 681 702 return false; 682 703 704 if (!m_tiler->numTiles()) 705 return false; 706 683 707 IntRect idlePaintLayerRect = idlePaintRect(layerRect); 708 if (idlePaintLayerRect.isEmpty()) 709 return false; 684 710 685 711 int left, top, right, bottom; … … 687 713 for (int j = top; j <= bottom; ++j) { 688 714 for (int i = left; i <= right; ++i) { 715 // If the layerRect is empty, then we are painting the outer-most set of tiles only. 716 if (layerRect.isEmpty() && i != left && i != right && j != top && j != bottom) 717 continue; 689 718 if (m_requestedUpdateTilesRect.contains(IntPoint(i, j))) 690 719 continue; … … 699 728 IntRect TiledLayerChromium::idlePaintRect(const IntRect& visibleLayerRect) 700 729 { 730 // For layers that are animating transforms but not visible at all, we don't know what part 731 // of them is going to become visible. For small layers we return the entire layer, for larger 732 // ones we avoid prepainting the layer at all. 733 if (visibleLayerRect.isEmpty()) { 734 if ((drawTransformIsAnimating() || screenSpaceTransformIsAnimating()) && m_tiler->numTiles() <= 9) 735 return IntRect(IntPoint(), contentBounds()); 736 return IntRect(); 737 } 738 701 739 IntRect prepaintRect = visibleLayerRect; 702 740 // FIXME: This can be made a lot larger if we can: -
trunk/Source/WebCore/platform/graphics/chromium/TiledLayerChromium.h
r110945 r112049 78 78 void setBorderTexelOption(CCLayerTilingData::BorderTexelOption); 79 79 void setSampledTexelFormat(LayerTextureUpdater::SampledTexelFormat sampledTexelFormat) { m_sampledTexelFormat = sampledTexelFormat; } 80 size_t numPaintedTiles() { return m_tiler->tiles().size(); } 80 81 81 82 virtual LayerTextureUpdater* textureUpdater() const = 0; … … 97 98 bool needsIdlePaint(const IntRect& layerRect); 98 99 100 IntRect idlePaintRect(const IntRect& visibleLayerRect); 101 99 102 bool skipsDraw() const { return m_skipsDraw; } 100 103 … … 113 116 114 117 void prepareToUpdateTiles(bool idle, int left, int top, int right, int bottom, const CCOcclusionTracker*); 115 IntRect idlePaintRect(const IntRect& visibleLayerRect);116 118 117 119 UpdatableTile* tileAt(int, int) const; -
trunk/Source/WebKit/chromium/ChangeLog
r112024 r112049 1 2012-03-25 Dana Jansens <danakj@chromium.org> 2 3 [chromium] Layers with animating transforms should prepaint even if they are not visible yet 4 https://bugs.webkit.org/show_bug.cgi?id=82117 5 6 Reviewed by Adrienne Walker. 7 8 * tests/TiledLayerChromiumTest.cpp: 9 (WTF::FakeTiledLayerChromium::FakeTiledLayerChromium): 10 (WTF::FakeTiledLayerChromium::tileSize): 11 (FakeTiledLayerChromium): 12 (WTF::TEST): 13 (WTF): 14 (WTF::idlePaintRepeat): 15 (WTF::testHaveOuterTiles): 16 1 17 2012-03-24 Nat Duca <nduca@chromium.org> 2 18 -
trunk/Source/WebKit/chromium/tests/TiledLayerChromiumTest.cpp
r111978 r112049 27 27 #include "TiledLayerChromium.h" 28 28 29 #include "CCAnimationTestCommon.h" 29 30 #include "CCLayerTreeTestCommon.h" 30 31 #include "FakeCCLayerTreeHostClient.h" … … 39 40 40 41 using namespace WebCore; 42 using namespace WebKitTests; 41 43 using namespace WTF; 42 44 … … 161 163 , m_textureManager(textureManager) 162 164 { 163 setTileSize( IntSize(100, 100));165 setTileSize(tileSize()); 164 166 setTextureFormat(GraphicsContext3D::RGBA); 165 167 setBorderTexelOption(CCLayerTilingData::NoBorderTexels); … … 168 170 virtual ~FakeTiledLayerChromium() { } 169 171 170 void invalidateRect(const IntRect& rect) 171 { 172 TiledLayerChromium::invalidateRect(rect); 173 } 174 175 void prepareToUpdate(const IntRect& rect, const CCOcclusionTracker* occlusion) 176 { 177 TiledLayerChromium::prepareToUpdate(rect, occlusion); 178 } 179 180 void prepareToUpdateIdle(const IntRect& rect, const CCOcclusionTracker* occlusion) 181 { 182 TiledLayerChromium::prepareToUpdateIdle(rect, occlusion); 183 } 184 185 bool needsIdlePaint(const IntRect& rect) 186 { 187 return TiledLayerChromium::needsIdlePaint(rect); 188 } 189 190 bool skipsDraw() const 191 { 192 return TiledLayerChromium::skipsDraw(); 193 } 172 static IntSize tileSize() { return IntSize(100, 100); } 173 174 using TiledLayerChromium::invalidateRect; 175 using TiledLayerChromium::prepareToUpdate; 176 using TiledLayerChromium::prepareToUpdateIdle; 177 using TiledLayerChromium::needsIdlePaint; 178 using TiledLayerChromium::skipsDraw; 179 using TiledLayerChromium::numPaintedTiles; 180 using TiledLayerChromium::idlePaintRect; 194 181 195 182 virtual void setNeedsDisplayRect(const FloatRect& rect) … … 686 673 layer->updateCompositorResources(0, updater); 687 674 layer->pushPropertiesTo(layerImpl.get()); 675 } 676 677 TEST(TiledLayerChromiumTest, idlePaintZeroSizedLayer) 678 { 679 OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024); 680 RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); 681 DebugScopedSetImplThread implThread; 682 OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0))); 683 684 FakeTextureAllocator textureAllocator; 685 CCTextureUpdater updater(&textureAllocator); 686 687 // The layer's bounds are empty. 688 IntRect contentRect; 689 690 layer->setBounds(contentRect.size()); 691 layer->setVisibleLayerRect(contentRect); 692 layer->invalidateRect(contentRect); 693 layer->prepareToUpdate(contentRect, 0); 694 695 // Empty layers don't have tiles. 696 EXPECT_EQ(0u, layer->numPaintedTiles()); 697 698 // Empty layers don't need prepaint. 699 EXPECT_FALSE(layer->needsIdlePaint(contentRect)); 700 701 layer->updateCompositorResources(0, updater); 702 layer->pushPropertiesTo(layerImpl.get()); 703 704 // Empty layers don't have tiles. 705 EXPECT_FALSE(layerImpl->hasTileAt(0, 0)); 706 707 // Non-visible layers don't idle paint. 708 layer->prepareToUpdateIdle(contentRect, 0); 709 710 // Empty layers don't have tiles. 711 EXPECT_EQ(0u, layer->numPaintedTiles()); 712 713 layer->updateCompositorResources(0, updater); 714 layer->pushPropertiesTo(layerImpl.get()); 715 716 // Empty layers don't have tiles. 717 EXPECT_FALSE(layerImpl->hasTileAt(0, 0)); 718 } 719 720 TEST(TiledLayerChromiumTest, idlePaintZeroSizedAnimatingLayer) 721 { 722 OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024); 723 RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); 724 DebugScopedSetImplThread implThread; 725 OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0))); 726 727 FakeTextureAllocator textureAllocator; 728 CCTextureUpdater updater(&textureAllocator); 729 730 // Pretend the layer is animating. 731 layer->setDrawTransformIsAnimating(true); 732 733 // The layer's bounds are empty. 734 IntRect contentRect; 735 736 layer->setBounds(contentRect.size()); 737 layer->setVisibleLayerRect(contentRect); 738 layer->invalidateRect(contentRect); 739 layer->prepareToUpdate(contentRect, 0); 740 741 // Empty layers don't have tiles. 742 EXPECT_EQ(0u, layer->numPaintedTiles()); 743 744 // Empty layers don't need prepaint. 745 EXPECT_FALSE(layer->needsIdlePaint(contentRect)); 746 747 layer->updateCompositorResources(0, updater); 748 layer->pushPropertiesTo(layerImpl.get()); 749 750 // Empty layers don't have tiles. 751 EXPECT_FALSE(layerImpl->hasTileAt(0, 0)); 752 753 // Non-visible layers don't idle paint. 754 layer->prepareToUpdateIdle(contentRect, 0); 755 756 // Empty layers don't have tiles. 757 EXPECT_EQ(0u, layer->numPaintedTiles()); 758 759 layer->updateCompositorResources(0, updater); 760 layer->pushPropertiesTo(layerImpl.get()); 761 762 // Empty layers don't have tiles. 763 EXPECT_FALSE(layerImpl->hasTileAt(0, 0)); 764 } 765 766 TEST(TiledLayerChromiumTest, idlePaintNonVisibleLayers) 767 { 768 IntSize contentBounds(100, 100); 769 IntRect contentRect(IntPoint::zero(), contentBounds); 770 771 OwnPtr<TextureManager> textureManager = TextureManager::create(20000, 10000, 1024); 772 RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); 773 DebugScopedSetImplThread implThread; 774 OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0))); 775 776 FakeTextureAllocator textureAllocator; 777 CCTextureUpdater updater(&textureAllocator); 778 779 // Invalidate the layer but make none of it visible, so nothing paints. 780 IntRect visibleRect; 781 782 layer->setBounds(contentBounds); 783 layer->setVisibleLayerRect(visibleRect); 784 layer->invalidateRect(contentRect); 785 layer->prepareToUpdate(visibleRect, 0); 786 787 // Non-visible layers don't need idle paint. 788 EXPECT_FALSE(layer->needsIdlePaint(visibleRect)); 789 790 layer->updateCompositorResources(0, updater); 791 layer->pushPropertiesTo(layerImpl.get()); 792 793 // We should not have any tiles pushed since the layer is not visible. 794 EXPECT_FALSE(layerImpl->hasTileAt(0, 0)); 795 796 // Non-visible layers don't idle paint. 797 layer->prepareToUpdateIdle(visibleRect, 0); 798 799 layer->updateCompositorResources(0, updater); 800 layer->pushPropertiesTo(layerImpl.get()); 801 802 // We should not have any tiles pushed since the layer is not visible. 803 EXPECT_FALSE(layerImpl->hasTileAt(0, 0)); 804 } 805 806 static void idlePaintRepeat(int repeatTimes, FakeTiledLayerChromium* layer, FakeCCTiledLayerImpl* layerImpl, CCTextureUpdater& updater, const IntRect& visibleRect) 807 { 808 for (int i = 0; i < repeatTimes; ++i) { 809 layer->prepareToUpdate(visibleRect, 0); 810 layer->prepareToUpdateIdle(visibleRect, 0); 811 layer->updateCompositorResources(0, updater); 812 layer->pushPropertiesTo(layerImpl); 813 } 814 } 815 816 static void testHaveOuterTiles(FakeCCTiledLayerImpl* layerImpl, int width, int height, int have) 817 { 818 for (int i = 0; i < width; ++i) { 819 for (int j = 0; j < height; ++j) { 820 bool hasTile = i < have || j < have || i >= width - have || j >= height - have; 821 EXPECT_EQ(hasTile, layerImpl->hasTileAt(i, j)); 822 } 823 } 824 } 825 826 TEST(TiledLayerChromiumTest, idlePaintNonVisibleAnimatingLayers) 827 { 828 OwnPtr<TextureManager> textureManager = TextureManager::create(8000*8000*8, 8000*8000*4, 1024); 829 DebugScopedSetImplThread implThread; 830 831 FakeTextureAllocator textureAllocator; 832 CCTextureUpdater updater(&textureAllocator); 833 834 int tileWidth = FakeTiledLayerChromium::tileSize().width(); 835 int tileHeight = FakeTiledLayerChromium::tileSize().height(); 836 int width[] = { 1, 2, 3, 4, 9, 10, 0 }; 837 int height[] = { 1, 2, 3, 4, 9, 10, 0 }; 838 839 for (int j = 0; height[j]; ++j) { 840 for (int i = 0; width[i]; ++i) { 841 RefPtr<FakeTiledLayerChromium> layer = adoptRef(new FakeTiledLayerChromium(textureManager.get())); 842 OwnPtr<FakeCCTiledLayerImpl> layerImpl(adoptPtr(new FakeCCTiledLayerImpl(0))); 843 844 // Pretend the layer is animating. 845 layer->setDrawTransformIsAnimating(true); 846 847 IntSize contentBounds(width[i] * tileWidth, height[j] * tileHeight); 848 IntRect contentRect(IntPoint::zero(), contentBounds); 849 IntRect visibleRect; 850 851 layer->setBounds(contentBounds); 852 layer->setVisibleLayerRect(visibleRect); 853 layer->invalidateRect(contentRect); 854 855 // If idlePaintRect gives back a non-empty result then we should paint it. Otherwise, 856 // we shoud paint nothing. 857 bool shouldPrepaint = !layer->idlePaintRect(visibleRect).isEmpty(); 858 859 // This paints the layer but there's nothing visible so it's a no-op. 860 layer->prepareToUpdate(visibleRect, 0); 861 layer->updateCompositorResources(0, updater); 862 layer->pushPropertiesTo(layerImpl.get()); 863 864 // We should not have any tiles pushed yet since the layer is not visible and we've not prepainted. 865 testHaveOuterTiles(layerImpl.get(), width[i], height[j], 0); 866 867 // Normally we don't allow non-visible layers to pre-paint, but if they are animating then we should. 868 EXPECT_EQ(shouldPrepaint, layer->needsIdlePaint(visibleRect)); 869 870 // If the layer is to be prepainted at all, then after four updates we should have the outer row/columns painted. 871 idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect); 872 testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0); 873 874 // We don't currently idle paint past the outermost tiles. 875 EXPECT_FALSE(layer->needsIdlePaint(visibleRect)); 876 idlePaintRepeat(4, layer.get(), layerImpl.get(), updater, visibleRect); 877 testHaveOuterTiles(layerImpl.get(), width[i], height[j], shouldPrepaint ? 1 : 0); 878 } 879 } 688 880 } 689 881
Note: See TracChangeset
for help on using the changeset viewer.