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

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

Issue 2726343004: cc: Optimize decode scheduling for checker-images. (Closed)
Patch Set: .. Created 3 years, 9 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
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/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 10
(...skipping 18 matching lines...) Expand all
29 client_(client), 29 client_(client),
30 enable_checker_imaging_(enable_checker_imaging), 30 enable_checker_imaging_(enable_checker_imaging),
31 weak_factory_(this) {} 31 weak_factory_(this) {}
32 32
33 CheckerImageTracker::~CheckerImageTracker() { 33 CheckerImageTracker::~CheckerImageTracker() {
34 // Unlock all images pending decode requests. 34 // Unlock all images pending decode requests.
35 for (auto it : image_id_to_decode_request_id_) 35 for (auto it : image_id_to_decode_request_id_)
36 image_controller_->UnlockImageDecode(it.second); 36 image_controller_->UnlockImageDecode(it.second);
37 } 37 }
38 38
39 void CheckerImageTracker::FilterImagesForCheckeringForTile( 39 void CheckerImageTracker::ScheduleImageDecodeQueue(
40 std::vector<DrawImage>* images, 40 ImageDecodeQueue image_decode_queue) {
41 ImageIdFlatSet* checkered_images, 41 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
42 WhichTree tree) { 42 "CheckerImageTracker::ScheduleImageDecodeQueue");
43 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 43 image_decode_queue_ = std::move(image_decode_queue);
44 "CheckerImageTracker::FilterImagesForCheckeringForTile", "tree", 44 next_image_index_to_decode_ = 0;
45 tree); 45 ScheduleNextImageDecode();
46 DCHECK(checkered_images->empty());
47
48 base::EraseIf(*images,
49 [this, tree, &checkered_images](const DrawImage& draw_image) {
50 const sk_sp<const SkImage>& image = draw_image.image();
51 DCHECK(image->isLazyGenerated());
52 if (ShouldCheckerImage(image, tree)) {
53 ScheduleImageDecodeIfNecessary(image);
54 checkered_images->insert(image->uniqueID());
55 return true;
56 }
57 return false;
58 });
59 } 46 }
60 47
61 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { 48 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() {
62 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 49 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
63 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); 50 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree");
64 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) 51 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u)
65 << "Sync tree can not be invalidated more than once"; 52 << "Sync tree can not be invalidated more than once";
66 53
67 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); 54 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_);
68 images_pending_invalidation_.clear(); 55 images_pending_invalidation_.clear();
(...skipping 14 matching lines...) Expand all
83 70
84 void CheckerImageTracker::DidFinishImageDecode( 71 void CheckerImageTracker::DidFinishImageDecode(
85 ImageId image_id, 72 ImageId image_id,
86 ImageController::ImageDecodeRequestId request_id, 73 ImageController::ImageDecodeRequestId request_id,
87 ImageController::ImageDecodeResult result) { 74 ImageController::ImageDecodeResult result) {
88 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 75 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
89 "CheckerImageTracker::DidFinishImageDecode"); 76 "CheckerImageTracker::DidFinishImageDecode");
90 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", 77 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode",
91 image_id); 78 image_id);
92 79
93 DCHECK_NE(result, ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED); 80 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result);
94 DCHECK_NE(pending_image_decodes_.count(image_id), 0u); 81 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id);
95 pending_image_decodes_.erase(image_id); 82 outstanding_image_decode_ = nullptr;
96
97 images_decoded_once_.insert(image_id); 83 images_decoded_once_.insert(image_id);
98 images_pending_invalidation_.insert(image_id); 84 images_pending_invalidation_.insert(image_id);
85
86 ScheduleNextImageDecode();
99 client_->NeedsInvalidationForCheckerImagedTiles(); 87 client_->NeedsInvalidationForCheckerImagedTiles();
100 } 88 }
101 89
102 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, 90 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image,
103 WhichTree tree) const { 91 WhichTree tree) const {
104 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", 92 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id",
105 image->uniqueID()); 93 image->uniqueID());
106 94
107 if (!enable_checker_imaging_) 95 if (!enable_checker_imaging_)
108 return false; 96 return false;
109 97
110 // If the image was invalidated on the current sync tree and the tile is 98 // If the image was invalidated on the current sync tree and the tile is
111 // for the active tree, continue checkering it on the active tree to ensure 99 // for the active tree, continue checkering it on the active tree to ensure
112 // the image update is atomic for the frame. 100 // the image update is atomic for the frame.
113 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 && 101 if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 &&
114 tree == WhichTree::ACTIVE_TREE) { 102 tree == WhichTree::ACTIVE_TREE) {
115 return true; 103 return true;
116 } 104 }
117 105
118 // If a decode request is pending for this image, continue checkering it.
vmpstr 2017/03/29 19:11:45 Why is this check gone?
Khushal 2017/03/29 22:10:20 This shouldn't be necessary I think. It was making
119 if (pending_image_decodes_.find(image->uniqueID()) !=
120 pending_image_decodes_.end()) {
121 return true;
122 }
123
124 // If the image is pending invalidation, continue checkering it. All tiles 106 // If the image is pending invalidation, continue checkering it. All tiles
125 // for these images will be invalidated on the next pending tree. 107 // for these images will be invalidated on the next pending tree.
126 if (images_pending_invalidation_.find(image->uniqueID()) != 108 if (images_pending_invalidation_.find(image->uniqueID()) !=
127 images_pending_invalidation_.end()) { 109 images_pending_invalidation_.end()) {
128 return true; 110 return true;
129 } 111 }
130 112
131 // If the image has been decoded once before, don't checker it again. 113 // If the image has been decoded once before, don't checker it again.
132 if (images_decoded_once_.find(image->uniqueID()) != 114 if (images_decoded_once_.find(image->uniqueID()) !=
133 images_decoded_once_.end()) { 115 images_decoded_once_.end()) {
134 return false; 116 return false;
135 } 117 }
136 118
137 return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes; 119 return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes;
138 } 120 }
139 121
140 void CheckerImageTracker::ScheduleImageDecodeIfNecessary( 122 void CheckerImageTracker::ScheduleNextImageDecode() {
141 const sk_sp<const SkImage>& image) {
142 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 123 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
143 "CheckerImageTracker::ScheduleImageDecodeIfNecessary"); 124 "CheckerImageTracker::ScheduleNextImageDecode");
144 ImageId image_id = image->uniqueID();
145 125
146 // If the image has already been decoded, or a decode request is pending, we 126 if (image_decode_queue_.empty())
147 // don't need to schedule another decode.
148 if (images_decoded_once_.count(image_id) != 0 ||
149 pending_image_decodes_.count(image_id) != 0) {
150 return; 127 return;
128
129 // We can have only one outsanding decode pending completion with the decode
130 // service. We'll come back here when it is completed.
131 if (outstanding_image_decode_)
132 return;
133
134 DCHECK_GE(next_image_index_to_decode_, 0u);
135 DCHECK_LT(next_image_index_to_decode_, image_decode_queue_.size());
136 while (next_image_index_to_decode_ != image_decode_queue_.size()) {
vmpstr 2017/03/29 19:11:45 It's not clear to me why you're using an index her
Khushal 2017/03/29 22:10:20 Erasing from the beginning of the vector is going
Khushal 2017/03/31 04:31:00 Discussed offline. Changed to erase instead.
137 outstanding_image_decode_ =
138 std::move(image_decode_queue_[next_image_index_to_decode_++]);
139
140 // Schedule decode for this image if it has not already been decoded,
141 // otherwise try the next image in the queue.
142 ImageId image_id = outstanding_image_decode_->uniqueID();
143 if (images_decoded_once_.count(image_id) == 0)
144 break;
145 outstanding_image_decode_ = nullptr;
151 } 146 }
152 147
148 // If we have reached the end of the queue, reset to default state.
149 if (next_image_index_to_decode_ == image_decode_queue_.size()) {
150 next_image_index_to_decode_ = 0;
151 image_decode_queue_.clear();
152 }
153
154 if (!outstanding_image_decode_)
155 return;
156
157 ImageId image_id = outstanding_image_decode_->uniqueID();
158 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u);
153 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", 159 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode",
154 image_id); 160 image_id);
155 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0U);
156
157 image_id_to_decode_request_id_[image_id] = 161 image_id_to_decode_request_id_[image_id] =
158 image_controller_->QueueImageDecode( 162 image_controller_->QueueImageDecode(
159 image, base::Bind(&CheckerImageTracker::DidFinishImageDecode, 163 outstanding_image_decode_,
160 weak_factory_.GetWeakPtr(), image_id)); 164 base::Bind(&CheckerImageTracker::DidFinishImageDecode,
161 pending_image_decodes_.insert(image_id); 165 weak_factory_.GetWeakPtr(), image_id));
162 } 166 }
163 167
164 } // namespace cc 168 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698