FileSystem mods: Changes to snapshot file creation to remove dependencies on blobs.
[chromium-blink-merge.git] / cc / prioritized_resource_unittest.cc
blob1cc343c8740100fe1b7b4cbe22b3b6d572241c33
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "cc/prioritized_resource.h"
7 #include "cc/prioritized_resource_manager.h"
8 #include "cc/resource.h"
9 #include "cc/single_thread_proxy.h" // For DebugScopedSetImplThread
10 #include "cc/test/fake_output_surface.h"
11 #include "cc/test/fake_proxy.h"
12 #include "cc/test/tiled_layer_test_common.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace cc {
17 class PrioritizedResourceTest : public testing::Test {
18 public:
19 PrioritizedResourceTest()
20 : m_proxy(scoped_ptr<Thread>(NULL))
21 , m_textureSize(256, 256)
22 , m_textureFormat(GL_RGBA)
23 , m_outputSurface(createFakeOutputSurface())
25 DebugScopedSetImplThread implThread(&m_proxy);
26 m_resourceProvider = ResourceProvider::create(m_outputSurface.get());
29 virtual ~PrioritizedResourceTest()
31 DebugScopedSetImplThread implThread(&m_proxy);
32 m_resourceProvider.reset();
35 size_t texturesMemorySize(size_t textureCount)
37 return Resource::MemorySizeBytes(m_textureSize, m_textureFormat) * textureCount;
40 scoped_ptr<PrioritizedResourceManager> createManager(size_t maxTextures)
42 scoped_ptr<PrioritizedResourceManager> manager = PrioritizedResourceManager::create(&m_proxy);
43 manager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures));
44 return manager.Pass();
47 bool validateTexture(scoped_ptr<PrioritizedResource>& texture, bool requestLate)
49 resourceManagerAssertInvariants(texture->resourceManager());
50 if (requestLate)
51 texture->requestLate();
52 resourceManagerAssertInvariants(texture->resourceManager());
53 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
54 bool success = texture->canAcquireBackingTexture();
55 if (success)
56 texture->acquireBackingTexture(resourceProvider());
57 return success;
60 void prioritizeTexturesAndBackings(PrioritizedResourceManager* resourceManager)
62 resourceManager->prioritizeTextures();
63 resourceManagerUpdateBackingsPriorities(resourceManager);
66 void resourceManagerUpdateBackingsPriorities(PrioritizedResourceManager* resourceManager)
68 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
69 resourceManager->pushTexturePrioritiesToBackings();
72 ResourceProvider* resourceProvider()
74 return m_resourceProvider.get();
77 void resourceManagerAssertInvariants(PrioritizedResourceManager* resourceManager)
79 #ifndef NDEBUG
80 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
81 resourceManager->assertInvariants();
82 #endif
85 bool textureBackingIsAbovePriorityCutoff(PrioritizedResource* texture)
87 return texture->m_backing->wasAbovePriorityCutoffAtLastPriorityUpdate();
90 size_t evictedBackingCount(PrioritizedResourceManager* resourceManager)
92 return resourceManager->m_evictedBackings.size();
95 protected:
96 FakeProxy m_proxy;
97 const gfx::Size m_textureSize;
98 const GLenum m_textureFormat;
99 scoped_ptr<OutputSurface> m_outputSurface;
100 scoped_ptr<ResourceProvider> m_resourceProvider;
103 namespace {
105 TEST_F(PrioritizedResourceTest, requestTextureExceedingMaxLimit)
107 const size_t maxTextures = 8;
108 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
110 // Create textures for double our memory limit.
111 scoped_ptr<PrioritizedResource> textures[maxTextures*2];
113 for (size_t i = 0; i < maxTextures*2; ++i)
114 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
116 // Set decreasing priorities
117 for (size_t i = 0; i < maxTextures*2; ++i)
118 textures[i]->setRequestPriority(100 + i);
120 // Only lower half should be available.
121 prioritizeTexturesAndBackings(resourceManager.get());
122 EXPECT_TRUE(validateTexture(textures[0], false));
123 EXPECT_TRUE(validateTexture(textures[7], false));
124 EXPECT_FALSE(validateTexture(textures[8], false));
125 EXPECT_FALSE(validateTexture(textures[15], false));
127 // Set increasing priorities
128 for (size_t i = 0; i < maxTextures*2; ++i)
129 textures[i]->setRequestPriority(100 - i);
131 // Only upper half should be available.
132 prioritizeTexturesAndBackings(resourceManager.get());
133 EXPECT_FALSE(validateTexture(textures[0], false));
134 EXPECT_FALSE(validateTexture(textures[7], false));
135 EXPECT_TRUE(validateTexture(textures[8], false));
136 EXPECT_TRUE(validateTexture(textures[15], false));
138 EXPECT_EQ(texturesMemorySize(maxTextures), resourceManager->memoryAboveCutoffBytes());
139 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
141 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
142 resourceManager->clearAllMemory(resourceProvider());
145 TEST_F(PrioritizedResourceTest, changeMemoryLimits)
147 const size_t maxTextures = 8;
148 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
149 scoped_ptr<PrioritizedResource> textures[maxTextures];
151 for (size_t i = 0; i < maxTextures; ++i)
152 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
153 for (size_t i = 0; i < maxTextures; ++i)
154 textures[i]->setRequestPriority(100 + i);
156 // Set max limit to 8 textures
157 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(8));
158 prioritizeTexturesAndBackings(resourceManager.get());
159 for (size_t i = 0; i < maxTextures; ++i)
160 validateTexture(textures[i], false);
162 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
163 resourceManager->reduceMemory(resourceProvider());
166 EXPECT_EQ(texturesMemorySize(8), resourceManager->memoryAboveCutoffBytes());
167 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
169 // Set max limit to 5 textures
170 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(5));
171 prioritizeTexturesAndBackings(resourceManager.get());
172 for (size_t i = 0; i < maxTextures; ++i)
173 EXPECT_EQ(validateTexture(textures[i], false), i < 5);
175 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
176 resourceManager->reduceMemory(resourceProvider());
179 EXPECT_EQ(texturesMemorySize(5), resourceManager->memoryAboveCutoffBytes());
180 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
182 // Set max limit to 4 textures
183 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(4));
184 prioritizeTexturesAndBackings(resourceManager.get());
185 for (size_t i = 0; i < maxTextures; ++i)
186 EXPECT_EQ(validateTexture(textures[i], false), i < 4);
188 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
189 resourceManager->reduceMemory(resourceProvider());
192 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryAboveCutoffBytes());
193 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
195 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
196 resourceManager->clearAllMemory(resourceProvider());
199 TEST_F(PrioritizedResourceTest, changePriorityCutoff)
201 const size_t maxTextures = 8;
202 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
203 scoped_ptr<PrioritizedResource> textures[maxTextures];
205 for (size_t i = 0; i < maxTextures; ++i)
206 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
207 for (size_t i = 0; i < maxTextures; ++i)
208 textures[i]->setRequestPriority(100 + i);
210 // Set the cutoff to drop two textures. Try to requestLate on all textures, and
211 // make sure that requestLate doesn't work on a texture with equal priority to
212 // the cutoff.
213 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(8));
214 resourceManager->setExternalPriorityCutoff(106);
215 prioritizeTexturesAndBackings(resourceManager.get());
216 for (size_t i = 0; i < maxTextures; ++i)
217 EXPECT_EQ(validateTexture(textures[i], true), i < 6);
219 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
220 resourceManager->reduceMemory(resourceProvider());
222 EXPECT_EQ(texturesMemorySize(6), resourceManager->memoryAboveCutoffBytes());
223 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
225 // Set the cutoff to drop two more textures.
226 resourceManager->setExternalPriorityCutoff(104);
227 prioritizeTexturesAndBackings(resourceManager.get());
228 for (size_t i = 0; i < maxTextures; ++i)
229 EXPECT_EQ(validateTexture(textures[i], false), i < 4);
231 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
232 resourceManager->reduceMemory(resourceProvider());
234 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryAboveCutoffBytes());
236 // Do a one-time eviction for one more texture based on priority cutoff
237 PrioritizedResourceManager::BackingList evictedBackings;
238 resourceManager->unlinkAndClearEvictedBackings();
240 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
241 resourceManager->reduceMemoryOnImplThread(texturesMemorySize(8), 104, resourceProvider());
242 EXPECT_EQ(0, evictedBackingCount(resourceManager.get()));
243 resourceManager->reduceMemoryOnImplThread(texturesMemorySize(8), 103, resourceProvider());
244 EXPECT_EQ(1, evictedBackingCount(resourceManager.get()));
246 resourceManager->unlinkAndClearEvictedBackings();
247 EXPECT_EQ(texturesMemorySize(3), resourceManager->memoryUseBytes());
249 // Re-allocate the the texture after the one-time drop.
250 prioritizeTexturesAndBackings(resourceManager.get());
251 for (size_t i = 0; i < maxTextures; ++i)
252 EXPECT_EQ(validateTexture(textures[i], false), i < 4);
254 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
255 resourceManager->reduceMemory(resourceProvider());
257 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryAboveCutoffBytes());
259 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
260 resourceManager->clearAllMemory(resourceProvider());
263 TEST_F(PrioritizedResourceTest, resourceManagerPartialUpdateTextures)
265 const size_t maxTextures = 4;
266 const size_t numTextures = 4;
267 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
268 scoped_ptr<PrioritizedResource> textures[numTextures];
269 scoped_ptr<PrioritizedResource> moreTextures[numTextures];
271 for (size_t i = 0; i < numTextures; ++i) {
272 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
273 moreTextures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
276 for (size_t i = 0; i < numTextures; ++i)
277 textures[i]->setRequestPriority(200 + i);
278 prioritizeTexturesAndBackings(resourceManager.get());
280 // Allocate textures which are currently high priority.
281 EXPECT_TRUE(validateTexture(textures[0], false));
282 EXPECT_TRUE(validateTexture(textures[1], false));
283 EXPECT_TRUE(validateTexture(textures[2], false));
284 EXPECT_TRUE(validateTexture(textures[3], false));
286 EXPECT_TRUE(textures[0]->haveBackingTexture());
287 EXPECT_TRUE(textures[1]->haveBackingTexture());
288 EXPECT_TRUE(textures[2]->haveBackingTexture());
289 EXPECT_TRUE(textures[3]->haveBackingTexture());
291 for (size_t i = 0; i < numTextures; ++i)
292 moreTextures[i]->setRequestPriority(100 + i);
293 prioritizeTexturesAndBackings(resourceManager.get());
295 // Textures are now below cutoff.
296 EXPECT_FALSE(validateTexture(textures[0], false));
297 EXPECT_FALSE(validateTexture(textures[1], false));
298 EXPECT_FALSE(validateTexture(textures[2], false));
299 EXPECT_FALSE(validateTexture(textures[3], false));
301 // But they are still valid to use.
302 EXPECT_TRUE(textures[0]->haveBackingTexture());
303 EXPECT_TRUE(textures[1]->haveBackingTexture());
304 EXPECT_TRUE(textures[2]->haveBackingTexture());
305 EXPECT_TRUE(textures[3]->haveBackingTexture());
307 // Higher priority textures are finally needed.
308 EXPECT_TRUE(validateTexture(moreTextures[0], false));
309 EXPECT_TRUE(validateTexture(moreTextures[1], false));
310 EXPECT_TRUE(validateTexture(moreTextures[2], false));
311 EXPECT_TRUE(validateTexture(moreTextures[3], false));
313 // Lower priority have been fully evicted.
314 EXPECT_FALSE(textures[0]->haveBackingTexture());
315 EXPECT_FALSE(textures[1]->haveBackingTexture());
316 EXPECT_FALSE(textures[2]->haveBackingTexture());
317 EXPECT_FALSE(textures[3]->haveBackingTexture());
319 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
320 resourceManager->clearAllMemory(resourceProvider());
323 TEST_F(PrioritizedResourceTest, resourceManagerPrioritiesAreEqual)
325 const size_t maxTextures = 16;
326 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
327 scoped_ptr<PrioritizedResource> textures[maxTextures];
329 for (size_t i = 0; i < maxTextures; ++i)
330 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
332 // All 16 textures have the same priority except 2 higher priority.
333 for (size_t i = 0; i < maxTextures; ++i)
334 textures[i]->setRequestPriority(100);
335 textures[0]->setRequestPriority(99);
336 textures[1]->setRequestPriority(99);
338 // Set max limit to 8 textures
339 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(8));
340 prioritizeTexturesAndBackings(resourceManager.get());
342 // The two high priority textures should be available, others should not.
343 for (size_t i = 0; i < 2; ++i)
344 EXPECT_TRUE(validateTexture(textures[i], false));
345 for (size_t i = 2; i < maxTextures; ++i)
346 EXPECT_FALSE(validateTexture(textures[i], false));
347 EXPECT_EQ(texturesMemorySize(2), resourceManager->memoryAboveCutoffBytes());
348 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
350 // Manually reserving textures should only succeed on the higher priority textures,
351 // and on remaining textures up to the memory limit.
352 for (size_t i = 0; i < 8; i++)
353 EXPECT_TRUE(validateTexture(textures[i], true));
354 for (size_t i = 9; i < maxTextures; i++)
355 EXPECT_FALSE(validateTexture(textures[i], true));
356 EXPECT_EQ(texturesMemorySize(8), resourceManager->memoryAboveCutoffBytes());
357 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
359 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
360 resourceManager->clearAllMemory(resourceProvider());
363 TEST_F(PrioritizedResourceTest, resourceManagerDestroyedFirst)
365 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(1);
366 scoped_ptr<PrioritizedResource> texture = resourceManager->createTexture(m_textureSize, m_textureFormat);
368 // Texture is initially invalid, but it will become available.
369 EXPECT_FALSE(texture->haveBackingTexture());
371 texture->setRequestPriority(100);
372 prioritizeTexturesAndBackings(resourceManager.get());
374 EXPECT_TRUE(validateTexture(texture, false));
375 EXPECT_TRUE(texture->canAcquireBackingTexture());
376 EXPECT_TRUE(texture->haveBackingTexture());
379 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
380 resourceManager->clearAllMemory(resourceProvider());
382 resourceManager.reset();
384 EXPECT_FALSE(texture->canAcquireBackingTexture());
385 EXPECT_FALSE(texture->haveBackingTexture());
388 TEST_F(PrioritizedResourceTest, textureMovedToNewManager)
390 scoped_ptr<PrioritizedResourceManager> resourceManagerOne = createManager(1);
391 scoped_ptr<PrioritizedResourceManager> resourceManagerTwo = createManager(1);
392 scoped_ptr<PrioritizedResource> texture = resourceManagerOne->createTexture(m_textureSize, m_textureFormat);
394 // Texture is initially invalid, but it will become available.
395 EXPECT_FALSE(texture->haveBackingTexture());
397 texture->setRequestPriority(100);
398 prioritizeTexturesAndBackings(resourceManagerOne.get());
400 EXPECT_TRUE(validateTexture(texture, false));
401 EXPECT_TRUE(texture->canAcquireBackingTexture());
402 EXPECT_TRUE(texture->haveBackingTexture());
404 texture->setTextureManager(0);
407 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
408 resourceManagerOne->clearAllMemory(resourceProvider());
410 resourceManagerOne.reset();
412 EXPECT_FALSE(texture->canAcquireBackingTexture());
413 EXPECT_FALSE(texture->haveBackingTexture());
415 texture->setTextureManager(resourceManagerTwo.get());
417 prioritizeTexturesAndBackings(resourceManagerTwo.get());
419 EXPECT_TRUE(validateTexture(texture, false));
420 EXPECT_TRUE(texture->canAcquireBackingTexture());
421 EXPECT_TRUE(texture->haveBackingTexture());
423 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
424 resourceManagerTwo->clearAllMemory(resourceProvider());
427 TEST_F(PrioritizedResourceTest, renderSurfacesReduceMemoryAvailableOutsideRootSurface)
429 const size_t maxTextures = 8;
430 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
432 // Half of the memory is taken by surfaces (with high priority place-holder)
433 scoped_ptr<PrioritizedResource> renderSurfacePlaceHolder = resourceManager->createTexture(m_textureSize, m_textureFormat);
434 renderSurfacePlaceHolder->setToSelfManagedMemoryPlaceholder(texturesMemorySize(4));
435 renderSurfacePlaceHolder->setRequestPriority(PriorityCalculator::renderSurfacePriority());
437 // Create textures to fill our memory limit.
438 scoped_ptr<PrioritizedResource> textures[maxTextures];
440 for (size_t i = 0; i < maxTextures; ++i)
441 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
443 // Set decreasing non-visible priorities outside root surface.
444 for (size_t i = 0; i < maxTextures; ++i)
445 textures[i]->setRequestPriority(100 + i);
447 // Only lower half should be available.
448 prioritizeTexturesAndBackings(resourceManager.get());
449 EXPECT_TRUE(validateTexture(textures[0], false));
450 EXPECT_TRUE(validateTexture(textures[3], false));
451 EXPECT_FALSE(validateTexture(textures[4], false));
452 EXPECT_FALSE(validateTexture(textures[7], false));
454 // Set increasing non-visible priorities outside root surface.
455 for (size_t i = 0; i < maxTextures; ++i)
456 textures[i]->setRequestPriority(100 - i);
458 // Only upper half should be available.
459 prioritizeTexturesAndBackings(resourceManager.get());
460 EXPECT_FALSE(validateTexture(textures[0], false));
461 EXPECT_FALSE(validateTexture(textures[3], false));
462 EXPECT_TRUE(validateTexture(textures[4], false));
463 EXPECT_TRUE(validateTexture(textures[7], false));
465 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryAboveCutoffBytes());
466 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryForSelfManagedTextures());
467 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
469 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
470 resourceManager->clearAllMemory(resourceProvider());
473 TEST_F(PrioritizedResourceTest, renderSurfacesReduceMemoryAvailableForRequestLate)
475 const size_t maxTextures = 8;
476 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
478 // Half of the memory is taken by surfaces (with high priority place-holder)
479 scoped_ptr<PrioritizedResource> renderSurfacePlaceHolder = resourceManager->createTexture(m_textureSize, m_textureFormat);
480 renderSurfacePlaceHolder->setToSelfManagedMemoryPlaceholder(texturesMemorySize(4));
481 renderSurfacePlaceHolder->setRequestPriority(PriorityCalculator::renderSurfacePriority());
483 // Create textures to fill our memory limit.
484 scoped_ptr<PrioritizedResource> textures[maxTextures];
486 for (size_t i = 0; i < maxTextures; ++i)
487 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
489 // Set equal priorities.
490 for (size_t i = 0; i < maxTextures; ++i)
491 textures[i]->setRequestPriority(100);
493 // The first four to be requested late will be available.
494 prioritizeTexturesAndBackings(resourceManager.get());
495 for (unsigned i = 0; i < maxTextures; ++i)
496 EXPECT_FALSE(validateTexture(textures[i], false));
497 for (unsigned i = 0; i < maxTextures; i += 2)
498 EXPECT_TRUE(validateTexture(textures[i], true));
499 for (unsigned i = 1; i < maxTextures; i += 2)
500 EXPECT_FALSE(validateTexture(textures[i], true));
502 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryAboveCutoffBytes());
503 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryForSelfManagedTextures());
504 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
506 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
507 resourceManager->clearAllMemory(resourceProvider());
510 TEST_F(PrioritizedResourceTest, whenRenderSurfaceNotAvailableTexturesAlsoNotAvailable)
512 const size_t maxTextures = 8;
513 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
515 // Half of the memory is taken by surfaces (with high priority place-holder)
516 scoped_ptr<PrioritizedResource> renderSurfacePlaceHolder = resourceManager->createTexture(m_textureSize, m_textureFormat);
517 renderSurfacePlaceHolder->setToSelfManagedMemoryPlaceholder(texturesMemorySize(4));
518 renderSurfacePlaceHolder->setRequestPriority(PriorityCalculator::renderSurfacePriority());
520 // Create textures to fill our memory limit.
521 scoped_ptr<PrioritizedResource> textures[maxTextures];
523 for (size_t i = 0; i < maxTextures; ++i)
524 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
526 // Set 6 visible textures in the root surface, and 2 in a child surface.
527 for (size_t i = 0; i < 6; ++i)
528 textures[i]->setRequestPriority(PriorityCalculator::visiblePriority(true));
529 for (size_t i = 6; i < 8; ++i)
530 textures[i]->setRequestPriority(PriorityCalculator::visiblePriority(false));
532 prioritizeTexturesAndBackings(resourceManager.get());
534 // Unable to requestLate textures in the child surface.
535 EXPECT_FALSE(validateTexture(textures[6], true));
536 EXPECT_FALSE(validateTexture(textures[7], true));
538 // Root surface textures are valid.
539 for (size_t i = 0; i < 6; ++i)
540 EXPECT_TRUE(validateTexture(textures[i], false));
542 EXPECT_EQ(texturesMemorySize(6), resourceManager->memoryAboveCutoffBytes());
543 EXPECT_EQ(texturesMemorySize(2), resourceManager->memoryForSelfManagedTextures());
544 EXPECT_LE(resourceManager->memoryUseBytes(), resourceManager->memoryAboveCutoffBytes());
546 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
547 resourceManager->clearAllMemory(resourceProvider());
550 TEST_F(PrioritizedResourceTest, requestLateBackingsSorting)
552 const size_t maxTextures = 8;
553 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
554 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures));
556 // Create textures to fill our memory limit.
557 scoped_ptr<PrioritizedResource> textures[maxTextures];
558 for (size_t i = 0; i < maxTextures; ++i)
559 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
561 // Set equal priorities, and allocate backings for all textures.
562 for (size_t i = 0; i < maxTextures; ++i)
563 textures[i]->setRequestPriority(100);
564 prioritizeTexturesAndBackings(resourceManager.get());
565 for (unsigned i = 0; i < maxTextures; ++i)
566 EXPECT_TRUE(validateTexture(textures[i], false));
568 // Drop the memory limit and prioritize (none will be above the threshold,
569 // but they still have backings because reduceMemory hasn't been called).
570 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures / 2));
571 prioritizeTexturesAndBackings(resourceManager.get());
573 // Push half of them back over the limit.
574 for (size_t i = 0; i < maxTextures; i += 2)
575 EXPECT_TRUE(textures[i]->requestLate());
577 // Push the priorities to the backings array and sort the backings array
578 resourceManagerUpdateBackingsPriorities(resourceManager.get());
580 // Assert that the backings list be sorted with the below-limit backings
581 // before the above-limit backings.
582 resourceManagerAssertInvariants(resourceManager.get());
584 // Make sure that we have backings for all of the textures.
585 for (size_t i = 0; i < maxTextures; ++i)
586 EXPECT_TRUE(textures[i]->haveBackingTexture());
588 // Make sure that only the requestLate textures are above the priority cutoff
589 for (size_t i = 0; i < maxTextures; i += 2)
590 EXPECT_TRUE(textureBackingIsAbovePriorityCutoff(textures[i].get()));
591 for (size_t i = 1; i < maxTextures; i += 2)
592 EXPECT_FALSE(textureBackingIsAbovePriorityCutoff(textures[i].get()));
594 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
595 resourceManager->clearAllMemory(resourceProvider());
598 TEST_F(PrioritizedResourceTest, clearUploadsToEvictedResources)
600 const size_t maxTextures = 4;
601 scoped_ptr<PrioritizedResourceManager> resourceManager =
602 createManager(maxTextures);
603 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(maxTextures));
605 // Create textures to fill our memory limit.
606 scoped_ptr<PrioritizedResource> textures[maxTextures];
608 for (size_t i = 0; i < maxTextures; ++i)
609 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
611 // Set equal priorities, and allocate backings for all textures.
612 for (size_t i = 0; i < maxTextures; ++i)
613 textures[i]->setRequestPriority(100);
614 prioritizeTexturesAndBackings(resourceManager.get());
615 for (unsigned i = 0; i < maxTextures; ++i)
616 EXPECT_TRUE(validateTexture(textures[i], false));
618 ResourceUpdateQueue queue;
619 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
620 for (size_t i = 0; i < maxTextures; ++i) {
621 const ResourceUpdate upload = ResourceUpdate::Create(
622 textures[i].get(), NULL, gfx::Rect(), gfx::Rect(), gfx::Vector2d());
623 queue.appendFullUpload(upload);
626 // Make sure that we have backings for all of the textures.
627 for (size_t i = 0; i < maxTextures; ++i)
628 EXPECT_TRUE(textures[i]->haveBackingTexture());
630 queue.clearUploadsToEvictedResources();
631 EXPECT_EQ(4, queue.fullUploadSize());
633 resourceManager->reduceMemoryOnImplThread(
634 texturesMemorySize(1), PriorityCalculator::allowEverythingCutoff(), resourceProvider());
635 queue.clearUploadsToEvictedResources();
636 EXPECT_EQ(1, queue.fullUploadSize());
638 resourceManager->reduceMemoryOnImplThread(0, PriorityCalculator::allowEverythingCutoff(), resourceProvider());
639 queue.clearUploadsToEvictedResources();
640 EXPECT_EQ(0, queue.fullUploadSize());
644 TEST_F(PrioritizedResourceTest, usageStatistics)
646 const size_t maxTextures = 5;
647 scoped_ptr<PrioritizedResourceManager> resourceManager = createManager(maxTextures);
648 scoped_ptr<PrioritizedResource> textures[maxTextures];
650 for (size_t i = 0; i < maxTextures; ++i)
651 textures[i] = resourceManager->createTexture(m_textureSize, m_textureFormat);
653 textures[0]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
654 textures[1]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff());
655 textures[2]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff() - 1);
656 textures[3]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff());
657 textures[4]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff() + 1);
659 // Set max limit to 2 textures.
660 resourceManager->setMaxMemoryLimitBytes(texturesMemorySize(2));
661 prioritizeTexturesAndBackings(resourceManager.get());
663 // The first two textures should be available, others should not.
664 for (size_t i = 0; i < 2; ++i)
665 EXPECT_TRUE(validateTexture(textures[i], false));
666 for (size_t i = 2; i < maxTextures; ++i)
667 EXPECT_FALSE(validateTexture(textures[i], false));
669 // Validate the statistics.
671 DebugScopedSetImplThread implThread(&m_proxy);
672 EXPECT_EQ(texturesMemorySize(2), resourceManager->memoryUseBytes());
673 EXPECT_EQ(texturesMemorySize(1), resourceManager->memoryVisibleBytes());
674 EXPECT_EQ(texturesMemorySize(3), resourceManager->memoryVisibleAndNearbyBytes());
677 // Re-prioritize the textures, but do not push the values to backings.
678 textures[0]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
679 textures[1]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
680 textures[2]->setRequestPriority(PriorityCalculator::allowVisibleOnlyCutoff() - 1);
681 textures[3]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff() - 1);
682 textures[4]->setRequestPriority(PriorityCalculator::allowVisibleAndNearbyCutoff());
683 resourceManager->prioritizeTextures();
685 // Verify that we still see the old values.
687 DebugScopedSetImplThread implThread(&m_proxy);
688 EXPECT_EQ(texturesMemorySize(2), resourceManager->memoryUseBytes());
689 EXPECT_EQ(texturesMemorySize(1), resourceManager->memoryVisibleBytes());
690 EXPECT_EQ(texturesMemorySize(3), resourceManager->memoryVisibleAndNearbyBytes());
693 // Push priorities to backings, and verify we see the new values.
695 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
696 resourceManager->pushTexturePrioritiesToBackings();
697 EXPECT_EQ(texturesMemorySize(2), resourceManager->memoryUseBytes());
698 EXPECT_EQ(texturesMemorySize(3), resourceManager->memoryVisibleBytes());
699 EXPECT_EQ(texturesMemorySize(4), resourceManager->memoryVisibleAndNearbyBytes());
702 DebugScopedSetImplThreadAndMainThreadBlocked implThreadAndMainThreadBlocked(&m_proxy);
703 resourceManager->clearAllMemory(resourceProvider());
706 } // namespace
707 } // namespace cc