| Index: cc/CCPrioritizedTextureTest.cpp | 
| diff --git a/cc/CCPrioritizedTextureTest.cpp b/cc/CCPrioritizedTextureTest.cpp | 
| index e032d8a69202a7da23790da62989997375706398..d3596da1a788ee6cddbd47a592e5962da81261e5 100644 | 
| --- a/cc/CCPrioritizedTextureTest.cpp | 
| +++ b/cc/CCPrioritizedTextureTest.cpp | 
| @@ -18,7 +18,7 @@ using namespace cc; | 
| using namespace WebKitTests; | 
| using namespace WTF; | 
|  | 
| -namespace { | 
| +namespace cc { | 
|  | 
| class CCPrioritizedTextureTest : public testing::Test { | 
| public: | 
| @@ -50,11 +50,10 @@ public: | 
|  | 
| bool validateTexture(OwnPtr<CCPrioritizedTexture>& texture, bool requestLate) | 
| { | 
| -#if !ASSERT_DISABLED | 
| -        texture->textureManager()->assertInvariants(); | 
| -#endif | 
| +        textureManagerAssertInvariants(texture->textureManager()); | 
| if (requestLate) | 
| texture->requestLate(); | 
| +        textureManagerAssertInvariants(texture->textureManager()); | 
| DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked; | 
| bool success = texture->canAcquireBackingTexture(); | 
| if (success) | 
| @@ -62,11 +61,36 @@ public: | 
| return success; | 
| } | 
|  | 
| +    void prioritizeTexturesAndBackings(CCPrioritizedTextureManager* textureManager) | 
| +    { | 
| +        textureManager->prioritizeTextures(); | 
| +        textureManagerUpdateBackingsPriorities(textureManager); | 
| +    } | 
| + | 
| +    void textureManagerUpdateBackingsPriorities(CCPrioritizedTextureManager* textureManager) | 
| +    { | 
| +        DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked; | 
| +        textureManager->updateBackingsPriorities(); | 
| +    } | 
| + | 
| CCResourceProvider* resourceProvider() | 
| { | 
| return m_resourceProvider.get(); | 
| } | 
|  | 
| +    void textureManagerAssertInvariants(CCPrioritizedTextureManager* textureManager) | 
| +    { | 
| +#if !ASSERT_DISABLED | 
| +        DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked; | 
| +        textureManager->assertInvariants(); | 
| +#endif | 
| +    } | 
| + | 
| +    bool textureBackingIsAbovePriorityCutoff(CCPrioritizedTexture* texture) | 
| +    { | 
| +        return texture->m_backing->wasAbovePriorityCutoffAtLastPriorityUpdate(); | 
| +    } | 
| + | 
| protected: | 
| const IntSize m_textureSize; | 
| const GC3Denum m_textureFormat; | 
| @@ -75,6 +99,10 @@ protected: | 
| OwnPtr<CCResourceProvider> m_resourceProvider; | 
| }; | 
|  | 
| +} | 
| + | 
| +namespace { | 
| + | 
| TEST_F(CCPrioritizedTextureTest, requestTextureExceedingMaxLimit) | 
| { | 
| const size_t maxTextures = 8; | 
| @@ -91,7 +119,7 @@ TEST_F(CCPrioritizedTextureTest, requestTextureExceedingMaxLimit) | 
| textures[i]->setRequestPriority(100 + i); | 
|  | 
| // Only lower half should be available. | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| EXPECT_TRUE(validateTexture(textures[0], false)); | 
| EXPECT_TRUE(validateTexture(textures[7], false)); | 
| EXPECT_FALSE(validateTexture(textures[8], false)); | 
| @@ -102,7 +130,7 @@ TEST_F(CCPrioritizedTextureTest, requestTextureExceedingMaxLimit) | 
| textures[i]->setRequestPriority(100 - i); | 
|  | 
| // Only upper half should be available. | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| EXPECT_FALSE(validateTexture(textures[0], false)); | 
| EXPECT_FALSE(validateTexture(textures[7], false)); | 
| EXPECT_TRUE(validateTexture(textures[8], false)); | 
| @@ -128,7 +156,7 @@ TEST_F(CCPrioritizedTextureTest, changeMemoryLimits) | 
|  | 
| // Set max limit to 8 textures | 
| textureManager->setMaxMemoryLimitBytes(texturesMemorySize(8)); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| for (size_t i = 0; i < maxTextures; ++i) | 
| validateTexture(textures[i], false); | 
| { | 
| @@ -141,7 +169,7 @@ TEST_F(CCPrioritizedTextureTest, changeMemoryLimits) | 
|  | 
| // Set max limit to 5 textures | 
| textureManager->setMaxMemoryLimitBytes(texturesMemorySize(5)); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| for (size_t i = 0; i < maxTextures; ++i) | 
| EXPECT_EQ(validateTexture(textures[i], false), i < 5); | 
| { | 
| @@ -154,7 +182,7 @@ TEST_F(CCPrioritizedTextureTest, changeMemoryLimits) | 
|  | 
| // Set max limit to 4 textures | 
| textureManager->setMaxMemoryLimitBytes(texturesMemorySize(4)); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| for (size_t i = 0; i < maxTextures; ++i) | 
| EXPECT_EQ(validateTexture(textures[i], false), i < 4); | 
| { | 
| @@ -184,7 +212,7 @@ TEST_F(CCPrioritizedTextureTest, textureManagerPartialUpdateTextures) | 
|  | 
| for (size_t i = 0; i < numTextures; ++i) | 
| textures[i]->setRequestPriority(200 + i); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
|  | 
| // Allocate textures which are currently high priority. | 
| EXPECT_TRUE(validateTexture(textures[0], false)); | 
| @@ -199,7 +227,7 @@ TEST_F(CCPrioritizedTextureTest, textureManagerPartialUpdateTextures) | 
|  | 
| for (size_t i = 0; i < numTextures; ++i) | 
| moreTextures[i]->setRequestPriority(100 + i); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
|  | 
| // Textures are now below cutoff. | 
| EXPECT_FALSE(validateTexture(textures[0], false)); | 
| @@ -246,7 +274,7 @@ TEST_F(CCPrioritizedTextureTest, textureManagerPrioritiesAreEqual) | 
|  | 
| // Set max limit to 8 textures | 
| textureManager->setMaxMemoryLimitBytes(texturesMemorySize(8)); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
|  | 
| // The two high priority textures should be available, others should not. | 
| for (size_t i = 0; i < 2; ++i) | 
| @@ -278,7 +306,7 @@ TEST_F(CCPrioritizedTextureTest, textureManagerDestroyedFirst) | 
| EXPECT_FALSE(texture->haveBackingTexture()); | 
|  | 
| texture->setRequestPriority(100); | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
|  | 
| EXPECT_TRUE(validateTexture(texture, false)); | 
| EXPECT_TRUE(texture->canAcquireBackingTexture()); | 
| @@ -304,7 +332,7 @@ TEST_F(CCPrioritizedTextureTest, textureMovedToNewManager) | 
| EXPECT_FALSE(texture->haveBackingTexture()); | 
|  | 
| texture->setRequestPriority(100); | 
| -    textureManagerOne->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManagerOne.get()); | 
|  | 
| EXPECT_TRUE(validateTexture(texture, false)); | 
| EXPECT_TRUE(texture->canAcquireBackingTexture()); | 
| @@ -323,7 +351,7 @@ TEST_F(CCPrioritizedTextureTest, textureMovedToNewManager) | 
|  | 
| texture->setTextureManager(textureManagerTwo.get()); | 
|  | 
| -    textureManagerTwo->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManagerTwo.get()); | 
|  | 
| EXPECT_TRUE(validateTexture(texture, false)); | 
| EXPECT_TRUE(texture->canAcquireBackingTexture()); | 
| @@ -354,7 +382,7 @@ TEST_F(CCPrioritizedTextureTest, renderSurfacesReduceMemoryAvailableOutsideRootS | 
| textures[i]->setRequestPriority(100 + i); | 
|  | 
| // Only lower half should be available. | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| EXPECT_TRUE(validateTexture(textures[0], false)); | 
| EXPECT_TRUE(validateTexture(textures[3], false)); | 
| EXPECT_FALSE(validateTexture(textures[4], false)); | 
| @@ -365,7 +393,7 @@ TEST_F(CCPrioritizedTextureTest, renderSurfacesReduceMemoryAvailableOutsideRootS | 
| textures[i]->setRequestPriority(100 - i); | 
|  | 
| // Only upper half should be available. | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| EXPECT_FALSE(validateTexture(textures[0], false)); | 
| EXPECT_FALSE(validateTexture(textures[3], false)); | 
| EXPECT_TRUE(validateTexture(textures[4], false)); | 
| @@ -400,7 +428,7 @@ TEST_F(CCPrioritizedTextureTest, renderSurfacesReduceMemoryAvailableForRequestLa | 
| textures[i]->setRequestPriority(100); | 
|  | 
| // The first four to be requested late will be available. | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| for (unsigned i = 0; i < maxTextures; ++i) | 
| EXPECT_FALSE(validateTexture(textures[i], false)); | 
| for (unsigned i = 0; i < maxTextures; i += 2) | 
| @@ -438,7 +466,7 @@ TEST_F(CCPrioritizedTextureTest, whenRenderSurfaceNotAvailableTexturesAlsoNotAva | 
| for (size_t i = 6; i < 8; ++i) | 
| textures[i]->setRequestPriority(CCPriorityCalculator::visiblePriority(false)); | 
|  | 
| -    textureManager->prioritizeTextures(); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
|  | 
| // Unable to requestLate textures in the child surface. | 
| EXPECT_FALSE(validateTexture(textures[6], true)); | 
| @@ -456,4 +484,53 @@ TEST_F(CCPrioritizedTextureTest, whenRenderSurfaceNotAvailableTexturesAlsoNotAva | 
| textureManager->clearAllMemory(resourceProvider()); | 
| } | 
|  | 
| +TEST_F(CCPrioritizedTextureTest, requestLateBackingsSorting) | 
| +{ | 
| +    const size_t maxTextures = 8; | 
| +    OwnPtr<CCPrioritizedTextureManager> textureManager = createManager(maxTextures); | 
| +    textureManager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures)); | 
| + | 
| +    // Create textures to fill our memory limit. | 
| +    OwnPtr<CCPrioritizedTexture> textures[maxTextures]; | 
| +    for (size_t i = 0; i < maxTextures; ++i) | 
| +        textures[i] = textureManager->createTexture(m_textureSize, m_textureFormat); | 
| + | 
| +    // Set equal priorities, and allocate backings for all textures. | 
| +    for (size_t i = 0; i < maxTextures; ++i) | 
| +        textures[i]->setRequestPriority(100); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| +    for (unsigned i = 0; i < maxTextures; ++i) | 
| +        EXPECT_TRUE(validateTexture(textures[i], false)); | 
| + | 
| +    // Drop the memory limit and prioritize (none will be above the threshold, | 
| +    // but they still have backings because reduceMemory hasn't been called). | 
| +    textureManager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures / 2)); | 
| +    prioritizeTexturesAndBackings(textureManager.get()); | 
| + | 
| +    // Push half of them back over the limit. | 
| +    for (size_t i = 0; i < maxTextures; i += 2) | 
| +        EXPECT_TRUE(textures[i]->requestLate()); | 
| + | 
| +    // Push the priorities to the backings array and sort the backings array | 
| +    textureManagerUpdateBackingsPriorities(textureManager.get()); | 
| + | 
| +    // Assert that the backings list be sorted with the below-limit backings | 
| +    // before the above-limit backings. | 
| +    textureManagerAssertInvariants(textureManager.get()); | 
| + | 
| +    // Make sure that we have backings for all of the textures. | 
| +    for (size_t i = 0; i < maxTextures; ++i) | 
| +        EXPECT_TRUE(textures[i]->haveBackingTexture()); | 
| + | 
| +    // Make sure that only the requestLate textures are above the priority cutoff | 
| +    for (size_t i = 0; i < maxTextures; i += 2) | 
| +        EXPECT_TRUE(textureBackingIsAbovePriorityCutoff(textures[i].get())); | 
| +    for (size_t i = 1; i < maxTextures; i += 2) | 
| +        EXPECT_FALSE(textureBackingIsAbovePriorityCutoff(textures[i].get())); | 
| + | 
| +    DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked; | 
| +    textureManager->clearAllMemory(resourceProvider()); | 
| +} | 
| + | 
| + | 
| } // namespace | 
|  |