| 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 "TraceEvent.h" |
| 13 #include <limits> |
| 12 #include <wtf/CurrentTime.h> | 14 #include <wtf/CurrentTime.h> |
| 13 | 15 |
| 14 namespace { | 16 namespace { |
| 15 | 17 |
| 16 // Number of textures to update with each call to updateMoreTexturesIfEnoughTime
Remaining(). | 18 static const size_t pixelsPerTexture = 256 * 256; |
| 17 static const size_t textureUpdatesPerTick = 12; | 19 |
| 20 // Minimum number of textures to update with each call to updateMoreTexturesIfEn
oughTimeRemaining(). |
| 21 static const size_t textureUpdatesPerFullTickMin = 12; |
| 18 | 22 |
| 19 // Measured in seconds. | 23 // Measured in seconds. |
| 20 static const double textureUpdateTickRate = 0.004; | 24 static const double textureUpdateTickRate = 0.004; |
| 21 | 25 |
| 22 // Flush interval when performing texture uploads. | 26 // Flush interval when performing texture uploads. |
| 23 static const int textureUploadFlushPeriod = 4; | 27 static const int textureUploadFlushPeriod = 4; |
| 24 | 28 |
| 25 } // anonymous namespace | 29 } // anonymous namespace |
| 26 | 30 |
| 27 namespace WebCore { | 31 namespace WebCore { |
| 28 | 32 |
| 29 size_t CCTextureUpdateController::maxPartialTextureUpdates() | 33 size_t CCTextureUpdateController::maxTextureUpdates(TextureUploader* uploader) |
| 30 { | 34 { |
| 31 return textureUpdatesPerTick; | 35 double texturesPerSecond = uploader->estimatedPixelsPerSecond() / pixelsPerT
exture; |
| 36 |
| 37 return std::max(textureUpdatesPerFullTickMin, |
| 38 (size_t) floor(textureUpdateTickRate * texturesPerSecond)); |
| 39 } |
| 40 |
| 41 PassOwnPtr<CCTextureUpdateController> CCTextureUpdateController::create(CCThread
* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourcePr
ovider, TextureCopier* copier, TextureUploader* uploader, size_t maxTextureUpdat
es) |
| 42 { |
| 43 return adoptPtr(new CCTextureUpdateController(thread, queue, resourceProvide
r, copier, uploader, maxTextureUpdates)); |
| 32 } | 44 } |
| 33 | 45 |
| 34 void CCTextureUpdateController::updateTextures(CCResourceProvider* resourceProvi
der, TextureCopier* copier, TextureUploader* uploader, CCTextureUpdateQueue* que
ue, size_t count) | 46 void CCTextureUpdateController::updateTextures(CCResourceProvider* resourceProvi
der, TextureCopier* copier, TextureUploader* uploader, CCTextureUpdateQueue* que
ue, size_t count) |
| 35 { | 47 { |
| 36 if (queue->fullUploadSize() || queue->partialUploadSize()) { | 48 if (queue->fullUploadSize() || queue->partialUploadSize()) { |
| 37 if (uploader->isBusy()) | 49 if (uploader->isBusy()) |
| 38 return; | 50 return; |
| 39 | 51 |
| 40 uploader->beginUploads(); | 52 uploader->beginUploads(); |
| 41 | 53 |
| 42 size_t fullUploadCount = 0; | 54 size_t fullUploadCount = 0; |
| 43 while (queue->fullUploadSize() && fullUploadCount < count) { | 55 bool uploadMore = queue->fullUploadSize() && fullUploadCount < count; |
| 56 while (uploadMore) { |
| 44 uploader->uploadTexture(resourceProvider, queue->takeFirstFullUpload
()); | 57 uploader->uploadTexture(resourceProvider, queue->takeFirstFullUpload
()); |
| 45 fullUploadCount++; | 58 fullUploadCount++; |
| 46 if (!(fullUploadCount % textureUploadFlushPeriod)) | 59 uploadMore = queue->fullUploadSize() && fullUploadCount < count; |
| 60 |
| 61 // Flush periodically, but deffer our last flush until after uploade
r->endUploads() |
| 62 // in order to keep the query associated with endUploads grouped wit
h our last texture upload. |
| 63 if (!(fullUploadCount % textureUploadFlushPeriod) && uploadMore) |
| 47 resourceProvider->shallowFlushIfSupported(); | 64 resourceProvider->shallowFlushIfSupported(); |
| 48 } | 65 } |
| 49 | 66 |
| 50 // Make sure there are no dangling uploads without a flush. | 67 ASSERT(queue->partialUploadSize() <= count); |
| 51 if (fullUploadCount % textureUploadFlushPeriod) | 68 bool needAnotherTick = queue->fullUploadSize() || ((count - fullUploadCo
unt) < queue->partialUploadSize()); |
| 69 if (needAnotherTick) { |
| 70 uploader->endUploads(); |
| 52 resourceProvider->shallowFlushIfSupported(); | 71 resourceProvider->shallowFlushIfSupported(); |
| 53 | |
| 54 bool moreUploads = queue->fullUploadSize(); | |
| 55 | |
| 56 ASSERT(queue->partialUploadSize() <= count); | |
| 57 // We need another update batch if the number of updates remaining | |
| 58 // in |count| is greater than the remaining partial entries. | |
| 59 if ((count - fullUploadCount) < queue->partialUploadSize()) | |
| 60 moreUploads = true; | |
| 61 | |
| 62 if (moreUploads) { | |
| 63 uploader->endUploads(); | |
| 64 return; | 72 return; |
| 65 } | 73 } |
| 74 resourceProvider->shallowFlushIfSupported(); |
| 66 | 75 |
| 67 size_t partialUploadCount = 0; | 76 size_t partialUploadCount = 0; |
| 68 while (queue->partialUploadSize()) { | 77 while (queue->partialUploadSize()) { |
| 69 uploader->uploadTexture(resourceProvider, queue->takeFirstPartialUpl
oad()); | 78 uploader->uploadTexture(resourceProvider, queue->takeFirstPartialUpl
oad()); |
| 70 partialUploadCount++; | 79 partialUploadCount++; |
| 71 if (!(partialUploadCount % textureUploadFlushPeriod)) | 80 |
| 81 // Flush periodically, but deffer our last flush until after uploade
r->endUploads() |
| 82 // in order to keep the query associated with endUploads grouped wit
h our last texture upload. |
| 83 if (!(partialUploadCount % textureUploadFlushPeriod) && queue->parti
alUploadSize()) |
| 72 resourceProvider->shallowFlushIfSupported(); | 84 resourceProvider->shallowFlushIfSupported(); |
| 73 } | 85 } |
| 74 | 86 |
| 75 // Make sure there are no dangling partial uploads without a flush. | |
| 76 if (partialUploadCount % textureUploadFlushPeriod) | |
| 77 resourceProvider->shallowFlushIfSupported(); | |
| 78 | |
| 79 uploader->endUploads(); | 87 uploader->endUploads(); |
| 88 resourceProvider->shallowFlushIfSupported(); |
| 80 } | 89 } |
| 81 | 90 |
| 82 size_t copyCount = 0; | 91 size_t copyCount = 0; |
| 83 while (queue->copySize()) { | 92 while (queue->copySize()) { |
| 84 copier->copyTexture(queue->takeFirstCopy()); | 93 copier->copyTexture(queue->takeFirstCopy()); |
| 85 copyCount++; | 94 copyCount++; |
| 86 } | 95 } |
| 87 | 96 |
| 88 // If we've performed any texture copies, we need to insert a flush here int
o the compositor context | 97 // If we've performed any texture copies, we need to insert a flush here int
o the compositor context |
| 89 // before letting the main thread proceed as it may make draw calls to the s
ource texture of one of | 98 // before letting the main thread proceed as it may make draw calls to the s
ource texture of one of |
| 90 // our copy operations. | 99 // our copy operations. |
| 91 if (copyCount) | 100 if (copyCount) |
| 92 copier->flush(); | 101 copier->flush(); |
| 93 } | 102 } |
| 94 | 103 |
| 95 CCTextureUpdateController::CCTextureUpdateController(CCThread* thread, PassOwnPt
r<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopi
er* copier, TextureUploader* uploader) | 104 CCTextureUpdateController::CCTextureUpdateController(CCThread* thread, PassOwnPt
r<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureCopi
er* copier, TextureUploader* uploader, size_t maxTextureUpdates) |
| 96 : m_timer(adoptPtr(new CCTimer(thread, this))) | 105 : m_timer(adoptPtr(new CCTimer(thread, this))) |
| 97 , m_queue(queue) | 106 , m_queue(queue) |
| 98 , m_resourceProvider(resourceProvider) | 107 , m_resourceProvider(resourceProvider) |
| 99 , m_copier(copier) | 108 , m_copier(copier) |
| 100 , m_uploader(uploader) | 109 , m_uploader(uploader) |
| 101 , m_monotonicTimeLimit(0) | 110 , m_monotonicTimeLimit(0) |
| 111 , m_textureUpdatesPerTick(maxTextureUpdates) |
| 102 , m_firstUpdateAttempt(true) | 112 , m_firstUpdateAttempt(true) |
| 103 { | 113 { |
| 104 } | 114 } |
| 105 | 115 |
| 106 CCTextureUpdateController::~CCTextureUpdateController() | 116 CCTextureUpdateController::~CCTextureUpdateController() |
| 107 { | 117 { |
| 108 } | 118 } |
| 109 | 119 |
| 110 bool CCTextureUpdateController::hasMoreUpdates() const | 120 bool CCTextureUpdateController::hasMoreUpdates() const |
| 111 { | 121 { |
| 112 return m_queue->hasMoreUpdates(); | 122 return m_queue->hasMoreUpdates(); |
| 113 } | 123 } |
| 114 | 124 |
| 115 void CCTextureUpdateController::updateMoreTextures(double monotonicTimeLimit) | 125 void CCTextureUpdateController::updateMoreTextures(double monotonicTimeLimit) |
| 116 { | 126 { |
| 117 m_monotonicTimeLimit = monotonicTimeLimit; | 127 m_monotonicTimeLimit = monotonicTimeLimit; |
| 118 | 128 |
| 119 if (!m_queue->hasMoreUpdates()) | 129 if (!m_queue->hasMoreUpdates()) |
| 120 return; | 130 return; |
| 121 | 131 |
| 122 // Call updateMoreTexturesNow() directly unless it's the first update | 132 // Call updateMoreTexturesNow() directly unless it's the first update |
| 123 // attempt. This ensures that we empty the update queue in a finite | 133 // attempt. This ensures that we empty the update queue in a finite |
| 124 // amount of time. | 134 // amount of time. |
| 125 if (m_firstUpdateAttempt) { | 135 if (m_firstUpdateAttempt) { |
| 126 updateMoreTexturesIfEnoughTimeRemaining(); | 136 updateMoreTexturesIfEnoughTimeRemaining(); |
| 127 m_firstUpdateAttempt = false; | 137 m_firstUpdateAttempt = false; |
| 128 } else | 138 } else |
| 129 updateMoreTexturesNow(); | 139 updateMoreTexturesNow(); |
| 140 |
| 130 } | 141 } |
| 131 | 142 |
| 132 void CCTextureUpdateController::onTimerFired() | 143 void CCTextureUpdateController::onTimerFired() |
| 133 { | 144 { |
| 134 if (!m_queue->hasMoreUpdates()) | 145 if (!m_queue->hasMoreUpdates()) |
| 135 return; | 146 return; |
| 136 | 147 |
| 137 updateMoreTexturesIfEnoughTimeRemaining(); | 148 updateMoreTexturesIfEnoughTimeRemaining(); |
| 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 m_textureUpdatesPerTick; |
| 153 } | 164 } |
| 154 | 165 |
| 155 void CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() | 166 void CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() |
| 156 { | 167 { |
| 157 bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMo
reTexturesTime(); | 168 bool hasTimeRemaining = monotonicTimeNow() < m_monotonicTimeLimit - updateMo
reTexturesTime(); |
| 158 if (hasTimeRemaining) | 169 if (hasTimeRemaining) |
| 159 updateMoreTexturesNow(); | 170 updateMoreTexturesNow(); |
| 160 } | 171 } |
| 161 | 172 |
| 162 void CCTextureUpdateController::updateMoreTexturesNow() | 173 void CCTextureUpdateController::updateMoreTexturesNow() |
| 163 { | 174 { |
| 164 m_timer->startOneShot(updateMoreTexturesTime()); | 175 m_timer->startOneShot(updateMoreTexturesTime()); |
| 165 updateTextures(m_resourceProvider, m_copier, m_uploader, m_queue.get(), upda
teMoreTexturesSize()); | 176 updateTextures(m_resourceProvider, m_copier, m_uploader, m_queue.get(), upda
teMoreTexturesSize()); |
| 166 } | 177 } |
| 167 | 178 |
| 168 } | 179 } |
| OLD | NEW |