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

Side by Side Diff: cc/CCTextureUpdateController.cpp

Issue 10916292: Adaptively throttle texture uploads (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 3 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
OLDNEW
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698