| OLD | NEW | 
|---|
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 "cc/tiles/checker_image_tracker.h" | 5 #include "cc/tiles/checker_image_tracker.h" | 
| 6 | 6 | 
| 7 #include "base/bind.h" | 7 #include "base/bind.h" | 
| 8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" | 
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" | 
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 32                         base::ThreadTaskRunnerHandle::Get()) { | 32                         base::ThreadTaskRunnerHandle::Get()) { | 
| 33     SetMaxImageCacheLimitBytesForTesting(kMaxImageCacheSizeBytes); | 33     SetMaxImageCacheLimitBytesForTesting(kMaxImageCacheSizeBytes); | 
| 34   } | 34   } | 
| 35 | 35 | 
| 36   ~TestImageController() override { DCHECK_EQ(locked_images_.size(), 0U); } | 36   ~TestImageController() override { DCHECK_EQ(locked_images_.size(), 0U); } | 
| 37 | 37 | 
| 38   int num_of_locked_images() const { return locked_images_.size(); } | 38   int num_of_locked_images() const { return locked_images_.size(); } | 
| 39   const PaintImageIdFlatSet& decodes_requested() const { | 39   const PaintImageIdFlatSet& decodes_requested() const { | 
| 40     return decodes_requested_; | 40     return decodes_requested_; | 
| 41   } | 41   } | 
|  | 42   const std::vector<DrawImage>& decoded_images() const { | 
|  | 43     return decoded_images_; | 
|  | 44   } | 
| 42 | 45 | 
| 43   void UnlockImageDecode(ImageDecodeRequestId id) override { | 46   void UnlockImageDecode(ImageDecodeRequestId id) override { | 
| 44     DCHECK_EQ(locked_images_.count(id), 1U); | 47     DCHECK_EQ(locked_images_.count(id), 1U); | 
| 45     locked_images_.erase(id); | 48     locked_images_.erase(id); | 
| 46   } | 49   } | 
| 47 | 50 | 
| 48   ImageDecodeRequestId QueueImageDecode( | 51   ImageDecodeRequestId QueueImageDecode( | 
| 49       sk_sp<const SkImage> image, | 52       const DrawImage& image, | 
| 50       const ImageDecodedCallback& callback) override { | 53       const ImageDecodedCallback& callback) override { | 
| 51     ImageDecodeRequestId request_id = next_image_request_id_++; | 54     ImageDecodeRequestId request_id = next_image_request_id_++; | 
| 52 | 55 | 
| 53     decodes_requested_.insert(image->uniqueID()); | 56     decoded_images_.push_back(image); | 
|  | 57     decodes_requested_.insert(image.image()->uniqueID()); | 
| 54     locked_images_.insert(request_id); | 58     locked_images_.insert(request_id); | 
| 55 | 59 | 
| 56     // Post the callback asynchronously to match the behaviour in | 60     // Post the callback asynchronously to match the behaviour in | 
| 57     // ImageController. | 61     // ImageController. | 
| 58     worker_task_runner_->PostTask( | 62     worker_task_runner_->PostTask( | 
| 59         FROM_HERE, | 63         FROM_HERE, | 
| 60         base::BindOnce(callback, request_id, ImageDecodeResult::SUCCESS)); | 64         base::BindOnce(callback, request_id, ImageDecodeResult::SUCCESS)); | 
| 61 | 65 | 
| 62     return request_id; | 66     return request_id; | 
| 63   } | 67   } | 
| 64 | 68 | 
| 65  private: | 69  private: | 
| 66   ImageDecodeRequestId next_image_request_id_ = 1U; | 70   ImageDecodeRequestId next_image_request_id_ = 1U; | 
| 67   std::unordered_set<ImageDecodeRequestId> locked_images_; | 71   std::unordered_set<ImageDecodeRequestId> locked_images_; | 
| 68   PaintImageIdFlatSet decodes_requested_; | 72   PaintImageIdFlatSet decodes_requested_; | 
|  | 73   std::vector<DrawImage> decoded_images_; | 
| 69 }; | 74 }; | 
| 70 | 75 | 
| 71 class CheckerImageTrackerTest : public testing::Test, | 76 class CheckerImageTrackerTest : public testing::Test, | 
| 72                                 public CheckerImageTrackerClient { | 77                                 public CheckerImageTrackerClient { | 
| 73  public: | 78  public: | 
| 74   enum class ImageType { | 79   enum class ImageType { | 
| 75     CHECKERABLE, | 80     CHECKERABLE, | 
| 76     SMALL_NON_CHECKERABLE, | 81     SMALL_NON_CHECKERABLE, | 
| 77     LARGE_NON_CHECKERABLE | 82     LARGE_NON_CHECKERABLE | 
| 78   }; | 83   }; | 
| 79 | 84 | 
| 80   void SetUpTracker(bool checker_images_enabled) { | 85   void SetUpTracker(bool checker_images_enabled) { | 
| 81     checker_image_tracker_ = base::MakeUnique<CheckerImageTracker>( | 86     checker_image_tracker_ = base::MakeUnique<CheckerImageTracker>( | 
| 82         &image_controller_, this, checker_images_enabled); | 87         &image_controller_, this, checker_images_enabled); | 
| 83   } | 88   } | 
| 84 | 89 | 
| 85   void TearDown() override { checker_image_tracker_.reset(); } | 90   void TearDown() override { checker_image_tracker_.reset(); } | 
| 86 | 91 | 
| 87   PaintImage CreateImage( | 92   DrawImage CreateImage( | 
| 88       ImageType image_type, | 93       ImageType image_type, | 
| 89       PaintImage::AnimationType animation = PaintImage::AnimationType::STATIC, | 94       PaintImage::AnimationType animation = PaintImage::AnimationType::STATIC, | 
| 90       PaintImage::CompletionState completion = | 95       PaintImage::CompletionState completion = | 
| 91           PaintImage::CompletionState::DONE) { | 96           PaintImage::CompletionState::DONE) { | 
| 92     int dimension = 0; | 97     int dimension = 0; | 
| 93     switch (image_type) { | 98     switch (image_type) { | 
| 94       case ImageType::CHECKERABLE: | 99       case ImageType::CHECKERABLE: | 
| 95         dimension = kCheckerableImageDimension; | 100         dimension = kCheckerableImageDimension; | 
| 96         break; | 101         break; | 
| 97       case ImageType::SMALL_NON_CHECKERABLE: | 102       case ImageType::SMALL_NON_CHECKERABLE: | 
| 98         dimension = kSmallNonCheckerableImageDimension; | 103         dimension = kSmallNonCheckerableImageDimension; | 
| 99         break; | 104         break; | 
| 100       case ImageType::LARGE_NON_CHECKERABLE: | 105       case ImageType::LARGE_NON_CHECKERABLE: | 
| 101         dimension = kLargeNonCheckerableImageDimension; | 106         dimension = kLargeNonCheckerableImageDimension; | 
| 102         break; | 107         break; | 
| 103     } | 108     } | 
| 104 | 109 | 
| 105     sk_sp<SkImage> image = | 110     sk_sp<SkImage> image = | 
| 106         CreateDiscardableImage(gfx::Size(dimension, dimension)); | 111         CreateDiscardableImage(gfx::Size(dimension, dimension)); | 
| 107     return PaintImage(PaintImage::GetNextId(), image, animation, completion); | 112     return DrawImage( | 
|  | 113         PaintImage(PaintImage::GetNextId(), image, animation, completion), | 
|  | 114         SkIRect::MakeWH(dimension, dimension), kNone_SkFilterQuality, | 
|  | 115         SkMatrix::I(), gfx::ColorSpace()); | 
| 108   } | 116   } | 
| 109 | 117 | 
| 110   CheckerImageTracker::ImageDecodeQueue BuildImageDecodeQueue( | 118   CheckerImageTracker::ImageDecodeQueue BuildImageDecodeQueue( | 
| 111       std::vector<PaintImage> images, | 119       std::vector<DrawImage> images, | 
| 112       WhichTree tree) { | 120       WhichTree tree) { | 
| 113     CheckerImageTracker::ImageDecodeQueue decode_queue; | 121     CheckerImageTracker::ImageDecodeQueue decode_queue; | 
| 114     for (const auto& image : images) { | 122     for (const auto& image : images) { | 
| 115       if (checker_image_tracker_->ShouldCheckerImage(image, tree)) | 123       if (checker_image_tracker_->ShouldCheckerImage(image, tree)) | 
| 116         decode_queue.push_back(image); | 124         decode_queue.push_back(image.paint_image()); | 
| 117     } | 125     } | 
| 118     return decode_queue; | 126     return decode_queue; | 
| 119   } | 127   } | 
| 120 | 128 | 
| 121   // CheckerImageTrackerClient implementation. | 129   // CheckerImageTrackerClient implementation. | 
| 122   void NeedsInvalidationForCheckerImagedTiles() override { | 130   void NeedsInvalidationForCheckerImagedTiles() override { | 
| 123     invalidation_request_pending_ = true; | 131     invalidation_request_pending_ = true; | 
| 124   } | 132   } | 
| 125 | 133 | 
| 126  protected: | 134  protected: | 
| 127   TestImageController image_controller_; | 135   TestImageController image_controller_; | 
| 128   std::unique_ptr<CheckerImageTracker> checker_image_tracker_; | 136   std::unique_ptr<CheckerImageTracker> checker_image_tracker_; | 
| 129 | 137 | 
| 130   bool invalidation_request_pending_ = false; | 138   bool invalidation_request_pending_ = false; | 
| 131 }; | 139 }; | 
| 132 | 140 | 
| 133 TEST_F(CheckerImageTrackerTest, CheckerImagesDisabled) { | 141 TEST_F(CheckerImageTrackerTest, CheckerImagesDisabled) { | 
| 134   // Ensures that the tracker doesn't filter any images for checkering if it is | 142   // Ensures that the tracker doesn't filter any images for checkering if it is | 
| 135   // disabled. | 143   // disabled. | 
| 136   SetUpTracker(false); | 144   SetUpTracker(false); | 
| 137 | 145 | 
| 138   PaintImageIdFlatSet checkered_images; | 146   PaintImageIdFlatSet checkered_images; | 
| 139   PaintImage paint_image = CreateImage(ImageType::CHECKERABLE); | 147   DrawImage draw_image = CreateImage(ImageType::CHECKERABLE); | 
| 140   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 148   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 141       paint_image, WhichTree::PENDING_TREE)); | 149       draw_image, WhichTree::PENDING_TREE)); | 
| 142   EXPECT_EQ(image_controller_.num_of_locked_images(), 0); | 150   EXPECT_EQ(image_controller_.num_of_locked_images(), 0); | 
| 143 } | 151 } | 
| 144 | 152 | 
| 145 TEST_F(CheckerImageTrackerTest, UpdatesImagesAtomically) { | 153 TEST_F(CheckerImageTrackerTest, UpdatesImagesAtomically) { | 
| 146   // Ensures that the tracker updates images atomically for each frame. | 154   // Ensures that the tracker updates images atomically for each frame. | 
| 147   SetUpTracker(true); | 155   SetUpTracker(true); | 
| 148 | 156 | 
| 149   PaintImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 157   DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 
| 150   PaintImage small_non_checkerable_image = | 158   DrawImage small_non_checkerable_image = | 
| 151       CreateImage(ImageType::SMALL_NON_CHECKERABLE); | 159       CreateImage(ImageType::SMALL_NON_CHECKERABLE); | 
| 152   PaintImage large_non_checkerable_image = | 160   DrawImage large_non_checkerable_image = | 
| 153       CreateImage(ImageType::LARGE_NON_CHECKERABLE); | 161       CreateImage(ImageType::LARGE_NON_CHECKERABLE); | 
| 154   CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 162   CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 
| 155 | 163 | 
| 156   // First request to filter images. | 164   // First request to filter images. | 
| 157   std::vector<PaintImage> paint_images = { | 165   std::vector<DrawImage> draw_images = { | 
| 158       checkerable_image, small_non_checkerable_image, | 166       checkerable_image, small_non_checkerable_image, | 
| 159       large_non_checkerable_image, checkerable_image}; | 167       large_non_checkerable_image, checkerable_image}; | 
| 160   image_decode_queue = | 168   image_decode_queue = | 
| 161       BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); | 169       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
| 162 | 170 | 
| 163   ASSERT_EQ(2u, image_decode_queue.size()); | 171   ASSERT_EQ(2u, image_decode_queue.size()); | 
| 164   EXPECT_EQ(checkerable_image, image_decode_queue[0]); | 172   EXPECT_EQ(checkerable_image.paint_image(), image_decode_queue[0]); | 
| 165   EXPECT_EQ(checkerable_image, image_decode_queue[1]); | 173   EXPECT_EQ(checkerable_image.paint_image(), image_decode_queue[1]); | 
| 166 | 174 | 
| 167   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 175   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 
| 168   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 176   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 
| 169 | 177 | 
| 170   // Run pending task to indicate completion of decode request to the tracker. | 178   // Run pending task to indicate completion of decode request to the tracker. | 
| 171   // This should send an impl-side invalidation request to the client. The | 179   // This should send an impl-side invalidation request to the client. The | 
| 172   // images must remain locked until the sync tree to which the invalidations | 180   // images must remain locked until the sync tree to which the invalidations | 
| 173   // are added is activated. | 181   // are added is activated. | 
| 174   base::RunLoop().RunUntilIdle(); | 182   base::RunLoop().RunUntilIdle(); | 
| 175   EXPECT_TRUE(invalidation_request_pending_); | 183   EXPECT_TRUE(invalidation_request_pending_); | 
| 176   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 184   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 
| 177 | 185 | 
| 178   // Continue checkering the image until the set of images to invalidate is | 186   // Continue checkering the image until the set of images to invalidate is | 
| 179   // pulled. | 187   // pulled. | 
| 180   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 188   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 181       checkerable_image, WhichTree::PENDING_TREE)); | 189       checkerable_image, WhichTree::PENDING_TREE)); | 
| 182 | 190 | 
| 183   PaintImageIdFlatSet invalidated_images = | 191   PaintImageIdFlatSet invalidated_images = | 
| 184       checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 192       checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 
| 185   EXPECT_EQ(invalidated_images.size(), 1U); | 193   EXPECT_EQ(invalidated_images.size(), 1U); | 
| 186   EXPECT_EQ(invalidated_images.count(checkerable_image.stable_id()), 1U); | 194   EXPECT_EQ( | 
|  | 195       invalidated_images.count(checkerable_image.paint_image().stable_id()), | 
|  | 196       1U); | 
| 187 | 197 | 
| 188   // Use the same set of draw images to ensure that they are not checkered on | 198   // Use the same set of draw images to ensure that they are not checkered on | 
| 189   // the pending tree now. | 199   // the pending tree now. | 
| 190   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 200   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 191       checkerable_image, WhichTree::PENDING_TREE)); | 201       checkerable_image, WhichTree::PENDING_TREE)); | 
| 192   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 202   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 193       small_non_checkerable_image, WhichTree::PENDING_TREE)); | 203       small_non_checkerable_image, WhichTree::PENDING_TREE)); | 
| 194   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 204   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 195       large_non_checkerable_image, WhichTree::PENDING_TREE)); | 205       large_non_checkerable_image, WhichTree::PENDING_TREE)); | 
| 196 | 206 | 
| 197   // Use this set to make the same request from the active tree, we should | 207   // Use this set to make the same request from the active tree, we should | 
| 198   // continue checkering this image on the active tree until activation. | 208   // continue checkering this image on the active tree until activation. | 
| 199   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 209   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 200       checkerable_image, WhichTree::ACTIVE_TREE)); | 210       checkerable_image, WhichTree::ACTIVE_TREE)); | 
| 201   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 211   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 202       small_non_checkerable_image, WhichTree::ACTIVE_TREE)); | 212       small_non_checkerable_image, WhichTree::ACTIVE_TREE)); | 
| 203   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 213   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 204       large_non_checkerable_image, WhichTree::ACTIVE_TREE)); | 214       large_non_checkerable_image, WhichTree::ACTIVE_TREE)); | 
| 205 | 215 | 
| 206   // Activate the sync tree. The images should be unlocked upon activation. | 216   // Activate the sync tree. The images should be unlocked upon activation. | 
| 207   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 217   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 
| 208   checker_image_tracker_->DidActivateSyncTree(); | 218   checker_image_tracker_->DidActivateSyncTree(); | 
| 209 } | 219 } | 
| 210 | 220 | 
| 211 TEST_F(CheckerImageTrackerTest, NoConsecutiveCheckeringForImage) { | 221 TEST_F(CheckerImageTrackerTest, NoConsecutiveCheckeringForImage) { | 
| 212   // Ensures that if an image is decoded and invalidated once, it is not | 222   // Ensures that if an image is decoded and invalidated once, it is not | 
| 213   // checkered again in subsequent frames. | 223   // checkered again in subsequent frames. | 
| 214   SetUpTracker(true); | 224   SetUpTracker(true); | 
| 215 | 225 | 
| 216   PaintImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 226   DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 
| 217   std::vector<PaintImage> paint_images = {checkerable_image}; | 227   std::vector<DrawImage> draw_images = {checkerable_image}; | 
| 218 | 228 | 
| 219   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 229   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 
| 220       BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); | 230       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
| 221   EXPECT_EQ(image_decode_queue.size(), 1U); | 231   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 222   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 232   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 
| 223 | 233 | 
| 224   // Trigger decode completion, take images to invalidate and activate the sync | 234   // Trigger decode completion, take images to invalidate and activate the sync | 
| 225   // tree. | 235   // tree. | 
| 226   base::RunLoop().RunUntilIdle(); | 236   base::RunLoop().RunUntilIdle(); | 
| 227   checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 237   checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 
| 228   checker_image_tracker_->DidActivateSyncTree(); | 238   checker_image_tracker_->DidActivateSyncTree(); | 
| 229 | 239 | 
| 230   // Subsequent requests for this image should not be checkered. | 240   // Subsequent requests for this image should not be checkered. | 
| 231   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 241   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 232       checkerable_image, WhichTree::PENDING_TREE)); | 242       checkerable_image, WhichTree::PENDING_TREE)); | 
| 233 } | 243 } | 
| 234 | 244 | 
| 235 TEST_F(CheckerImageTrackerTest, | 245 TEST_F(CheckerImageTrackerTest, | 
| 236        TracksCheckeredImagesSeperatelyInConsecutiveFrames) { | 246        TracksCheckeredImagesSeperatelyInConsecutiveFrames) { | 
| 237   // Ensures that the set of images being checkered on the pending tree, and the | 247   // Ensures that the set of images being checkered on the pending tree, and the | 
| 238   // active tree are tracked correctly. | 248   // active tree are tracked correctly. | 
| 239   SetUpTracker(true); | 249   SetUpTracker(true); | 
| 240 | 250 | 
| 241   PaintImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); | 251   DrawImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); | 
| 242   std::vector<PaintImage> paint_images; | 252   std::vector<DrawImage> draw_images; | 
| 243   CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 253   CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 
| 244 | 254 | 
| 245   // First request to filter images on the pending and active tree. | 255   // First request to filter images on the pending and active tree. | 
| 246   paint_images.push_back(checkerable_image1); | 256   draw_images.push_back(checkerable_image1); | 
| 247   image_decode_queue = | 257   image_decode_queue = | 
| 248       BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); | 258       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
| 249   EXPECT_EQ(image_decode_queue.size(), 1U); | 259   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 250   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 260   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 
| 251 | 261 | 
| 252   // The image is also checkered on the active tree while a decode request is | 262   // The image is also checkered on the active tree while a decode request is | 
| 253   // pending. | 263   // pending. | 
| 254   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 264   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 255       checkerable_image1, WhichTree::ACTIVE_TREE)); | 265       checkerable_image1, WhichTree::ACTIVE_TREE)); | 
| 256 | 266 | 
| 257   // Trigger decode completion and take images to invalidate on the sync tree. | 267   // Trigger decode completion and take images to invalidate on the sync tree. | 
| 258   base::RunLoop().RunUntilIdle(); | 268   base::RunLoop().RunUntilIdle(); | 
| 259   EXPECT_TRUE(invalidation_request_pending_); | 269   EXPECT_TRUE(invalidation_request_pending_); | 
| 260   PaintImageIdFlatSet invalidated_images = | 270   PaintImageIdFlatSet invalidated_images = | 
| 261       checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 271       checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 
| 262   EXPECT_EQ(invalidated_images.size(), 1U); | 272   EXPECT_EQ(invalidated_images.size(), 1U); | 
| 263   EXPECT_EQ(invalidated_images.count(checkerable_image1.stable_id()), 1U); | 273   EXPECT_EQ( | 
|  | 274       invalidated_images.count(checkerable_image1.paint_image().stable_id()), | 
|  | 275       1U); | 
| 264 | 276 | 
| 265   // Second request to filter the same image on the pending and active tree. It | 277   // Second request to filter the same image on the pending and active tree. It | 
| 266   // should be checkered on the active tree, but not the pending tree. | 278   // should be checkered on the active tree, but not the pending tree. | 
| 267   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 279   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 268       checkerable_image1, WhichTree::ACTIVE_TREE)); | 280       checkerable_image1, WhichTree::ACTIVE_TREE)); | 
| 269   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 281   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 270       checkerable_image1, WhichTree::PENDING_TREE)); | 282       checkerable_image1, WhichTree::PENDING_TREE)); | 
| 271 | 283 | 
| 272   // New checkerable image on the pending tree. | 284   // New checkerable image on the pending tree. | 
| 273   PaintImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 285   DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 
| 274   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 286   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 275       checkerable_image2, WhichTree::PENDING_TREE)); | 287       checkerable_image2, WhichTree::PENDING_TREE)); | 
| 276 | 288 | 
| 277   // Activate the sync tree. The initial image should no longer be checkered on | 289   // Activate the sync tree. The initial image should no longer be checkered on | 
| 278   // the active tree. | 290   // the active tree. | 
| 279   checker_image_tracker_->DidActivateSyncTree(); | 291   checker_image_tracker_->DidActivateSyncTree(); | 
| 280   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 292   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 281       checkerable_image1, WhichTree::ACTIVE_TREE)); | 293       checkerable_image1, WhichTree::ACTIVE_TREE)); | 
| 282 } | 294 } | 
| 283 | 295 | 
| 284 TEST_F(CheckerImageTrackerTest, CancelsScheduledDecodes) { | 296 TEST_F(CheckerImageTrackerTest, CancelsScheduledDecodes) { | 
| 285   SetUpTracker(true); | 297   SetUpTracker(true); | 
| 286 | 298 | 
| 287   PaintImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); | 299   DrawImage checkerable_image1 = CreateImage(ImageType::CHECKERABLE); | 
| 288   PaintImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 300   DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 
| 289   std::vector<PaintImage> paint_images = {checkerable_image1, | 301   std::vector<DrawImage> draw_images = {checkerable_image1, checkerable_image2}; | 
| 290                                           checkerable_image2}; |  | 
| 291 | 302 | 
| 292   CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 303   CheckerImageTracker::ImageDecodeQueue image_decode_queue; | 
| 293   image_decode_queue = | 304   image_decode_queue = | 
| 294       BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); | 305       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
| 295   EXPECT_EQ(image_decode_queue.size(), 2U); | 306   EXPECT_EQ(image_decode_queue.size(), 2U); | 
| 296   checker_image_tracker_->ScheduleImageDecodeQueue( | 307   checker_image_tracker_->ScheduleImageDecodeQueue( | 
| 297       std::move(image_decode_queue)); | 308       std::move(image_decode_queue)); | 
| 298 | 309 | 
| 299   // Only the first image in the queue should have been decoded. | 310   // Only the first image in the queue should have been decoded. | 
| 300   EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); | 311   EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); | 
| 301   EXPECT_EQ(image_controller_.decodes_requested().count( | 312   EXPECT_EQ(image_controller_.decodes_requested().count( | 
| 302                 checkerable_image1.sk_image()->uniqueID()), | 313                 checkerable_image1.image()->uniqueID()), | 
| 303             1U); | 314             1U); | 
| 304 | 315 | 
| 305   // Rebuild the queue before the tracker is notified of decode completion, | 316   // Rebuild the queue before the tracker is notified of decode completion, | 
| 306   // removing the second image and adding a new one. | 317   // removing the second image and adding a new one. | 
| 307   PaintImage checkerable_image3 = CreateImage(ImageType::CHECKERABLE); | 318   DrawImage checkerable_image3 = CreateImage(ImageType::CHECKERABLE); | 
| 308   paint_images = {checkerable_image1, checkerable_image3}; | 319   draw_images = {checkerable_image1, checkerable_image3}; | 
| 309   image_decode_queue = | 320   image_decode_queue = | 
| 310       BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); | 321       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
| 311 | 322 | 
| 312   // The queue has 2 decodes because we are still checkering on the first one. | 323   // The queue has 2 decodes because we are still checkering on the first one. | 
| 313   EXPECT_EQ(image_decode_queue.size(), 2U); | 324   EXPECT_EQ(image_decode_queue.size(), 2U); | 
| 314   checker_image_tracker_->ScheduleImageDecodeQueue( | 325   checker_image_tracker_->ScheduleImageDecodeQueue( | 
| 315       std::move(image_decode_queue)); | 326       std::move(image_decode_queue)); | 
| 316 | 327 | 
| 317   // We still have only one decode because the tracker keeps only one decode | 328   // We still have only one decode because the tracker keeps only one decode | 
| 318   // pending at a time. | 329   // pending at a time. | 
| 319   EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); | 330   EXPECT_EQ(image_controller_.decodes_requested().size(), 1U); | 
| 320   EXPECT_EQ(image_controller_.decodes_requested().count( | 331   EXPECT_EQ(image_controller_.decodes_requested().count( | 
| 321                 checkerable_image1.sk_image()->uniqueID()), | 332                 checkerable_image1.image()->uniqueID()), | 
| 322             1U); | 333             1U); | 
| 323 | 334 | 
| 324   // Trigger completion for all decodes. Only 2 images should have been decoded | 335   // Trigger completion for all decodes. Only 2 images should have been decoded | 
| 325   // since the second image was cancelled. | 336   // since the second image was cancelled. | 
| 326   base::RunLoop().RunUntilIdle(); | 337   base::RunLoop().RunUntilIdle(); | 
| 327   EXPECT_EQ(image_controller_.decodes_requested().size(), 2U); | 338   EXPECT_EQ(image_controller_.decodes_requested().size(), 2U); | 
| 328   EXPECT_EQ(image_controller_.decodes_requested().count( | 339   EXPECT_EQ(image_controller_.decodes_requested().count( | 
| 329                 checkerable_image3.sk_image()->uniqueID()), | 340                 checkerable_image3.image()->uniqueID()), | 
| 330             1U); | 341             1U); | 
| 331   EXPECT_EQ(image_controller_.num_of_locked_images(), 2); | 342   EXPECT_EQ(image_controller_.num_of_locked_images(), 2); | 
| 332 } | 343 } | 
| 333 | 344 | 
| 334 TEST_F(CheckerImageTrackerTest, ClearsTracker) { | 345 TEST_F(CheckerImageTrackerTest, ClearsTracker) { | 
| 335   SetUpTracker(true); | 346   SetUpTracker(true); | 
| 336 | 347 | 
| 337   PaintImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 348   DrawImage checkerable_image = CreateImage(ImageType::CHECKERABLE); | 
| 338   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 349   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 
| 339       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 350       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 
| 340   EXPECT_EQ(image_decode_queue.size(), 1U); | 351   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 341   checker_image_tracker_->ScheduleImageDecodeQueue( | 352   checker_image_tracker_->ScheduleImageDecodeQueue( | 
| 342       std::move(image_decode_queue)); | 353       std::move(image_decode_queue)); | 
| 343   base::RunLoop().RunUntilIdle(); | 354   base::RunLoop().RunUntilIdle(); | 
| 344   checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 355   checker_image_tracker_->TakeImagesToInvalidateOnSyncTree(); | 
| 345 | 356 | 
| 346   // The image is no longer checkered on the pending tree. | 357   // The image is no longer checkered on the pending tree. | 
| 347   image_decode_queue = | 358   image_decode_queue = | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 363   can_clear_decode_policy_tracking = true; | 374   can_clear_decode_policy_tracking = true; | 
| 364   checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); | 375   checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); | 
| 365   image_decode_queue = | 376   image_decode_queue = | 
| 366       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 377       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 
| 367   image_decode_queue = | 378   image_decode_queue = | 
| 368       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 379       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 
| 369   EXPECT_EQ(image_decode_queue.size(), 1U); | 380   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 370 | 381 | 
| 371   // If an image had been decoded and tracker was cleared after it, we should | 382   // If an image had been decoded and tracker was cleared after it, we should | 
| 372   // continue checkering it. | 383   // continue checkering it. | 
| 373   PaintImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 384   DrawImage checkerable_image2 = CreateImage(ImageType::CHECKERABLE); | 
| 374   image_decode_queue = | 385   image_decode_queue = | 
| 375       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 386       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 
| 376   EXPECT_EQ(image_decode_queue.size(), 1U); | 387   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 377   checker_image_tracker_->ScheduleImageDecodeQueue( | 388   checker_image_tracker_->ScheduleImageDecodeQueue( | 
| 378       std::move(image_decode_queue)); | 389       std::move(image_decode_queue)); | 
| 379   base::RunLoop().RunUntilIdle(); | 390   base::RunLoop().RunUntilIdle(); | 
| 380 | 391 | 
| 381   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 392   EXPECT_EQ(image_controller_.num_of_locked_images(), 1); | 
| 382   can_clear_decode_policy_tracking = false; | 393   can_clear_decode_policy_tracking = false; | 
| 383   checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); | 394   checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); | 
| 384   EXPECT_EQ(image_controller_.num_of_locked_images(), 0); | 395   EXPECT_EQ(image_controller_.num_of_locked_images(), 0); | 
| 385   image_decode_queue = | 396   image_decode_queue = | 
| 386       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 397       BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); | 
| 387   EXPECT_EQ(image_decode_queue.size(), 1U); | 398   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 388 } | 399 } | 
| 389 | 400 | 
| 390 TEST_F(CheckerImageTrackerTest, CheckersOnlyStaticCompletedImages) { | 401 TEST_F(CheckerImageTrackerTest, CheckersOnlyStaticCompletedImages) { | 
| 391   SetUpTracker(true); | 402   SetUpTracker(true); | 
| 392 | 403 | 
| 393   PaintImage static_image = CreateImage(ImageType::CHECKERABLE); | 404   DrawImage static_image = CreateImage(ImageType::CHECKERABLE); | 
| 394   PaintImage animated_image = | 405   DrawImage animated_image = | 
| 395       CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::ANIMATED); | 406       CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::ANIMATED); | 
| 396   PaintImage partial_image = | 407   DrawImage partial_image = | 
| 397       CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::STATIC, | 408       CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::STATIC, | 
| 398                   PaintImage::CompletionState::PARTIALLY_DONE); | 409                   PaintImage::CompletionState::PARTIALLY_DONE); | 
| 399   PaintImage video_image = | 410   DrawImage video_image = | 
| 400       CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::VIDEO); | 411       CreateImage(ImageType::CHECKERABLE, PaintImage::AnimationType::VIDEO); | 
| 401   std::vector<PaintImage> paint_images = {static_image, animated_image, | 412   std::vector<DrawImage> draw_images = {static_image, animated_image, | 
| 402                                           partial_image, video_image}; | 413                                         partial_image, video_image}; | 
| 403 | 414 | 
| 404   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 415   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 
| 405       BuildImageDecodeQueue(paint_images, WhichTree::PENDING_TREE); | 416       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
| 406   EXPECT_EQ(image_decode_queue.size(), 1U); | 417   EXPECT_EQ(image_decode_queue.size(), 1U); | 
| 407   EXPECT_EQ(image_decode_queue[0], static_image); | 418   EXPECT_EQ(image_decode_queue[0], static_image.paint_image()); | 
| 408 | 419 | 
| 409   // Change the partial image to complete and try again. It should still not | 420   // Change the partial image to complete and try again. It should sstill not | 
| 410   // be checkered. | 421   // be checkered. | 
| 411   gfx::Size image_size = gfx::Size(partial_image.sk_image()->width(), | 422   gfx::Size image_size = gfx::Size(partial_image.image()->width(), | 
| 412                                    partial_image.sk_image()->height()); | 423                                    partial_image.image()->height()); | 
| 413   PaintImage completed_paint_image = | 424   DrawImage completed_paint_image = | 
| 414       PaintImage(partial_image.stable_id(), CreateDiscardableImage(image_size)); | 425       DrawImage(PaintImage(partial_image.paint_image().stable_id(), | 
|  | 426                            CreateDiscardableImage(image_size)), | 
|  | 427                 SkIRect::MakeWH(image_size.width(), image_size.height()), | 
|  | 428                 kNone_SkFilterQuality, SkMatrix::I(), gfx::ColorSpace()); | 
| 415   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 429   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 416       completed_paint_image, WhichTree::PENDING_TREE)); | 430       completed_paint_image, WhichTree::PENDING_TREE)); | 
| 417 } | 431 } | 
| 418 | 432 | 
| 419 TEST_F(CheckerImageTrackerTest, DontCheckerDisallowedImages) { | 433 TEST_F(CheckerImageTrackerTest, DontCheckerDisallowedImages) { | 
| 420   SetUpTracker(true); | 434   SetUpTracker(true); | 
| 421 | 435 | 
| 422   PaintImage image = CreateImage(ImageType::CHECKERABLE); | 436   DrawImage image = CreateImage(ImageType::CHECKERABLE); | 
| 423   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 437   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 424       image, WhichTree::PENDING_TREE)); | 438       image, WhichTree::PENDING_TREE)); | 
| 425   checker_image_tracker_->DisallowCheckeringForImage(image); | 439   checker_image_tracker_->DisallowCheckeringForImage(image.paint_image()); | 
| 426   // Since the tracker already saw the image, even disallowing it would still | 440   // Since the tracker already saw the image, even disallowing it would still | 
| 427   // ensure that we checker it until it's completed. | 441   // ensure that we checker it until it's completed. | 
| 428   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 442   EXPECT_TRUE(checker_image_tracker_->ShouldCheckerImage( | 
| 429       image, WhichTree::PENDING_TREE)); | 443       image, WhichTree::PENDING_TREE)); | 
| 430 | 444 | 
| 431   // Reset the tracker. | 445   // Reset the tracker. | 
| 432   checker_image_tracker_->ClearTracker(true); | 446   checker_image_tracker_->ClearTracker(true); | 
| 433   // If we haven't seen the image and disallow it first, then it's not | 447   // If we haven't seen the image and disallow it first, then it's not | 
| 434   // checkerable anymore. | 448   // checkerable anymore. | 
| 435   checker_image_tracker_->DisallowCheckeringForImage(image); | 449   checker_image_tracker_->DisallowCheckeringForImage(image.paint_image()); | 
| 436   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 450   EXPECT_FALSE(checker_image_tracker_->ShouldCheckerImage( | 
| 437       image, WhichTree::PENDING_TREE)); | 451       image, WhichTree::PENDING_TREE)); | 
| 438 } | 452 } | 
| 439 | 453 | 
|  | 454 TEST_F(CheckerImageTrackerTest, ChoosesMaxScaleAndQuality) { | 
|  | 455   SetUpTracker(true); | 
|  | 456 | 
|  | 457   DrawImage image = CreateImage(ImageType::CHECKERABLE); | 
|  | 458   DrawImage scaled_image1 = image.ApplyScale(0.5f); | 
|  | 459   DrawImage scaled_image2 = | 
|  | 460       DrawImage(image.paint_image(), image.src_rect(), kHigh_SkFilterQuality, | 
|  | 461                 SkMatrix::MakeScale(1.8f), gfx::ColorSpace()); | 
|  | 462 | 
|  | 463   std::vector<DrawImage> draw_images = {scaled_image1, scaled_image2}; | 
|  | 464   CheckerImageTracker::ImageDecodeQueue image_decode_queue = | 
|  | 465       BuildImageDecodeQueue(draw_images, WhichTree::PENDING_TREE); | 
|  | 466   checker_image_tracker_->ScheduleImageDecodeQueue(image_decode_queue); | 
|  | 467   EXPECT_EQ(image_controller_.decoded_images().size(), 1u); | 
|  | 468   EXPECT_EQ(image_controller_.decoded_images()[0].scale(), | 
|  | 469             SkSize::Make(1.8f, 1.8f)); | 
|  | 470   EXPECT_EQ(image_controller_.decoded_images()[0].filter_quality(), | 
|  | 471             kHigh_SkFilterQuality); | 
|  | 472 } | 
|  | 473 | 
| 440 }  // namespace | 474 }  // namespace | 
| 441 }  // namespace cc | 475 }  // namespace cc | 
| OLD | NEW | 
|---|