| 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 |