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/prioritized_resource_manager.h" | 5 #include "cc/prioritized_resource_manager.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "cc/prioritized_resource.h" | 9 #include "cc/prioritized_resource.h" |
10 #include "cc/priority_calculator.h" | 10 #include "cc/priority_calculator.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 , m_memoryVisibleLastPushedBytes(0) | 29 , m_memoryVisibleLastPushedBytes(0) |
30 , m_memoryVisibleAndNearbyLastPushedBytes(0) | 30 , m_memoryVisibleAndNearbyLastPushedBytes(0) |
31 { | 31 { |
32 } | 32 } |
33 | 33 |
34 PrioritizedResourceManager::~PrioritizedResourceManager() | 34 PrioritizedResourceManager::~PrioritizedResourceManager() |
35 { | 35 { |
36 while (m_textures.size() > 0) | 36 while (m_textures.size() > 0) |
37 unregisterTexture(*m_textures.begin()); | 37 unregisterTexture(*m_textures.begin()); |
38 | 38 |
39 deleteAllEvictedBackings(); | 39 unlinkAndClearEvictedBackings(); |
40 DCHECK(m_evictedBackings.empty()); | 40 DCHECK(m_evictedBackings.empty()); |
41 | 41 |
42 // Each remaining backing is a leaked opengl texture. There should be none. | 42 // Each remaining backing is a leaked opengl texture. There should be none. |
43 DCHECK(m_backings.empty()); | 43 DCHECK(m_backings.empty()); |
44 } | 44 } |
45 | 45 |
46 size_t PrioritizedResourceManager::memoryVisibleBytes() const | 46 size_t PrioritizedResourceManager::memoryVisibleBytes() const |
47 { | 47 { |
48 DCHECK(m_proxy->isImplThread()); | 48 DCHECK(m_proxy->isImplThread()); |
49 return m_memoryVisibleLastPushedBytes; | 49 return m_memoryVisibleLastPushedBytes; |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 break; | 299 break; |
300 wastedMemory += (*it)->bytes(); | 300 wastedMemory += (*it)->bytes(); |
301 } | 301 } |
302 size_t tenPercentOfMemory = m_memoryAvailableBytes / 10; | 302 size_t tenPercentOfMemory = m_memoryAvailableBytes / 10; |
303 if (wastedMemory > tenPercentOfMemory) | 303 if (wastedMemory > tenPercentOfMemory) |
304 evictBackingsToReduceMemory(memoryUseBytes() - (wastedMemory - tenPercen
tOfMemory), | 304 evictBackingsToReduceMemory(memoryUseBytes() - (wastedMemory - tenPercen
tOfMemory), |
305 PriorityCalculator::allowEverythingCutoff(), | 305 PriorityCalculator::allowEverythingCutoff(), |
306 EvictOnlyRecyclable, | 306 EvictOnlyRecyclable, |
307 UnlinkBackings, | 307 UnlinkBackings, |
308 resourceProvider); | 308 resourceProvider); |
309 | |
310 // Unlink all evicted backings | |
311 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | |
312 if ((*it)->owner()) | |
313 (*it)->owner()->unlink(); | |
314 } | |
315 | |
316 // And clear the list of evicted backings | |
317 deleteAllEvictedBackings(); | |
318 } | 309 } |
319 | 310 |
320 void PrioritizedResourceManager::clearAllMemory(ResourceProvider* resourceProvid
er) | 311 void PrioritizedResourceManager::clearAllMemory(ResourceProvider* resourceProvid
er) |
321 { | 312 { |
322 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); | 313 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
323 DCHECK(resourceProvider); | 314 DCHECK(resourceProvider); |
324 evictBackingsToReduceMemory(0, | 315 evictBackingsToReduceMemory(0, |
325 PriorityCalculator::allowEverythingCutoff(), | 316 PriorityCalculator::allowEverythingCutoff(), |
326 EvictAnything, | 317 EvictAnything, |
327 DoNotUnlinkBackings, | 318 DoNotUnlinkBackings, |
328 resourceProvider); | 319 resourceProvider); |
329 } | 320 } |
330 | 321 |
331 bool PrioritizedResourceManager::reduceMemoryOnImplThread(size_t limitBytes, int
priorityCutoff, ResourceProvider* resourceProvider) | 322 bool PrioritizedResourceManager::reduceMemoryOnImplThread(size_t limitBytes, int
priorityCutoff, ResourceProvider* resourceProvider) |
332 { | 323 { |
333 DCHECK(m_proxy->isImplThread()); | 324 DCHECK(m_proxy->isImplThread()); |
334 DCHECK(resourceProvider); | 325 DCHECK(resourceProvider); |
335 // If we are in the process of uploading a new frame then the backings at th
e very end of | 326 // If we are in the process of uploading a new frame then the backings at th
e very end of |
336 // the list are not sorted by priority. Sort them before doing the eviction. | 327 // the list are not sorted by priority. Sort them before doing the eviction. |
337 if (m_backingsTailNotSorted) | 328 if (m_backingsTailNotSorted) |
338 sortBackings(); | 329 sortBackings(); |
339 return evictBackingsToReduceMemory(limitBytes, | 330 return evictBackingsToReduceMemory(limitBytes, |
340 priorityCutoff, | 331 priorityCutoff, |
341 EvictAnything, | 332 EvictAnything, |
342 DoNotUnlinkBackings, | 333 DoNotUnlinkBackings, |
343 resourceProvider); | 334 resourceProvider); |
344 } | 335 } |
345 | 336 |
346 void PrioritizedResourceManager::getEvictedBackings(BackingList& evictedBackings
) | 337 void PrioritizedResourceManager::unlinkAndClearEvictedBackings() |
347 { | |
348 DCHECK(m_proxy->isImplThread()); | |
349 evictedBackings.clear(); | |
350 evictedBackings.insert(evictedBackings.begin(), m_evictedBackings.begin(), m
_evictedBackings.end()); | |
351 for (BackingList::const_iterator it = evictedBackings.begin(); it != evicted
Backings.end(); ++it) { | |
352 PrioritizedResource::Backing* backing = (*it); | |
353 CHECK(!backing->m_inMainThreadEvictedList); | |
354 backing->m_inMainThreadEvictedList = true; | |
355 } | |
356 } | |
357 | |
358 void PrioritizedResourceManager::unlinkEvictedBackings(const BackingList& evicte
dBackings) | |
359 { | 338 { |
360 DCHECK(m_proxy->isMainThread()); | 339 DCHECK(m_proxy->isMainThread()); |
361 for (BackingList::const_iterator it = evictedBackings.begin(); it != evicted
Backings.end(); ++it) { | 340 base::AutoLock scoped_lock(m_evictedBackingsLock); |
362 PrioritizedResource::Backing* backing = (*it); | |
363 CHECK(backing->m_inMainThreadEvictedList); | |
364 backing->m_inMainThreadEvictedList = false; | |
365 if (backing->owner()) { | |
366 CHECK(backing->owner()->backing()); | |
367 CHECK(backing->owner()->backing() == backing); | |
368 backing->owner()->unlink(); | |
369 } | |
370 } | |
371 } | |
372 | |
373 void PrioritizedResourceManager::deleteAllEvictedBackings() | |
374 { | |
375 DCHECK(m_proxy->isMainThread() || (m_proxy->isImplThread() && m_proxy->isMai
nThreadBlocked())); | |
376 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | 341 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { |
377 PrioritizedResource::Backing* backing = (*it); | 342 PrioritizedResource::Backing* backing = (*it); |
378 CHECK(!backing->owner()); | 343 if (backing->owner()) |
| 344 backing->owner()->unlink(); |
379 delete backing; | 345 delete backing; |
380 } | 346 } |
381 m_evictedBackings.clear(); | 347 m_evictedBackings.clear(); |
382 } | 348 } |
383 | 349 |
384 bool PrioritizedResourceManager::linkedEvictedBackingsExist() const | 350 bool PrioritizedResourceManager::linkedEvictedBackingsExist() |
385 { | 351 { |
| 352 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
| 353 base::AutoLock scoped_lock(m_evictedBackingsLock); |
386 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { | 354 for (BackingList::const_iterator it = m_evictedBackings.begin(); it != m_evi
ctedBackings.end(); ++it) { |
387 if ((*it)->owner()) | 355 if ((*it)->owner()) |
388 return true; | 356 return true; |
389 } | 357 } |
390 return false; | 358 return false; |
391 } | 359 } |
392 | 360 |
393 void PrioritizedResourceManager::registerTexture(PrioritizedResource* texture) | 361 void PrioritizedResourceManager::registerTexture(PrioritizedResource* texture) |
394 { | 362 { |
395 DCHECK(m_proxy->isMainThread()); | 363 DCHECK(m_proxy->isMainThread()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 DCHECK(!m_backings.empty()); | 407 DCHECK(!m_backings.empty()); |
440 PrioritizedResource::Backing* backing = m_backings.front(); | 408 PrioritizedResource::Backing* backing = m_backings.front(); |
441 | 409 |
442 // Note that we create a backing and its resource at the same time, but we | 410 // Note that we create a backing and its resource at the same time, but we |
443 // delete the backing structure and its resource in two steps. This is becau
se | 411 // delete the backing structure and its resource in two steps. This is becau
se |
444 // we can delete the resource while the main thread is running, but we canno
t | 412 // we can delete the resource while the main thread is running, but we canno
t |
445 // unlink backings while the main thread is running. | 413 // unlink backings while the main thread is running. |
446 backing->deleteResource(resourceProvider); | 414 backing->deleteResource(resourceProvider); |
447 m_memoryUseBytes -= backing->bytes(); | 415 m_memoryUseBytes -= backing->bytes(); |
448 m_backings.pop_front(); | 416 m_backings.pop_front(); |
| 417 base::AutoLock scoped_lock(m_evictedBackingsLock); |
449 m_evictedBackings.push_back(backing); | 418 m_evictedBackings.push_back(backing); |
450 } | 419 } |
451 | 420 |
452 void PrioritizedResourceManager::assertInvariants() | 421 void PrioritizedResourceManager::assertInvariants() |
453 { | 422 { |
454 #ifndef NDEBUG | 423 #ifndef NDEBUG |
455 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); | 424 DCHECK(m_proxy->isImplThread() && m_proxy->isMainThreadBlocked()); |
456 | 425 |
457 // If we hit any of these asserts, there is a bug in this class. To see | 426 // If we hit any of these asserts, there is a bug in this class. To see |
458 // where the bug is, call this function at the beginning and end of | 427 // where the bug is, call this function at the beginning and end of |
459 // every public function. | 428 // every public function. |
460 | 429 |
461 // Backings/textures must be doubly-linked and only to other backings/textur
es in this manager. | 430 // Backings/textures must be doubly-linked and only to other backings/textur
es in this manager. |
462 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { | 431 for (BackingList::iterator it = m_backings.begin(); it != m_backings.end();
++it) { |
463 if ((*it)->owner()) { | 432 if ((*it)->owner()) { |
464 DCHECK(ContainsKey(m_textures, (*it)->owner())); | 433 DCHECK(ContainsKey(m_textures, (*it)->owner())); |
465 DCHECK((*it)->owner()->backing() == (*it)); | 434 DCHECK((*it)->owner()->backing() == (*it)); |
466 } | 435 } |
467 } | 436 } |
468 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) { | 437 for (TextureSet::iterator it = m_textures.begin(); it != m_textures.end(); +
+it) { |
469 PrioritizedResource* texture = (*it); | 438 PrioritizedResource* texture = (*it); |
470 PrioritizedResource::Backing* backing = texture->backing(); | 439 PrioritizedResource::Backing* backing = texture->backing(); |
| 440 base::AutoLock scoped_lock(m_evictedBackingsLock); |
471 if (backing) { | 441 if (backing) { |
472 if (backing->resourceHasBeenDeleted()) { | 442 if (backing->resourceHasBeenDeleted()) { |
473 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
== m_backings.end()); | 443 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
== m_backings.end()); |
474 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) != m_evictedBackings.end()); | 444 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) != m_evictedBackings.end()); |
475 } else { | 445 } else { |
476 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
!= m_backings.end()); | 446 DCHECK(std::find(m_backings.begin(), m_backings.end(), backing)
!= m_backings.end()); |
477 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) == m_evictedBackings.end()); | 447 DCHECK(std::find(m_evictedBackings.begin(), m_evictedBackings.en
d(), backing) == m_evictedBackings.end()); |
478 } | 448 } |
479 DCHECK(backing->owner() == texture); | 449 DCHECK(backing->owner() == texture); |
480 } | 450 } |
(...skipping 18 matching lines...) Expand all Loading... |
499 } | 469 } |
500 #endif | 470 #endif |
501 } | 471 } |
502 | 472 |
503 const Proxy* PrioritizedResourceManager::proxyForDebug() const | 473 const Proxy* PrioritizedResourceManager::proxyForDebug() const |
504 { | 474 { |
505 return m_proxy; | 475 return m_proxy; |
506 } | 476 } |
507 | 477 |
508 } // namespace cc | 478 } // namespace cc |
OLD | NEW |