Diff
Modified: trunk/Source/WebCore/ChangeLog (128252 => 128253)
--- trunk/Source/WebCore/ChangeLog 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebCore/ChangeLog 2012-09-12 01:35:47 UTC (rev 128253)
@@ -1,3 +1,45 @@
+2012-09-11 Christopher Cameron <[email protected]>
+
+ [chromium] Make prioritized texture manager not touch backings array on the main thread
+ https://bugs.webkit.org/show_bug.cgi?id=96114
+
+ Reviewed by James Robinson.
+
+ Take a snapshot of the textures' priorities from the main thread,
+ and save it in their backings for access by the impl thread.
+ Update functions that access the sorted backings array to use the
+ snapshotted values instead of the values that the main thread may
+ have computed for the next frame.
+
+ Make the main thread not touch the m_backings array. Split
+ prioritizeTextures into a updateBackingsPriorities function.
+ In places where the main thread would have touched m_backings,
+ set a flag specifying that m_backings needs to be re-sorted
+ before any function that requires it be sorted by priority be
+ executed.
+
+ Update the two functions that require sorted order (acquireBacking
+ and reduceMemory) to sort the backings array (if needed) before
+ traversing it.
+
+ Updated tests to set correct thread during asserts. Add a test to
+ verify that requestLate is correctly incorporated into the backing
+ sorting.
+
+ * platform/graphics/chromium/cc/CCPrioritizedTextureManager.cpp:
+ (WebCore::CCPrioritizedTextureManager::CCPrioritizedTextureManager):
+ (WebCore::CCPrioritizedTextureManager::prioritizeTextures):
+ (WebCore):
+ (WebCore::CCPrioritizedTextureManager::prioritizeBackings):
+ (WebCore::CCPrioritizedTextureManager::requestLate):
+ (WebCore::CCPrioritizedTextureManager::acquireBackingTextureIfNeeded):
+ (WebCore::CCPrioritizedTextureManager::reduceMemory):
+ (WebCore::CCPrioritizedTextureManager::returnBackingTexture):
+ (WebCore::CCPrioritizedTextureManager::destroyBacking):
+ (WebCore::CCPrioritizedTextureManager::assertInvariants):
+ * platform/graphics/chromium/cc/CCPrioritizedTextureManager.h:
+ (CCPrioritizedTextureManager):
+
2012-09-11 Adam Barth <[email protected]>
Update bindings test results after http://trac.webkit.org/changeset/128242
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTexture.cpp (128252 => 128253)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTexture.cpp 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTexture.cpp 2012-09-12 01:35:47 UTC (rev 128253)
@@ -28,6 +28,7 @@
#include "CCPrioritizedTextureManager.h"
#include "CCPriorityCalculator.h"
+#include "CCProxy.h"
#include <algorithm>
using namespace std;
@@ -139,4 +140,32 @@
m_bytes = bytes;
}
+CCPrioritizedTexture::Backing::Backing(unsigned id, IntSize size, GC3Denum format)
+ : CCTexture(id, size, format)
+ , m_owner(0)
+ , m_priorityAtLastPriorityUpdate(CCPriorityCalculator::lowestPriority())
+ , m_ownerExistedAtLastPriorityUpdate(false)
+ , m_wasAbovePriorityCutoffAtLastPriorityUpdate(false)
+{
+}
+
+CCPrioritizedTexture::Backing::~Backing()
+{
+ ASSERT(!m_owner);
+}
+
+void CCPrioritizedTexture::Backing::updatePriority()
+{
+ ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
+ if (m_owner) {
+ m_ownerExistedAtLastPriorityUpdate = true;
+ m_priorityAtLastPriorityUpdate = m_owner->requestPriority();
+ m_wasAbovePriorityCutoffAtLastPriorityUpdate = m_owner->isAbovePriorityCutoff();
+ } else {
+ m_ownerExistedAtLastPriorityUpdate = false;
+ m_priorityAtLastPriorityUpdate = CCPriorityCalculator::lowestPriority();
+ m_wasAbovePriorityCutoffAtLastPriorityUpdate = false;
+ }
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTexture.h (128252 => 128253)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTexture.h 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTexture.h 2012-09-12 01:35:47 UTC (rev 128253)
@@ -100,18 +100,26 @@
private:
friend class CCPrioritizedTextureManager;
+ friend class CCPrioritizedTextureTest;
class Backing : public CCTexture {
WTF_MAKE_NONCOPYABLE(Backing);
public:
- Backing(unsigned id, IntSize size, GC3Denum format)
- : CCTexture(id, size, format), m_owner(0) { }
- ~Backing() { ASSERT(!m_owner); }
+ Backing(unsigned id, IntSize, GC3Denum format);
+ ~Backing();
+ void updatePriority();
CCPrioritizedTexture* owner() { return m_owner; }
+ bool hadOwnerAtLastPriorityUpdate() const { return m_ownerExistedAtLastPriorityUpdate; }
+ bool requestPriorityAtLastPriorityUpdate() const { return m_priorityAtLastPriorityUpdate; }
+ bool wasAbovePriorityCutoffAtLastPriorityUpdate() const { return m_wasAbovePriorityCutoffAtLastPriorityUpdate; }
+
private:
friend class CCPrioritizedTexture;
CCPrioritizedTexture* m_owner;
+ int m_priorityAtLastPriorityUpdate;
+ bool m_ownerExistedAtLastPriorityUpdate;
+ bool m_wasAbovePriorityCutoffAtLastPriorityUpdate;
};
CCPrioritizedTexture(CCPrioritizedTextureManager*, IntSize, GC3Denum format);
@@ -128,7 +136,7 @@
GC3Denum m_format;
size_t m_bytes;
- size_t m_priority;
+ int m_priority;
bool m_isAbovePriorityCutoff;
bool m_isSelfManaged;
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTextureManager.cpp (128252 => 128253)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTextureManager.cpp 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTextureManager.cpp 2012-09-12 01:35:47 UTC (rev 128253)
@@ -42,6 +42,7 @@
, m_memoryAboveCutoffBytes(0)
, m_memoryAvailableBytes(0)
, m_pool(pool)
+ , m_needsUpdateBackingsPrioritites(false)
{
}
@@ -61,18 +62,12 @@
TRACE_EVENT0("cc", "CCPrioritizedTextureManager::prioritizeTextures");
ASSERT(CCProxy::isMainThread());
-#if !ASSERT_DISABLED
- assertInvariants();
-#endif
-
// Sorting textures in this function could be replaced by a slightly
// modified O(n) quick-select to partition textures rather than
// sort them (if performance of the sort becomes an issue).
TextureVector& sortedTextures = m_tempTextureVector;
- BackingVector& sortedBackings = m_tempBackingVector;
sortedTextures.clear();
- sortedBackings.clear();
// Copy all textures into a vector and sort them.
for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); ++it)
@@ -116,24 +111,44 @@
if (isAbovePriorityCutoff && !(*it)->isSelfManaged())
m_memoryAboveCutoffBytes += (*it)->bytes();
}
+ sortedTextures.clear();
+
+ m_needsUpdateBackingsPrioritites = true;
+
ASSERT(m_memoryAboveCutoffBytes <= m_memoryAvailableBytes);
+ ASSERT(memoryAboveCutoffBytes() <= maxMemoryLimitBytes());
+}
- // Put backings in eviction/recycling order.
- for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it)
+void CCPrioritizedTextureManager::updateBackingsPriorities()
+{
+ TRACE_EVENT0("cc", "CCPrioritizedTextureManager::updateBackingsPriorities");
+ ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
+
+ if (!m_needsUpdateBackingsPrioritites)
+ return;
+
+#if !ASSERT_DISABLED
+ assertInvariants();
+#endif
+
+ // Update backings' priorities and put backings in eviction/recycling order.
+ BackingVector& sortedBackings = m_tempBackingVector;
+ sortedBackings.clear();
+ for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
+ (*it)->updatePriority();
sortedBackings.append(*it);
+ }
std::sort(sortedBackings.begin(), sortedBackings.end(), compareBackings);
for (BackingVector::iterator it = sortedBackings.begin(); it != sortedBackings.end(); ++it) {
m_backings.remove(*it);
m_backings.add(*it);
}
-
- sortedTextures.clear();
sortedBackings.clear();
+ m_needsUpdateBackingsPrioritites = false;
#if !ASSERT_DISABLED
assertInvariants();
- ASSERT(memoryAboveCutoffBytes() <= maxMemoryLimitBytes());
#endif
}
@@ -166,10 +181,7 @@
m_memoryAboveCutoffBytes = newMemoryBytes;
texture->setAbovePriorityCutoff(true);
- if (texture->backing()) {
- m_backings.remove(texture->backing());
- m_backings.add(texture->backing());
- }
+ m_needsUpdateBackingsPrioritites = true;
return true;
}
@@ -181,12 +193,15 @@
if (texture->backing() || !texture->isAbovePriorityCutoff())
return;
+ // Make sure that the backings list is up to date and sorted before traversing it.
+ updateBackingsPriorities();
+
// Find a backing below, by either recycling or allocating.
CCPrioritizedTexture::Backing* backing = 0;
// First try to recycle
for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
- if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
+ if ((*it)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate())
break;
if ((*it)->size() == texture->size() && (*it)->format() == texture->format()) {
backing = (*it);
@@ -206,6 +221,9 @@
texture->link(backing);
m_backings.remove(backing);
m_backings.add(backing);
+
+ // Update the backing's priority from its new owner.
+ backing->updatePriority();
}
void CCPrioritizedTextureManager::reduceMemory(size_t limitBytes, CCResourceProvider* resourceProvider)
@@ -217,7 +235,7 @@
// or until all backings remaining are above the cutoff.
while (memoryUseBytes() > limitBytes && m_backings.size() > 0) {
BackingSet::iterator it = m_backings.begin();
- if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
+ if ((*it)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate())
break;
destroyBacking((*it), resourceProvider);
}
@@ -226,6 +244,10 @@
void CCPrioritizedTextureManager::reduceMemory(CCResourceProvider* resourceProvider)
{
ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
+
+ // Make sure that the backings list is up to date and sorted before traversing it.
+ updateBackingsPriorities();
+
reduceMemory(m_memoryAvailableBytes, resourceProvider);
ASSERT(memoryUseBytes() <= maxMemoryLimitBytes());
@@ -308,10 +330,8 @@
{
ASSERT(CCProxy::isMainThread() || (CCProxy::isImplThread() && CCProxy::isMainThreadBlocked()));
if (texture->backing()) {
- // Move the backing texture to the front for eviction/recycling and unlink it.
- m_backings.remove(texture->backing());
- m_backings.insertBefore(m_backings.begin(), texture->backing());
texture->unlink();
+ m_needsUpdateBackingsPrioritites = true;
}
}
@@ -329,6 +349,7 @@
void CCPrioritizedTextureManager::destroyBacking(CCPrioritizedTexture::Backing* backing, CCResourceProvider* resourceProvider)
{
+ ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
ASSERT(backing);
ASSERT(!backing->owner() || !backing->owner()->isAbovePriorityCutoff());
ASSERT(!backing->owner() || !backing->owner()->isSelfManaged());
@@ -344,11 +365,10 @@
delete backing;
}
-
#if !ASSERT_DISABLED
void CCPrioritizedTextureManager::assertInvariants()
{
- ASSERT(CCProxy::isMainThread());
+ ASSERT(CCProxy::isImplThread() && CCProxy::isMainThreadBlocked());
// If we hit any of these asserts, there is a bug in this class. To see
// where the bug is, call this function at the beginning and end of
@@ -371,15 +391,21 @@
// At all times, backings that can be evicted must always come before
// backings that can't be evicted in the backing texture list (otherwise
// reduceMemory will not find all textures available for eviction/recycling).
- bool reachedProtected = false;
+ bool reachedOwned = false;
+ bool reachedAboveCutoff = false;
for (BackingSet::iterator it = m_backings.begin(); it != m_backings.end(); ++it) {
- if ((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff())
- reachedProtected = true;
- if (reachedProtected)
- ASSERT((*it)->owner() && (*it)->owner()->isAbovePriorityCutoff());
+ if ((*it)->hadOwnerAtLastPriorityUpdate())
+ reachedOwned = true;
+ if ((*it)->wasAbovePriorityCutoffAtLastPriorityUpdate())
+ reachedAboveCutoff = true;
+ if (reachedOwned)
+ ASSERT((*it)->hadOwnerAtLastPriorityUpdate());
+ if (reachedAboveCutoff) {
+ ASSERT((*it)->hadOwnerAtLastPriorityUpdate() && (*it)->wasAbovePriorityCutoffAtLastPriorityUpdate());
+ ASSERT(reachedOwned);
+ }
}
}
#endif
-
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTextureManager.h (128252 => 128253)
--- trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTextureManager.h 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebCore/platform/graphics/chromium/cc/CCPrioritizedTextureManager.h 2012-09-12 01:35:47 UTC (rev 128253)
@@ -87,11 +87,9 @@
void unregisterTexture(CCPrioritizedTexture*);
void returnBackingTexture(CCPrioritizedTexture*);
-#if !ASSERT_DISABLED
- void assertInvariants();
-#endif
+private:
+ friend class CCPrioritizedTextureTest;
-private:
// Compare textures. Highest priority first.
static inline bool compareTextures(CCPrioritizedTexture* a, CCPrioritizedTexture* b)
{
@@ -102,20 +100,30 @@
// Compare backings. Lowest priority first.
static inline bool compareBackings(CCPrioritizedTexture::Backing* a, CCPrioritizedTexture::Backing* b)
{
- int priorityA = a->owner() ? a->owner()->requestPriority() : CCPriorityCalculator::lowestPriority();
- int priorityB = b->owner() ? b->owner()->requestPriority() : CCPriorityCalculator::lowestPriority();
- if (priorityA == priorityB)
- return a < b;
- return CCPriorityCalculator::priorityIsLower(priorityA, priorityB);
+ int priorityA = a->requestPriorityAtLastPriorityUpdate();
+ int priorityB = b->requestPriorityAtLastPriorityUpdate();
+ if (priorityA != priorityB)
+ return CCPriorityCalculator::priorityIsLower(priorityA, priorityB);
+ bool aboveCutoffA = a->wasAbovePriorityCutoffAtLastPriorityUpdate();
+ bool aboveCutoffB = b->wasAbovePriorityCutoffAtLastPriorityUpdate();
+ if (!aboveCutoffA && aboveCutoffB)
+ return true;
+ if (aboveCutoffA && !aboveCutoffB)
+ return false;
+ return a < b;
}
CCPrioritizedTextureManager(size_t maxMemoryLimitBytes, int maxTextureSize, int pool);
+ void updateBackingsPriorities();
void reduceMemory(size_t limit, CCResourceProvider*);
-
CCPrioritizedTexture::Backing* createBacking(IntSize, GC3Denum format, CCResourceProvider*);
void destroyBacking(CCPrioritizedTexture::Backing*, CCResourceProvider*);
+#if !ASSERT_DISABLED
+ void assertInvariants();
+#endif
+
size_t m_maxMemoryLimitBytes;
unsigned m_priorityCutoff;
size_t m_memoryUseBytes;
@@ -133,6 +141,10 @@
TextureVector m_tempTextureVector;
BackingVector m_tempBackingVector;
+
+ // Set by the main thread when it adjust priorities in such a way that
+ // the m_backings array's view of priorities is now out of date.
+ bool m_needsUpdateBackingsPrioritites;
};
} // WebCore
Modified: trunk/Source/WebKit/chromium/ChangeLog (128252 => 128253)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-09-12 01:35:47 UTC (rev 128253)
@@ -1,3 +1,34 @@
+2012-09-11 Christopher Cameron <[email protected]>
+
+ [chromium] Make prioritized texture manager not touch backings array on the main thread
+ https://bugs.webkit.org/show_bug.cgi?id=96114
+
+ Reviewed by James Robinson.
+
+ Take a snapshot of the textures' priorities from the main thread,
+ and save it in their backings for access by the impl thread.
+ Update functions that access the sorted backings array to use the
+ snapshotted values instead of the values that the main thread may
+ have computed for the next frame.
+
+ Make the main thread not touch the m_backings array. Split
+ prioritizeTextures into a updateBackingsPriorities function.
+ In places where the main thread would have touched m_backings,
+ set a flag specifying that m_backings needs to be re-sorted
+ before any function that requires it be sorted by priority be
+ executed.
+
+ Update the two functions that require sorted order (acquireBacking
+ and reduceMemory) to sort the backings array (if needed) before
+ traversing it.
+
+ Updated tests to set correct thread during asserts. Add a test to
+ verify that requestLate is correctly incorporated into the backing
+ sorting.
+
+ * tests/CCPrioritizedTextureTest.cpp:
+ (WTF::CCPrioritizedTextureTest::validateTexture):
+
2012-09-11 Sheriff Bot <[email protected]>
Unreviewed. Rolled DEPS.
Modified: trunk/Source/WebKit/chromium/tests/CCPrioritizedTextureTest.cpp (128252 => 128253)
--- trunk/Source/WebKit/chromium/tests/CCPrioritizedTextureTest.cpp 2012-09-12 01:25:17 UTC (rev 128252)
+++ trunk/Source/WebKit/chromium/tests/CCPrioritizedTextureTest.cpp 2012-09-12 01:35:47 UTC (rev 128253)
@@ -38,7 +38,7 @@
using namespace WebKitTests;
using namespace WTF;
-namespace {
+namespace WebCore {
class CCPrioritizedTextureTest : public testing::Test {
public:
@@ -70,11 +70,10 @@
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)
@@ -82,11 +81,36 @@
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;
@@ -95,6 +119,10 @@
OwnPtr<CCResourceProvider> m_resourceProvider;
};
+}
+
+namespace {
+
TEST_F(CCPrioritizedTextureTest, requestTextureExceedingMaxLimit)
{
const size_t maxTextures = 8;
@@ -111,7 +139,7 @@
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));
@@ -122,7 +150,7 @@
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));
@@ -148,7 +176,7 @@
// 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);
{
@@ -161,7 +189,7 @@
// 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);
{
@@ -174,7 +202,7 @@
// 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);
{
@@ -204,7 +232,7 @@
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));
@@ -219,7 +247,7 @@
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));
@@ -266,7 +294,7 @@
// 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)
@@ -298,7 +326,7 @@
EXPECT_FALSE(texture->haveBackingTexture());
texture->setRequestPriority(100);
- textureManager->prioritizeTextures();
+ prioritizeTexturesAndBackings(textureManager.get());
EXPECT_TRUE(validateTexture(texture, false));
EXPECT_TRUE(texture->canAcquireBackingTexture());
@@ -324,7 +352,7 @@
EXPECT_FALSE(texture->haveBackingTexture());
texture->setRequestPriority(100);
- textureManagerOne->prioritizeTextures();
+ prioritizeTexturesAndBackings(textureManagerOne.get());
EXPECT_TRUE(validateTexture(texture, false));
EXPECT_TRUE(texture->canAcquireBackingTexture());
@@ -343,7 +371,7 @@
texture->setTextureManager(textureManagerTwo.get());
- textureManagerTwo->prioritizeTextures();
+ prioritizeTexturesAndBackings(textureManagerTwo.get());
EXPECT_TRUE(validateTexture(texture, false));
EXPECT_TRUE(texture->canAcquireBackingTexture());
@@ -374,7 +402,7 @@
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));
@@ -385,7 +413,7 @@
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));
@@ -420,7 +448,7 @@
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)
@@ -458,7 +486,7 @@
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));
@@ -476,4 +504,53 @@
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