diff options
author | weiliangc <weiliangc@chromium.org> | 2015-04-01 13:50:22 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-01 20:51:13 +0000 |
commit | 2f958f4157655afa8e86afb0549fafe51b79f219 (patch) | |
tree | 59567a0ca0e7cc698b5d240f8dcd9a049aaf1154 /cc/resources | |
parent | 2b57cae50ca0245a37a2581b84587ad3702f8c33 (diff) | |
download | chromium_src-2f958f4157655afa8e86afb0549fafe51b79f219.zip chromium_src-2f958f4157655afa8e86afb0549fafe51b79f219.tar.gz chromium_src-2f958f4157655afa8e86afb0549fafe51b79f219.tar.bz2 |
Revert of Revert of Implement DisplayList GatherPixelRefs (patchset #1 id:1 of https://codereview.chromium.org/1047413003/)
Reason for revert:
Break tree
Original issue's description:
> Revert of Implement DisplayList GatherPixelRefs (patchset #5 id:80001 of https://codereview.chromium.org/1045953002/)
>
> Reason for revert:
> Cause of crbug.com/472590
>
> Original issue's description:
> > Implement DisplayList GatherPixelRefs
> >
> > Take advantage of DisplayList playing back to generate SkPicture, and
> > use existing functions that gathers pixel ref from a single SkPicture.
> >
> > R=ajuma, enne, vmpstr
> > BUG=440468
> >
> > Committed: https://crrev.com/3d69b19b57904847ffec31b0f5d4f3568b5c6f35
> > Cr-Commit-Position: refs/heads/master@{#323152}
>
> TBR=enne@chromium.org,ajuma@chromium.org,vmpstr@chromium.org
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=440468
>
> Committed: https://crrev.com/74cb97d8d5c4e62a694c7f029a7c8c0b09e5bd92
> Cr-Commit-Position: refs/heads/master@{#323321}
TBR=enne@chromium.org,ajuma@chromium.org,vmpstr@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=440468
Review URL: https://codereview.chromium.org/1050103003
Cr-Commit-Position: refs/heads/master@{#323324}
Diffstat (limited to 'cc/resources')
-rw-r--r-- | cc/resources/display_item_list.cc | 10 | ||||
-rw-r--r-- | cc/resources/display_item_list.h | 6 | ||||
-rw-r--r-- | cc/resources/display_list_raster_source.cc | 11 | ||||
-rw-r--r-- | cc/resources/display_list_recording_source.cc | 6 | ||||
-rw-r--r-- | cc/resources/display_list_recording_source.h | 3 | ||||
-rw-r--r-- | cc/resources/display_list_recording_source_unittest.cc | 164 | ||||
-rw-r--r-- | cc/resources/picture_pile_impl_unittest.cc | 388 | ||||
-rw-r--r-- | cc/resources/pixel_ref_map.cc | 89 | ||||
-rw-r--r-- | cc/resources/pixel_ref_map.h | 6 | ||||
-rw-r--r-- | cc/resources/recording_source_unittest.cc | 445 |
10 files changed, 708 insertions, 420 deletions
diff --git a/cc/resources/display_item_list.cc b/cc/resources/display_item_list.cc index f8ffbfd..26ff003 100644 --- a/cc/resources/display_item_list.cc +++ b/cc/resources/display_item_list.cc @@ -143,4 +143,14 @@ void DisplayItemList::EmitTraceSnapshot() const { "cc::DisplayItemList", this, AsValue()); } +void DisplayItemList::GatherPixelRefs(const gfx::Size& grid_cell_size) { + // This should be only called once, and only after CreateAndCacheSkPicture. + DCHECK(picture_); + DCHECK(!pixel_refs_); + pixel_refs_ = make_scoped_ptr(new PixelRefMap(grid_cell_size)); + if (!picture_->willPlayBackBitmaps()) + return; + + pixel_refs_->GatherPixelRefsFromPicture(picture_.get()); +} } // namespace cc diff --git a/cc/resources/display_item_list.h b/cc/resources/display_item_list.h index 39694d7..f490552 100644 --- a/cc/resources/display_item_list.h +++ b/cc/resources/display_item_list.h @@ -11,6 +11,7 @@ #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_vector.h" #include "cc/resources/display_item.h" +#include "cc/resources/pixel_ref_map.h" #include "skia/ext/refptr.h" #include "third_party/skia/include/core/SkPicture.h" #include "ui/gfx/geometry/rect.h" @@ -44,6 +45,8 @@ class CC_EXPORT DisplayItemList void EmitTraceSnapshot() const; + void GatherPixelRefs(const gfx::Size& grid_cell_size); + private: DisplayItemList(); ~DisplayItemList(); @@ -54,7 +57,10 @@ class CC_EXPORT DisplayItemList bool is_suitable_for_gpu_rasterization_; int approximate_op_count_; + scoped_ptr<PixelRefMap> pixel_refs_; + friend class base::RefCountedThreadSafe<DisplayItemList>; + friend class PixelRefMap::Iterator; DISALLOW_COPY_AND_ASSIGN(DisplayItemList); }; diff --git a/cc/resources/display_list_raster_source.cc b/cc/resources/display_list_raster_source.cc index e35900a..9a0bc91 100644 --- a/cc/resources/display_list_raster_source.cc +++ b/cc/resources/display_list_raster_source.cc @@ -159,7 +159,16 @@ void DisplayListRasterSource::GatherPixelRefs( const gfx::Rect& content_rect, float contents_scale, std::vector<SkPixelRef*>* pixel_refs) const { - // TODO(ajuma): Implement this. + DCHECK_EQ(0u, pixel_refs->size()); + + gfx::Rect layer_rect = + gfx::ScaleToEnclosingRect(content_rect, 1.0f / contents_scale); + + PixelRefMap::Iterator iterator(layer_rect, display_list_.get()); + while (iterator) { + pixel_refs->push_back(*iterator); + ++iterator; + } } bool DisplayListRasterSource::CoversRect(const gfx::Rect& content_rect, diff --git a/cc/resources/display_list_recording_source.cc b/cc/resources/display_list_recording_source.cc index 296036d..e6488687 100644 --- a/cc/resources/display_list_recording_source.cc +++ b/cc/resources/display_list_recording_source.cc @@ -26,7 +26,8 @@ const int kOpCountThatIsOkToAnalyze = 10; namespace cc { -DisplayListRecordingSource::DisplayListRecordingSource() +DisplayListRecordingSource::DisplayListRecordingSource( + const gfx::Size& grid_cell_size) : slow_down_raster_scale_factor_for_debug_(0), gather_pixel_refs_(false), requires_clear_(false), @@ -34,6 +35,7 @@ DisplayListRecordingSource::DisplayListRecordingSource() solid_color_(SK_ColorTRANSPARENT), background_color_(SK_ColorTRANSPARENT), pixel_record_distance_(kPixelDistanceToRecord), + grid_cell_size_(grid_cell_size), is_suitable_for_gpu_rasterization_(true) { } @@ -115,6 +117,8 @@ bool DisplayListRecordingSource::UpdateAndExpandInvalidation( display_list_->EmitTraceSnapshot(); display_list_->CreateAndCacheSkPicture(); + if (gather_pixel_refs_) + display_list_->GatherPixelRefs(grid_cell_size_); return true; } diff --git a/cc/resources/display_list_recording_source.h b/cc/resources/display_list_recording_source.h index 53d7fa5..a87c848 100644 --- a/cc/resources/display_list_recording_source.h +++ b/cc/resources/display_list_recording_source.h @@ -14,7 +14,7 @@ class DisplayListRasterSource; class CC_EXPORT DisplayListRecordingSource : public RecordingSource { public: - DisplayListRecordingSource(); + explicit DisplayListRecordingSource(const gfx::Size& grid_cell_size); ~DisplayListRecordingSource() override; // RecordingSource overrides. @@ -49,6 +49,7 @@ class CC_EXPORT DisplayListRecordingSource : public RecordingSource { SkColor solid_color_; SkColor background_color_; int pixel_record_distance_; + gfx::Size grid_cell_size_; scoped_refptr<DisplayItemList> display_list_; diff --git a/cc/resources/display_list_recording_source_unittest.cc b/cc/resources/display_list_recording_source_unittest.cc new file mode 100644 index 0000000..45c3b80 --- /dev/null +++ b/cc/resources/display_list_recording_source_unittest.cc @@ -0,0 +1,164 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "cc/resources/display_list_raster_source.h" +#include "cc/test/fake_display_list_recording_source.h" +#include "cc/test/skia_common.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +TEST(DisplayListRecordingSourceTest, DiscardablePixelRefsWithTransform) { + gfx::Size grid_cell_size(128, 128); + gfx::Rect recorded_viewport(0, 0, 256, 256); + + scoped_ptr<FakeDisplayListRecordingSource> recording_source = + FakeDisplayListRecordingSource::CreateRecordingSource(recorded_viewport); + recording_source->SetGridCellSize(grid_cell_size); + SkBitmap discardable_bitmap[2][2]; + gfx::Transform identity_transform; + CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][0]); + // Translate transform is equivalent to moving using point. + gfx::Transform translate_transform; + translate_transform.Translate(0, 130); + CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][0]); + // This moves the bitmap to center of viewport and rotate, this would make + // this bitmap in all four tile grids. + gfx::Transform rotate_transform; + rotate_transform.Translate(112, 112); + rotate_transform.Rotate(45); + CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][1]); + + recording_source->add_draw_bitmap_with_transform(discardable_bitmap[0][0], + identity_transform); + recording_source->add_draw_bitmap_with_transform(discardable_bitmap[1][0], + translate_transform); + recording_source->add_draw_bitmap_with_transform(discardable_bitmap[1][1], + rotate_transform); + recording_source->Rerecord(); + + bool can_use_lcd_text = true; + scoped_refptr<DisplayListRasterSource> raster_source = + DisplayListRasterSource::CreateFromDisplayListRecordingSource( + recording_source.get(), can_use_lcd_text); + + // Tile sized iterators. These should find only one pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 1.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(2u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 2.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(2u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 64, 64), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(2u, pixel_refs.size()); + } + + // Shifted tile sized iterators. These should find only one pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(140, 140, 128, 128), 1.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(280, 280, 256, 256), 2.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(70, 70, 64, 64), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + + // The rotated bitmap would still be in the top right tile. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(140, 0, 128, 128), 1.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + + // Layer sized iterators. These should find all 6 pixel refs, including 1 + // pixel ref bitmap[0][0], 1 pixel ref for bitmap[1][0], and 4 pixel refs for + // bitmap[1][1]. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 1.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + // Top left tile with bitmap[0][0] and bitmap[1][1]. + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][1].pixelRef()); + // Top right tile with bitmap[1][1]. + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + // Bottom left tile with bitmap[1][0] and bitmap[1][1]. + EXPECT_TRUE(pixel_refs[3] == discardable_bitmap[1][0].pixelRef()); + EXPECT_TRUE(pixel_refs[4] == discardable_bitmap[1][1].pixelRef()); + // Bottom right tile with bitmap[1][1]. + EXPECT_TRUE(pixel_refs[5] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(6u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 2.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + // Top left tile with bitmap[0][0] and bitmap[1][1]. + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][1].pixelRef()); + // Top right tile with bitmap[1][1]. + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + // Bottom left tile with bitmap[1][0] and bitmap[1][1]. + EXPECT_TRUE(pixel_refs[3] == discardable_bitmap[1][0].pixelRef()); + EXPECT_TRUE(pixel_refs[4] == discardable_bitmap[1][1].pixelRef()); + // Bottom right tile with bitmap[1][1]. + EXPECT_TRUE(pixel_refs[5] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(6u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + // Top left tile with bitmap[0][0] and bitmap[1][1]. + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][1].pixelRef()); + // Top right tile with bitmap[1][1]. + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + // Bottom left tile with bitmap[1][0] and bitmap[1][1]. + EXPECT_TRUE(pixel_refs[3] == discardable_bitmap[1][0].pixelRef()); + EXPECT_TRUE(pixel_refs[4] == discardable_bitmap[1][1].pixelRef()); + // Bottom right tile with bitmap[1][1]. + EXPECT_TRUE(pixel_refs[5] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(6u, pixel_refs.size()); + } +} + +} // namespace +} // namespace cc diff --git a/cc/resources/picture_pile_impl_unittest.cc b/cc/resources/picture_pile_impl_unittest.cc index 72a8158..82f3608 100644 --- a/cc/resources/picture_pile_impl_unittest.cc +++ b/cc/resources/picture_pile_impl_unittest.cc @@ -32,7 +32,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidUnscaled) { recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400), solid_paint); - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); @@ -51,7 +51,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidUnscaled) { // Add one non-solid pixel and recreate the raster source. recording_source->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1), non_solid_paint); - recording_source->RerecordPile(); + recording_source->Rerecord(); pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); RasterSource::SolidColorAnalysis analysis; @@ -97,7 +97,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidScaled) { recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 400, 400), solid_paint); - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); @@ -116,7 +116,7 @@ TEST(PicturePileImplTest, AnalyzeIsSolidScaled) { // Add one non-solid pixel and recreate the raster source. recording_source->add_draw_rect_with_paint(gfx::Rect(50, 50, 1, 1), non_solid_paint); - recording_source->RerecordPile(); + recording_source->Rerecord(); pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); RasterSource::SolidColorAnalysis analysis; @@ -159,257 +159,6 @@ TEST(PicturePileImplTest, AnalyzeIsSolidEmpty) { EXPECT_EQ(analysis.solid_color, SkColorSetARGB(0, 0, 0, 0)); } -TEST(PicturePileImplTest, PixelRefIteratorEmpty) { - gfx::Size tile_size(128, 128); - gfx::Size layer_bounds(256, 256); - - // Create a filled pile with no recording. - scoped_refptr<FakePicturePileImpl> pile = - FakePicturePileImpl::CreateFilledPile(tile_size, layer_bounds); - - // Tile sized iterators. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 2.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 64, 64), 0.5, pile.get()); - EXPECT_FALSE(iterator); - } - // Shifted tile sized iterators. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(140, 140, 128, 128), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(280, 280, 256, 256), 2.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(70, 70, 64, 64), 0.5, pile.get()); - EXPECT_FALSE(iterator); - } - // Layer sized iterators. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 512, 512), 2.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 0.5, pile.get()); - EXPECT_FALSE(iterator); - } -} - -TEST(PicturePileImplTest, PixelRefIteratorNoDiscardableRefs) { - gfx::Size tile_size(128, 128); - gfx::Size layer_bounds(256, 256); - - scoped_ptr<FakePicturePile> recording_source = - FakePicturePile::CreateFilledPile(tile_size, layer_bounds); - SkPaint simple_paint; - simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); - - SkBitmap non_discardable_bitmap; - CreateBitmap(gfx::Size(128, 128), "notdiscardable", &non_discardable_bitmap); - - recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 256, 256), - simple_paint); - recording_source->add_draw_rect_with_paint(gfx::Rect(128, 128, 512, 512), - simple_paint); - recording_source->add_draw_rect_with_paint(gfx::Rect(512, 0, 256, 256), - simple_paint); - recording_source->add_draw_rect_with_paint(gfx::Rect(0, 512, 256, 256), - simple_paint); - recording_source->add_draw_bitmap(non_discardable_bitmap, gfx::Point(128, 0)); - recording_source->add_draw_bitmap(non_discardable_bitmap, gfx::Point(0, 128)); - recording_source->add_draw_bitmap(non_discardable_bitmap, - gfx::Point(150, 150)); - recording_source->RerecordPile(); - - scoped_refptr<FakePicturePileImpl> pile = - FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); - - // Tile sized iterators. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 2.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 64, 64), 0.5, pile.get()); - EXPECT_FALSE(iterator); - } - // Shifted tile sized iterators. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(140, 140, 128, 128), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(280, 280, 256, 256), 2.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(70, 70, 64, 64), 0.5, pile.get()); - EXPECT_FALSE(iterator); - } - // Layer sized iterators. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 512, 512), 2.0, pile.get()); - EXPECT_FALSE(iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 0.5, pile.get()); - EXPECT_FALSE(iterator); - } -} - -TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefs) { - gfx::Size tile_size(128, 128); - gfx::Size layer_bounds(256, 256); - - scoped_ptr<FakePicturePile> recording_source = - FakePicturePile::CreateFilledPile(tile_size, layer_bounds); - - SkBitmap discardable_bitmap[2][2]; - CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][0]); - CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][0]); - CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][1]); - - // Discardable pixel refs are found in the following cells: - // |---|---| - // | x | | - // |---|---| - // | x | x | - // |---|---| - recording_source->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0)); - recording_source->add_draw_bitmap(discardable_bitmap[1][0], - gfx::Point(0, 130)); - recording_source->add_draw_bitmap(discardable_bitmap[1][1], - gfx::Point(140, 140)); - recording_source->RerecordPile(); - - scoped_refptr<FakePicturePileImpl> pile = - FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); - - // Tile sized iterators. These should find only one pixel ref. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 1.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 2.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 64, 64), 0.5, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_FALSE(++iterator); - } - // Shifted tile sized iterators. These should find only one pixel ref. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(140, 140, 128, 128), 1.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(280, 280, 256, 256), 2.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(70, 70, 64, 64), 0.5, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - // Ensure there's no discardable pixel refs in the empty cell - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(140, 0, 128, 128), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - // Layer sized iterators. These should find all 3 pixel refs. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 1.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 512, 512), 2.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 0.5, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } -} - TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefsOneTile) { gfx::Size tile_size(256, 256); gfx::Size layer_bounds(512, 512); @@ -433,7 +182,7 @@ TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefsOneTile) { gfx::Point(260, 0)); recording_source->add_draw_bitmap(discardable_bitmap[1][1], gfx::Point(260, 260)); - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); @@ -545,125 +294,6 @@ TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefsOneTile) { EXPECT_FALSE(++copy); } -TEST(PicturePileImplTest, PixelRefIteratorDiscardableRefsBaseNonDiscardable) { - gfx::Size tile_size(256, 256); - gfx::Size layer_bounds(512, 512); - - scoped_ptr<FakePicturePile> recording_source = - FakePicturePile::CreateFilledPile(tile_size, layer_bounds); - - SkBitmap non_discardable_bitmap; - CreateBitmap(gfx::Size(512, 512), "notdiscardable", &non_discardable_bitmap); - - SkBitmap discardable_bitmap[2][2]; - CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[0][0]); - CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[0][1]); - CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[1][1]); - - // One large non-discardable bitmap covers the whole grid. - // Discardable pixel refs are found in the following cells: - // |---|---| - // | x | x | - // |---|---| - // | | x | - // |---|---| - recording_source->add_draw_bitmap(non_discardable_bitmap, gfx::Point(0, 0)); - recording_source->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0)); - recording_source->add_draw_bitmap(discardable_bitmap[0][1], - gfx::Point(260, 0)); - recording_source->add_draw_bitmap(discardable_bitmap[1][1], - gfx::Point(260, 260)); - recording_source->RerecordPile(); - - scoped_refptr<FakePicturePileImpl> pile = - FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); - - // Tile sized iterators. These should find only one pixel ref. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 1.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 512, 512), 2.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 128, 128), 0.5, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_FALSE(++iterator); - } - // Shifted tile sized iterators. These should find only one pixel ref. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(260, 260, 256, 256), 1.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(520, 520, 512, 512), 2.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(130, 130, 128, 128), 0.5, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - // Ensure there's no discardable pixel refs in the empty cell - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 256, 256, 256), 1.0, pile.get()); - EXPECT_FALSE(iterator); - } - // Layer sized iterators. These should find three pixel ref. - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 512, 512), 1.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 1024, 1024), 2.0, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } - { - PicturePileImpl::PixelRefIterator iterator( - gfx::Rect(0, 0, 256, 256), 0.5, pile.get()); - EXPECT_TRUE(iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][0].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[0][1].pixelRef()); - EXPECT_TRUE(++iterator); - EXPECT_TRUE(*iterator == discardable_bitmap[1][1].pixelRef()); - EXPECT_FALSE(++iterator); - } -} - TEST(PicturePileImplTest, RasterFullContents) { gfx::Size tile_size(1000, 1000); gfx::Size layer_bounds(3, 5); @@ -685,7 +315,7 @@ TEST(PicturePileImplTest, RasterFullContents) { white_paint); recording_source->SetMinContentsScale(contents_scale); - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); @@ -745,7 +375,7 @@ TEST(PicturePileImpl, RasterContentsTransparent) { recording_source->SetRequiresClear(true); recording_source->SetMinContentsScale(contents_scale); recording_source->SetClearCanvasWithDebugColor(false); - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); @@ -795,7 +425,7 @@ TEST_P(OverlapTest, NoOverlap) { // Paint outside the layer to make sure that blending works. recording_source->add_draw_rect_with_paint( gfx::RectF(bigger_than_layer_bounds), color_paint); - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); @@ -856,7 +486,7 @@ TEST(PicturePileImplTest, PixelRefIteratorBorders) { bitmap_rects[i].origin()); } - recording_source->RerecordPile(); + recording_source->Rerecord(); scoped_refptr<FakePicturePileImpl> pile = FakePicturePileImpl::CreateFromPile(recording_source.get(), nullptr); diff --git a/cc/resources/pixel_ref_map.cc b/cc/resources/pixel_ref_map.cc index dc50851..11ca5fd 100644 --- a/cc/resources/pixel_ref_map.cc +++ b/cc/resources/pixel_ref_map.cc @@ -8,6 +8,7 @@ #include <limits> #include "cc/base/util.h" +#include "cc/resources/display_item_list.h" #include "cc/resources/picture.h" #include "skia/ext/pixel_ref_utils.h" @@ -75,44 +76,19 @@ PixelRefMap::Iterator::Iterator(const gfx::Rect& rect, const Picture* picture) : target_pixel_ref_map_(&(picture->pixel_refs_)), current_pixel_refs_(empty_pixel_refs_.Pointer()), current_index_(0) { - gfx::Rect layer_rect = picture->layer_rect_; - gfx::Size cell_size = target_pixel_ref_map_->cell_size_; - DCHECK(!cell_size.IsEmpty()); - gfx::Rect query_rect(rect); - // Early out if the query rect doesn't intersect this picture. - if (!query_rect.Intersects(layer_rect)) { - min_point_ = gfx::Point(0, 0); - max_point_ = gfx::Point(0, 0); - current_x_ = 1; - current_y_ = 1; - return; - } - - // First, subtract the layer origin as cells are stored in layer space. - query_rect.Offset(-layer_rect.OffsetFromOrigin()); - - // We have to find a cell_size aligned point that corresponds to - // query_rect. Point is a multiple of cell_size. - min_point_ = gfx::Point(RoundDown(query_rect.x(), cell_size.width()), - RoundDown(query_rect.y(), cell_size.height())); - max_point_ = - gfx::Point(RoundDown(query_rect.right() - 1, cell_size.width()), - RoundDown(query_rect.bottom() - 1, cell_size.height())); - - // Limit the points to known pixel ref boundaries. - min_point_ = gfx::Point( - std::max(min_point_.x(), target_pixel_ref_map_->min_pixel_cell_.x()), - std::max(min_point_.y(), target_pixel_ref_map_->min_pixel_cell_.y())); - max_point_ = gfx::Point( - std::min(max_point_.x(), target_pixel_ref_map_->max_pixel_cell_.x()), - std::min(max_point_.y(), target_pixel_ref_map_->max_pixel_cell_.y())); + map_layer_rect_ = picture->layer_rect_; + DCHECK(!target_pixel_ref_map_->cell_size_.IsEmpty()); + PointToFirstPixelRef(rect); +} - // Make the current x be cell_size.width() less than min point, so that - // the first increment will point at min_point_. - current_x_ = min_point_.x() - cell_size.width(); - current_y_ = min_point_.y(); - if (current_y_ <= max_point_.y()) - ++(*this); +PixelRefMap::Iterator::Iterator(const gfx::Rect& rect, + const DisplayItemList* display_list) + : target_pixel_ref_map_(display_list->pixel_refs_.get()), + current_pixel_refs_(empty_pixel_refs_.Pointer()), + current_index_(0) { + map_layer_rect_ = display_list->layer_rect_; + DCHECK(!target_pixel_ref_map_->cell_size_.IsEmpty()); + PointToFirstPixelRef(rect); } PixelRefMap::Iterator::~Iterator() { @@ -155,4 +131,43 @@ PixelRefMap::Iterator& PixelRefMap::Iterator::operator++() { return *this; } +void PixelRefMap::Iterator::PointToFirstPixelRef(const gfx::Rect& rect) { + gfx::Rect query_rect(rect); + // Early out if the query rect doesn't intersect this picture. + if (!query_rect.Intersects(map_layer_rect_)) { + min_point_ = gfx::Point(0, 0); + max_point_ = gfx::Point(0, 0); + current_x_ = 1; + current_y_ = 1; + return; + } + + // First, subtract the layer origin as cells are stored in layer space. + query_rect.Offset(-map_layer_rect_.OffsetFromOrigin()); + + gfx::Size cell_size(target_pixel_ref_map_->cell_size_); + // We have to find a cell_size aligned point that corresponds to + // query_rect. Point is a multiple of cell_size. + min_point_ = gfx::Point(RoundDown(query_rect.x(), cell_size.width()), + RoundDown(query_rect.y(), cell_size.height())); + max_point_ = + gfx::Point(RoundDown(query_rect.right() - 1, cell_size.width()), + RoundDown(query_rect.bottom() - 1, cell_size.height())); + + // Limit the points to known pixel ref boundaries. + min_point_ = gfx::Point( + std::max(min_point_.x(), target_pixel_ref_map_->min_pixel_cell_.x()), + std::max(min_point_.y(), target_pixel_ref_map_->min_pixel_cell_.y())); + max_point_ = gfx::Point( + std::min(max_point_.x(), target_pixel_ref_map_->max_pixel_cell_.x()), + std::min(max_point_.y(), target_pixel_ref_map_->max_pixel_cell_.y())); + + // Make the current x be cell_size.width() less than min point, so that + // the first increment will point at min_point_. + current_x_ = min_point_.x() - cell_size.width(); + current_y_ = min_point_.y(); + if (current_y_ <= max_point_.y()) + ++(*this); +} + } // namespace cc diff --git a/cc/resources/pixel_ref_map.h b/cc/resources/pixel_ref_map.h index f50a841..b258809 100644 --- a/cc/resources/pixel_ref_map.h +++ b/cc/resources/pixel_ref_map.h @@ -21,6 +21,7 @@ class SkPixelRef; namespace cc { class Picture; +class DisplayItemList; typedef std::pair<int, int> PixelRefMapKey; typedef std::vector<SkPixelRef*> PixelRefs; @@ -46,6 +47,7 @@ class CC_EXPORT PixelRefMap { // Iterator. Iterator(); Iterator(const gfx::Rect& layer_rect, const Picture* picture); + Iterator(const gfx::Rect& layer_rect, const DisplayItemList* picture); ~Iterator(); SkPixelRef* operator->() const { @@ -64,12 +66,14 @@ class CC_EXPORT PixelRefMap { } private: + void PointToFirstPixelRef(const gfx::Rect& query_rect); + static base::LazyInstance<PixelRefs> empty_pixel_refs_; const PixelRefMap* target_pixel_ref_map_; const PixelRefs* current_pixel_refs_; unsigned current_index_; - gfx::Rect layer_rect_; + gfx::Rect map_layer_rect_; gfx::Point min_point_; gfx::Point max_point_; diff --git a/cc/resources/recording_source_unittest.cc b/cc/resources/recording_source_unittest.cc new file mode 100644 index 0000000..4fae652 --- /dev/null +++ b/cc/resources/recording_source_unittest.cc @@ -0,0 +1,445 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <vector> + +#include "cc/resources/display_list_raster_source.h" +#include "cc/test/fake_display_list_recording_source.h" +#include "cc/test/fake_picture_pile.h" +#include "cc/test/fake_picture_pile_impl.h" +#include "cc/test/impl_side_painting_settings.h" +#include "cc/test/skia_common.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +template <class T> +scoped_ptr<T> CreateRecordingSource(const gfx::Rect& viewport, + const gfx::Size& grid_cell_size); + +template <> +scoped_ptr<FakePicturePile> CreateRecordingSource<FakePicturePile>( + const gfx::Rect& viewport, + const gfx::Size& grid_cell_size) { + return FakePicturePile::CreateFilledPile(grid_cell_size, viewport.size()); +} + +template <> +scoped_ptr<FakeDisplayListRecordingSource> CreateRecordingSource< + FakeDisplayListRecordingSource>(const gfx::Rect& viewport, + const gfx::Size& grid_cell_size) { + scoped_ptr<FakeDisplayListRecordingSource> recording_source = + FakeDisplayListRecordingSource::CreateRecordingSource(viewport); + recording_source->SetGridCellSize(grid_cell_size); + + return recording_source.Pass(); +} + +template <class T> +scoped_refptr<RasterSource> CreateRasterSource(T* recording_source); + +template <> +scoped_refptr<RasterSource> CreateRasterSource( + FakePicturePile* recording_source) { + return FakePicturePileImpl::CreateFromPile(recording_source, nullptr); +} + +template <> +scoped_refptr<RasterSource> CreateRasterSource( + FakeDisplayListRecordingSource* recording_source) { + bool can_use_lcd_text = true; + return DisplayListRasterSource::CreateFromDisplayListRecordingSource( + recording_source, can_use_lcd_text); +} + +template <typename T> +class RecordingSourceTest : public testing::Test {}; + +using testing::Types; + +typedef Types<FakePicturePile, FakeDisplayListRecordingSource> + RecordingSourceImplementations; + +TYPED_TEST_CASE(RecordingSourceTest, RecordingSourceImplementations); + +TYPED_TEST(RecordingSourceTest, EmptyPixelRefs) { + gfx::Size grid_cell_size(128, 128); + gfx::Rect recorded_viewport(0, 0, 256, 256); + + scoped_ptr<TypeParam> recording_source = + CreateRecordingSource<TypeParam>(recorded_viewport, grid_cell_size); + recording_source->Rerecord(); + + scoped_refptr<RasterSource> raster_source = + CreateRasterSource<TypeParam>(recording_source.get()); + + // Tile sized iterators. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 1.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 2.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 64, 64), 0.5, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + // Shifted tile sized iterators. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(140, 140, 128, 128), 1.0, + &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(280, 280, 256, 256), 2.0, + &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(70, 70, 64, 64), 0.5, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + // Layer sized iterators. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 1.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 2.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 0.5, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } +} + +TYPED_TEST(RecordingSourceTest, NoDiscardablePixelRefs) { + gfx::Size grid_cell_size(128, 128); + gfx::Rect recorded_viewport(0, 0, 256, 256); + + scoped_ptr<TypeParam> recording_source = + CreateRecordingSource<TypeParam>(recorded_viewport, grid_cell_size); + + SkPaint simple_paint; + simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); + + SkBitmap non_discardable_bitmap; + CreateBitmap(gfx::Size(128, 128), "notdiscardable", &non_discardable_bitmap); + + recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 256, 256), + simple_paint); + recording_source->add_draw_rect_with_paint(gfx::Rect(128, 128, 512, 512), + simple_paint); + recording_source->add_draw_rect_with_paint(gfx::Rect(512, 0, 256, 256), + simple_paint); + recording_source->add_draw_rect_with_paint(gfx::Rect(0, 512, 256, 256), + simple_paint); + recording_source->add_draw_bitmap(non_discardable_bitmap, gfx::Point(128, 0)); + recording_source->add_draw_bitmap(non_discardable_bitmap, gfx::Point(0, 128)); + recording_source->add_draw_bitmap(non_discardable_bitmap, + gfx::Point(150, 150)); + recording_source->Rerecord(); + + scoped_refptr<RasterSource> raster_source = + CreateRasterSource<TypeParam>(recording_source.get()); + + // Tile sized iterators. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 1.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 2.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 64, 64), 0.5, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + // Shifted tile sized iterators. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(140, 140, 128, 128), 1.0, + &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(280, 280, 256, 256), 2.0, + &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(70, 70, 64, 64), 0.5, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + // Layer sized iterators. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 1.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 2.0, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 0.5, &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } +} + +TYPED_TEST(RecordingSourceTest, DiscardablePixelRefs) { + gfx::Size grid_cell_size(128, 128); + gfx::Rect recorded_viewport(0, 0, 256, 256); + + scoped_ptr<TypeParam> recording_source = + CreateRecordingSource<TypeParam>(recorded_viewport, grid_cell_size); + + SkBitmap discardable_bitmap[2][2]; + CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[0][0]); + CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][0]); + CreateBitmap(gfx::Size(32, 32), "discardable", &discardable_bitmap[1][1]); + + // Discardable pixel refs are found in the following cells: + // |---|---| + // | x | | + // |---|---| + // | x | x | + // |---|---| + recording_source->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0)); + recording_source->add_draw_bitmap(discardable_bitmap[1][0], + gfx::Point(0, 130)); + recording_source->add_draw_bitmap(discardable_bitmap[1][1], + gfx::Point(140, 140)); + recording_source->Rerecord(); + + scoped_refptr<RasterSource> raster_source = + CreateRasterSource<TypeParam>(recording_source.get()); + + // Tile sized iterators. These should find only one pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 1.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 2.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 64, 64), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + + // Shifted tile sized iterators. These should find only one pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(140, 140, 128, 128), 1.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(280, 280, 256, 256), 2.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(70, 70, 64, 64), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + + // Ensure there's no discardable pixel refs in the empty cell + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(140, 0, 128, 128), 1.0, + &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + + // Layer sized iterators. These should find all 3 pixel refs. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 1.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][0].pixelRef()); + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(3u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 2.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][0].pixelRef()); + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(3u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[1][0].pixelRef()); + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(3u, pixel_refs.size()); + } +} + +TYPED_TEST(RecordingSourceTest, DiscardablePixelRefsBaseNonDiscardable) { + gfx::Size grid_cell_size(256, 256); + gfx::Rect recorded_viewport(0, 0, 512, 512); + + scoped_ptr<TypeParam> recording_source = + CreateRecordingSource<TypeParam>(recorded_viewport, grid_cell_size); + + SkBitmap non_discardable_bitmap; + CreateBitmap(gfx::Size(512, 512), "notdiscardable", &non_discardable_bitmap); + + SkBitmap discardable_bitmap[2][2]; + CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[0][0]); + CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[0][1]); + CreateBitmap(gfx::Size(128, 128), "discardable", &discardable_bitmap[1][1]); + + // One large non-discardable bitmap covers the whole grid. + // Discardable pixel refs are found in the following cells: + // |---|---| + // | x | x | + // |---|---| + // | | x | + // |---|---| + recording_source->add_draw_bitmap(non_discardable_bitmap, gfx::Point(0, 0)); + recording_source->add_draw_bitmap(discardable_bitmap[0][0], gfx::Point(0, 0)); + recording_source->add_draw_bitmap(discardable_bitmap[0][1], + gfx::Point(260, 0)); + recording_source->add_draw_bitmap(discardable_bitmap[1][1], + gfx::Point(260, 260)); + recording_source->Rerecord(); + + scoped_refptr<RasterSource> raster_source = + CreateRasterSource<TypeParam>(recording_source.get()); + + // Tile sized iterators. These should find only one pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 1.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 2.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 128, 128), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + // Shifted tile sized iterators. These should find only one pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(260, 260, 256, 256), 1.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(520, 520, 512, 512), 2.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(130, 130, 128, 128), 0.5, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(1u, pixel_refs.size()); + } + // Ensure there's no discardable pixel refs in the empty cell + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 256, 256, 256), 1.0, + &pixel_refs); + EXPECT_TRUE(pixel_refs.empty()); + } + // Layer sized iterators. These should find three pixel ref. + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 512, 512), 1.0, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[0][1].pixelRef()); + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(3u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 1024, 1024), 2.0, + &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[0][1].pixelRef()); + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(3u, pixel_refs.size()); + } + { + std::vector<SkPixelRef*> pixel_refs; + raster_source->GatherPixelRefs(gfx::Rect(0, 0, 256, 256), 0.5, &pixel_refs); + EXPECT_FALSE(pixel_refs.empty()); + EXPECT_TRUE(pixel_refs[0] == discardable_bitmap[0][0].pixelRef()); + EXPECT_TRUE(pixel_refs[1] == discardable_bitmap[0][1].pixelRef()); + EXPECT_TRUE(pixel_refs[2] == discardable_bitmap[1][1].pixelRef()); + EXPECT_EQ(3u, pixel_refs.size()); + } +} + +} // namespace +} // namespace cc |