| Index: cc/ThrottledTextureUploader.cpp
|
| diff --git a/cc/ThrottledTextureUploader.cpp b/cc/ThrottledTextureUploader.cpp
|
| index 274205da3970520c5168a57e6012e7b99442e657..f9de78cc32fe9e1f497ae9ff2764e42196d5d589 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());
|
| }
|
| }
|
|
|