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

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

Issue 2726343004: cc: Optimize decode scheduling for checker-images. (Closed)
Patch Set: tested Created 3 years, 8 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 DCHECK(image_decode_queue.empty() || enable_checker_imaging_);
vmpstr 2017/04/18 00:20:00 Can you comment to explain the dcheck a bit.
Khushal 2017/04/19 06:16:41 Done.
44 "CheckerImageTracker::FilterImagesForCheckeringForTile", "tree",
45 tree);
46 DCHECK(checkered_images->empty());
47 44
48 base::EraseIf(*images, 45 image_decode_queue_ = std::move(image_decode_queue);
49 [this, tree, &checkered_images](const DrawImage& draw_image) { 46 ScheduleNextImageDecode();
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 } 47 }
60 48
61 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() { 49 const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() {
62 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 50 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
63 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree"); 51 "CheckerImageTracker::TakeImagesToInvalidateOnSyncTree");
64 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u) 52 DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u)
65 << "Sync tree can not be invalidated more than once"; 53 << "Sync tree can not be invalidated more than once";
66 54
67 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_); 55 invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_);
68 images_pending_invalidation_.clear(); 56 images_pending_invalidation_.clear();
(...skipping 14 matching lines...) Expand all
83 71
84 void CheckerImageTracker::DidFinishImageDecode( 72 void CheckerImageTracker::DidFinishImageDecode(
85 ImageId image_id, 73 ImageId image_id,
86 ImageController::ImageDecodeRequestId request_id, 74 ImageController::ImageDecodeRequestId request_id,
87 ImageController::ImageDecodeResult result) { 75 ImageController::ImageDecodeResult result) {
88 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 76 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
89 "CheckerImageTracker::DidFinishImageDecode"); 77 "CheckerImageTracker::DidFinishImageDecode");
90 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode", 78 TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode",
91 image_id); 79 image_id);
92 80
93 DCHECK_NE(result, ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED); 81 DCHECK_NE(ImageController::ImageDecodeResult::DECODE_NOT_REQUIRED, result);
94 DCHECK_NE(pending_image_decodes_.count(image_id), 0u); 82 DCHECK_EQ(outstanding_image_decode_->uniqueID(), image_id);
95 DCHECK_NE(image_async_decode_state_.count(image_id), 0u);
96 83
97 pending_image_decodes_.erase(image_id); 84 outstanding_image_decode_ = nullptr;
98
99 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE; 85 image_async_decode_state_[image_id] = DecodePolicy::SYNC_DECODED_ONCE;
100 images_pending_invalidation_.insert(image_id); 86 images_pending_invalidation_.insert(image_id);
87
88 ScheduleNextImageDecode();
101 client_->NeedsInvalidationForCheckerImagedTiles(); 89 client_->NeedsInvalidationForCheckerImagedTiles();
102 } 90 }
103 91
104 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image, 92 bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage>& image,
105 WhichTree tree) { 93 WhichTree tree) {
106 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id", 94 TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id",
107 image->uniqueID()); 95 image->uniqueID());
108 96
109 if (!enable_checker_imaging_) 97 if (!enable_checker_imaging_)
110 return false; 98 return false;
(...skipping 19 matching lines...) Expand all
130 auto it = insert_result.first; 118 auto it = insert_result.first;
131 if (insert_result.second) { 119 if (insert_result.second) {
132 it->second = SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes 120 it->second = SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes
133 ? DecodePolicy::ASYNC 121 ? DecodePolicy::ASYNC
134 : DecodePolicy::SYNC_PERMANENT; 122 : DecodePolicy::SYNC_PERMANENT;
135 } 123 }
136 124
137 return it->second == DecodePolicy::ASYNC; 125 return it->second == DecodePolicy::ASYNC;
138 } 126 }
139 127
140 void CheckerImageTracker::ScheduleImageDecodeIfNecessary( 128 void CheckerImageTracker::ScheduleNextImageDecode() {
141 const sk_sp<const SkImage>& image) {
142 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), 129 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
143 "CheckerImageTracker::ScheduleImageDecodeIfNecessary"); 130 "CheckerImageTracker::ScheduleNextImageDecode");
144 ImageId image_id = image->uniqueID(); 131 // We can have only one outsanding decode pending completion with the decode
145 132 // service. We'll come back here when it is completed.
146 // Once an image has been decoded, they can still be present in the decode 133 if (outstanding_image_decode_)
147 // queue (duplicate entries), or while an image is still being skipped on the
148 // active tree. Check if the image is still ASYNC to see if a decode is
149 // needed.
150 auto it = image_async_decode_state_.find(image_id);
151 DCHECK(it != image_async_decode_state_.end());
152 if (it->second != DecodePolicy::ASYNC)
153 return; 134 return;
154 135
155 // If a decode request is pending, we don't need to schedule another decode. 136 while (!image_decode_queue_.empty()) {
156 if (pending_image_decodes_.count(image_id) != 0) { 137 auto candidate = image_decode_queue_.front();
vmpstr 2017/04/18 00:20:00 std::move
Khushal 2017/04/19 06:16:41 Done.
138 image_decode_queue_.erase(image_decode_queue_.begin());
139
140 // Once an image has been decoded, they can still be present in the decode
vmpstr 2017/04/18 00:20:00 s/they/it/
Khushal 2017/04/19 06:16:41 Done.
141 // queue (duplicate entries), or while an image is still being skipped on
142 // the active tree. Check if the image is still ASYNC to see if a decode is
143 // needed.
144 ImageId image_id = candidate->uniqueID();
145 auto it = image_async_decode_state_.find(image_id);
146 DCHECK(it != image_async_decode_state_.end());
147 if (it->second != DecodePolicy::ASYNC)
148 continue;
149
150 outstanding_image_decode_ = std::move(candidate);
151 break;
152 }
153
154 // We either found an image to decode or we reached the end of the queue. If
155 // we couldn't find an image, we're done.
156 if (!outstanding_image_decode_) {
157 DCHECK(image_decode_queue_.empty());
157 return; 158 return;
158 } 159 }
159 160
161 ImageId image_id = outstanding_image_decode_->uniqueID();
162 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0u);
160 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode", 163 TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode",
161 image_id); 164 image_id);
162 DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0U);
163
164 image_id_to_decode_request_id_[image_id] = 165 image_id_to_decode_request_id_[image_id] =
165 image_controller_->QueueImageDecode( 166 image_controller_->QueueImageDecode(
166 image, base::Bind(&CheckerImageTracker::DidFinishImageDecode, 167 outstanding_image_decode_,
167 weak_factory_.GetWeakPtr(), image_id)); 168 base::Bind(&CheckerImageTracker::DidFinishImageDecode,
168 pending_image_decodes_.insert(image_id); 169 weak_factory_.GetWeakPtr(), image_id));
169 } 170 }
170 171
171 } // namespace cc 172 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698