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

Unified Diff: cc/tiles/checker_image_tracker.cc

Issue 2668873002: cc: Add checker-imaging support to TileManager. (Closed)
Patch Set: remove include 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
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..c081132e6ece23c5e9569af2dc37968d9e69e5cb
--- /dev/null
+++ b/cc/tiles/checker_image_tracker.cc
@@ -0,0 +1,152 @@
+// 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;
+
+size_t SafeSizeOfImage(const SkImage* image) {
+ base::CheckedNumeric<size_t> checked_size = 4;
+ checked_size *= image->width();
+ checked_size *= image->height();
+ return checked_size.ValueOrDefault(std::numeric_limits<size_t>::max());
+}
+
+} // 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,
+ ImageIdFlatSet* checkered_images,
+ WhichTree tree) {
+ DCHECK(checkered_images->empty());
+
+ auto images_to_checker = std::remove_if(
+ images->begin(), images->end(),
+ [this, tree, &checkered_images](const DrawImage& draw_image) {
+ const sk_sp<const SkImage>& image = draw_image.image();
+ DCHECK(image->isLazyGenerated());
+ if (ShouldCheckerImage(image, tree)) {
+ ScheduleImageDecodeIfNecessary(image);
+ checkered_images->insert(image->uniqueID());
+ return true;
+ }
+ return false;
+ });
+ images->erase(images_to_checker, images->end());
+}
+
+const ImageIdFlatSet& CheckerImageTracker::TakeImagesToInvalidateOnSyncTree() {
+ DCHECK_EQ(invalidated_images_on_current_sync_tree_.size(), 0u)
+ << "Sync tree can not be invalidated more than once";
+
+ invalidated_images_on_current_sync_tree_.swap(images_pending_invalidation_);
+ 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,
+ 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;
+ }
+
+ return SafeSizeOfImage(image.get()) >= kMinImageSizeToCheckerBytes;
+}
+
+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) {
+ 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
« 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