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