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

Side by Side Diff: cc/texture_update_controller.cc

Issue 11270047: cc: Rename TextureUpdate to ResourceUpdate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sort includes and forward declarations. Created 8 years, 1 month 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/texture_update_controller.h ('k') | cc/texture_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 "config.h"
6
7 #include "cc/texture_update_controller.h"
8
9 #include "base/debug/trace_event.h"
10 #include "cc/prioritized_texture.h"
11 #include "cc/proxy.h"
12 #include "cc/resource_provider.h"
13 #include "cc/texture_copier.h"
14 #include "third_party/khronos/GLES2/gl2.h"
15 #include "third_party/skia/include/gpu/SkGpuDevice.h"
16 #include <limits>
17 #include <public/WebGraphicsContext3D.h>
18 #include <public/WebSharedGraphicsContext3D.h>
19 #include <wtf/CurrentTime.h>
20
21 using WebKit::WebGraphicsContext3D;
22 using WebKit::WebSharedGraphicsContext3D;
23
24 namespace {
25
26 // Number of partial updates we allow.
27 const size_t partialTextureUpdatesMax = 12;
28
29 // Measured in seconds.
30 const double textureUpdateTickRate = 0.004;
31
32 // Measured in seconds.
33 const double uploaderBusyTickRate = 0.001;
34
35 // Flush interval when performing texture uploads.
36 const int textureUploadFlushPeriod = 4;
37
38 // Number of blocking update intervals to allow.
39 const size_t maxBlockingUpdateIntervals = 4;
40
41 scoped_ptr<SkCanvas> createAcceleratedCanvas(
42 GrContext* grContext, cc::IntSize canvasSize, unsigned textureId)
43 {
44 GrPlatformTextureDesc textureDesc;
45 textureDesc.fFlags = kRenderTarget_GrPlatformTextureFlag;
46 textureDesc.fWidth = canvasSize.width();
47 textureDesc.fHeight = canvasSize.height();
48 textureDesc.fConfig = kSkia8888_GrPixelConfig;
49 textureDesc.fTextureHandle = textureId;
50 SkAutoTUnref<GrTexture> target(
51 grContext->createPlatformTexture(textureDesc));
52 SkAutoTUnref<SkDevice> device(new SkGpuDevice(grContext, target.get()));
53 return make_scoped_ptr(new SkCanvas(device.get()));
54 }
55
56 } // namespace
57
58 namespace cc {
59
60 size_t TextureUpdateController::maxPartialTextureUpdates()
61 {
62 return partialTextureUpdatesMax;
63 }
64
65 size_t TextureUpdateController::maxFullUpdatesPerTick(
66 ResourceProvider* resourceProvider)
67 {
68 double texturesPerSecond = resourceProvider->estimatedUploadsPerSecond();
69 size_t texturesPerTick = floor(textureUpdateTickRate * texturesPerSecond);
70 return texturesPerTick ? texturesPerTick : 1;
71 }
72
73 TextureUpdateController::TextureUpdateController(TextureUpdateControllerClient* client, Thread* thread, scoped_ptr<TextureUpdateQueue> queue, ResourceProvider* resourceProvider)
74 : m_client(client)
75 , m_timer(new Timer(thread, this))
76 , m_queue(queue.Pass())
77 , m_resourceProvider(resourceProvider)
78 , m_textureUpdatesPerTick(maxFullUpdatesPerTick(resourceProvider))
79 , m_firstUpdateAttempt(true)
80 {
81 }
82
83 TextureUpdateController::~TextureUpdateController()
84 {
85 }
86
87 void TextureUpdateController::performMoreUpdates(
88 base::TimeTicks timeLimit)
89 {
90 m_timeLimit = timeLimit;
91
92 // Update already in progress.
93 if (m_timer->isActive())
94 return;
95
96 // Call updateMoreTexturesNow() directly unless it's the first update
97 // attempt. This ensures that we empty the update queue in a finite
98 // amount of time.
99 if (m_firstUpdateAttempt) {
100 // Post a 0-delay task when no updates were left. When it runs,
101 // readyToFinalizeTextureUpdates() will be called.
102 if (!updateMoreTexturesIfEnoughTimeRemaining())
103 m_timer->startOneShot(0);
104
105 m_firstUpdateAttempt = false;
106 } else
107 updateMoreTexturesNow();
108 }
109
110 void TextureUpdateController::discardUploadsToEvictedResources()
111 {
112 m_queue->clearUploadsToEvictedResources();
113 }
114
115 void TextureUpdateController::updateTexture(ResourceUpdate update)
116 {
117 if (update.picture) {
118 PrioritizedTexture* texture = update.texture;
119 IntRect pictureRect = update.content_rect;
120 IntRect sourceRect = update.source_rect;
121 IntSize destOffset = update.dest_offset;
122
123 texture->acquireBackingTexture(m_resourceProvider);
124 DCHECK(texture->haveBackingTexture());
125
126 DCHECK(m_resourceProvider->resourceType(texture->resourceId()) ==
127 ResourceProvider::GLTexture);
128
129 WebGraphicsContext3D* paintContext = Proxy::hasImplThread() ?
130 WebSharedGraphicsContext3D::compositorThreadContext() :
131 WebSharedGraphicsContext3D::mainThreadContext();
132 GrContext* paintGrContext = Proxy::hasImplThread() ?
133 WebSharedGraphicsContext3D::compositorThreadGrContext() :
134 WebSharedGraphicsContext3D::mainThreadGrContext();
135
136 // Flush the context in which the backing texture is created so that it
137 // is available in other shared contexts. It is important to do here
138 // because the backing texture is created in one context while it is
139 // being written to in another.
140 m_resourceProvider->flush();
141 ResourceProvider::ScopedWriteLockGL lock(
142 m_resourceProvider, texture->resourceId());
143
144 // Make sure ganesh uses the correct GL context.
145 paintContext->makeContextCurrent();
146
147 // Create an accelerated canvas to draw on.
148 scoped_ptr<SkCanvas> canvas = createAcceleratedCanvas(
149 paintGrContext, texture->size(), lock.textureId());
150
151 // The compositor expects the textures to be upside-down so it can flip
152 // the final composited image. Ganesh renders the image upright so we
153 // need to do a y-flip.
154 canvas->translate(0.0, texture->size().height());
155 canvas->scale(1.0, -1.0);
156 // Clip to the destination on the texture that must be updated.
157 canvas->clipRect(SkRect::MakeXYWH(destOffset.width(),
158 destOffset.height(),
159 sourceRect.width(),
160 sourceRect.height()));
161 // Translate the origin of pictureRect to destOffset.
162 // Note that destOffset is defined relative to sourceRect.
163 canvas->translate(
164 pictureRect.x() - sourceRect.x() + destOffset.width(),
165 pictureRect.y() - sourceRect.y() + destOffset.height());
166 canvas->drawPicture(*update.picture);
167
168 // Flush ganesh context so that all the rendered stuff appears on the
169 // texture.
170 paintGrContext->flush();
171
172 // Flush the GL context so rendering results from this context are
173 // visible in the compositor's context.
174 paintContext->flush();
175 }
176
177 if (update.bitmap) {
178 update.bitmap->lockPixels();
179 update.texture->upload(
180 m_resourceProvider,
181 static_cast<const uint8_t*>(update.bitmap->getPixels()),
182 update.content_rect,
183 update.source_rect,
184 update.dest_offset);
185 update.bitmap->unlockPixels();
186 }
187 }
188
189 void TextureUpdateController::finalize()
190 {
191 size_t uploadCount = 0;
192 while (m_queue->fullUploadSize()) {
193 if (!(uploadCount % textureUploadFlushPeriod) && uploadCount)
194 m_resourceProvider->shallowFlushIfSupported();
195
196 updateTexture(m_queue->takeFirstFullUpload());
197 uploadCount++;
198 }
199
200 while (m_queue->partialUploadSize()) {
201 if (!(uploadCount % textureUploadFlushPeriod) && uploadCount)
202 m_resourceProvider->shallowFlushIfSupported();
203
204 updateTexture(m_queue->takeFirstPartialUpload());
205 uploadCount++;
206 }
207
208 if (uploadCount)
209 m_resourceProvider->shallowFlushIfSupported();
210
211 if (m_queue->copySize()) {
212 TextureCopier* copier = m_resourceProvider->textureCopier();
213 while (m_queue->copySize())
214 copier->copyTexture(m_queue->takeFirstCopy());
215
216 // If we've performed any texture copies, we need to insert a flush
217 // here into the compositor context before letting the main thread
218 // proceed as it may make draw calls to the source texture of one of
219 // our copy operations.
220 copier->flush();
221 }
222 }
223
224 void TextureUpdateController::onTimerFired()
225 {
226 ResourceProvider::debugNotifyEnterZone(0xB000000);
227 if (!updateMoreTexturesIfEnoughTimeRemaining())
228 m_client->readyToFinalizeTextureUpdates();
229 ResourceProvider::debugNotifyLeaveZone();
230 }
231
232 base::TimeTicks TextureUpdateController::now() const
233 {
234 return base::TimeTicks::Now();
235 }
236
237 base::TimeDelta TextureUpdateController::updateMoreTexturesTime() const
238 {
239 return base::TimeDelta::FromMilliseconds(textureUpdateTickRate * 1000);
240 }
241
242 size_t TextureUpdateController::updateMoreTexturesSize() const
243 {
244 return m_textureUpdatesPerTick;
245 }
246
247 size_t TextureUpdateController::maxBlockingUpdates() const
248 {
249 return updateMoreTexturesSize() * maxBlockingUpdateIntervals;
250 }
251
252 bool TextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining()
253 {
254 // Blocking uploads will increase when we're too aggressive in our upload
255 // time estimate. We use a different timeout here to prevent unnecessary
256 // amounts of idle time when blocking uploads have reached the max.
257 if (m_resourceProvider->numBlockingUploads() >= maxBlockingUpdates()) {
258 m_timer->startOneShot(uploaderBusyTickRate);
259 return true;
260 }
261
262 if (!m_queue->fullUploadSize())
263 return false;
264
265 bool hasTimeRemaining = m_timeLimit.is_null() ||
266 this->now() < m_timeLimit - updateMoreTexturesTime();
267 if (hasTimeRemaining)
268 updateMoreTexturesNow();
269
270 return true;
271 }
272
273 void TextureUpdateController::updateMoreTexturesNow()
274 {
275 size_t uploads = std::min(
276 m_queue->fullUploadSize(), updateMoreTexturesSize());
277 m_timer->startOneShot(
278 updateMoreTexturesTime().InSecondsF() / updateMoreTexturesSize() *
279 uploads);
280
281 if (!uploads)
282 return;
283
284 size_t uploadCount = 0;
285 while (m_queue->fullUploadSize() && uploadCount < uploads) {
286 if (!(uploadCount % textureUploadFlushPeriod) && uploadCount)
287 m_resourceProvider->shallowFlushIfSupported();
288 updateTexture(m_queue->takeFirstFullUpload());
289 uploadCount++;
290 }
291 m_resourceProvider->shallowFlushIfSupported();
292 }
293
294 } // namespace cc
OLDNEW
« no previous file with comments | « cc/texture_update_controller.h ('k') | cc/texture_update_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698