blob: 10ab12bf2a12022044c55b6f4b12d8881028a314 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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 "CCTextureUpdateController.h"
8
[email protected]ea8af90e2012-10-13 10:20:279#include "CCResourceProvider.h"
[email protected]94f206c12012-08-25 00:09:1410#include "TextureCopier.h"
11#include "TextureUploader.h"
[email protected]41b8f682012-09-19 01:51:1712#include "TraceEvent.h"
13#include <limits>
[email protected]94f206c12012-08-25 00:09:1414#include <wtf/CurrentTime.h>
15
16namespace {
17
[email protected]41b8f682012-09-19 01:51:1718// Number of partial updates we allow.
[email protected]2d86b922012-10-13 16:57:4719const size_t partialTextureUpdatesMax = 12;
[email protected]94f206c12012-08-25 00:09:1420
21// Measured in seconds.
[email protected]2d86b922012-10-13 16:57:4722const double textureUpdateTickRate = 0.004;
[email protected]94f206c12012-08-25 00:09:1423
[email protected]12695152012-09-17 22:28:1424// Measured in seconds.
[email protected]2d86b922012-10-13 16:57:4725const double uploaderBusyTickRate = 0.001;
[email protected]12695152012-09-17 22:28:1426
[email protected]94f206c12012-08-25 00:09:1427// Flush interval when performing texture uploads.
[email protected]2d86b922012-10-13 16:57:4728const int textureUploadFlushPeriod = 4;
[email protected]94f206c12012-08-25 00:09:1429
[email protected]b914e102012-10-02 08:11:5230// Number of blocking update intervals to allow.
[email protected]2d86b922012-10-13 16:57:4731const size_t maxBlockingUpdateIntervals = 4;
[email protected]549526e92012-09-29 15:43:0832
[email protected]2d86b922012-10-13 16:57:4733} // namespace
[email protected]94f206c12012-08-25 00:09:1434
[email protected]9c88e562012-09-14 22:21:3035namespace cc {
[email protected]94f206c12012-08-25 00:09:1436
37size_t CCTextureUpdateController::maxPartialTextureUpdates()
38{
[email protected]a7c078b2012-09-20 17:52:1239 return partialTextureUpdatesMax;
[email protected]41b8f682012-09-19 01:51:1740}
41
42size_t CCTextureUpdateController::maxFullUpdatesPerTick(TextureUploader* uploader)
43{
44 double texturesPerSecond = uploader->estimatedTexturesPerSecond();
45 size_t texturesPerTick = floor(textureUpdateTickRate * texturesPerSecond);
46 return texturesPerTick ? texturesPerTick : 1;
[email protected]94f206c12012-08-25 00:09:1447}
48
[email protected]b1b800c2012-10-16 05:03:5949CCTextureUpdateController::CCTextureUpdateController(CCTextureUpdateControllerClient* client, CCThread* thread, scoped_ptr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureUploader* uploader)
[email protected]3c496dc2012-09-13 23:14:2050 : m_client(client)
[email protected]2d86b922012-10-13 16:57:4751 , m_timer(new CCTimer(thread, this))
[email protected]b1b800c2012-10-16 05:03:5952 , m_queue(queue.Pass())
[email protected]94f206c12012-08-25 00:09:1453 , m_resourceProvider(resourceProvider)
[email protected]94f206c12012-08-25 00:09:1454 , m_uploader(uploader)
[email protected]41b8f682012-09-19 01:51:1755 , m_textureUpdatesPerTick(maxFullUpdatesPerTick(uploader))
[email protected]94f206c12012-08-25 00:09:1456 , m_firstUpdateAttempt(true)
57{
58}
59
60CCTextureUpdateController::~CCTextureUpdateController()
61{
62}
63
[email protected]12695152012-09-17 22:28:1464void CCTextureUpdateController::performMoreUpdates(
[email protected]d918afe2012-09-27 19:27:2165 base::TimeTicks timeLimit)
[email protected]94f206c12012-08-25 00:09:1466{
[email protected]d918afe2012-09-27 19:27:2167 m_timeLimit = timeLimit;
[email protected]94f206c12012-08-25 00:09:1468
[email protected]3c496dc2012-09-13 23:14:2069 // Update already in progress.
70 if (m_timer->isActive())
[email protected]94f206c12012-08-25 00:09:1471 return;
72
73 // Call updateMoreTexturesNow() directly unless it's the first update
74 // attempt. This ensures that we empty the update queue in a finite
75 // amount of time.
76 if (m_firstUpdateAttempt) {
[email protected]3c496dc2012-09-13 23:14:2077 // Post a 0-delay task when no updates were left. When it runs,
[email protected]12695152012-09-17 22:28:1478 // readyToFinalizeTextureUpdates() will be called.
[email protected]3c496dc2012-09-13 23:14:2079 if (!updateMoreTexturesIfEnoughTimeRemaining())
80 m_timer->startOneShot(0);
81
[email protected]94f206c12012-08-25 00:09:1482 m_firstUpdateAttempt = false;
83 } else
84 updateMoreTexturesNow();
85}
86
[email protected]77a60b9b2012-09-19 23:59:0187void CCTextureUpdateController::discardUploadsToEvictedResources()
88{
89 m_queue->clearUploadsToEvictedResources();
90}
91
[email protected]12695152012-09-17 22:28:1492void CCTextureUpdateController::finalize()
93{
[email protected]f961b792012-09-20 07:27:3394 size_t uploadCount = 0;
95 while (m_queue->fullUploadSize()) {
96 if (!(uploadCount % textureUploadFlushPeriod) && uploadCount)
97 m_resourceProvider->shallowFlushIfSupported();
98
99 m_uploader->uploadTexture(
100 m_resourceProvider, m_queue->takeFirstFullUpload());
101 uploadCount++;
102 }
103
104 while (m_queue->partialUploadSize()) {
105 if (!(uploadCount % textureUploadFlushPeriod) && uploadCount)
106 m_resourceProvider->shallowFlushIfSupported();
107
108 m_uploader->uploadTexture(
109 m_resourceProvider, m_queue->takeFirstPartialUpload());
110 uploadCount++;
111 }
112
113 if (uploadCount)
114 m_resourceProvider->shallowFlushIfSupported();
115
116 if (m_queue->copySize()) {
117 TextureCopier* copier = m_resourceProvider->textureCopier();
118 while (m_queue->copySize())
119 copier->copyTexture(m_queue->takeFirstCopy());
120
121 // If we've performed any texture copies, we need to insert a flush
122 // here into the compositor context before letting the main thread
123 // proceed as it may make draw calls to the source texture of one of
124 // our copy operations.
125 copier->flush();
126 }
[email protected]12695152012-09-17 22:28:14127}
128
[email protected]94f206c12012-08-25 00:09:14129void CCTextureUpdateController::onTimerFired()
130{
[email protected]3c496dc2012-09-13 23:14:20131 if (!updateMoreTexturesIfEnoughTimeRemaining())
[email protected]12695152012-09-17 22:28:14132 m_client->readyToFinalizeTextureUpdates();
[email protected]94f206c12012-08-25 00:09:14133}
134
[email protected]d918afe2012-09-27 19:27:21135base::TimeTicks CCTextureUpdateController::now() const
[email protected]94f206c12012-08-25 00:09:14136{
[email protected]d918afe2012-09-27 19:27:21137 return base::TimeTicks::Now();
[email protected]94f206c12012-08-25 00:09:14138}
139
[email protected]d918afe2012-09-27 19:27:21140base::TimeDelta CCTextureUpdateController::updateMoreTexturesTime() const
[email protected]94f206c12012-08-25 00:09:14141{
[email protected]d918afe2012-09-27 19:27:21142 return base::TimeDelta::FromMilliseconds(textureUpdateTickRate * 1000);
[email protected]94f206c12012-08-25 00:09:14143}
144
145size_t CCTextureUpdateController::updateMoreTexturesSize() const
146{
[email protected]41b8f682012-09-19 01:51:17147 return m_textureUpdatesPerTick;
[email protected]94f206c12012-08-25 00:09:14148}
149
[email protected]b914e102012-10-02 08:11:52150size_t CCTextureUpdateController::maxBlockingUpdates() const
[email protected]549526e92012-09-29 15:43:08151{
[email protected]b914e102012-10-02 08:11:52152 return updateMoreTexturesSize() * maxBlockingUpdateIntervals;
[email protected]549526e92012-09-29 15:43:08153}
154
[email protected]3c496dc2012-09-13 23:14:20155bool CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining()
[email protected]94f206c12012-08-25 00:09:14156{
[email protected]b914e102012-10-02 08:11:52157 // Blocking uploads will increase when we're too aggressive in our upload
[email protected]549526e92012-09-29 15:43:08158 // time estimate. We use a different timeout here to prevent unnecessary
[email protected]b914e102012-10-02 08:11:52159 // amounts of idle time when blocking uploads have reached the max.
160 if (m_uploader->numBlockingUploads() >= maxBlockingUpdates()) {
[email protected]12695152012-09-17 22:28:14161 m_timer->startOneShot(uploaderBusyTickRate);
162 return true;
163 }
164
165 if (!m_queue->fullUploadSize())
[email protected]3c496dc2012-09-13 23:14:20166 return false;
167
[email protected]e8e410d2012-09-28 01:47:01168 bool hasTimeRemaining = m_timeLimit.is_null() ||
169 this->now() < m_timeLimit - updateMoreTexturesTime();
[email protected]94f206c12012-08-25 00:09:14170 if (hasTimeRemaining)
171 updateMoreTexturesNow();
[email protected]3c496dc2012-09-13 23:14:20172
173 return true;
[email protected]94f206c12012-08-25 00:09:14174}
175
176void CCTextureUpdateController::updateMoreTexturesNow()
177{
[email protected]12695152012-09-17 22:28:14178 size_t uploads = std::min(
179 m_queue->fullUploadSize(), updateMoreTexturesSize());
180 m_timer->startOneShot(
[email protected]d918afe2012-09-27 19:27:21181 updateMoreTexturesTime().InSecondsF() / updateMoreTexturesSize() *
182 uploads);
[email protected]12695152012-09-17 22:28:14183
184 if (!uploads)
185 return;
186
[email protected]12695152012-09-17 22:28:14187 size_t uploadCount = 0;
[email protected]41b8f682012-09-19 01:51:17188 while (m_queue->fullUploadSize() && uploadCount < uploads) {
189 if (!(uploadCount % textureUploadFlushPeriod) && uploadCount)
[email protected]12695152012-09-17 22:28:14190 m_resourceProvider->shallowFlushIfSupported();
[email protected]41b8f682012-09-19 01:51:17191 m_uploader->uploadTexture(m_resourceProvider, m_queue->takeFirstFullUpload());
192 uploadCount++;
[email protected]12695152012-09-17 22:28:14193 }
[email protected]41b8f682012-09-19 01:51:17194 m_resourceProvider->shallowFlushIfSupported();
[email protected]94f206c12012-08-25 00:09:14195}
196
[email protected]2d86b922012-10-13 16:57:47197} // namespace cc