summaryrefslogtreecommitdiffstats
path: root/cc/ThrottledTextureUploader.cpp
diff options
context:
space:
mode:
authorbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-19 01:51:17 +0000
committerbrianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-19 01:51:17 +0000
commit41b8f68e385878d06d578febf0e6e700fb2a99ba (patch)
tree137928af89d5a22fadc7b68966979b9a9204b77a /cc/ThrottledTextureUploader.cpp
parent835af8b9cd3b376b6784a581cefa3dc4df4bf9d0 (diff)
downloadchromium_src-41b8f68e385878d06d578febf0e6e700fb2a99ba.zip
chromium_src-41b8f68e385878d06d578febf0e6e700fb2a99ba.tar.gz
chromium_src-41b8f68e385878d06d578febf0e6e700fb2a99ba.tar.bz2
Adaptively throttle texture uploads
We need adaptive texture uploading because we run on a wide variety of systems and a one size fits all policy will not work. This patch maintains a tick rate of 4ms and default upload count of 12 textures per tick, but allows for more textures per tick if we've measured that we can be faster. The number of partial updates allowed is also communicated from the impl thread to the main thread at the beggining of each frame. BUG=145825 Review URL: https://chromiumcodereview.appspot.com/10916292 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@157473 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/ThrottledTextureUploader.cpp')
-rw-r--r--cc/ThrottledTextureUploader.cpp67
1 files changed, 62 insertions, 5 deletions
diff --git a/cc/ThrottledTextureUploader.cpp b/cc/ThrottledTextureUploader.cpp
index 274205d..f9de78c 100644
--- a/cc/ThrottledTextureUploader.cpp
+++ b/cc/ThrottledTextureUploader.cpp
@@ -3,17 +3,26 @@
// found in the LICENSE file.
#include "config.h"
-
#include "ThrottledTextureUploader.h"
#include "Extensions3DChromium.h"
+#include <algorithm>
#include <public/WebGraphicsContext3D.h>
+#include <vector>
namespace {
// Number of pending texture update queries to allow.
static const size_t maxPendingQueries = 2;
+// How many previous uploads to use when predicting future throughput.
+static const size_t uploadHistorySize = 10;
+
+// Global estimated number of textures per second to maintain estimates across
+// subsequent instances of ThrottledTextureUploader.
+// More than one thread will not access this variable, so we do not need to synchronize access.
+static double estimatedTexturesPerSecondGlobal = 48.0 * 60.0;
+
} // anonymous namespace
namespace cc {
@@ -21,6 +30,9 @@ namespace cc {
ThrottledTextureUploader::Query::Query(WebKit::WebGraphicsContext3D* context)
: m_context(context)
, m_queryId(0)
+ , m_value(0)
+ , m_hasValue(false)
+ , m_texturesUploaded(0)
{
m_queryId = m_context->createQueryEXT();
}
@@ -35,9 +47,10 @@ void ThrottledTextureUploader::Query::begin()
m_context->beginQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM, m_queryId);
}
-void ThrottledTextureUploader::Query::end()
+void ThrottledTextureUploader::Query::end(double texturesUploaded)
{
m_context->endQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM);
+ m_texturesUploaded = texturesUploaded;
}
bool ThrottledTextureUploader::Query::isPending()
@@ -49,19 +62,37 @@ bool ThrottledTextureUploader::Query::isPending()
void ThrottledTextureUploader::Query::wait()
{
- unsigned result;
- m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_RESULT_EXT, &result);
+ value();
+ return;
+}
+
+unsigned ThrottledTextureUploader::Query::value()
+{
+ if (!m_hasValue) {
+ m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_RESULT_EXT, &m_value);
+ m_hasValue = true;
+ }
+ return m_value;
+}
+
+double ThrottledTextureUploader::Query::texturesUploaded()
+{
+ return m_texturesUploaded;
}
ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context)
: m_context(context)
, m_maxPendingQueries(maxPendingQueries)
+ , m_texturesPerSecondHistory(uploadHistorySize, estimatedTexturesPerSecondGlobal)
+ , m_texturesUploaded(0)
{
}
ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context, size_t pendingUploadLimit)
: m_context(context)
, m_maxPendingQueries(pendingUploadLimit)
+ , m_texturesPerSecondHistory(uploadHistorySize, estimatedTexturesPerSecondGlobal)
+ , m_texturesUploaded(0)
{
ASSERT(m_context);
}
@@ -84,8 +115,26 @@ bool ThrottledTextureUploader::isBusy()
return false;
}
+double ThrottledTextureUploader::estimatedTexturesPerSecond()
+{
+ processQueries();
+
+ // The history should never be empty because we initialize all elements with an estimate.
+ ASSERT(m_texturesPerSecondHistory.size() == uploadHistorySize);
+
+ // Sort the history and use the median as our estimate.
+ std::vector<double> sortedHistory(m_texturesPerSecondHistory.begin(),
+ m_texturesPerSecondHistory.end());
+ std::sort(sortedHistory.begin(), sortedHistory.end());
+
+ estimatedTexturesPerSecondGlobal = sortedHistory[sortedHistory.size() / 2];
+ return estimatedTexturesPerSecondGlobal;
+}
+
void ThrottledTextureUploader::beginUploads()
{
+ m_texturesUploaded = 0;
+
// Wait for query to become available.
while (isBusy())
m_pendingQueries.first()->wait();
@@ -96,12 +145,13 @@ void ThrottledTextureUploader::beginUploads()
void ThrottledTextureUploader::endUploads()
{
- m_availableQueries.first()->end();
+ m_availableQueries.first()->end(m_texturesUploaded);
m_pendingQueries.append(m_availableQueries.takeFirst());
}
void ThrottledTextureUploader::uploadTexture(CCResourceProvider* resourceProvider, Parameters upload)
{
+ m_texturesUploaded++;
upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destOffset);
}
@@ -111,6 +161,13 @@ void ThrottledTextureUploader::processQueries()
if (m_pendingQueries.first()->isPending())
break;
+ unsigned usElapsed = m_pendingQueries.first()->value();
+ double texturesPerSecond = m_pendingQueries.first()->texturesUploaded() / (usElapsed * 1e-6);
+
+ // Remove the oldest values from our history and insert the new one
+ m_texturesPerSecondHistory.pop_back();
+ m_texturesPerSecondHistory.push_front(texturesPerSecond);
+
m_availableQueries.append(m_pendingQueries.takeFirst());
}
}