Index: cc/ThrottledTextureUploader.cpp |
diff --git a/cc/ThrottledTextureUploader.cpp b/cc/ThrottledTextureUploader.cpp |
index 594342e54ec96873a141c2aad5535ea7a3e62894..410b0ca3a7bcefccc6bb1d93004f9691a00bd27a 100644 |
--- a/cc/ThrottledTextureUploader.cpp |
+++ b/cc/ThrottledTextureUploader.cpp |
@@ -3,10 +3,10 @@ |
// found in the LICENSE file. |
#include "config.h" |
- |
#include "ThrottledTextureUploader.h" |
#include "Extensions3DChromium.h" |
+#include <algorithm> |
#include <public/WebGraphicsContext3D.h> |
namespace { |
@@ -14,6 +14,12 @@ 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; |
+ |
+// Default number of pixels per second. |
+static double estimatedPixelsPerSecondDefault = 256 * 256 * 48; |
+ |
} // anonymous namespace |
namespace WebCore { |
@@ -21,6 +27,7 @@ namespace WebCore { |
ThrottledTextureUploader::Query::Query(WebKit::WebGraphicsContext3D* context) |
: m_context(context) |
, m_queryId(0) |
+ , m_pixelsUploaded(0) |
{ |
m_queryId = m_context->createQueryEXT(); |
} |
@@ -35,9 +42,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 +57,33 @@ bool ThrottledTextureUploader::Query::isPending() |
void ThrottledTextureUploader::Query::wait() |
{ |
+ value(); |
+ return; |
+} |
+ |
+unsigned ThrottledTextureUploader::Query::value() |
+{ |
unsigned result; |
m_context->getQueryObjectuivEXT(m_queryId, Extensions3DChromium::QUERY_RESULT_EXT, &result); |
+ return result; |
+} |
+ |
+double ThrottledTextureUploader::Query::pixelsUploaded() |
+{ |
+ return m_pixelsUploaded; |
} |
ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context) |
: m_context(context) |
, m_maxPendingQueries(maxPendingQueries) |
+ , m_pixelsUploaded(0) |
{ |
} |
ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* context, size_t pendingUploadLimit) |
: m_context(context) |
, m_maxPendingQueries(pendingUploadLimit) |
+ , m_pixelsUploaded(0) |
{ |
ASSERT(m_context); |
} |
@@ -69,7 +91,6 @@ ThrottledTextureUploader::ThrottledTextureUploader(WebKit::WebGraphicsContext3D* |
ThrottledTextureUploader::~ThrottledTextureUploader() |
{ |
} |
- |
bool ThrottledTextureUploader::isBusy() |
{ |
processQueries(); |
@@ -84,8 +105,23 @@ bool ThrottledTextureUploader::isBusy() |
return false; |
} |
+double ThrottledTextureUploader::estimatedPixelsPerSecond() |
+{ |
+ processQueries(); |
+ |
+ if (m_pixelsPerSecondHistory.empty()) |
+ return estimatedPixelsPerSecondDefault; |
+ |
+ // Sort the history and use the median as our estimate. |
+ std::deque<double> sortedHistory(m_pixelsPerSecondHistory); |
+ std::sort(sortedHistory.begin(), sortedHistory.end()); |
+ return sortedHistory[sortedHistory.size() / 2]; |
+} |
+ |
void ThrottledTextureUploader::beginUploads() |
{ |
+ m_pixelsUploaded = 0; |
+ |
// Wait for query to become available. |
while (isBusy()) |
m_pendingQueries.first()->wait(); |
@@ -96,12 +132,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 +148,14 @@ 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 |
+ if (m_pixelsPerSecondHistory.size() >= uploadHistorySize) |
+ m_pixelsPerSecondHistory.pop_back(); |
+ m_pixelsPerSecondHistory.push_front(pixelsPerSecond); |
+ |
m_availableQueries.append(m_pendingQueries.takeFirst()); |
} |
} |