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

Side by Side Diff: cc/tiles/checker_image_tracker.cc

Issue 2869513002: cc: Clear checker-image tracking on navigation and visibility changes. (Closed)
Patch Set: missed pending invalidations Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/tiles/checker_image_tracker.h ('k') | cc/tiles/checker_image_tracker_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/stl_util.h" 9 #include "base/stl_util.h"
9 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
10 11
11 namespace cc { 12 namespace cc {
12 namespace { 13 namespace {
13 // The minimum size of an image that we should consider checkering. 14 // The minimum size of an image that we should consider checkering.
14 size_t kMinImageSizeToCheckerBytes = 512 * 1024; 15 size_t kMinImageSizeToCheckerBytes = 512 * 1024;
15 16
16 size_t SafeSizeOfImage(const SkImage* image) { 17 size_t SafeSizeOfImage(const SkImage* image) {
17 base::CheckedNumeric<size_t> checked_size = 4; 18 base::CheckedNumeric<size_t> checked_size = 4;
18 checked_size *= image->width(); 19 checked_size *= image->width();
19 checked_size *= image->height(); 20 checked_size *= image->height();
20 return checked_size.ValueOrDefault(std::numeric_limits<size_t>::max()); 21 return checked_size.ValueOrDefault(std::numeric_limits<size_t>::max());
21 } 22 }
22 23
23 } // namespace 24 } // namespace
24 25
25 CheckerImageTracker::CheckerImageTracker(ImageController* image_controller, 26 CheckerImageTracker::CheckerImageTracker(ImageController* image_controller,
26 CheckerImageTrackerClient* client, 27 CheckerImageTrackerClient* client,
27 bool enable_checker_imaging) 28 bool enable_checker_imaging)
28 : image_controller_(image_controller), 29 : image_controller_(image_controller),
29 client_(client), 30 client_(client),
30 enable_checker_imaging_(enable_checker_imaging), 31 enable_checker_imaging_(enable_checker_imaging),
31 weak_factory_(this) {} 32 weak_factory_(this) {}
32 33
33 CheckerImageTracker::~CheckerImageTracker() { 34 CheckerImageTracker::~CheckerImageTracker() = default;
34 // Unlock all images pending decode requests.
35 for (auto it : image_id_to_decode_request_id_)
36 image_controller_->UnlockImageDecode(it.second);
37 }
38 35
39 void CheckerImageTracker::ScheduleImageDecodeQueue( 36 void CheckerImageTracker::ScheduleImageDecodeQueue(
40 ImageDecodeQueue image_decode_queue) { 37 ImageDecodeQueue image_decode_queue) {
41 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 38 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
42 "CheckerImageTracker::ScheduleImageDecodeQueue"); 39 "CheckerImageTracker::ScheduleImageDecodeQueue");
43 // Only checker-imaged (async updated) images are decoded using the image 40 // Only checker-imaged (async updated) images are decoded using the image
44 // decode service. If |enable_checker_imaging_| is false, no image should 41 // decode service. If |enable_checker_imaging_| is false, no image should
45 // be checkered. 42 // be checkered.
46 DCHECK(image_decode_queue.empty() || enable_checker_imaging_); 43 DCHECK(image_decode_queue.empty() || enable_checker_imaging_);
47 44
48 image_decode_queue_ = std::move(image_decode_queue); 45 image_decode_queue_ = std::move(image_decode_queue);
49 ScheduleNextImageDecode(); 46 ScheduleNextImageDecode();
50 } 47 }
51 48
52 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { 49 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() {
53 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 50 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
54 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); 51 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree");
55 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) 52 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u)
56 << "Sync tree can not be invalidated more than once"; 53 << "Sync tree can not be invalidated more than once";
57 54
58 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); 55 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_);
59 images_pending_invalidation_.clear(); 56 images_pending_invalidation_.clear();
60 return invalidated_images_on_current_sync_tree_; 57 return invalidated_images_on_current_sync_tree_;
61 } 58 }
62 59
63 void CheckerImageTracker::DidActivateSyncTree() { 60 void CheckerImageTracker::DidActivateSyncTree() {
64 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 61 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
65 "CheckerImageTracker::DidActivateSyncTree"); 62 "CheckerImageTracker::DidActivateSyncTree");
66 for (auto image_id : invalidated_images_on_current_sync_tree_) { 63 for (auto image_id : invalidated_images_on_current_sync_tree_)
67 auto it = image_id_to_decode_request_id_.find(image_id); 64 image_id_to_decode_.erase(image_id);
68 image_controller_->UnlockImageDecode(it->second); 65 invalidated_images_on_current_sync_tree_.clear();
69 image_id_to_decode_request_id_.erase(it); 66 }
67
68 void CheckerImageTracker::ClearTracker(bool can_clear_decode_policy_tracking) {
69 // Unlock all images and tracking for images pending invalidation. The
70 // |images_invalidated_on_current_sync_tree_| will be cleared when the sync
71 // tree is activated.
72 //
73 // Note that we assume that any images with DecodePolicy::ASYNC, which may be
74 // checkered, are safe to stop tracking here and will either be re-checkered
75 // and invalidated when the decode completes or be invalidated externally.
76 // This is because the policy decision for checkering an image is based on
77 // inputs received from a PaintImage in the DisplayItemList. The policy chosen
78 // for a PaintImage should remain unchanged.
79 // If the external inputs for deciding the decode policy for an image change,
80 // they should be accompanied with an invalidation during paint.
81 image_id_to_decode_.clear();
82
83 if (can_clear_decode_policy_tracking) {
84 image_async_decode_state_.clear();
85 } else {
86 // If we can't clear the decode policy, we need to make sure we still
87 // re-decode and checker images that were pending invalidation.
88 for (auto image_id : images_pending_invalidation_) {
Khushal 2017/05/13 03:24:43 Realized I was missing this case. I've added a tes
89 auto it = image_async_decode_state_.find(image_id);
90
91 DCHECK(it != image_async_decode_state_.end());
92 DCHECK_EQ(it->second, DecodePolicy::SYNC_DECODED_ONCE);
93
94 it->second = DecodePolicy::ASYNC;
95 }
70 } 96 }
71 97 images_pending_invalidation_.clear();
72 invalidated_images_on_current_sync_tree_.clear();
73 } 98 }
74 99
75 void CheckerImageTracker::DidFinishImageDecode( 100 void CheckerImageTracker::DidFinishImageDecode(
76 ImageId image_id, 101 ImageId image_id,
77 ImageController::ImageDecodeRequestId request_id, 102 ImageController::ImageDecodeRequestId request_id,
78 ImageController::ImageDecodeResult result) { 103 ImageController::ImageDecodeResult result) {
79 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 104 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
80 "CheckerImageTracker::DidFinishImageDecode"); 105 "CheckerImageTracker::DidFinishImageDecode");
81 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", 106 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode",
82 image_id); 107 image_id);
83 108
84 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result); 109 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result);
85 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id); 110 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id);
111 outstanding_image_decode_ = nullptr;
86 112
87 outstanding_image_decode_ = nullptr; 113 // The async decode state may have been cleared if the tracker was cleared
88 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE; 114 // before this decode could be finished.
115 auto it = image_async_decode_state_.find(image_id);
116 if (it == image_async_decode_state_.end()) {
117 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u);
118 return;
119 }
120
121 it->second = DecodePolicy::SYNC_DECODED_ONCE;
89 images_pending_invalidation_.insert(image_id); 122 images_pending_invalidation_.insert(image_id);
90
91 ScheduleNextImageDecode(); 123 ScheduleNextImageDecode();
92 client_->NeedsInvalidationForCheckerImagedTiles(); 124 client_->NeedsInvalidationForCheckerImagedTiles();
93 } 125 }
94 126
95 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, 127 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image,
96 WhichTree tree) { 128 WhichTree tree) {
97 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", 129 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id",
98 image->uniqueID()); 130 image->uniqueID());
99 131
100 if (!enable_checker_imaging_) 132 if (!enable_checker_imaging_)
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 } 189 }
158 190
159 // We either found an image to decode or we reached the end of the queue. If 191 // We either found an image to decode or we reached the end of the queue. If
160 // we couldn't find an image, we're done. 192 // we couldn't find an image, we're done.
161 if (!outstanding_image_decode_) { 193 if (!outstanding_image_decode_) {
162 DCHECK(image_decode_queue_.empty()); 194 DCHECK(image_decode_queue_.empty());
163 return; 195 return;
164 } 196 }
165 197
166 ImageId image_id = outstanding_image_decode_->uniqueID(); 198 ImageId image_id = outstanding_image_decode_->uniqueID();
167 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u); 199 DCHECK_EQ(image_id_to_decode_.count(image_id), 0u);
168 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", 200 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode",
169 image_id); 201 image_id);
170 image_id_to_decode_request_id_[image_id] = 202 ImageController::ImageDecodeRequestId request_id =
171 image_controller_->QueueImageDecode( 203 image_controller_->QueueImageDecode(
172 outstanding_image_decode_, 204 outstanding_image_decode_,
173 base::Bind(&CheckerImageTracker::DidFinishImageDecode, 205 base::Bind(&CheckerImageTracker::DidFinishImageDecode,
174 weak_factory_.GetWeakPtr(), image_id)); 206 weak_factory_.GetWeakPtr(), image_id));
207
208 image_id_to_decode_.emplace(image_id, base::MakeUnique<ScopedDecodeHolder>(
209 image_controller_, request_id));
175 } 210 }
176 211
177 } // namespace cc 212 } // namespace cc
OLDNEW
« no previous file with comments | « cc/tiles/checker_image_tracker.h ('k') | cc/tiles/checker_image_tracker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698