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

Unified Diff: cc/tiles/checker_image_tracker.cc

Issue 2668873002: cc: Add checker-imaging support to TileManager. (Closed)
Patch Set: Rebase Created 3 years, 10 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 side-by-side diff with in-line comments
Download patch
Index: cc/tiles/checker_image_tracker.cc
diff --git a/cc/tiles/checker_image_tracker.cc b/cc/tiles/checker_image_tracker.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f934a2a77f2b44d3cfe6e4596a18587802486930
--- /dev/null
+++ b/cc/tiles/checker_image_tracker.cc
@@ -0,0 +1,150 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/tiles/checker_image_tracker.h"
+
+#include "base/bind.h"
+#include "base/trace_event/trace_event.h"
+
+namespace cc {
+namespace {
+// The minimum size of an image that we should consider checkering.
+size_t kMinImageSizeToCheckerBytes = 512 * 1024;
+} // namespace
+
+CheckerImageTracker::CheckerImageTracker(ImageController* image_controller,
+ CheckerImageTrackerClient* client,
+ bool enable_checker_imaging)
+ : image_controller_(image_controller),
+ client_(client),
+ enable_checker_imaging_(enable_checker_imaging),
+ weak_factory_(this) {}
+
+CheckerImageTracker::~CheckerImageTracker() {
+ // Unlock all images pending decode requests.
+ for (auto it : image_id_to_decode_request_id_)
+ image_controller_->UnlockImageDecode(it.second);
+}
+
+void CheckerImageTracker::FilterImagesForCheckeringForTile(
+ std::vector<DrawImage>* images,
+ std::unordered_set<ImageId>* checkered_images,
+ WhichTree tree) {
+ DCHECK(checkered_images->empty());
+
+ for (std::vector<DrawImage>::iterator it = images->begin();
+ it != images->end();) {
+ const sk_sp<const SkImage> image = it->image();
vmpstr 2017/02/10 19:25:42 &
Khushal 2017/02/10 22:09:19 Done.
+ DCHECK(image->isLazyGenerated());
+ if (ShouldCheckerImage(image, tree)) {
+ ScheduleImageDecodeIfNecessary(image);
+ checkered_images->insert(image->uniqueID());
+ it = images->erase(it);
+ } else {
+ ++it;
+ }
+ }
+}
+
+const std::unordered_set<ImageId>&
+CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() {
+ DCHECK(invalidated_images_on_current_sync_tree_.empty())
+ << "Sync tree can not be invalidated more than once";
+
+ invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_);
vmpstr 2017/02/10 19:25:42 I think this should be std::unordered_set<ImageId
Khushal 2017/02/10 22:09:19 But doesn't this unnecessarily create a copy?
+ images_pending_invalidation_.clear();
+ return invalidated_images_on_current_sync_tree_;
+}
+
+void CheckerImageTracker::DidActivateSyncTree() {
+ for (auto image_id : invalidated_images_on_current_sync_tree_) {
+ auto it = image_id_to_decode_request_id_.find(image_id);
+ image_controller_->UnlockImageDecode(it->second);
+ image_id_to_decode_request_id_.erase(it);
+ }
+
+ invalidated_images_on_current_sync_tree_.clear();
+}
+
+void CheckerImageTracker::DidFinishImageDecode(
+ ImageId image_id,
+ ImageController::ImageDecodeRequestId request_id) {
+ TRACE_EVENT_ASYNC_END0("cc", "CheckerImageTracker::DeferImageDecode",
+ image_id);
+
+ DCHECK_NE(pending_image_decodes_.count(image_id), 0U);
+ pending_image_decodes_.erase(image_id);
+
+ images_decoded_once_.insert(image_id);
+ images_pending_invalidation_.insert(image_id);
+ client_->NeedsInvalidationForCheckerImagedTiles();
+}
+
+bool CheckerImageTracker::ShouldCheckerImage(const sk_sp<const SkImage> image,
vmpstr 2017/02/10 19:25:42 &
Khushal 2017/02/10 22:09:19 Done.
+ WhichTree tree) const {
+ TRACE_EVENT1("cc", "CheckerImageTracker::ShouldCheckerImage", "image_id",
+ image->uniqueID());
+
+ if (!enable_checker_imaging_)
+ return false;
+
+ // If the image was invalidated on the current sync tree and the tile is
+ // for the active tree, continue checkering it on the active tree to ensure
+ // the image update is atomic for the frame.
+ if (invalidated_images_on_current_sync_tree_.count(image->uniqueID()) != 0 &&
+ tree == WhichTree::ACTIVE_TREE) {
+ return true;
+ }
+
+ // If a decode request is pending for this image, continue checkering it.
+ if (pending_image_decodes_.find(image->uniqueID()) !=
+ pending_image_decodes_.end()) {
+ return true;
+ }
+
+ // If the image is pending invalidation, continue checkering it. All tiles
+ // for these images will be invalidated on the next pending tree.
+ if (images_pending_invalidation_.find(image->uniqueID()) !=
+ images_pending_invalidation_.end()) {
+ return true;
+ }
+
+ // If the image has been decoded once before, don't checker it again.
+ if (images_decoded_once_.find(image->uniqueID()) !=
+ images_decoded_once_.end()) {
+ return false;
+ }
+
+ base::CheckedNumeric<size_t> checked_size = 4;
+ checked_size *= image->width();
+ checked_size *= image->height();
+ size_t image_size =
+ checked_size.ValueOrDefault(std::numeric_limits<size_t>::max());
+
+ bool should_checker_image = image_size >= kMinImageSizeToCheckerBytes;
vmpstr 2017/02/10 19:25:42 just return image_size >= kMinImageSizeToCheckerBy
Khushal 2017/02/10 22:09:19 Done.
+ return should_checker_image;
+}
+
+void CheckerImageTracker::ScheduleImageDecodeIfNecessary(
+ const sk_sp<const SkImage> image) {
+ ImageId image_id = image->uniqueID();
+
+ // If the image has already been decoded, or a decode request is pending, we
+ // don't need to schedule another decode.
+ if (images_decoded_once_.count(image_id) != 0 ||
+ pending_image_decodes_.count(image_id) != 0)
vmpstr 2017/02/10 19:25:42 braces pls
Khushal 2017/02/10 22:09:19 Done.
+ return;
+
+ TRACE_EVENT_ASYNC_BEGIN0("cc", "CheckerImageTracker::DeferImageDecode",
+ image_id);
+ DCHECK_EQ(image_id_to_decode_request_id_.count(image_id), 0U);
+
+ image_id_to_decode_request_id_[image_id] =
+ image_controller_->QueueImageDecode(
+ image, base::Bind(&CheckerImageTracker::DidFinishImageDecode,
+ weak_factory_.GetWeakPtr(), image_id));
+ pending_image_decodes_.insert(image_id);
+}
+
+} // namespace cc

Powered by Google App Engine
This is Rietveld 408576698