Index: cc/CCTextureUpdateController.cpp |
diff --git a/cc/CCTextureUpdateController.cpp b/cc/CCTextureUpdateController.cpp |
index 200948da6b8522c1320df3e4d1e538c152389bca..7e0800142eca6416a082319984661bcc1f64969f 100644 |
--- a/cc/CCTextureUpdateController.cpp |
+++ b/cc/CCTextureUpdateController.cpp |
@@ -16,7 +16,7 @@ |
namespace { |
// Number of partial updates we allow. |
-static const size_t partialTextureUpdatesMax = 12; |
+static const int partialTextureUpdatesMax = 12; |
// Measured in seconds. |
static const double textureUpdateTickRate = 0.004; |
@@ -28,31 +28,28 @@ static const double uploaderBusyTickRate = 0.001; |
static const int textureUploadFlushPeriod = 4; |
// Number of blocking update intervals to allow. |
-static const size_t maxBlockingUpdateIntervals = 4; |
+static const double maxBlockingUpdateIntervals = 4; |
+ |
+// We will upload this many intervals worth of textures initially |
+// then attempt to keep at least this many intervals queued. |
+static const double targetBlockingUpdateIntervals = 2; |
} // anonymous namespace |
namespace cc { |
-size_t CCTextureUpdateController::maxPartialTextureUpdates() |
+int CCTextureUpdateController::maxPartialTextureUpdates() |
{ |
return partialTextureUpdatesMax; |
} |
-size_t CCTextureUpdateController::maxFullUpdatesPerTick(TextureUploader* uploader) |
-{ |
- double texturesPerSecond = uploader->estimatedTexturesPerSecond(); |
- size_t texturesPerTick = floor(textureUpdateTickRate * texturesPerSecond); |
- return texturesPerTick ? texturesPerTick : 1; |
-} |
- |
CCTextureUpdateController::CCTextureUpdateController(CCTextureUpdateControllerClient* client, CCThread* thread, PassOwnPtr<CCTextureUpdateQueue> queue, CCResourceProvider* resourceProvider, TextureUploader* uploader) |
: m_client(client) |
, m_timer(adoptPtr(new CCTimer(thread, this))) |
, m_queue(queue) |
, m_resourceProvider(resourceProvider) |
, m_uploader(uploader) |
- , m_textureUpdatesPerTick(maxFullUpdatesPerTick(uploader)) |
+ , m_estimatedTexturesPerSecond(uploader->estimatedTexturesPerSecond()) |
, m_firstUpdateAttempt(true) |
{ |
} |
@@ -81,7 +78,7 @@ void CCTextureUpdateController::performMoreUpdates( |
m_firstUpdateAttempt = false; |
} else |
- updateMoreTexturesNow(); |
+ updateMoreTexturesNow(updateMoreTexturesSize()); |
} |
void CCTextureUpdateController::discardUploadsToEvictedResources() |
@@ -91,7 +88,7 @@ void CCTextureUpdateController::discardUploadsToEvictedResources() |
void CCTextureUpdateController::finalize() |
{ |
- size_t uploadCount = 0; |
+ int uploadCount = 0; |
while (m_queue->fullUploadSize()) { |
if (!(uploadCount % textureUploadFlushPeriod) && uploadCount) |
m_resourceProvider->shallowFlushIfSupported(); |
@@ -142,49 +139,80 @@ base::TimeDelta CCTextureUpdateController::updateMoreTexturesTime() const |
return base::TimeDelta::FromMilliseconds(textureUpdateTickRate * 1000); |
} |
-size_t CCTextureUpdateController::updateMoreTexturesSize() const |
+int CCTextureUpdateController::updateMoreTexturesSize() const |
{ |
- return m_textureUpdatesPerTick; |
+ return m_estimatedTexturesPerSecond * textureUpdateTickRate; |
} |
-size_t CCTextureUpdateController::maxBlockingUpdates() const |
+int CCTextureUpdateController::maxBlockingUploads() const |
{ |
return updateMoreTexturesSize() * maxBlockingUpdateIntervals; |
} |
+int CCTextureUpdateController::targetBlockingUploads() const |
+{ |
+ return updateMoreTexturesSize() * targetBlockingUpdateIntervals; |
+} |
+ |
+int CCTextureUpdateController::maxTexturesBeforeTimeLimit() |
+{ |
+ if (m_timeLimit.is_null()) |
+ return std::numeric_limits<int>::max(); |
+ |
+ return m_estimatedTexturesPerSecond * |
+ (m_timeLimit - this->now()).InSecondsF(); |
+} |
+ |
bool CCTextureUpdateController::updateMoreTexturesIfEnoughTimeRemaining() |
{ |
+ if (!m_queue->fullUploadSize()) |
+ return false; |
+ |
// Blocking uploads will increase when we're too aggressive in our upload |
// time estimate. We use a different timeout here to prevent unnecessary |
// amounts of idle time when blocking uploads have reached the max. |
- if (m_uploader->numBlockingUploads() >= maxBlockingUpdates()) { |
+ int numBlockingUploads = m_uploader->numBlockingUploads(); |
+ if (numBlockingUploads >= maxBlockingUploads()) { |
m_timer->startOneShot(uploaderBusyTickRate); |
return true; |
} |
- if (!m_queue->fullUploadSize()) |
- return false; |
+ int maxTextures = 0; |
+ bool highLatencyMode = numBlockingUploads >= targetBlockingUploads(); |
+ if (highLatencyMode) { |
+ // If we are in a high latency mode, we do not have enough feedback |
+ // so we blindly upload the estimated number of textures. |
+ maxTextures = updateMoreTexturesSize(); |
+ } else { |
+ // If we are in a low latency mode, we can throttle our uploads |
+ // to a well defined target. |
+ maxTextures = targetBlockingUploads() - numBlockingUploads; |
+ } |
- bool hasTimeRemaining = m_timeLimit.is_null() || |
- this->now() < m_timeLimit - updateMoreTexturesTime(); |
- if (hasTimeRemaining) |
- updateMoreTexturesNow(); |
+ // Make sure our texture uploads don't block drawing. |
+ maxTextures = std::min(maxTextures, maxTexturesBeforeTimeLimit()); |
- return true; |
+ updateMoreTexturesNow(maxTextures); |
+ return m_queue->fullUploadSize(); |
} |
-void CCTextureUpdateController::updateMoreTexturesNow() |
+void CCTextureUpdateController::updateMoreTexturesNow(int maxTextures) |
{ |
- size_t uploads = std::min( |
- m_queue->fullUploadSize(), updateMoreTexturesSize()); |
- m_timer->startOneShot( |
- updateMoreTexturesTime().InSecondsF() / updateMoreTexturesSize() * |
- uploads); |
+ int uploads = std::min((int)m_queue->fullUploadSize(), maxTextures); |
+ ASSERT(uploads >= 0); |
- if (!uploads) |
+ if (uploads <= 0) { |
+ m_timer->startOneShot(uploaderBusyTickRate); |
return; |
+ } else if (uploads == m_queue->fullUploadSize()) { |
+ m_timer->startOneShot( |
+ updateMoreTexturesTime().InSecondsF() / updateMoreTexturesSize() * |
+ uploads); |
+ } else { |
+ m_timer->startOneShot(updateMoreTexturesTime().InSecondsF()); |
+ } |
- size_t uploadCount = 0; |
+ int uploadCount = 0; |
while (m_queue->fullUploadSize() && uploadCount < uploads) { |
if (!(uploadCount % textureUploadFlushPeriod) && uploadCount) |
m_resourceProvider->shallowFlushIfSupported(); |