| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "cc/resources/prioritized_resource.h" | 5 #include "cc/resources/prioritized_resource.h" |
| 6 | 6 |
| 7 #include "cc/resources/prioritized_resource_manager.h" | 7 #include "cc/resources/prioritized_resource_manager.h" |
| 8 #include "cc/resources/resource.h" | 8 #include "cc/resources/resource.h" |
| 9 #include "cc/test/fake_output_surface.h" | 9 #include "cc/test/fake_output_surface.h" |
| 10 #include "cc/test/fake_proxy.h" | 10 #include "cc/test/fake_proxy.h" |
| 11 #include "cc/test/tiled_layer_test_common.h" | 11 #include "cc/test/tiled_layer_test_common.h" |
| 12 #include "cc/trees/single_thread_proxy.h" // For DebugScopedSetImplThread | 12 #include "cc/trees/single_thread_proxy.h" // For DebugScopedSetImplThread |
| 13 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 14 | 14 |
| 15 namespace cc { | 15 namespace cc { |
| 16 | 16 |
| 17 class PrioritizedResourceTest : public testing::Test { | 17 class PrioritizedResourceTest : public testing::Test { |
| 18 public: | 18 public: |
| 19 PrioritizedResourceTest() | 19 PrioritizedResourceTest() |
| 20 : proxy_(scoped_ptr<Thread>(NULL)), | 20 : proxy_(scoped_ptr<Thread>(NULL)), |
| 21 texture_size_(256, 256), | 21 texture_size_(256, 256), |
| 22 texture_format_(GL_RGBA), | 22 texture_format_(GL_RGBA), |
| 23 output_surface_(CreateFakeOutputSurface()) { | 23 output_surface_(CreateFakeOutputSurface()) { |
| 24 DebugScopedSetImplThread impl_thread(&proxy_); | 24 DebugScopedSetImplThread impl_thread(&proxy_); |
| 25 resource_provider_ = cc::ResourceProvider::Create(output_surface_.get())
; | 25 resource_provider_ = cc::ResourceProvider::Create(output_surface_.get()); |
| 26 } | 26 } |
| 27 | 27 |
| 28 virtual ~PrioritizedResourceTest() { | 28 virtual ~PrioritizedResourceTest() { |
| 29 DebugScopedSetImplThread impl_thread(&proxy_); | 29 DebugScopedSetImplThread impl_thread(&proxy_); |
| 30 resource_provider_.reset(); | 30 resource_provider_.reset(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 size_t TexturesMemorySize(size_t texture_count) { | 33 size_t TexturesMemorySize(size_t texture_count) { |
| 34 return Resource::MemorySizeBytes(texture_size_, texture_format_) * | 34 return Resource::MemorySizeBytes(texture_size_, texture_format_) * |
| 35 texture_count; | 35 texture_count; |
| 36 } | 36 } |
| 37 | 37 |
| 38 scoped_ptr<PrioritizedResourceManager> CreateManager(size_t max_textures) { | 38 scoped_ptr<PrioritizedResourceManager> CreateManager(size_t max_textures) { |
| 39 scoped_ptr<PrioritizedResourceManager> manager = | 39 scoped_ptr<PrioritizedResourceManager> manager = |
| 40 PrioritizedResourceManager::Create(&proxy_); | 40 PrioritizedResourceManager::Create(&proxy_); |
| 41 manager->SetMaxMemoryLimitBytes(TexturesMemorySize(max_textures)); | 41 manager->SetMaxMemoryLimitBytes(TexturesMemorySize(max_textures)); |
| 42 return manager.Pass(); | 42 return manager.Pass(); |
| 43 } | 43 } |
| 44 | 44 |
| 45 bool ValidateTexture(scoped_ptr<PrioritizedResource>& texture, | 45 bool ValidateTexture(PrioritizedResource* texture, |
| 46 bool request_late) { | 46 bool request_late) { |
| 47 ResourceManagerAssertInvariants(texture->resource_manager()); | 47 ResourceManagerAssertInvariants(texture->resource_manager()); |
| 48 if (request_late) | 48 if (request_late) |
| 49 texture->RequestLate(); | 49 texture->RequestLate(); |
| 50 ResourceManagerAssertInvariants(texture->resource_manager()); | 50 ResourceManagerAssertInvariants(texture->resource_manager()); |
| 51 DebugScopedSetImplThreadAndMainThreadBlocked | 51 DebugScopedSetImplThreadAndMainThreadBlocked |
| 52 impl_thread_and_main_thread_blocked(&proxy_); | 52 impl_thread_and_main_thread_blocked(&proxy_); |
| 53 bool success = texture->can_acquire_backing_texture(); | 53 bool success = texture->can_acquire_backing_texture(); |
| 54 if (success) | 54 if (success) |
| 55 texture->AcquireBackingTexture(ResourceProvider()); | 55 texture->AcquireBackingTexture(ResourceProvider()); |
| 56 return success; | 56 return success; |
| 57 } | 57 } |
| 58 | 58 |
| 59 void PrioritizeTexturesAndBackings( | 59 void PrioritizeTexturesAndBackings( |
| 60 PrioritizedResourceManager* resource_manager) { | 60 PrioritizedResourceManager* resource_manager) { |
| 61 resource_manager->PrioritizeTextures(); | 61 resource_manager->PrioritizeTextures(); |
| 62 ResourceManagerUpdateBackingsPriorities(resource_manager); | 62 ResourceManagerUpdateBackingsPriorities(resource_manager); |
| 63 } | 63 } |
| 64 | 64 |
| 65 void ResourceManagerUpdateBackingsPriorities( | 65 void ResourceManagerUpdateBackingsPriorities( |
| 66 PrioritizedResourceManager* resource_manager) { | 66 PrioritizedResourceManager* resource_manager) { |
| 67 DebugScopedSetImplThreadAndMainThreadBlocked | 67 DebugScopedSetImplThreadAndMainThreadBlocked |
| 68 impl_thread_and_main_thread_blocked(&proxy_); | 68 impl_thread_and_main_thread_blocked(&proxy_); |
| 69 resource_manager->PushTexturePrioritiesToBackings(); | 69 resource_manager->PushTexturePrioritiesToBackings(); |
| 70 } | 70 } |
| 71 | 71 |
| 72 cc::ResourceProvider* ResourceProvider() { return resource_provider_.get();
} | 72 cc::ResourceProvider* ResourceProvider() { return resource_provider_.get(); } |
| 73 | 73 |
| 74 void ResourceManagerAssertInvariants( | 74 void ResourceManagerAssertInvariants( |
| 75 PrioritizedResourceManager* resource_manager) { | 75 PrioritizedResourceManager* resource_manager) { |
| 76 #ifndef NDEBUG | 76 #ifndef NDEBUG |
| 77 DebugScopedSetImplThreadAndMainThreadBlocked | 77 DebugScopedSetImplThreadAndMainThreadBlocked |
| 78 impl_thread_and_main_thread_blocked(&proxy_); | 78 impl_thread_and_main_thread_blocked(&proxy_); |
| 79 resource_manager->AssertInvariants(); | 79 resource_manager->AssertInvariants(); |
| 80 #endif | 80 #endif |
| 81 } | 81 } |
| 82 | 82 |
| 83 bool TextureBackingIsAbovePriorityCutoff(PrioritizedResource* texture) { | 83 bool TextureBackingIsAbovePriorityCutoff(PrioritizedResource* texture) { |
| 84 return texture->backing()-> | 84 return texture->backing()-> |
| 85 was_above_priority_cutoff_at_last_priority_update(); | 85 was_above_priority_cutoff_at_last_priority_update(); |
| 86 } | 86 } |
| 87 | 87 |
| 88 size_t EvictedBackingCount(PrioritizedResourceManager* resource_manager) { | 88 size_t EvictedBackingCount(PrioritizedResourceManager* resource_manager) { |
| 89 return resource_manager->evicted_backings_.size(); | 89 return resource_manager->evicted_backings_.size(); |
| 90 } | 90 } |
| 91 | 91 |
| 92 protected: | 92 protected: |
| 93 FakeProxy proxy_; | 93 FakeProxy proxy_; |
| 94 const gfx::Size texture_size_; | 94 const gfx::Size texture_size_; |
| 95 const GLenum texture_format_; | 95 const GLenum texture_format_; |
| 96 scoped_ptr<OutputSurface> output_surface_; | 96 scoped_ptr<OutputSurface> output_surface_; |
| 97 scoped_ptr<cc::ResourceProvider> resource_provider_; | 97 scoped_ptr<cc::ResourceProvider> resource_provider_; |
| 98 }; | 98 }; |
| 99 | 99 |
| 100 namespace { | 100 namespace { |
| 101 | 101 |
| 102 TEST_F(PrioritizedResourceTest, RequestTextureExceedingMaxLimit) { | 102 TEST_F(PrioritizedResourceTest, RequestTextureExceedingMaxLimit) { |
| 103 const size_t max_textures = 8; | 103 const size_t kMaxTextures = 8; |
| 104 scoped_ptr<PrioritizedResourceManager> resource_manager = | 104 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 105 CreateManager(max_textures); | 105 CreateManager(kMaxTextures); |
| 106 | 106 |
| 107 // Create textures for double our memory limit. | 107 // Create textures for double our memory limit. |
| 108 scoped_ptr<PrioritizedResource> textures[max_textures * 2]; | 108 scoped_ptr<PrioritizedResource> textures[kMaxTextures * 2]; |
| 109 | 109 |
| 110 for (size_t i = 0; i < max_textures * 2; ++i) | 110 for (size_t i = 0; i < kMaxTextures * 2; ++i) |
| 111 textures[i] = | 111 textures[i] = |
| 112 resource_manager->CreateTexture(texture_size_, texture_format_); | 112 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 113 | 113 |
| 114 // Set decreasing priorities | 114 // Set decreasing priorities |
| 115 for (size_t i = 0; i < max_textures * 2; ++i) | 115 for (size_t i = 0; i < kMaxTextures * 2; ++i) |
| 116 textures[i]->set_request_priority(100 + i); | 116 textures[i]->set_request_priority(100 + i); |
| 117 | 117 |
| 118 // Only lower half should be available. | 118 // Only lower half should be available. |
| 119 PrioritizeTexturesAndBackings(resource_manager.get()); | 119 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 120 EXPECT_TRUE(ValidateTexture(textures[0], false)); | 120 EXPECT_TRUE(ValidateTexture(textures[0].get(), false)); |
| 121 EXPECT_TRUE(ValidateTexture(textures[7], false)); | 121 EXPECT_TRUE(ValidateTexture(textures[7].get(), false)); |
| 122 EXPECT_FALSE(ValidateTexture(textures[8], false)); | 122 EXPECT_FALSE(ValidateTexture(textures[8].get(), false)); |
| 123 EXPECT_FALSE(ValidateTexture(textures[15], false)); | 123 EXPECT_FALSE(ValidateTexture(textures[15].get(), false)); |
| 124 | 124 |
| 125 // Set increasing priorities | 125 // Set increasing priorities |
| 126 for (size_t i = 0; i < max_textures * 2; ++i) | 126 for (size_t i = 0; i < kMaxTextures * 2; ++i) |
| 127 textures[i]->set_request_priority(100 - i); | 127 textures[i]->set_request_priority(100 - i); |
| 128 | 128 |
| 129 // Only upper half should be available. | 129 // Only upper half should be available. |
| 130 PrioritizeTexturesAndBackings(resource_manager.get()); | 130 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 131 EXPECT_FALSE(ValidateTexture(textures[0], false)); | 131 EXPECT_FALSE(ValidateTexture(textures[0].get(), false)); |
| 132 EXPECT_FALSE(ValidateTexture(textures[7], false)); | 132 EXPECT_FALSE(ValidateTexture(textures[7].get(), false)); |
| 133 EXPECT_TRUE(ValidateTexture(textures[8], false)); | 133 EXPECT_TRUE(ValidateTexture(textures[8].get(), false)); |
| 134 EXPECT_TRUE(ValidateTexture(textures[15], false)); | 134 EXPECT_TRUE(ValidateTexture(textures[15].get(), false)); |
| 135 | 135 |
| 136 EXPECT_EQ(TexturesMemorySize(max_textures), | 136 EXPECT_EQ(TexturesMemorySize(kMaxTextures), |
| 137 resource_manager->MemoryAboveCutoffBytes()); | 137 resource_manager->MemoryAboveCutoffBytes()); |
| 138 EXPECT_LE(resource_manager->MemoryUseBytes(), | 138 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 139 resource_manager->MemoryAboveCutoffBytes()); | 139 resource_manager->MemoryAboveCutoffBytes()); |
| 140 | 140 |
| 141 DebugScopedSetImplThreadAndMainThreadBlocked |
| 142 impl_thread_and_main_thread_blocked(&proxy_); |
| 143 resource_manager->ClearAllMemory(ResourceProvider()); |
| 144 } |
| 145 |
| 146 TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) { |
| 147 const size_t kMaxTextures = 8; |
| 148 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 149 CreateManager(kMaxTextures); |
| 150 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 151 |
| 152 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 153 textures[i] = |
| 154 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 155 } |
| 156 for (size_t i = 0; i < kMaxTextures; ++i) |
| 157 textures[i]->set_request_priority(100 + i); |
| 158 |
| 159 // Set max limit to 8 textures |
| 160 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8)); |
| 161 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 162 for (size_t i = 0; i < kMaxTextures; ++i) |
| 163 ValidateTexture(textures[i].get(), false); |
| 164 { |
| 165 DebugScopedSetImplThreadAndMainThreadBlocked |
| 166 impl_thread_and_main_thread_blocked(&proxy_); |
| 167 resource_manager->ReduceMemory(ResourceProvider()); |
| 168 } |
| 169 |
| 170 EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes()); |
| 171 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 172 resource_manager->MemoryAboveCutoffBytes()); |
| 173 |
| 174 // Set max limit to 5 textures |
| 175 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(5)); |
| 176 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 177 for (size_t i = 0; i < kMaxTextures; ++i) |
| 178 EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 5); |
| 179 { |
| 180 DebugScopedSetImplThreadAndMainThreadBlocked |
| 181 impl_thread_and_main_thread_blocked(&proxy_); |
| 182 resource_manager->ReduceMemory(ResourceProvider()); |
| 183 } |
| 184 |
| 185 EXPECT_EQ(TexturesMemorySize(5), resource_manager->MemoryAboveCutoffBytes()); |
| 186 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 187 resource_manager->MemoryAboveCutoffBytes()); |
| 188 |
| 189 // Set max limit to 4 textures |
| 190 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(4)); |
| 191 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 192 for (size_t i = 0; i < kMaxTextures; ++i) |
| 193 EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4); |
| 194 { |
| 195 DebugScopedSetImplThreadAndMainThreadBlocked |
| 196 impl_thread_and_main_thread_blocked(&proxy_); |
| 197 resource_manager->ReduceMemory(ResourceProvider()); |
| 198 } |
| 199 |
| 200 EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes()); |
| 201 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 202 resource_manager->MemoryAboveCutoffBytes()); |
| 203 |
| 204 DebugScopedSetImplThreadAndMainThreadBlocked |
| 205 impl_thread_and_main_thread_blocked(&proxy_); |
| 206 resource_manager->ClearAllMemory(ResourceProvider()); |
| 207 } |
| 208 |
| 209 TEST_F(PrioritizedResourceTest, ChangePriorityCutoff) { |
| 210 const size_t kMaxTextures = 8; |
| 211 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 212 CreateManager(kMaxTextures); |
| 213 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 214 |
| 215 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 216 textures[i] = |
| 217 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 218 } |
| 219 for (size_t i = 0; i < kMaxTextures; ++i) |
| 220 textures[i]->set_request_priority(100 + i); |
| 221 |
| 222 // Set the cutoff to drop two textures. Try to request_late on all textures, |
| 223 // and make sure that request_late doesn't work on a texture with equal |
| 224 // priority to the cutoff. |
| 225 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8)); |
| 226 resource_manager->SetExternalPriorityCutoff(106); |
| 227 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 228 for (size_t i = 0; i < kMaxTextures; ++i) |
| 229 EXPECT_EQ(ValidateTexture(textures[i].get(), true), i < 6); |
| 230 { |
| 231 DebugScopedSetImplThreadAndMainThreadBlocked |
| 232 impl_thread_and_main_thread_blocked(&proxy_); |
| 233 resource_manager->ReduceMemory(ResourceProvider()); |
| 234 } |
| 235 EXPECT_EQ(TexturesMemorySize(6), resource_manager->MemoryAboveCutoffBytes()); |
| 236 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 237 resource_manager->MemoryAboveCutoffBytes()); |
| 238 |
| 239 // Set the cutoff to drop two more textures. |
| 240 resource_manager->SetExternalPriorityCutoff(104); |
| 241 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 242 for (size_t i = 0; i < kMaxTextures; ++i) |
| 243 EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4); |
| 244 { |
| 245 DebugScopedSetImplThreadAndMainThreadBlocked |
| 246 impl_thread_and_main_thread_blocked(&proxy_); |
| 247 resource_manager->ReduceMemory(ResourceProvider()); |
| 248 } |
| 249 EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes()); |
| 250 |
| 251 // Do a one-time eviction for one more texture based on priority cutoff |
| 252 PrioritizedResourceManager::BackingList evicted_backings; |
| 253 resource_manager->UnlinkAndClearEvictedBackings(); |
| 254 { |
| 255 DebugScopedSetImplThreadAndMainThreadBlocked |
| 256 impl_thread_and_main_thread_blocked(&proxy_); |
| 257 resource_manager->ReduceMemoryOnImplThread( |
| 258 TexturesMemorySize(8), 104, ResourceProvider()); |
| 259 EXPECT_EQ(0, EvictedBackingCount(resource_manager.get())); |
| 260 resource_manager->ReduceMemoryOnImplThread( |
| 261 TexturesMemorySize(8), 103, ResourceProvider()); |
| 262 EXPECT_EQ(1, EvictedBackingCount(resource_manager.get())); |
| 263 } |
| 264 resource_manager->UnlinkAndClearEvictedBackings(); |
| 265 EXPECT_EQ(TexturesMemorySize(3), resource_manager->MemoryUseBytes()); |
| 266 |
| 267 // Re-allocate the the texture after the one-time drop. |
| 268 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 269 for (size_t i = 0; i < kMaxTextures; ++i) |
| 270 EXPECT_EQ(ValidateTexture(textures[i].get(), false), i < 4); |
| 271 { |
| 272 DebugScopedSetImplThreadAndMainThreadBlocked |
| 273 impl_thread_and_main_thread_blocked(&proxy_); |
| 274 resource_manager->ReduceMemory(ResourceProvider()); |
| 275 } |
| 276 EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes()); |
| 277 |
| 278 DebugScopedSetImplThreadAndMainThreadBlocked |
| 279 impl_thread_and_main_thread_blocked(&proxy_); |
| 280 resource_manager->ClearAllMemory(ResourceProvider()); |
| 281 } |
| 282 |
| 283 TEST_F(PrioritizedResourceTest, ResourceManagerPartialUpdateTextures) { |
| 284 const size_t kMaxTextures = 4; |
| 285 const size_t kNumTextures = 4; |
| 286 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 287 CreateManager(kMaxTextures); |
| 288 scoped_ptr<PrioritizedResource> textures[kNumTextures]; |
| 289 scoped_ptr<PrioritizedResource> more_textures[kNumTextures]; |
| 290 |
| 291 for (size_t i = 0; i < kNumTextures; ++i) { |
| 292 textures[i] = |
| 293 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 294 more_textures[i] = |
| 295 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 296 } |
| 297 |
| 298 for (size_t i = 0; i < kNumTextures; ++i) |
| 299 textures[i]->set_request_priority(200 + i); |
| 300 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 301 |
| 302 // Allocate textures which are currently high priority. |
| 303 EXPECT_TRUE(ValidateTexture(textures[0].get(), false)); |
| 304 EXPECT_TRUE(ValidateTexture(textures[1].get(), false)); |
| 305 EXPECT_TRUE(ValidateTexture(textures[2].get(), false)); |
| 306 EXPECT_TRUE(ValidateTexture(textures[3].get(), false)); |
| 307 |
| 308 EXPECT_TRUE(textures[0]->have_backing_texture()); |
| 309 EXPECT_TRUE(textures[1]->have_backing_texture()); |
| 310 EXPECT_TRUE(textures[2]->have_backing_texture()); |
| 311 EXPECT_TRUE(textures[3]->have_backing_texture()); |
| 312 |
| 313 for (size_t i = 0; i < kNumTextures; ++i) |
| 314 more_textures[i]->set_request_priority(100 + i); |
| 315 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 316 |
| 317 // Textures are now below cutoff. |
| 318 EXPECT_FALSE(ValidateTexture(textures[0].get(), false)); |
| 319 EXPECT_FALSE(ValidateTexture(textures[1].get(), false)); |
| 320 EXPECT_FALSE(ValidateTexture(textures[2].get(), false)); |
| 321 EXPECT_FALSE(ValidateTexture(textures[3].get(), false)); |
| 322 |
| 323 // But they are still valid to use. |
| 324 EXPECT_TRUE(textures[0]->have_backing_texture()); |
| 325 EXPECT_TRUE(textures[1]->have_backing_texture()); |
| 326 EXPECT_TRUE(textures[2]->have_backing_texture()); |
| 327 EXPECT_TRUE(textures[3]->have_backing_texture()); |
| 328 |
| 329 // Higher priority textures are finally needed. |
| 330 EXPECT_TRUE(ValidateTexture(more_textures[0].get(), false)); |
| 331 EXPECT_TRUE(ValidateTexture(more_textures[1].get(), false)); |
| 332 EXPECT_TRUE(ValidateTexture(more_textures[2].get(), false)); |
| 333 EXPECT_TRUE(ValidateTexture(more_textures[3].get(), false)); |
| 334 |
| 335 // Lower priority have been fully evicted. |
| 336 EXPECT_FALSE(textures[0]->have_backing_texture()); |
| 337 EXPECT_FALSE(textures[1]->have_backing_texture()); |
| 338 EXPECT_FALSE(textures[2]->have_backing_texture()); |
| 339 EXPECT_FALSE(textures[3]->have_backing_texture()); |
| 340 |
| 341 DebugScopedSetImplThreadAndMainThreadBlocked |
| 342 impl_thread_and_main_thread_blocked(&proxy_); |
| 343 resource_manager->ClearAllMemory(ResourceProvider()); |
| 344 } |
| 345 |
| 346 TEST_F(PrioritizedResourceTest, ResourceManagerPrioritiesAreEqual) { |
| 347 const size_t kMaxTextures = 16; |
| 348 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 349 CreateManager(kMaxTextures); |
| 350 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 351 |
| 352 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 353 textures[i] = |
| 354 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 355 } |
| 356 |
| 357 // All 16 textures have the same priority except 2 higher priority. |
| 358 for (size_t i = 0; i < kMaxTextures; ++i) |
| 359 textures[i]->set_request_priority(100); |
| 360 textures[0]->set_request_priority(99); |
| 361 textures[1]->set_request_priority(99); |
| 362 |
| 363 // Set max limit to 8 textures |
| 364 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8)); |
| 365 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 366 |
| 367 // The two high priority textures should be available, others should not. |
| 368 for (size_t i = 0; i < 2; ++i) |
| 369 EXPECT_TRUE(ValidateTexture(textures[i].get(), false)); |
| 370 for (size_t i = 2; i < kMaxTextures; ++i) |
| 371 EXPECT_FALSE(ValidateTexture(textures[i].get(), false)); |
| 372 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryAboveCutoffBytes()); |
| 373 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 374 resource_manager->MemoryAboveCutoffBytes()); |
| 375 |
| 376 // Manually reserving textures should only succeed on the higher priority |
| 377 // textures, and on remaining textures up to the memory limit. |
| 378 for (size_t i = 0; i < 8; i++) |
| 379 EXPECT_TRUE(ValidateTexture(textures[i].get(), true)); |
| 380 for (size_t i = 9; i < kMaxTextures; i++) |
| 381 EXPECT_FALSE(ValidateTexture(textures[i].get(), true)); |
| 382 EXPECT_EQ(TexturesMemorySize(8), resource_manager->MemoryAboveCutoffBytes()); |
| 383 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 384 resource_manager->MemoryAboveCutoffBytes()); |
| 385 |
| 386 DebugScopedSetImplThreadAndMainThreadBlocked |
| 387 impl_thread_and_main_thread_blocked(&proxy_); |
| 388 resource_manager->ClearAllMemory(ResourceProvider()); |
| 389 } |
| 390 |
| 391 TEST_F(PrioritizedResourceTest, ResourceManagerDestroyedFirst) { |
| 392 scoped_ptr<PrioritizedResourceManager> resource_manager = CreateManager(1); |
| 393 scoped_ptr<PrioritizedResource> texture = |
| 394 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 395 |
| 396 // Texture is initially invalid, but it will become available. |
| 397 EXPECT_FALSE(texture->have_backing_texture()); |
| 398 |
| 399 texture->set_request_priority(100); |
| 400 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 401 |
| 402 EXPECT_TRUE(ValidateTexture(texture.get(), false)); |
| 403 EXPECT_TRUE(texture->can_acquire_backing_texture()); |
| 404 EXPECT_TRUE(texture->have_backing_texture()); |
| 405 { |
| 141 DebugScopedSetImplThreadAndMainThreadBlocked | 406 DebugScopedSetImplThreadAndMainThreadBlocked |
| 142 impl_thread_and_main_thread_blocked(&proxy_); | 407 impl_thread_and_main_thread_blocked(&proxy_); |
| 143 resource_manager->ClearAllMemory(ResourceProvider()); | 408 resource_manager->ClearAllMemory(ResourceProvider()); |
| 144 } | 409 } |
| 145 | 410 resource_manager.reset(); |
| 146 TEST_F(PrioritizedResourceTest, ChangeMemoryLimits) { | 411 |
| 147 const size_t max_textures = 8; | 412 EXPECT_FALSE(texture->can_acquire_backing_texture()); |
| 148 scoped_ptr<PrioritizedResourceManager> resource_manager = | 413 EXPECT_FALSE(texture->have_backing_texture()); |
| 149 CreateManager(max_textures); | |
| 150 scoped_ptr<PrioritizedResource> textures[max_textures]; | |
| 151 | |
| 152 for (size_t i = 0; i < max_textures; ++i) | |
| 153 textures[i] = | |
| 154 resource_manager->CreateTexture(texture_size_, texture_format_); | |
| 155 for (size_t i = 0; i < max_textures; ++i) | |
| 156 textures[i]->set_request_priority(100 + i); | |
| 157 | |
| 158 // Set max limit to 8 textures | |
| 159 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8)); | |
| 160 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 161 for (size_t i = 0; i < max_textures; ++i) | |
| 162 ValidateTexture(textures[i], false); { | |
| 163 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 164 impl_thread_and_main_thread_blocked(&proxy_); | |
| 165 resource_manager->ReduceMemory(ResourceProvider()); | |
| 166 } | |
| 167 | |
| 168 EXPECT_EQ(TexturesMemorySize(8), | |
| 169 resource_manager->MemoryAboveCutoffBytes()); | |
| 170 EXPECT_LE(resource_manager->MemoryUseBytes(), | |
| 171 resource_manager->MemoryAboveCutoffBytes()); | |
| 172 | |
| 173 // Set max limit to 5 textures | |
| 174 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(5)); | |
| 175 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 176 for (size_t i = 0; i < max_textures; ++i) | |
| 177 EXPECT_EQ(ValidateTexture(textures[i], false), i < 5); { | |
| 178 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 179 impl_thread_and_main_thread_blocked(&proxy_); | |
| 180 resource_manager->ReduceMemory(ResourceProvider()); | |
| 181 } | |
| 182 | |
| 183 EXPECT_EQ(TexturesMemorySize(5), | |
| 184 resource_manager->MemoryAboveCutoffBytes()); | |
| 185 EXPECT_LE(resource_manager->MemoryUseBytes(), | |
| 186 resource_manager->MemoryAboveCutoffBytes()); | |
| 187 | |
| 188 // Set max limit to 4 textures | |
| 189 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(4)); | |
| 190 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 191 for (size_t i = 0; i < max_textures; ++i) | |
| 192 EXPECT_EQ(ValidateTexture(textures[i], false), i < 4); { | |
| 193 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 194 impl_thread_and_main_thread_blocked(&proxy_); | |
| 195 resource_manager->ReduceMemory(ResourceProvider()); | |
| 196 } | |
| 197 | |
| 198 EXPECT_EQ(TexturesMemorySize(4), | |
| 199 resource_manager->MemoryAboveCutoffBytes()); | |
| 200 EXPECT_LE(resource_manager->MemoryUseBytes(), | |
| 201 resource_manager->MemoryAboveCutoffBytes()); | |
| 202 | |
| 203 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 204 impl_thread_and_main_thread_blocked(&proxy_); | |
| 205 resource_manager->ClearAllMemory(ResourceProvider()); | |
| 206 } | |
| 207 | |
| 208 TEST_F(PrioritizedResourceTest, ChangePriorityCutoff) { | |
| 209 const size_t max_textures = 8; | |
| 210 scoped_ptr<PrioritizedResourceManager> resource_manager = | |
| 211 CreateManager(max_textures); | |
| 212 scoped_ptr<PrioritizedResource> textures[max_textures]; | |
| 213 | |
| 214 for (size_t i = 0; i < max_textures; ++i) | |
| 215 textures[i] = | |
| 216 resource_manager->CreateTexture(texture_size_, texture_format_); | |
| 217 for (size_t i = 0; i < max_textures; ++i) | |
| 218 textures[i]->set_request_priority(100 + i); | |
| 219 | |
| 220 // Set the cutoff to drop two textures. Try to request_late on all textures, | |
| 221 // and make sure that request_late doesn't work on a texture with equal | |
| 222 // priority to the cutoff. | |
| 223 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8)); | |
| 224 resource_manager->SetExternalPriorityCutoff(106); | |
| 225 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 226 for (size_t i = 0; i < max_textures; ++i) | |
| 227 EXPECT_EQ(ValidateTexture(textures[i], true), i < 6); { | |
| 228 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 229 impl_thread_and_main_thread_blocked(&proxy_); | |
| 230 resource_manager->ReduceMemory(ResourceProvider()); | |
| 231 } | |
| 232 EXPECT_EQ(TexturesMemorySize(6), | |
| 233 resource_manager->MemoryAboveCutoffBytes()); | |
| 234 EXPECT_LE(resource_manager->MemoryUseBytes(), | |
| 235 resource_manager->MemoryAboveCutoffBytes()); | |
| 236 | |
| 237 // Set the cutoff to drop two more textures. | |
| 238 resource_manager->SetExternalPriorityCutoff(104); | |
| 239 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 240 for (size_t i = 0; i < max_textures; ++i) | |
| 241 EXPECT_EQ(ValidateTexture(textures[i], false), i < 4); { | |
| 242 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 243 impl_thread_and_main_thread_blocked(&proxy_); | |
| 244 resource_manager->ReduceMemory(ResourceProvider()); | |
| 245 } | |
| 246 EXPECT_EQ(TexturesMemorySize(4), | |
| 247 resource_manager->MemoryAboveCutoffBytes()); | |
| 248 | |
| 249 // Do a one-time eviction for one more texture based on priority cutoff | |
| 250 PrioritizedResourceManager::BackingList evicted_backings; | |
| 251 resource_manager->UnlinkAndClearEvictedBackings(); { | |
| 252 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 253 impl_thread_and_main_thread_blocked(&proxy_); | |
| 254 resource_manager->ReduceMemoryOnImplThread( | |
| 255 TexturesMemorySize(8), 104, ResourceProvider()); | |
| 256 EXPECT_EQ(0, EvictedBackingCount(resource_manager.get())); | |
| 257 resource_manager->ReduceMemoryOnImplThread( | |
| 258 TexturesMemorySize(8), 103, ResourceProvider()); | |
| 259 EXPECT_EQ(1, EvictedBackingCount(resource_manager.get())); | |
| 260 } | |
| 261 resource_manager->UnlinkAndClearEvictedBackings(); | |
| 262 EXPECT_EQ(TexturesMemorySize(3), resource_manager->MemoryUseBytes()); | |
| 263 | |
| 264 // Re-allocate the the texture after the one-time drop. | |
| 265 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 266 for (size_t i = 0; i < max_textures; ++i) | |
| 267 EXPECT_EQ(ValidateTexture(textures[i], false), i < 4); { | |
| 268 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 269 impl_thread_and_main_thread_blocked(&proxy_); | |
| 270 resource_manager->ReduceMemory(ResourceProvider()); | |
| 271 } | |
| 272 EXPECT_EQ(TexturesMemorySize(4), | |
| 273 resource_manager->MemoryAboveCutoffBytes()); | |
| 274 | |
| 275 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 276 impl_thread_and_main_thread_blocked(&proxy_); | |
| 277 resource_manager->ClearAllMemory(ResourceProvider()); | |
| 278 } | |
| 279 | |
| 280 TEST_F(PrioritizedResourceTest, ResourceManagerPartialUpdateTextures) { | |
| 281 const size_t max_textures = 4; | |
| 282 const size_t num_textures = 4; | |
| 283 scoped_ptr<PrioritizedResourceManager> resource_manager = | |
| 284 CreateManager(max_textures); | |
| 285 scoped_ptr<PrioritizedResource> textures[num_textures]; | |
| 286 scoped_ptr<PrioritizedResource> more_textures[num_textures]; | |
| 287 | |
| 288 for (size_t i = 0; i < num_textures; ++i) { | |
| 289 textures[i] = | |
| 290 resource_manager->CreateTexture(texture_size_, texture_format_); | |
| 291 more_textures[i] = | |
| 292 resource_manager->CreateTexture(texture_size_, texture_format_); | |
| 293 } | |
| 294 | |
| 295 for (size_t i = 0; i < num_textures; ++i) | |
| 296 textures[i]->set_request_priority(200 + i); | |
| 297 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 298 | |
| 299 // Allocate textures which are currently high priority. | |
| 300 EXPECT_TRUE(ValidateTexture(textures[0], false)); | |
| 301 EXPECT_TRUE(ValidateTexture(textures[1], false)); | |
| 302 EXPECT_TRUE(ValidateTexture(textures[2], false)); | |
| 303 EXPECT_TRUE(ValidateTexture(textures[3], false)); | |
| 304 | |
| 305 EXPECT_TRUE(textures[0]->have_backing_texture()); | |
| 306 EXPECT_TRUE(textures[1]->have_backing_texture()); | |
| 307 EXPECT_TRUE(textures[2]->have_backing_texture()); | |
| 308 EXPECT_TRUE(textures[3]->have_backing_texture()); | |
| 309 | |
| 310 for (size_t i = 0; i < num_textures; ++i) | |
| 311 more_textures[i]->set_request_priority(100 + i); | |
| 312 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 313 | |
| 314 // Textures are now below cutoff. | |
| 315 EXPECT_FALSE(ValidateTexture(textures[0], false)); | |
| 316 EXPECT_FALSE(ValidateTexture(textures[1], false)); | |
| 317 EXPECT_FALSE(ValidateTexture(textures[2], false)); | |
| 318 EXPECT_FALSE(ValidateTexture(textures[3], false)); | |
| 319 | |
| 320 // But they are still valid to use. | |
| 321 EXPECT_TRUE(textures[0]->have_backing_texture()); | |
| 322 EXPECT_TRUE(textures[1]->have_backing_texture()); | |
| 323 EXPECT_TRUE(textures[2]->have_backing_texture()); | |
| 324 EXPECT_TRUE(textures[3]->have_backing_texture()); | |
| 325 | |
| 326 // Higher priority textures are finally needed. | |
| 327 EXPECT_TRUE(ValidateTexture(more_textures[0], false)); | |
| 328 EXPECT_TRUE(ValidateTexture(more_textures[1], false)); | |
| 329 EXPECT_TRUE(ValidateTexture(more_textures[2], false)); | |
| 330 EXPECT_TRUE(ValidateTexture(more_textures[3], false)); | |
| 331 | |
| 332 // Lower priority have been fully evicted. | |
| 333 EXPECT_FALSE(textures[0]->have_backing_texture()); | |
| 334 EXPECT_FALSE(textures[1]->have_backing_texture()); | |
| 335 EXPECT_FALSE(textures[2]->have_backing_texture()); | |
| 336 EXPECT_FALSE(textures[3]->have_backing_texture()); | |
| 337 | |
| 338 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 339 impl_thread_and_main_thread_blocked(&proxy_); | |
| 340 resource_manager->ClearAllMemory(ResourceProvider()); | |
| 341 } | |
| 342 | |
| 343 TEST_F(PrioritizedResourceTest, ResourceManagerPrioritiesAreEqual) { | |
| 344 const size_t max_textures = 16; | |
| 345 scoped_ptr<PrioritizedResourceManager> resource_manager = | |
| 346 CreateManager(max_textures); | |
| 347 scoped_ptr<PrioritizedResource> textures[max_textures]; | |
| 348 | |
| 349 for (size_t i = 0; i < max_textures; ++i) | |
| 350 textures[i] = | |
| 351 resource_manager->CreateTexture(texture_size_, texture_format_); | |
| 352 | |
| 353 // All 16 textures have the same priority except 2 higher priority. | |
| 354 for (size_t i = 0; i < max_textures; ++i) | |
| 355 textures[i]->set_request_priority(100); | |
| 356 textures[0]->set_request_priority(99); | |
| 357 textures[1]->set_request_priority(99); | |
| 358 | |
| 359 // Set max limit to 8 textures | |
| 360 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(8)); | |
| 361 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 362 | |
| 363 // The two high priority textures should be available, others should not. | |
| 364 for (size_t i = 0; i < 2; ++i) | |
| 365 EXPECT_TRUE(ValidateTexture(textures[i], false)); | |
| 366 for (size_t i = 2; i < max_textures; ++i) | |
| 367 EXPECT_FALSE(ValidateTexture(textures[i], false)); | |
| 368 EXPECT_EQ(TexturesMemorySize(2), | |
| 369 resource_manager->MemoryAboveCutoffBytes()); | |
| 370 EXPECT_LE(resource_manager->MemoryUseBytes(), | |
| 371 resource_manager->MemoryAboveCutoffBytes()); | |
| 372 | |
| 373 // Manually reserving textures should only succeed on the higher priority | |
| 374 // textures, and on remaining textures up to the memory limit. | |
| 375 for (size_t i = 0; i < 8; i++) | |
| 376 EXPECT_TRUE(ValidateTexture(textures[i], true)); | |
| 377 for (size_t i = 9; i < max_textures; i++) | |
| 378 EXPECT_FALSE(ValidateTexture(textures[i], true)); | |
| 379 EXPECT_EQ(TexturesMemorySize(8), | |
| 380 resource_manager->MemoryAboveCutoffBytes()); | |
| 381 EXPECT_LE(resource_manager->MemoryUseBytes(), | |
| 382 resource_manager->MemoryAboveCutoffBytes()); | |
| 383 | |
| 384 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 385 impl_thread_and_main_thread_blocked(&proxy_); | |
| 386 resource_manager->ClearAllMemory(ResourceProvider()); | |
| 387 } | |
| 388 | |
| 389 TEST_F(PrioritizedResourceTest, ResourceManagerDestroyedFirst) { | |
| 390 scoped_ptr<PrioritizedResourceManager> resource_manager = CreateManager(1); | |
| 391 scoped_ptr<PrioritizedResource> texture = | |
| 392 resource_manager->CreateTexture(texture_size_, texture_format_); | |
| 393 | |
| 394 // Texture is initially invalid, but it will become available. | |
| 395 EXPECT_FALSE(texture->have_backing_texture()); | |
| 396 | |
| 397 texture->set_request_priority(100); | |
| 398 PrioritizeTexturesAndBackings(resource_manager.get()); | |
| 399 | |
| 400 EXPECT_TRUE(ValidateTexture(texture, false)); | |
| 401 EXPECT_TRUE(texture->can_acquire_backing_texture()); | |
| 402 EXPECT_TRUE(texture->have_backing_texture()); { | |
| 403 DebugScopedSetImplThreadAndMainThreadBlocked | |
| 404 impl_thread_and_main_thread_blocked(&proxy_); | |
| 405 resource_manager->ClearAllMemory(ResourceProvider()); | |
| 406 } | |
| 407 resource_manager.reset(); | |
| 408 | |
| 409 EXPECT_FALSE(texture->can_acquire_backing_texture()); | |
| 410 EXPECT_FALSE(texture->have_backing_texture()); | |
| 411 } | 414 } |
| 412 | 415 |
| 413 TEST_F(PrioritizedResourceTest, TextureMovedToNewManager) { | 416 TEST_F(PrioritizedResourceTest, TextureMovedToNewManager) { |
| 414 scoped_ptr<PrioritizedResourceManager> resource_manager_one = | 417 scoped_ptr<PrioritizedResourceManager> resource_manager_one = |
| 415 CreateManager(1); | 418 CreateManager(1); |
| 416 scoped_ptr<PrioritizedResourceManager> resource_manager_two = | 419 scoped_ptr<PrioritizedResourceManager> resource_manager_two = |
| 417 CreateManager(1); | 420 CreateManager(1); |
| 418 scoped_ptr<PrioritizedResource> texture = | 421 scoped_ptr<PrioritizedResource> texture = |
| 419 resource_manager_one->CreateTexture(texture_size_, texture_format_); | 422 resource_manager_one->CreateTexture(texture_size_, texture_format_); |
| 420 | 423 |
| 421 // Texture is initially invalid, but it will become available. | 424 // Texture is initially invalid, but it will become available. |
| 422 EXPECT_FALSE(texture->have_backing_texture()); | 425 EXPECT_FALSE(texture->have_backing_texture()); |
| 423 | 426 |
| 424 texture->set_request_priority(100); | 427 texture->set_request_priority(100); |
| 425 PrioritizeTexturesAndBackings(resource_manager_one.get()); | 428 PrioritizeTexturesAndBackings(resource_manager_one.get()); |
| 426 | 429 |
| 427 EXPECT_TRUE(ValidateTexture(texture, false)); | 430 EXPECT_TRUE(ValidateTexture(texture.get(), false)); |
| 428 EXPECT_TRUE(texture->can_acquire_backing_texture()); | 431 EXPECT_TRUE(texture->can_acquire_backing_texture()); |
| 429 EXPECT_TRUE(texture->have_backing_texture()); | 432 EXPECT_TRUE(texture->have_backing_texture()); |
| 430 | 433 |
| 431 texture->SetTextureManager(0); { | 434 texture->SetTextureManager(NULL); |
| 432 DebugScopedSetImplThreadAndMainThreadBlocked | 435 { |
| 433 impl_thread_and_main_thread_blocked(&proxy_); | 436 DebugScopedSetImplThreadAndMainThreadBlocked |
| 434 resource_manager_one->ClearAllMemory(ResourceProvider()); | 437 impl_thread_and_main_thread_blocked(&proxy_); |
| 435 } | 438 resource_manager_one->ClearAllMemory(ResourceProvider()); |
| 436 resource_manager_one.reset(); | 439 } |
| 437 | 440 resource_manager_one.reset(); |
| 438 EXPECT_FALSE(texture->can_acquire_backing_texture()); | 441 |
| 439 EXPECT_FALSE(texture->have_backing_texture()); | 442 EXPECT_FALSE(texture->can_acquire_backing_texture()); |
| 440 | 443 EXPECT_FALSE(texture->have_backing_texture()); |
| 441 texture->SetTextureManager(resource_manager_two.get()); | 444 |
| 442 | 445 texture->SetTextureManager(resource_manager_two.get()); |
| 443 PrioritizeTexturesAndBackings(resource_manager_two.get()); | 446 |
| 444 | 447 PrioritizeTexturesAndBackings(resource_manager_two.get()); |
| 445 EXPECT_TRUE(ValidateTexture(texture, false)); | 448 |
| 446 EXPECT_TRUE(texture->can_acquire_backing_texture()); | 449 EXPECT_TRUE(ValidateTexture(texture.get(), false)); |
| 447 EXPECT_TRUE(texture->have_backing_texture()); | 450 EXPECT_TRUE(texture->can_acquire_backing_texture()); |
| 448 | 451 EXPECT_TRUE(texture->have_backing_texture()); |
| 449 DebugScopedSetImplThreadAndMainThreadBlocked | 452 |
| 450 impl_thread_and_main_thread_blocked(&proxy_); | 453 DebugScopedSetImplThreadAndMainThreadBlocked |
| 451 resource_manager_two->ClearAllMemory(ResourceProvider()); | 454 impl_thread_and_main_thread_blocked(&proxy_); |
| 455 resource_manager_two->ClearAllMemory(ResourceProvider()); |
| 452 } | 456 } |
| 453 | 457 |
| 454 TEST_F(PrioritizedResourceTest, | 458 TEST_F(PrioritizedResourceTest, |
| 455 RenderSurfacesReduceMemoryAvailableOutsideRootSurface) { | 459 RenderSurfacesReduceMemoryAvailableOutsideRootSurface) { |
| 456 const size_t max_textures = 8; | 460 const size_t kMaxTextures = 8; |
| 457 scoped_ptr<PrioritizedResourceManager> resource_manager = | 461 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 458 CreateManager(max_textures); | 462 CreateManager(kMaxTextures); |
| 459 | 463 |
| 460 // Half of the memory is taken by surfaces (with high priority place-holder) | 464 // Half of the memory is taken by surfaces (with high priority place-holder) |
| 461 scoped_ptr<PrioritizedResource> render_surface_place_holder = | 465 scoped_ptr<PrioritizedResource> render_surface_place_holder = |
| 462 resource_manager->CreateTexture(texture_size_, texture_format_); | 466 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 463 render_surface_place_holder->SetToSelfManagedMemoryPlaceholder( | 467 render_surface_place_holder->SetToSelfManagedMemoryPlaceholder( |
| 464 TexturesMemorySize(4)); | 468 TexturesMemorySize(4)); |
| 465 render_surface_place_holder->set_request_priority( | 469 render_surface_place_holder->set_request_priority( |
| 466 PriorityCalculator::RenderSurfacePriority()); | 470 PriorityCalculator::RenderSurfacePriority()); |
| 467 | 471 |
| 468 // Create textures to fill our memory limit. | 472 // Create textures to fill our memory limit. |
| 469 scoped_ptr<PrioritizedResource> textures[max_textures]; | 473 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 470 | 474 |
| 471 for (size_t i = 0; i < max_textures; ++i) | 475 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 472 textures[i] = | 476 textures[i] = |
| 473 resource_manager->CreateTexture(texture_size_, texture_format_); | 477 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 474 | 478 } |
| 475 // Set decreasing non-visible priorities outside root surface. | 479 |
| 476 for (size_t i = 0; i < max_textures; ++i) | 480 // Set decreasing non-visible priorities outside root surface. |
| 477 textures[i]->set_request_priority(100 + i); | 481 for (size_t i = 0; i < kMaxTextures; ++i) |
| 478 | 482 textures[i]->set_request_priority(100 + i); |
| 479 // Only lower half should be available. | 483 |
| 480 PrioritizeTexturesAndBackings(resource_manager.get()); | 484 // Only lower half should be available. |
| 481 EXPECT_TRUE(ValidateTexture(textures[0], false)); | 485 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 482 EXPECT_TRUE(ValidateTexture(textures[3], false)); | 486 EXPECT_TRUE(ValidateTexture(textures[0].get(), false)); |
| 483 EXPECT_FALSE(ValidateTexture(textures[4], false)); | 487 EXPECT_TRUE(ValidateTexture(textures[3].get(), false)); |
| 484 EXPECT_FALSE(ValidateTexture(textures[7], false)); | 488 EXPECT_FALSE(ValidateTexture(textures[4].get(), false)); |
| 485 | 489 EXPECT_FALSE(ValidateTexture(textures[7].get(), false)); |
| 486 // Set increasing non-visible priorities outside root surface. | 490 |
| 487 for (size_t i = 0; i < max_textures; ++i) | 491 // Set increasing non-visible priorities outside root surface. |
| 488 textures[i]->set_request_priority(100 - i); | 492 for (size_t i = 0; i < kMaxTextures; ++i) |
| 489 | 493 textures[i]->set_request_priority(100 - i); |
| 490 // Only upper half should be available. | 494 |
| 491 PrioritizeTexturesAndBackings(resource_manager.get()); | 495 // Only upper half should be available. |
| 492 EXPECT_FALSE(ValidateTexture(textures[0], false)); | 496 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 493 EXPECT_FALSE(ValidateTexture(textures[3], false)); | 497 EXPECT_FALSE(ValidateTexture(textures[0].get(), false)); |
| 494 EXPECT_TRUE(ValidateTexture(textures[4], false)); | 498 EXPECT_FALSE(ValidateTexture(textures[3].get(), false)); |
| 495 EXPECT_TRUE(ValidateTexture(textures[7], false)); | 499 EXPECT_TRUE(ValidateTexture(textures[4].get(), false)); |
| 496 | 500 EXPECT_TRUE(ValidateTexture(textures[7].get(), false)); |
| 497 EXPECT_EQ(TexturesMemorySize(4), | 501 |
| 498 resource_manager->MemoryAboveCutoffBytes()); | 502 EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes()); |
| 499 EXPECT_EQ(TexturesMemorySize(4), | 503 EXPECT_EQ(TexturesMemorySize(4), |
| 500 resource_manager->MemoryForSelfManagedTextures()); | 504 resource_manager->MemoryForSelfManagedTextures()); |
| 501 EXPECT_LE(resource_manager->MemoryUseBytes(), | 505 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 502 resource_manager->MemoryAboveCutoffBytes()); | 506 resource_manager->MemoryAboveCutoffBytes()); |
| 503 | 507 |
| 504 DebugScopedSetImplThreadAndMainThreadBlocked | 508 DebugScopedSetImplThreadAndMainThreadBlocked |
| 505 impl_thread_and_main_thread_blocked(&proxy_); | 509 impl_thread_and_main_thread_blocked(&proxy_); |
| 506 resource_manager->ClearAllMemory(ResourceProvider()); | 510 resource_manager->ClearAllMemory(ResourceProvider()); |
| 507 } | 511 } |
| 508 | 512 |
| 509 TEST_F(PrioritizedResourceTest, | 513 TEST_F(PrioritizedResourceTest, |
| 510 RenderSurfacesReduceMemoryAvailableForRequestLate) { | 514 RenderSurfacesReduceMemoryAvailableForRequestLate) { |
| 511 const size_t max_textures = 8; | 515 const size_t kMaxTextures = 8; |
| 512 scoped_ptr<PrioritizedResourceManager> resource_manager = | 516 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 513 CreateManager(max_textures); | 517 CreateManager(kMaxTextures); |
| 514 | 518 |
| 515 // Half of the memory is taken by surfaces (with high priority place-holder) | 519 // Half of the memory is taken by surfaces (with high priority place-holder) |
| 516 scoped_ptr<PrioritizedResource> render_surface_place_holder = | 520 scoped_ptr<PrioritizedResource> render_surface_place_holder = |
| 517 resource_manager->CreateTexture(texture_size_, texture_format_); | 521 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 518 render_surface_place_holder->SetToSelfManagedMemoryPlaceholder( | 522 render_surface_place_holder->SetToSelfManagedMemoryPlaceholder( |
| 519 TexturesMemorySize(4)); | 523 TexturesMemorySize(4)); |
| 520 render_surface_place_holder->set_request_priority( | 524 render_surface_place_holder->set_request_priority( |
| 521 PriorityCalculator::RenderSurfacePriority()); | 525 PriorityCalculator::RenderSurfacePriority()); |
| 522 | 526 |
| 523 // Create textures to fill our memory limit. | 527 // Create textures to fill our memory limit. |
| 524 scoped_ptr<PrioritizedResource> textures[max_textures]; | 528 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 525 | 529 |
| 526 for (size_t i = 0; i < max_textures; ++i) | 530 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 527 textures[i] = | 531 textures[i] = |
| 528 resource_manager->CreateTexture(texture_size_, texture_format_); | 532 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 529 | 533 } |
| 530 // Set equal priorities. | 534 |
| 531 for (size_t i = 0; i < max_textures; ++i) | 535 // Set equal priorities. |
| 532 textures[i]->set_request_priority(100); | 536 for (size_t i = 0; i < kMaxTextures; ++i) |
| 533 | 537 textures[i]->set_request_priority(100); |
| 534 // The first four to be requested late will be available. | 538 |
| 535 PrioritizeTexturesAndBackings(resource_manager.get()); | 539 // The first four to be requested late will be available. |
| 536 for (unsigned i = 0; i < max_textures; ++i) | 540 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 537 EXPECT_FALSE(ValidateTexture(textures[i], false)); | 541 for (unsigned i = 0; i < kMaxTextures; ++i) |
| 538 for (unsigned i = 0; i < max_textures; i += 2) | 542 EXPECT_FALSE(ValidateTexture(textures[i].get(), false)); |
| 539 EXPECT_TRUE(ValidateTexture(textures[i], true)); | 543 for (unsigned i = 0; i < kMaxTextures; i += 2) |
| 540 for (unsigned i = 1; i < max_textures; i += 2) | 544 EXPECT_TRUE(ValidateTexture(textures[i].get(), true)); |
| 541 EXPECT_FALSE(ValidateTexture(textures[i], true)); | 545 for (unsigned i = 1; i < kMaxTextures; i += 2) |
| 542 | 546 EXPECT_FALSE(ValidateTexture(textures[i].get(), true)); |
| 543 EXPECT_EQ(TexturesMemorySize(4), | 547 |
| 544 resource_manager->MemoryAboveCutoffBytes()); | 548 EXPECT_EQ(TexturesMemorySize(4), resource_manager->MemoryAboveCutoffBytes()); |
| 545 EXPECT_EQ(TexturesMemorySize(4), | 549 EXPECT_EQ(TexturesMemorySize(4), |
| 546 resource_manager->MemoryForSelfManagedTextures()); | 550 resource_manager->MemoryForSelfManagedTextures()); |
| 547 EXPECT_LE(resource_manager->MemoryUseBytes(), | 551 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 548 resource_manager->MemoryAboveCutoffBytes()); | 552 resource_manager->MemoryAboveCutoffBytes()); |
| 549 | 553 |
| 550 DebugScopedSetImplThreadAndMainThreadBlocked | 554 DebugScopedSetImplThreadAndMainThreadBlocked |
| 551 impl_thread_and_main_thread_blocked(&proxy_); | 555 impl_thread_and_main_thread_blocked(&proxy_); |
| 552 resource_manager->ClearAllMemory(ResourceProvider()); | 556 resource_manager->ClearAllMemory(ResourceProvider()); |
| 553 } | 557 } |
| 554 | 558 |
| 555 TEST_F(PrioritizedResourceTest, | 559 TEST_F(PrioritizedResourceTest, |
| 556 WhenRenderSurfaceNotAvailableTexturesAlsoNotAvailable) { | 560 WhenRenderSurfaceNotAvailableTexturesAlsoNotAvailable) { |
| 557 const size_t max_textures = 8; | 561 const size_t kMaxTextures = 8; |
| 558 scoped_ptr<PrioritizedResourceManager> resource_manager = | 562 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 559 CreateManager(max_textures); | 563 CreateManager(kMaxTextures); |
| 560 | 564 |
| 561 // Half of the memory is taken by surfaces (with high priority place-holder) | 565 // Half of the memory is taken by surfaces (with high priority place-holder) |
| 562 scoped_ptr<PrioritizedResource> render_surface_place_holder = | 566 scoped_ptr<PrioritizedResource> render_surface_place_holder = |
| 563 resource_manager->CreateTexture(texture_size_, texture_format_); | 567 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 564 render_surface_place_holder->SetToSelfManagedMemoryPlaceholder( | 568 render_surface_place_holder->SetToSelfManagedMemoryPlaceholder( |
| 565 TexturesMemorySize(4)); | 569 TexturesMemorySize(4)); |
| 566 render_surface_place_holder->set_request_priority( | 570 render_surface_place_holder->set_request_priority( |
| 567 PriorityCalculator::RenderSurfacePriority()); | 571 PriorityCalculator::RenderSurfacePriority()); |
| 568 | 572 |
| 569 // Create textures to fill our memory limit. | 573 // Create textures to fill our memory limit. |
| 570 scoped_ptr<PrioritizedResource> textures[max_textures]; | 574 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 571 | 575 |
| 572 for (size_t i = 0; i < max_textures; ++i) | 576 for (size_t i = 0; i < kMaxTextures; ++i) |
| 573 textures[i] = | 577 textures[i] = |
| 574 resource_manager->CreateTexture(texture_size_, texture_format_); | 578 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 575 | 579 |
| 576 // Set 6 visible textures in the root surface, and 2 in a child surface. | 580 // Set 6 visible textures in the root surface, and 2 in a child surface. |
| 577 for (size_t i = 0; i < 6; ++i) | 581 for (size_t i = 0; i < 6; ++i) { |
| 578 textures[i]-> | 582 textures[i]-> |
| 579 set_request_priority(PriorityCalculator::VisiblePriority(true)); | 583 set_request_priority(PriorityCalculator::VisiblePriority(true)); |
| 580 for (size_t i = 6; i < 8; ++i) | 584 } |
| 581 textures[i]-> | 585 for (size_t i = 6; i < 8; ++i) { |
| 582 set_request_priority(PriorityCalculator::VisiblePriority(false)); | 586 textures[i]-> |
| 583 | 587 set_request_priority(PriorityCalculator::VisiblePriority(false)); |
| 584 PrioritizeTexturesAndBackings(resource_manager.get()); | 588 } |
| 585 | 589 |
| 586 // Unable to request_late textures in the child surface. | 590 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 587 EXPECT_FALSE(ValidateTexture(textures[6], true)); | 591 |
| 588 EXPECT_FALSE(ValidateTexture(textures[7], true)); | 592 // Unable to request_late textures in the child surface. |
| 589 | 593 EXPECT_FALSE(ValidateTexture(textures[6].get(), true)); |
| 590 // Root surface textures are valid. | 594 EXPECT_FALSE(ValidateTexture(textures[7].get(), true)); |
| 591 for (size_t i = 0; i < 6; ++i) | 595 |
| 592 EXPECT_TRUE(ValidateTexture(textures[i], false)); | 596 // Root surface textures are valid. |
| 593 | 597 for (size_t i = 0; i < 6; ++i) |
| 594 EXPECT_EQ(TexturesMemorySize(6), | 598 EXPECT_TRUE(ValidateTexture(textures[i].get(), false)); |
| 595 resource_manager->MemoryAboveCutoffBytes()); | 599 |
| 596 EXPECT_EQ(TexturesMemorySize(2), | 600 EXPECT_EQ(TexturesMemorySize(6), resource_manager->MemoryAboveCutoffBytes()); |
| 597 resource_manager->MemoryForSelfManagedTextures()); | 601 EXPECT_EQ(TexturesMemorySize(2), |
| 598 EXPECT_LE(resource_manager->MemoryUseBytes(), | 602 resource_manager->MemoryForSelfManagedTextures()); |
| 599 resource_manager->MemoryAboveCutoffBytes()); | 603 EXPECT_LE(resource_manager->MemoryUseBytes(), |
| 600 | 604 resource_manager->MemoryAboveCutoffBytes()); |
| 601 DebugScopedSetImplThreadAndMainThreadBlocked | 605 |
| 602 impl_thread_and_main_thread_blocked(&proxy_); | 606 DebugScopedSetImplThreadAndMainThreadBlocked |
| 603 resource_manager->ClearAllMemory(ResourceProvider()); | 607 impl_thread_and_main_thread_blocked(&proxy_); |
| 608 resource_manager->ClearAllMemory(ResourceProvider()); |
| 604 } | 609 } |
| 605 | 610 |
| 606 TEST_F(PrioritizedResourceTest, RequestLateBackingsSorting) { | 611 TEST_F(PrioritizedResourceTest, RequestLateBackingsSorting) { |
| 607 const size_t max_textures = 8; | 612 const size_t kMaxTextures = 8; |
| 608 scoped_ptr<PrioritizedResourceManager> resource_manager = | 613 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 609 CreateManager(max_textures); | 614 CreateManager(kMaxTextures); |
| 610 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(max_textures)); | 615 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(kMaxTextures)); |
| 611 | 616 |
| 612 // Create textures to fill our memory limit. | 617 // Create textures to fill our memory limit. |
| 613 scoped_ptr<PrioritizedResource> textures[max_textures]; | 618 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 614 for (size_t i = 0; i < max_textures; ++i) | 619 for (size_t i = 0; i < kMaxTextures; ++i) |
| 615 textures[i] = | 620 textures[i] = |
| 616 resource_manager->CreateTexture(texture_size_, texture_format_); | 621 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 617 | 622 |
| 618 // Set equal priorities, and allocate backings for all textures. | 623 // Set equal priorities, and allocate backings for all textures. |
| 619 for (size_t i = 0; i < max_textures; ++i) | 624 for (size_t i = 0; i < kMaxTextures; ++i) |
| 620 textures[i]->set_request_priority(100); | 625 textures[i]->set_request_priority(100); |
| 621 PrioritizeTexturesAndBackings(resource_manager.get()); | 626 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 622 for (unsigned i = 0; i < max_textures; ++i) | 627 for (unsigned i = 0; i < kMaxTextures; ++i) |
| 623 EXPECT_TRUE(ValidateTexture(textures[i], false)); | 628 EXPECT_TRUE(ValidateTexture(textures[i].get(), false)); |
| 624 | 629 |
| 625 // Drop the memory limit and prioritize (none will be above the threshold, | 630 // Drop the memory limit and prioritize (none will be above the threshold, |
| 626 // but they still have backings because ReduceMemory hasn't been called). | 631 // but they still have backings because ReduceMemory hasn't been called). |
| 627 resource_manager->SetMaxMemoryLimitBytes( | 632 resource_manager->SetMaxMemoryLimitBytes( |
| 628 TexturesMemorySize(max_textures / 2)); | 633 TexturesMemorySize(kMaxTextures / 2)); |
| 629 PrioritizeTexturesAndBackings(resource_manager.get()); | 634 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 630 | 635 |
| 631 // Push half of them back over the limit. | 636 // Push half of them back over the limit. |
| 632 for (size_t i = 0; i < max_textures; i += 2) | 637 for (size_t i = 0; i < kMaxTextures; i += 2) |
| 633 EXPECT_TRUE(textures[i]->RequestLate()); | 638 EXPECT_TRUE(textures[i]->RequestLate()); |
| 634 | 639 |
| 635 // Push the priorities to the backings array and sort the backings array | 640 // Push the priorities to the backings array and sort the backings array |
| 636 ResourceManagerUpdateBackingsPriorities(resource_manager.get()); | 641 ResourceManagerUpdateBackingsPriorities(resource_manager.get()); |
| 637 | 642 |
| 638 // Assert that the backings list be sorted with the below-limit backings | 643 // Assert that the backings list be sorted with the below-limit backings |
| 639 // before the above-limit backings. | 644 // before the above-limit backings. |
| 640 ResourceManagerAssertInvariants(resource_manager.get()); | 645 ResourceManagerAssertInvariants(resource_manager.get()); |
| 641 | 646 |
| 642 // Make sure that we have backings for all of the textures. | 647 // Make sure that we have backings for all of the textures. |
| 643 for (size_t i = 0; i < max_textures; ++i) | 648 for (size_t i = 0; i < kMaxTextures; ++i) |
| 644 EXPECT_TRUE(textures[i]->have_backing_texture()); | 649 EXPECT_TRUE(textures[i]->have_backing_texture()); |
| 645 | 650 |
| 646 // Make sure that only the request_late textures are above the priority | 651 // Make sure that only the request_late textures are above the priority |
| 647 // cutoff | 652 // cutoff |
| 648 for (size_t i = 0; i < max_textures; i += 2) | 653 for (size_t i = 0; i < kMaxTextures; i += 2) |
| 649 EXPECT_TRUE(TextureBackingIsAbovePriorityCutoff(textures[i].get())); | 654 EXPECT_TRUE(TextureBackingIsAbovePriorityCutoff(textures[i].get())); |
| 650 for (size_t i = 1; i < max_textures; i += 2) | 655 for (size_t i = 1; i < kMaxTextures; i += 2) |
| 651 EXPECT_FALSE(TextureBackingIsAbovePriorityCutoff(textures[i].get())); | 656 EXPECT_FALSE(TextureBackingIsAbovePriorityCutoff(textures[i].get())); |
| 652 | 657 |
| 653 DebugScopedSetImplThreadAndMainThreadBlocked | 658 DebugScopedSetImplThreadAndMainThreadBlocked |
| 654 impl_thread_and_main_thread_blocked(&proxy_); | 659 impl_thread_and_main_thread_blocked(&proxy_); |
| 655 resource_manager->ClearAllMemory(ResourceProvider()); | 660 resource_manager->ClearAllMemory(ResourceProvider()); |
| 656 } | 661 } |
| 657 | 662 |
| 658 TEST_F(PrioritizedResourceTest, ClearUploadsToEvictedResources) { | 663 TEST_F(PrioritizedResourceTest, ClearUploadsToEvictedResources) { |
| 659 const size_t max_textures = 4; | 664 const size_t kMaxTextures = 4; |
| 660 scoped_ptr<PrioritizedResourceManager> resource_manager = | 665 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 661 CreateManager(max_textures); | 666 CreateManager(kMaxTextures); |
| 662 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(max_textures)); | 667 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(kMaxTextures)); |
| 663 | 668 |
| 664 // Create textures to fill our memory limit. | 669 // Create textures to fill our memory limit. |
| 665 scoped_ptr<PrioritizedResource> textures[max_textures]; | 670 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 666 | 671 |
| 667 for (size_t i = 0; i < max_textures; ++i) | 672 for (size_t i = 0; i < kMaxTextures; ++i) |
| 668 textures[i] = | 673 textures[i] = |
| 669 resource_manager->CreateTexture(texture_size_, texture_format_); | 674 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 670 | 675 |
| 671 // Set equal priorities, and allocate backings for all textures. | 676 // Set equal priorities, and allocate backings for all textures. |
| 672 for (size_t i = 0; i < max_textures; ++i) | 677 for (size_t i = 0; i < kMaxTextures; ++i) |
| 673 textures[i]->set_request_priority(100); | 678 textures[i]->set_request_priority(100); |
| 674 PrioritizeTexturesAndBackings(resource_manager.get()); | 679 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 675 for (unsigned i = 0; i < max_textures; ++i) | 680 for (unsigned i = 0; i < kMaxTextures; ++i) |
| 676 EXPECT_TRUE(ValidateTexture(textures[i], false)); | 681 EXPECT_TRUE(ValidateTexture(textures[i].get(), false)); |
| 677 | 682 |
| 678 ResourceUpdateQueue queue; | 683 ResourceUpdateQueue queue; |
| 679 DebugScopedSetImplThreadAndMainThreadBlocked | 684 DebugScopedSetImplThreadAndMainThreadBlocked |
| 680 impl_thread_and_main_thread_blocked(&proxy_); | 685 impl_thread_and_main_thread_blocked(&proxy_); |
| 681 for (size_t i = 0; i < max_textures; ++i) { | 686 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 682 const ResourceUpdate upload = ResourceUpdate::Create( | 687 const ResourceUpdate upload = ResourceUpdate::Create( |
| 683 textures[i].get(), NULL, gfx::Rect(), gfx::Rect(), gfx::Vector2d()); | 688 textures[i].get(), NULL, gfx::Rect(), gfx::Rect(), gfx::Vector2d()); |
| 684 queue.AppendFullUpload(upload); | 689 queue.AppendFullUpload(upload); |
| 685 } | 690 } |
| 686 | 691 |
| 687 // Make sure that we have backings for all of the textures. | 692 // Make sure that we have backings for all of the textures. |
| 688 for (size_t i = 0; i < max_textures; ++i) | 693 for (size_t i = 0; i < kMaxTextures; ++i) |
| 689 EXPECT_TRUE(textures[i]->have_backing_texture()); | 694 EXPECT_TRUE(textures[i]->have_backing_texture()); |
| 690 | 695 |
| 691 queue.ClearUploadsToEvictedResources(); | 696 queue.ClearUploadsToEvictedResources(); |
| 692 EXPECT_EQ(4, queue.FullUploadSize()); | 697 EXPECT_EQ(4, queue.FullUploadSize()); |
| 693 | 698 |
| 694 resource_manager->ReduceMemoryOnImplThread( | 699 resource_manager->ReduceMemoryOnImplThread( |
| 695 TexturesMemorySize(1), | 700 TexturesMemorySize(1), |
| 696 PriorityCalculator::AllowEverythingCutoff(), | 701 PriorityCalculator::AllowEverythingCutoff(), |
| 697 ResourceProvider()); | 702 ResourceProvider()); |
| 698 queue.ClearUploadsToEvictedResources(); | 703 queue.ClearUploadsToEvictedResources(); |
| 699 EXPECT_EQ(1, queue.FullUploadSize()); | 704 EXPECT_EQ(1, queue.FullUploadSize()); |
| 700 | 705 |
| 701 resource_manager->ReduceMemoryOnImplThread( | 706 resource_manager->ReduceMemoryOnImplThread( |
| 702 0, PriorityCalculator::AllowEverythingCutoff(), ResourceProvider()); | 707 0, PriorityCalculator::AllowEverythingCutoff(), ResourceProvider()); |
| 703 queue.ClearUploadsToEvictedResources(); | 708 queue.ClearUploadsToEvictedResources(); |
| 704 EXPECT_EQ(0, queue.FullUploadSize()); | 709 EXPECT_EQ(0, queue.FullUploadSize()); |
| 705 } | 710 } |
| 706 | 711 |
| 707 TEST_F(PrioritizedResourceTest, UsageStatistics) { | 712 TEST_F(PrioritizedResourceTest, UsageStatistics) { |
| 708 const size_t max_textures = 5; | 713 const size_t kMaxTextures = 5; |
| 709 scoped_ptr<PrioritizedResourceManager> resource_manager = | 714 scoped_ptr<PrioritizedResourceManager> resource_manager = |
| 710 CreateManager(max_textures); | 715 CreateManager(kMaxTextures); |
| 711 scoped_ptr<PrioritizedResource> textures[max_textures]; | 716 scoped_ptr<PrioritizedResource> textures[kMaxTextures]; |
| 712 | 717 |
| 713 for (size_t i = 0; i < max_textures; ++i) | 718 for (size_t i = 0; i < kMaxTextures; ++i) { |
| 714 textures[i] = | 719 textures[i] = |
| 715 resource_manager->CreateTexture(texture_size_, texture_format_); | 720 resource_manager->CreateTexture(texture_size_, texture_format_); |
| 716 | 721 } |
| 717 textures[0]->set_request_priority( | 722 |
| 718 PriorityCalculator::AllowVisibleOnlyCutoff() - 1); | 723 textures[0]-> |
| 719 textures[1]-> | 724 set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1); |
| 720 set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff()); | 725 textures[1]-> |
| 721 textures[2]->set_request_priority( | 726 set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff()); |
| 722 PriorityCalculator::AllowVisibleAndNearbyCutoff() - 1); | 727 textures[2]->set_request_priority( |
| 723 textures[3]->set_request_priority( | 728 PriorityCalculator::AllowVisibleAndNearbyCutoff() - 1); |
| 724 PriorityCalculator::AllowVisibleAndNearbyCutoff()); | 729 textures[3]-> |
| 725 textures[4]->set_request_priority( | 730 set_request_priority(PriorityCalculator::AllowVisibleAndNearbyCutoff()); |
| 726 PriorityCalculator::AllowVisibleAndNearbyCutoff() + 1); | 731 textures[4]->set_request_priority( |
| 727 | 732 PriorityCalculator::AllowVisibleAndNearbyCutoff() + 1); |
| 728 // Set max limit to 2 textures. | 733 |
| 729 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(2)); | 734 // Set max limit to 2 textures. |
| 730 PrioritizeTexturesAndBackings(resource_manager.get()); | 735 resource_manager->SetMaxMemoryLimitBytes(TexturesMemorySize(2)); |
| 731 | 736 PrioritizeTexturesAndBackings(resource_manager.get()); |
| 732 // The first two textures should be available, others should not. | 737 |
| 733 for (size_t i = 0; i < 2; ++i) | 738 // The first two textures should be available, others should not. |
| 734 EXPECT_TRUE(ValidateTexture(textures[i], false)); | 739 for (size_t i = 0; i < 2; ++i) |
| 735 for (size_t i = 2; i < max_textures; ++i) | 740 EXPECT_TRUE(ValidateTexture(textures[i].get(), false)); |
| 736 EXPECT_FALSE(ValidateTexture(textures[i], false)); | 741 for (size_t i = 2; i < kMaxTextures; ++i) |
| 737 | 742 EXPECT_FALSE(ValidateTexture(textures[i].get(), false)); |
| 738 // Validate the statistics. | 743 |
| 739 { | 744 // Validate the statistics. |
| 740 DebugScopedSetImplThread impl_thread(&proxy_); | 745 { |
| 741 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes()); | 746 DebugScopedSetImplThread impl_thread(&proxy_); |
| 742 EXPECT_EQ(TexturesMemorySize(1), | 747 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes()); |
| 743 resource_manager->MemoryVisibleBytes()); | 748 EXPECT_EQ(TexturesMemorySize(1), resource_manager->MemoryVisibleBytes()); |
| 744 EXPECT_EQ(TexturesMemorySize(3), | 749 EXPECT_EQ(TexturesMemorySize(3), |
| 745 resource_manager->MemoryVisibleAndNearbyBytes()); | 750 resource_manager->MemoryVisibleAndNearbyBytes()); |
| 746 } | 751 } |
| 747 | 752 |
| 748 // Re-prioritize the textures, but do not push the values to backings. | 753 // Re-prioritize the textures, but do not push the values to backings. |
| 749 textures[0]->set_request_priority( | 754 textures[0]-> |
| 750 PriorityCalculator::AllowVisibleOnlyCutoff() - 1); | 755 set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1); |
| 751 textures[1]->set_request_priority( | 756 textures[1]-> |
| 752 PriorityCalculator::AllowVisibleOnlyCutoff() - 1); | 757 set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1); |
| 753 textures[2]->set_request_priority( | 758 textures[2]-> |
| 754 PriorityCalculator::AllowVisibleOnlyCutoff() - 1); | 759 set_request_priority(PriorityCalculator::AllowVisibleOnlyCutoff() - 1); |
| 755 textures[3]->set_request_priority( | 760 textures[3]->set_request_priority( |
| 756 PriorityCalculator::AllowVisibleAndNearbyCutoff() - 1); | 761 PriorityCalculator::AllowVisibleAndNearbyCutoff() - 1); |
| 757 textures[4]->set_request_priority( | 762 textures[4]-> |
| 758 PriorityCalculator::AllowVisibleAndNearbyCutoff()); | 763 set_request_priority(PriorityCalculator::AllowVisibleAndNearbyCutoff()); |
| 759 resource_manager->PrioritizeTextures(); | 764 resource_manager->PrioritizeTextures(); |
| 760 | 765 |
| 761 // Verify that we still see the old values. | 766 // Verify that we still see the old values. |
| 762 { | 767 { |
| 763 DebugScopedSetImplThread impl_thread (& proxy_); | 768 DebugScopedSetImplThread impl_thread(&proxy_); |
| 764 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes()); | 769 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes()); |
| 765 EXPECT_EQ(TexturesMemorySize(1), | 770 EXPECT_EQ(TexturesMemorySize(1), resource_manager->MemoryVisibleBytes()); |
| 766 resource_manager->MemoryVisibleBytes()); | 771 EXPECT_EQ(TexturesMemorySize(3), |
| 767 EXPECT_EQ(TexturesMemorySize(3), | 772 resource_manager->MemoryVisibleAndNearbyBytes()); |
| 768 resource_manager->MemoryVisibleAndNearbyBytes()); | 773 } |
| 769 } | 774 |
| 770 | 775 // Push priorities to backings, and verify we see the new values. |
| 771 // Push priorities to backings, and verify we see the new values. | 776 { |
| 772 { | 777 DebugScopedSetImplThreadAndMainThreadBlocked |
| 773 DebugScopedSetImplThreadAndMainThreadBlocked | 778 impl_thread_and_main_thread_blocked(&proxy_); |
| 774 impl_thread_and_main_thread_blocked (& proxy_); | 779 resource_manager->PushTexturePrioritiesToBackings(); |
| 775 resource_manager->PushTexturePrioritiesToBackings(); | 780 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes()); |
| 776 EXPECT_EQ(TexturesMemorySize(2), resource_manager->MemoryUseBytes()); | 781 EXPECT_EQ(TexturesMemorySize(3), resource_manager->MemoryVisibleBytes()); |
| 777 EXPECT_EQ(TexturesMemorySize(3), | 782 EXPECT_EQ(TexturesMemorySize(4), |
| 778 resource_manager->MemoryVisibleBytes()); | 783 resource_manager->MemoryVisibleAndNearbyBytes()); |
| 779 EXPECT_EQ(TexturesMemorySize(4), | 784 } |
| 780 resource_manager->MemoryVisibleAndNearbyBytes()); | 785 |
| 781 } | 786 DebugScopedSetImplThreadAndMainThreadBlocked |
| 782 | 787 impl_thread_and_main_thread_blocked(&proxy_); |
| 783 DebugScopedSetImplThreadAndMainThreadBlocked | 788 resource_manager->ClearAllMemory(ResourceProvider()); |
| 784 impl_thread_and_main_thread_blocked (& proxy_); | |
| 785 resource_manager->ClearAllMemory(ResourceProvider()); | |
| 786 } | 789 } |
| 787 | 790 |
| 788 } // namespace | 791 } // namespace |
| 789 } // namespace cc | 792 } // namespace cc |
| OLD | NEW |