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

Side by Side Diff: cc/resource_update_controller.cc

Issue 12471007: Part 8 of cc/ directory shuffles: resources (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 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 | Annotate | Revision Log
« no previous file with comments | « cc/resource_update_controller.h ('k') | cc/resource_update_controller_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "cc/resource_update_controller.h"
6
7 #include <limits>
8
9 #include "base/debug/trace_event.h"
10 #include "cc/base/thread.h"
11 #include "cc/output/context_provider.h"
12 #include "cc/output/texture_copier.h"
13 #include "cc/prioritized_resource.h"
14 #include "cc/resource_provider.h"
15 #include "skia/ext/refptr.h"
16 #include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3 D.h"
17 #include "third_party/khronos/GLES2/gl2.h"
18 #include "third_party/skia/include/gpu/SkGpuDevice.h"
19
20 using WebKit::WebGraphicsContext3D;
21
22 namespace {
23
24 // Number of partial updates we allow.
25 const size_t kPartialTextureUpdatesMax = 12;
26
27 // Measured in seconds.
28 const double kTextureUpdateTickRate = 0.004;
29
30 // Measured in seconds.
31 const double kUploaderBusyTickRate = 0.001;
32
33 // Number of blocking update intervals to allow.
34 const size_t kMaxBlockingUpdateIntervals = 4;
35
36 skia::RefPtr<SkCanvas> CreateAcceleratedCanvas(
37 GrContext* gr_context, gfx::Size canvasSize, unsigned textureId) {
38 GrBackendTextureDesc texture_desc;
39 texture_desc.fFlags = kRenderTarget_GrBackendTextureFlag;
40 texture_desc.fWidth = canvasSize.width();
41 texture_desc.fHeight = canvasSize.height();
42 texture_desc.fConfig = kSkia8888_GrPixelConfig;
43 texture_desc.fTextureHandle = textureId;
44 skia::RefPtr<GrTexture> target =
45 skia::AdoptRef(gr_context->wrapBackendTexture(texture_desc));
46 skia::RefPtr<SkDevice> device =
47 skia::AdoptRef(new SkGpuDevice(gr_context, target.get()));
48 return skia::AdoptRef(new SkCanvas(device.get()));
49 }
50
51 } // namespace
52
53 namespace cc {
54
55 size_t ResourceUpdateController::MaxPartialTextureUpdates() {
56 return kPartialTextureUpdatesMax;
57 }
58
59 size_t ResourceUpdateController::MaxFullUpdatesPerTick(
60 ResourceProvider* resource_provider) {
61 double textures_per_second = resource_provider->EstimatedUploadsPerSecond();
62 size_t textures_per_tick =
63 floor(kTextureUpdateTickRate * textures_per_second);
64 return textures_per_tick ? textures_per_tick : 1;
65 }
66
67 ResourceUpdateController::ResourceUpdateController(
68 ResourceUpdateControllerClient* client,
69 Thread* thread,
70 scoped_ptr<ResourceUpdateQueue> queue,
71 ResourceProvider* resource_provider)
72 : client_(client),
73 queue_(queue.Pass()),
74 resource_provider_(resource_provider),
75 texture_updates_per_tick_(MaxFullUpdatesPerTick(resource_provider)),
76 first_update_attempt_(true),
77 thread_(thread),
78 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
79 task_posted_(false) {}
80
81 ResourceUpdateController::~ResourceUpdateController() {}
82
83 void ResourceUpdateController::PerformMoreUpdates(
84 base::TimeTicks timeLimit) {
85 time_limit_ = timeLimit;
86
87 // Update already in progress.
88 if (task_posted_)
89 return;
90
91 // Call UpdateMoreTexturesNow() directly unless it's the first update
92 // attempt. This ensures that we empty the update queue in a finite
93 // amount of time.
94 if (!first_update_attempt_)
95 UpdateMoreTexturesNow();
96
97 // Post a 0-delay task when no updates were left. When it runs,
98 // ReadyToFinalizeTextureUpdates() will be called.
99 if (!UpdateMoreTexturesIfEnoughTimeRemaining()) {
100 task_posted_ = true;
101 thread_->PostTask(
102 base::Bind(&ResourceUpdateController::OnTimerFired,
103 weak_factory_.GetWeakPtr()));
104 }
105
106 first_update_attempt_ = false;
107 }
108
109 void ResourceUpdateController::DiscardUploadsToEvictedResources() {
110 queue_->clearUploadsToEvictedResources();
111 }
112
113 void ResourceUpdateController::UpdateTexture(ResourceUpdate update) {
114 if (update.picture) {
115 PrioritizedResource* texture = update.texture;
116 gfx::Rect picture_rect = update.content_rect;
117 gfx::Rect source_rect = update.source_rect;
118 gfx::Vector2d dest_offset = update.dest_offset;
119
120 texture->acquireBackingTexture(resource_provider_);
121 DCHECK(texture->haveBackingTexture());
122
123 DCHECK(resource_provider_->GetResourceType(texture->resourceId()) ==
124 ResourceProvider::GLTexture);
125
126 cc::ContextProvider* offscreen_contexts =
127 resource_provider_->offscreen_context_provider();
128
129 ResourceProvider::ScopedWriteLockGL lock(
130 resource_provider_, texture->resourceId());
131
132 // Flush the compositor context to ensure that textures there are available
133 // in the shared context. Do this after locking/creating the compositor
134 // texture.
135 resource_provider_->Flush();
136
137 // Make sure skia uses the correct GL context.
138 offscreen_contexts->Context3d()->makeContextCurrent();
139
140 // Create an accelerated canvas to draw on.
141 skia::RefPtr<SkCanvas> canvas = CreateAcceleratedCanvas(
142 offscreen_contexts->GrContext(), texture->size(), lock.texture_id());
143
144 // The compositor expects the textures to be upside-down so it can flip
145 // the final composited image. Ganesh renders the image upright so we
146 // need to do a y-flip.
147 canvas->translate(0.0, texture->size().height());
148 canvas->scale(1.0, -1.0);
149 // Clip to the destination on the texture that must be updated.
150 canvas->clipRect(SkRect::MakeXYWH(dest_offset.x(),
151 dest_offset.y(),
152 source_rect.width(),
153 source_rect.height()));
154 // Translate the origin of picture_rect to dest_offset.
155 // Note that dest_offset is defined relative to source_rect.
156 canvas->translate(
157 picture_rect.x() - source_rect.x() + dest_offset.x(),
158 picture_rect.y() - source_rect.y() + dest_offset.y());
159 canvas->drawPicture(*update.picture);
160
161 // Flush skia context so that all the rendered stuff appears on the
162 // texture.
163 offscreen_contexts->GrContext()->flush();
164
165 // Flush the GL context so rendering results from this context are
166 // visible in the compositor's context.
167 offscreen_contexts->Context3d()->flush();
168
169 // Use the compositor's GL context again.
170 resource_provider_->GraphicsContext3D()->makeContextCurrent();
171 }
172
173 if (update.bitmap) {
174 update.bitmap->lockPixels();
175 update.texture->setPixels(
176 resource_provider_,
177 static_cast<const uint8_t*>(update.bitmap->getPixels()),
178 update.content_rect,
179 update.source_rect,
180 update.dest_offset);
181 update.bitmap->unlockPixels();
182 }
183 }
184
185 void ResourceUpdateController::Finalize() {
186 while (queue_->fullUploadSize())
187 UpdateTexture(queue_->takeFirstFullUpload());
188
189 while (queue_->partialUploadSize())
190 UpdateTexture(queue_->takeFirstPartialUpload());
191
192 resource_provider_->FlushUploads();
193
194 if (queue_->copySize()) {
195 TextureCopier* copier = resource_provider_->texture_copier();
196 while (queue_->copySize())
197 copier->CopyTexture(queue_->takeFirstCopy());
198
199 // If we've performed any texture copies, we need to insert a flush
200 // here into the compositor context before letting the main thread
201 // proceed as it may make draw calls to the source texture of one of
202 // our copy operations.
203 copier->Flush();
204 }
205 }
206
207 void ResourceUpdateController::OnTimerFired() {
208 task_posted_ = false;
209 if (!UpdateMoreTexturesIfEnoughTimeRemaining())
210 client_->ReadyToFinalizeTextureUpdates();
211 }
212
213 base::TimeTicks ResourceUpdateController::Now() const {
214 return base::TimeTicks::Now();
215 }
216
217 base::TimeDelta ResourceUpdateController::UpdateMoreTexturesTime() const {
218 return base::TimeDelta::FromMilliseconds(kTextureUpdateTickRate * 1000);
219 }
220
221 size_t ResourceUpdateController::UpdateMoreTexturesSize() const {
222 return texture_updates_per_tick_;
223 }
224
225 size_t ResourceUpdateController::MaxBlockingUpdates() const {
226 return UpdateMoreTexturesSize() * kMaxBlockingUpdateIntervals;
227 }
228
229 base::TimeDelta ResourceUpdateController::PendingUpdateTime() const {
230 base::TimeDelta update_one_resource_time =
231 UpdateMoreTexturesTime() / UpdateMoreTexturesSize();
232 return update_one_resource_time * resource_provider_->NumBlockingUploads();
233 }
234
235 bool ResourceUpdateController::UpdateMoreTexturesIfEnoughTimeRemaining() {
236 while (resource_provider_->NumBlockingUploads() < MaxBlockingUpdates()) {
237 if (!queue_->fullUploadSize())
238 return false;
239
240 if (!time_limit_.is_null()) {
241 // Estimated completion time of all pending updates.
242 base::TimeTicks completion_time = Now() + PendingUpdateTime();
243
244 // Time remaining based on current completion estimate.
245 base::TimeDelta time_remaining = time_limit_ - completion_time;
246
247 if (time_remaining < UpdateMoreTexturesTime())
248 return true;
249 }
250
251 UpdateMoreTexturesNow();
252 }
253
254 task_posted_ = true;
255 thread_->PostDelayedTask(
256 base::Bind(&ResourceUpdateController::OnTimerFired,
257 weak_factory_.GetWeakPtr()),
258 base::TimeDelta::FromMilliseconds(kUploaderBusyTickRate * 1000));
259 return true;
260 }
261
262 void ResourceUpdateController::UpdateMoreTexturesNow() {
263 size_t uploads = std::min(
264 queue_->fullUploadSize(), UpdateMoreTexturesSize());
265
266 if (!uploads)
267 return;
268
269 while (queue_->fullUploadSize() && uploads--)
270 UpdateTexture(queue_->takeFirstFullUpload());
271
272 resource_provider_->FlushUploads();
273 }
274
275 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resource_update_controller.h ('k') | cc/resource_update_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698