Chromium Code Reviews| Index: cc/ThrottledTextureUploader.cpp |
| diff --git a/cc/ThrottledTextureUploader.cpp b/cc/ThrottledTextureUploader.cpp |
| index 274205da3970520c5168a57e6012e7b99442e657..2c8abc80441e514089c2dca53f16bcdc2b217658 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 pixels 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 estimatedPixelsPerSecondGlobal = 256.0 * 256.0 * 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_pixelsUploaded(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 pixelsUploaded) |
| { |
| m_context->endQueryEXT(Extensions3DChromium::COMMANDS_ISSUED_CHROMIUM); |
| + m_pixelsUploaded = pixelsUploaded; |
| } |
| bool ThrottledTextureUploader::Query::isPending() |
| @@ -49,19 +62,35 @@ 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); |
| + return m_value; |
| +} |
| + |
| +double ThrottledTextureUploader::Query::pixelsUploaded() |
| +{ |
| + return m_pixelsUploaded; |
| } |
| ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context) |
| : m_context(context) |
| , m_maxPendingQueries(maxPendingQueries) |
| + , m_pixelsPerSecondHistory(uploadHistorySize, estimatedPixelsPerSecondGlobal) |
| + , m_pixelsUploaded(0) |
| { |
| } |
| ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context, size_t pendingUploadLimit) |
| : m_context(context) |
| , m_maxPendingQueries(pendingUploadLimit) |
| + , m_pixelsPerSecondHistory(uploadHistorySize, estimatedPixelsPerSecondGlobal) |
| + , m_pixelsUploaded(0) |
| { |
| ASSERT(m_context); |
| } |
| @@ -69,7 +98,6 @@ ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* |
| ThrottledTextureUploader::~ThrottledTextureUploader() |
| { |
| } |
|
reveman
2012/09/18 05:30:35
nit: prefer if you keep the blank line you removed
brianderson
2012/09/18 20:03:00
Done.
|
| - |
| bool ThrottledTextureUploader::isBusy() |
| { |
| processQueries(); |
| @@ -84,8 +112,26 @@ bool ThrottledTextureUploader::isBusy() |
| return false; |
| } |
| +double ThrottledTextureUploader::estimatedPixelsPerSecond() |
| +{ |
| + processQueries(); |
| + |
| + // The history should never be empty because we initialize all elements with an estimate. |
| + ASSERT(m_pixelsPerSecondHistory.size() == uploadHistorySize); |
| + |
| + // Sort the history and use the median as our estimate. |
| + std::vector<double> sortedHistory(m_pixelsPerSecondHistory.begin(), |
| + m_pixelsPerSecondHistory.end()); |
| + std::sort(sortedHistory.begin(), sortedHistory.end()); |
| + |
| + estimatedPixelsPerSecondGlobal = sortedHistory[sortedHistory.size() / 2]; |
| + return estimatedPixelsPerSecondGlobal; |
| +} |
| + |
| void ThrottledTextureUploader::beginUploads() |
| { |
| + m_pixelsUploaded = 0; |
| + |
| // Wait for query to become available. |
| while (isBusy()) |
| m_pendingQueries.first()->wait(); |
| @@ -96,12 +142,13 @@ void ThrottledTextureUploader::beginUploads() |
| void ThrottledTextureUploader::endUploads() |
| { |
| - m_availableQueries.first()->end(); |
| + m_availableQueries.first()->end(m_pixelsUploaded); |
| m_pendingQueries.append(m_availableQueries.takeFirst()); |
| } |
| void ThrottledTextureUploader::uploadTexture(CCResourceProvider* resourceProvider, Parameters upload) |
| { |
| + m_pixelsUploaded += upload.sourceRect.width() * upload.sourceRect.width(); |
| upload.texture->updateRect(resourceProvider, upload.sourceRect, upload.destOffset); |
| } |
| @@ -111,6 +158,13 @@ void ThrottledTextureUploader::processQueries() |
| if (m_pendingQueries.first()->isPending()) |
| break; |
| + unsigned usElapsed = m_pendingQueries.first()->value(); |
| + double pixelsPerSecond = m_pendingQueries.first()->pixelsUploaded() / (usElapsed * 1e-6); |
| + |
| + // Remove the oldest values from our history and insert the new one |
| + m_pixelsPerSecondHistory.pop_back(); |
| + m_pixelsPerSecondHistory.push_front(pixelsPerSecond); |
| + |
| m_availableQueries.append(m_pendingQueries.takeFirst()); |
| } |
| } |