0

cc: Maximize pending updates.

This makes the resource update controller maintain a maximum number of
pending updates. This keeps our pipeline better filled without
theoretically increasing the risk that we delay drawing at vsync tick.

BUG=145825
TEST=cc_unittests and manual testing


Review URL: https://chromiumcodereview.appspot.com/11347019

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166298 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
reveman@chromium.org
2012-11-06 23:26:51 +00:00
parent 45ee09a2bb
commit bb87580f83
3 changed files with 71 additions and 35 deletions

@ -95,18 +95,19 @@ void ResourceUpdateController::performMoreUpdates(
// Call updateMoreTexturesNow() directly unless it's the first update
// attempt. This ensures that we empty the update queue in a finite
// amount of time.
if (m_firstUpdateAttempt) {
// Post a 0-delay task when no updates were left. When it runs,
// readyToFinalizeTextureUpdates() will be called.
if (!updateMoreTexturesIfEnoughTimeRemaining()) {
m_taskPosted = true;
m_thread->postTask(base::Bind(&ResourceUpdateController::onTimerFired,
m_weakFactory.GetWeakPtr()));
}
m_firstUpdateAttempt = false;
} else
if (!m_firstUpdateAttempt)
updateMoreTexturesNow();
// Post a 0-delay task when no updates were left. When it runs,
// readyToFinalizeTextureUpdates() will be called.
if (!updateMoreTexturesIfEnoughTimeRemaining()) {
m_taskPosted = true;
m_thread->postTask(
base::Bind(&ResourceUpdateController::onTimerFired,
m_weakFactory.GetWeakPtr()));
}
m_firstUpdateAttempt = false;
}
void ResourceUpdateController::discardUploadsToEvictedResources()
@ -240,27 +241,38 @@ size_t ResourceUpdateController::maxBlockingUpdates() const
return updateMoreTexturesSize() * maxBlockingUpdateIntervals;
}
base::TimeDelta ResourceUpdateController::pendingUpdateTime() const
{
base::TimeDelta updateOneResourceTime =
updateMoreTexturesTime() / updateMoreTexturesSize();
return updateOneResourceTime * m_resourceProvider->numBlockingUploads();
}
bool ResourceUpdateController::updateMoreTexturesIfEnoughTimeRemaining()
{
// Blocking uploads will increase when we're too aggressive in our upload
// time estimate. We use a different timeout here to prevent unnecessary
// amounts of idle time when blocking uploads have reached the max.
if (m_resourceProvider->numBlockingUploads() >= maxBlockingUpdates()) {
m_taskPosted = true;
m_thread->postDelayedTask(base::Bind(&ResourceUpdateController::onTimerFired,
m_weakFactory.GetWeakPtr()),
uploaderBusyTickRate * 1000);
return true;
while (m_resourceProvider->numBlockingUploads() < maxBlockingUpdates()) {
if (!m_queue->fullUploadSize())
return false;
if (!m_timeLimit.is_null()) {
// Estimated completion time of all pending updates.
base::TimeTicks completionTime = this->now() + pendingUpdateTime();
// Time remaining based on current completion estimate.
base::TimeDelta timeRemaining = m_timeLimit - completionTime;
if (timeRemaining < updateMoreTexturesTime())
return true;
}
updateMoreTexturesNow();
}
if (!m_queue->fullUploadSize())
return false;
bool hasTimeRemaining = m_timeLimit.is_null() ||
this->now() < m_timeLimit - updateMoreTexturesTime();
if (hasTimeRemaining)
updateMoreTexturesNow();
m_taskPosted = true;
m_thread->postDelayedTask(
base::Bind(&ResourceUpdateController::onTimerFired,
m_weakFactory.GetWeakPtr()),
uploaderBusyTickRate * 1000);
return true;
}
@ -268,10 +280,6 @@ void ResourceUpdateController::updateMoreTexturesNow()
{
size_t uploads = std::min(
m_queue->fullUploadSize(), updateMoreTexturesSize());
m_taskPosted = true;
m_thread->postDelayedTask(base::Bind(&ResourceUpdateController::onTimerFired,
m_weakFactory.GetWeakPtr()),
updateMoreTexturesTime().InSecondsF() / updateMoreTexturesSize() * uploads * 1000);
if (!uploads)
return;

@ -54,6 +54,7 @@ private:
static size_t maxFullUpdatesPerTick(ResourceProvider*);
size_t maxBlockingUpdates() const;
base::TimeDelta pendingUpdateTime() const;
void updateTexture(ResourceUpdate);

@ -12,6 +12,7 @@
#include "cc/test/scheduler_test_common.h"
#include "cc/test/tiled_layer_test_common.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/khronos/GLES2/gl2ext.h"
using namespace cc;
using namespace WebKit;
@ -52,6 +53,8 @@ public:
return WebString("");
}
virtual void getQueryObjectuivEXT(WebGLId, WGC3Denum, WGC3Duint*);
private:
ResourceUpdateControllerTest* m_test;
bool m_supportShallowFlush;
@ -71,6 +74,7 @@ public:
, m_numDanglingUploads(0)
, m_numTotalUploads(0)
, m_numTotalFlushes(0)
, m_queryResultsAvailable(0)
{
}
@ -105,6 +109,15 @@ public:
m_numTotalUploads++;
}
bool isQueryResultAvailable()
{
if (!m_queryResultsAvailable)
return false;
m_queryResultsAvailable--;
return true;
}
protected:
virtual void SetUp()
{
@ -177,6 +190,11 @@ protected:
updateController->finalize();
}
void makeQueryResultAvailable()
{
m_queryResultsAvailable++;
}
protected:
// Classes required to interact and test the ResourceUpdateController
scoped_ptr<GraphicsContext> m_context;
@ -185,6 +203,7 @@ protected:
scoped_ptr<PrioritizedTexture> m_textures[4];
scoped_ptr<PrioritizedTextureManager> m_textureManager;
SkBitmap m_bitmap;
int m_queryResultsAvailable;
// Properties / expectations of this test
int m_fullUploadCountExpected;
@ -222,6 +241,14 @@ void WebGraphicsContext3DForUploadTest::texSubImage2D(WGC3Denum target,
m_test->onUpload();
}
void WebGraphicsContext3DForUploadTest::getQueryObjectuivEXT(
WebGLId,
WGC3Denum pname,
WGC3Duint* params) {
if (pname == GL_QUERY_RESULT_AVAILABLE_EXT)
*params = m_test->isQueryResultAvailable();
}
// ZERO UPLOADS TESTS
TEST_F(ResourceUpdateControllerTest, ZeroUploads)
{
@ -381,10 +408,12 @@ TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures)
// Only enough time for 1 update.
controller->performMoreUpdates(
controller->now() + base::TimeDelta::FromMilliseconds(120));
runPendingTask(&thread, controller.get());
EXPECT_FALSE(thread.hasPendingTask());
EXPECT_EQ(1, m_numTotalUploads);
// Complete one upload.
makeQueryResultAvailable();
controller->setUpdateMoreTexturesTime(
base::TimeDelta::FromMilliseconds(100));
controller->setUpdateMoreTexturesSize(1);
@ -392,7 +421,6 @@ TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures)
controller->performMoreUpdates(
controller->now() + base::TimeDelta::FromMilliseconds(220));
runPendingTask(&thread, controller.get());
runPendingTask(&thread, controller.get());
EXPECT_FALSE(thread.hasPendingTask());
EXPECT_TRUE(client.readyToFinalizeCalled());
EXPECT_EQ(3, m_numTotalUploads);
@ -420,7 +448,6 @@ TEST_F(ResourceUpdateControllerTest, NoMoreUpdates)
controller->performMoreUpdates(
controller->now() + base::TimeDelta::FromMilliseconds(310));
runPendingTask(&thread, controller.get());
runPendingTask(&thread, controller.get());
EXPECT_FALSE(thread.hasPendingTask());
EXPECT_TRUE(client.readyToFinalizeCalled());
EXPECT_EQ(2, m_numTotalUploads);