| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 | 6 |
| 7 #include "CCTextureUpdateController.h" | 7 #include "CCTextureUpdateController.h" |
| 8 | 8 |
| 9 #include "GraphicsContext3D.h" | 9 #include "GraphicsContext3D.h" |
| 10 #include "TextureCopier.h" | 10 #include "TextureCopier.h" |
| 11 #include "TextureUploader.h" | 11 #include "TextureUploader.h" |
| 12 #include <wtf/CurrentTime.h> | 12 #include <wtf/CurrentTime.h> |
| 13 | 13 |
| 14 namespace { | 14 namespace { |
| 15 | 15 |
| 16 // Number of textures to update with each call to updateMoreTexturesIfEnoughTime
Remaining(). | 16 // Number of textures to update with each call to updateMoreTexturesIfEnoughTime
Remaining(). |
| 17 static const size_t textureUpdatesPerTick = 12; | 17 static const size_t textureUpdatesPerTick = 12; |
| 18 | 18 |
| 19 // Measured in seconds. | 19 // Measured in seconds. |
| 20 static const double textureUpdateTickRate = 0.004; | 20 static const double textureUpdateTickRate = 0.004; |
| 21 | 21 |
| 22 // Measured in seconds. |
| 23 static const double uploaderBusyTickRate = 0.001; |
| 24 |
| 22 // Flush interval when performing texture uploads. | 25 // Flush interval when performing texture uploads. |
| 23 static const int textureUploadFlushPeriod = 4; | 26 static const int textureUploadFlushPeriod = 4; |
| 24 | 27 |
| 25 } // anonymous namespace | 28 } // anonymous namespace |
| 26 | 29 |
| 27 namespace cc { | 30 namespace cc { |
| 28 | 31 |
| 29 size_t CCTextureUpdateController::maxPartialTextureUpdates() | 32 size_t CCTextureUpdateController::maxPartialTextureUpdates() |
| 30 { | 33 { |
| 31 return textureUpdatesPerTick; | 34 return textureUpdatesPerTick; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 , m_uploader(uploader) | 104 , m_uploader(uploader) |
| 102 , m_monotonicTimeLimit(0) | 105 , m_monotonicTimeLimit(0) |
| 103 , m_firstUpdateAttempt(true) | 106 , m_firstUpdateAttempt(true) |
| 104 { | 107 { |
| 105 } | 108 } |
| 106 | 109 |
| 107 CCTextureUpdateController::~CCTextureUpdateController() | 110 CCTextureUpdateController::~CCTextureUpdateController() |
| 108 { | 111 { |
| 109 } | 112 } |
| 110 | 113 |
| 111 void CCTextureUpdateController::updateMoreTextures(double monotonicTimeLimit) | 114 void CCTextureUpdateController::performMoreUpdates( |
| 115 double monotonicTimeLimit) |
| 112 { | 116 { |
| 113 ASSERT(monotonicTimeLimit >= m_monotonicTimeLimit); | 117 ASSERT(monotonicTimeLimit >= m_monotonicTimeLimit); |
| 114 m_monotonicTimeLimit = monotonicTimeLimit; | 118 m_monotonicTimeLimit = monotonicTimeLimit; |
| 115 | 119 |
| 116 // Update already in progress. | 120 // Update already in progress. |
| 117 if (m_timer->isActive()) | 121 if (m_timer->isActive()) |
| 118 return; | 122 return; |
| 119 | 123 |
| 120 // Call updateMoreTexturesNow() directly unless it's the first update | 124 // Call updateMoreTexturesNow() directly unless it's the first update |
| 121 // attempt. This ensures that we empty the update queue in a finite | 125 // attempt. This ensures that we empty the update queue in a finite |
| 122 // amount of time. | 126 // amount of time. |
| 123 if (m_firstUpdateAttempt) { | 127 if (m_firstUpdateAttempt) { |
| 124 // Post a 0-delay task when no updates were left. When it runs, | 128 // Post a 0-delay task when no updates were left. When it runs, |
| 125 // updateTexturesCompleted() will be called. | 129 // readyToFinalizeTextureUpdates() will be called. |
| 126 if (!updateMoreTexturesIfEnoughTimeRemaining()) | 130 if (!updateMoreTexturesIfEnoughTimeRemaining()) |
| 127 m_timer->startOneShot(0); | 131 m_timer->startOneShot(0); |
| 128 | 132 |
| 129 m_firstUpdateAttempt = false; | 133 m_firstUpdateAttempt = false; |
| 130 } else | 134 } else |
| 131 updateMoreTexturesNow(); | 135 updateMoreTexturesNow(); |
| 132 } | 136 } |
| 133 | 137 |
| 138 void CCTextureUpdateController::finalize() |
| 139 { |
| 140 while (m_queue->hasMoreUpdates()) |
| 141 updateTextures(m_resourceProvider, m_copier, m_uploader, m_queue.get(), |
| 142 updateMoreTexturesSize()); |
| 143 } |
| 144 |
| 134 void CCTextureUpdateController::onTimerFired() | 145 void CCTextureUpdateController::onTimerFired() |
| 135 { | 146 { |
| 136 if (!updateMoreTexturesIfEnoughTimeRemaining()) | 147 if (!updateMoreTexturesIfEnoughTimeRemaining()) |
| 137 m_client->updateTexturesCompleted(); | 148 m_client->readyToFinalizeTextureUpdates(); |
| 138 } | 149 } |
| 139 | 150 |
| 140 double CCTextureUpdateController::monotonicTimeNow() const | 151 double CCTextureUpdateController::monotonicTimeNow() const |
| 141 { | 152 { |
| 142 return monotonicallyIncreasingTime(); | 153 return monotonicallyIncreasingTime(); |
| 143 } | 154 } |
| 144 | 155 |
| 145 double CCTextureUpdateController::updateMoreTexturesTime() const | 156 double CCTextureUpdateController::updateMoreTexturesTime() const |
| 146 { | 157 { |
| 147 return textureUpdateTickRate; | 158 return textureUpdateTickRate; |
| 148 } | 159 } |
| 149 | 160 |
| 150 size_t CCTextureUpdateController::updateMoreTexturesSize() const | 161 size_t CCTextureUpdateController::updateMoreTexturesSize() const |
| 151 { | 162 { |
| 152 return textureUpdatesPerTick; | 163 return textureUpdatesPerTick; |
| 153 } | 164 } |
| 154 | 165 |
| 155 bool CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() | 166 bool CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() |
| 156 { | 167 { |
| 157 if (!m_queue->hasMoreUpdates()) | 168 // Uploader might be busy when we're too aggressive in our upload time |
| 169 // estimate. We use a different timeout here to prevent unnecessary |
| 170 // amounts of idle time. |
| 171 if (m_uploader->isBusy()) { |
| 172 m_timer->startOneShot(uploaderBusyTickRate); |
| 173 return true; |
| 174 } |
| 175 |
| 176 if (!m_queue->fullUploadSize()) |
| 158 return false; | 177 return false; |
| 159 | 178 |
| 160 bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMo
reTexturesTime(); | 179 bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMo
reTexturesTime(); |
| 161 if (hasTimeRemaining) | 180 if (hasTimeRemaining) |
| 162 updateMoreTexturesNow(); | 181 updateMoreTexturesNow(); |
| 163 | 182 |
| 164 return true; | 183 return true; |
| 165 } | 184 } |
| 166 | 185 |
| 167 void CCTextureUpdateController::updateMoreTexturesNow() | 186 void CCTextureUpdateController::updateMoreTexturesNow() |
| 168 { | 187 { |
| 169 m_timer->startOneShot(updateMoreTexturesTime()); | 188 size_t uploads = std::min( |
| 170 updateTextures(m_resourceProvider, m_copier, m_uploader, m_queue.get(), upda
teMoreTexturesSize()); | 189 m_queue->fullUploadSize(), updateMoreTexturesSize()); |
| 190 m_timer->startOneShot( |
| 191 updateMoreTexturesTime() / updateMoreTexturesSize() * uploads); |
| 192 |
| 193 if (!uploads) |
| 194 return; |
| 195 |
| 196 m_uploader->beginUploads(); |
| 197 |
| 198 size_t uploadCount = 0; |
| 199 while (uploads--) { |
| 200 m_uploader->uploadTexture( |
| 201 m_resourceProvider, m_queue->takeFirstFullUpload()); |
| 202 uploadCount++; |
| 203 if (!(uploadCount % textureUploadFlushPeriod)) |
| 204 m_resourceProvider->shallowFlushIfSupported(); |
| 205 } |
| 206 |
| 207 // Make sure there are no dangling partial uploads without a flush. |
| 208 if (uploadCount % textureUploadFlushPeriod) |
| 209 m_resourceProvider->shallowFlushIfSupported(); |
| 210 |
| 211 m_uploader->endUploads(); |
| 171 } | 212 } |
| 172 | 213 |
| 173 } | 214 } |
| OLD | NEW |