diff options
author | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 01:51:17 +0000 |
---|---|---|
committer | brianderson@chromium.org <brianderson@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-09-19 01:51:17 +0000 |
commit | 41b8f68e385878d06d578febf0e6e700fb2a99ba (patch) | |
tree | 137928af89d5a22fadc7b68966979b9a9204b77a /cc/ThrottledTextureUploader.cpp | |
parent | 835af8b9cd3b376b6784a581cefa3dc4df4bf9d0 (diff) | |
download | chromium_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.cpp | 67 |
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()); } } |