Setup a experiment to enable background tracing.
[chromium-blink-merge.git] / cc / resources / resource_update_controller.cc
blob2dbc0c74ac3ac0e689932ab6210c807b2f1f0035
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/resources/resource_update_controller.h"
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/single_thread_task_runner.h"
10 #include "cc/resources/prioritized_resource.h"
11 #include "cc/resources/resource_provider.h"
13 namespace {
15 // Number of partial updates we allow.
16 const size_t kPartialTextureUpdatesMax = 12;
18 // Measured in seconds.
19 const double kUploaderBusyTickRate = 0.001;
21 // Number of blocking update intervals to allow.
22 const size_t kMaxBlockingUpdateIntervals = 4;
24 } // namespace
26 namespace cc {
28 size_t ResourceUpdateController::MaxPartialTextureUpdates() {
29 return kPartialTextureUpdatesMax;
32 size_t ResourceUpdateController::MaxFullUpdatesPerTick(
33 ResourceProvider* resource_provider) {
34 return resource_provider->EstimatedUploadsPerTick();
37 ResourceUpdateController::ResourceUpdateController(
38 ResourceUpdateControllerClient* client,
39 base::SingleThreadTaskRunner* task_runner,
40 scoped_ptr<ResourceUpdateQueue> queue,
41 ResourceProvider* resource_provider)
42 : client_(client),
43 queue_(queue.Pass()),
44 resource_provider_(resource_provider),
45 texture_updates_per_tick_(MaxFullUpdatesPerTick(resource_provider)),
46 first_update_attempt_(true),
47 task_runner_(task_runner),
48 task_posted_(false),
49 ready_to_finalize_(false),
50 weak_factory_(this) {}
52 ResourceUpdateController::~ResourceUpdateController() {}
54 void ResourceUpdateController::PerformMoreUpdates(
55 base::TimeTicks time_limit) {
56 time_limit_ = time_limit;
58 // Update already in progress or we are already done.
59 if (task_posted_ || ready_to_finalize_)
60 return;
62 // Call UpdateMoreTexturesNow() directly unless it's the first update
63 // attempt. This ensures that we empty the update queue in a finite
64 // amount of time.
65 if (!first_update_attempt_)
66 UpdateMoreTexturesNow();
68 // Post a 0-delay task when no updates were left. When it runs,
69 // ReadyToFinalizeTextureUpdates() will be called.
70 if (!UpdateMoreTexturesIfEnoughTimeRemaining()) {
71 task_posted_ = true;
72 task_runner_->PostTask(
73 FROM_HERE,
74 base::Bind(&ResourceUpdateController::OnTimerFired,
75 weak_factory_.GetWeakPtr()));
78 first_update_attempt_ = false;
81 void ResourceUpdateController::DiscardUploadsToEvictedResources() {
82 queue_->ClearUploadsToEvictedResources();
85 void ResourceUpdateController::UpdateTexture(ResourceUpdate update) {
86 update.bitmap->lockPixels();
87 update.texture->SetPixels(
88 resource_provider_,
89 static_cast<const uint8_t*>(update.bitmap->getPixels()),
90 update.content_rect,
91 update.source_rect,
92 update.dest_offset);
93 update.bitmap->unlockPixels();
96 void ResourceUpdateController::Finalize() {
97 while (queue_->FullUploadSize())
98 UpdateTexture(queue_->TakeFirstFullUpload());
100 while (queue_->PartialUploadSize())
101 UpdateTexture(queue_->TakeFirstPartialUpload());
103 resource_provider_->FlushUploads();
106 void ResourceUpdateController::OnTimerFired() {
107 task_posted_ = false;
108 if (!UpdateMoreTexturesIfEnoughTimeRemaining()) {
109 ready_to_finalize_ = true;
110 client_->ReadyToFinalizeTextureUpdates();
114 base::TimeTicks ResourceUpdateController::UpdateMoreTexturesCompletionTime() {
115 return resource_provider_->EstimatedUploadCompletionTime(
116 texture_updates_per_tick_);
119 size_t ResourceUpdateController::UpdateMoreTexturesSize() const {
120 return texture_updates_per_tick_;
123 size_t ResourceUpdateController::MaxBlockingUpdates() const {
124 return UpdateMoreTexturesSize() * kMaxBlockingUpdateIntervals;
127 bool ResourceUpdateController::UpdateMoreTexturesIfEnoughTimeRemaining() {
128 while (resource_provider_->NumBlockingUploads() < MaxBlockingUpdates()) {
129 if (!queue_->FullUploadSize())
130 return false;
132 if (!time_limit_.is_null()) {
133 base::TimeTicks completion_time = UpdateMoreTexturesCompletionTime();
134 if (completion_time > time_limit_)
135 return true;
138 UpdateMoreTexturesNow();
141 task_posted_ = true;
142 task_runner_->PostDelayedTask(
143 FROM_HERE,
144 base::Bind(&ResourceUpdateController::OnTimerFired,
145 weak_factory_.GetWeakPtr()),
146 base::TimeDelta::FromMilliseconds(kUploaderBusyTickRate * 1000));
147 return true;
150 void ResourceUpdateController::UpdateMoreTexturesNow() {
151 size_t uploads = std::min(
152 queue_->FullUploadSize(), UpdateMoreTexturesSize());
154 if (!uploads)
155 return;
157 while (queue_->FullUploadSize() && uploads--)
158 UpdateTexture(queue_->TakeFirstFullUpload());
160 resource_provider_->FlushUploads();
163 } // namespace cc