| Index: content/common/gpu/gpu_memory_manager.cc
|
| diff --git a/content/common/gpu/gpu_memory_manager.cc b/content/common/gpu/gpu_memory_manager.cc
|
| index 163ebf0b3d6199bf943c0b806650c01a28d725d5..d174098dce369bd1e2eac4116bfede5f9743b647 100644
|
| --- a/content/common/gpu/gpu_memory_manager.cc
|
| +++ b/content/common/gpu/gpu_memory_manager.cc
|
| @@ -15,15 +15,6 @@
|
|
|
| namespace {
|
|
|
| -// These are predefined values (in bytes) for
|
| -// GpuMemoryAllocation::gpuResourceSizeInBytes. Currently, the value is only
|
| -// used to check if it is 0 or non-0. In the future, these values will not
|
| -// come from constants, but rather will be distributed dynamically.
|
| -enum {
|
| - kResourceSizeNonHibernatedTab = 1,
|
| - kResourceSizeHibernatedTab = 0
|
| -};
|
| -
|
| bool IsInSameContextShareGroupAsAnyOf(
|
| const GpuCommandBufferStubBase* stub,
|
| const std::vector<GpuCommandBufferStubBase*>& stubs) {
|
| @@ -35,6 +26,14 @@ bool IsInSameContextShareGroupAsAnyOf(
|
| return false;
|
| }
|
|
|
| +void AssignMemoryAllocations(std::vector<GpuCommandBufferStubBase*>& stubs,
|
| + GpuMemoryAllocation allocation) {
|
| + for (std::vector<GpuCommandBufferStubBase*>::iterator it = stubs.begin();
|
| + it != stubs.end(); ++it) {
|
| + (*it)->SetMemoryAllocation(allocation);
|
| + }
|
| +}
|
| +
|
| }
|
|
|
| GpuMemoryManager::GpuMemoryManager(GpuMemoryManagerClient* client,
|
| @@ -100,14 +99,6 @@ void GpuMemoryManager::ScheduleManage() {
|
| // 1. Find the most visible context-with-a-surface within each
|
| // context-without-a-surface's share group, and inherit its visibilty.
|
| void GpuMemoryManager::Manage() {
|
| - // Set up three allocation values for the three possible stub states
|
| - const GpuMemoryAllocation all_buffers_allocation(
|
| - kResourceSizeNonHibernatedTab, true, true);
|
| - const GpuMemoryAllocation front_buffers_allocation(
|
| - kResourceSizeNonHibernatedTab, false, true);
|
| - const GpuMemoryAllocation no_buffers_allocation(
|
| - kResourceSizeHibernatedTab, false, false);
|
| -
|
| manage_scheduled_ = false;
|
|
|
| // Create stub lists by separating out the two types received from client
|
| @@ -120,6 +111,8 @@ void GpuMemoryManager::Manage() {
|
| for (std::vector<GpuCommandBufferStubBase*>::iterator it = stubs.begin();
|
| it != stubs.end(); ++it) {
|
| GpuCommandBufferStubBase* stub = *it;
|
| + if (!stub->client_has_memory_allocation_changed_callback())
|
| + continue;
|
| if (stub->has_surface_state())
|
| stubs_with_surface.push_back(stub);
|
| else
|
| @@ -136,37 +129,73 @@ void GpuMemoryManager::Manage() {
|
| stubs_with_surface.end());
|
|
|
| // Separate stubs into memory allocation sets.
|
| - std::vector<GpuCommandBufferStubBase*> all_buffers, front_buffers, no_buffers;
|
| + std::vector<GpuCommandBufferStubBase*> stubs_with_surface_foreground,
|
| + stubs_with_surface_background,
|
| + stubs_with_surface_hibernated,
|
| + stubs_without_surface_foreground,
|
| + stubs_without_surface_background,
|
| + stubs_without_surface_hibernated;
|
|
|
| for (size_t i = 0; i < stubs_with_surface.size(); ++i) {
|
| GpuCommandBufferStubBase* stub = stubs_with_surface[i];
|
| DCHECK(stub->has_surface_state());
|
| - if (stub->surface_state().visible) {
|
| - all_buffers.push_back(stub);
|
| - stub->SetMemoryAllocation(all_buffers_allocation);
|
| - } else if (i < max_surfaces_with_frontbuffer_soft_limit_) {
|
| - front_buffers.push_back(stub);
|
| - stub->SetMemoryAllocation(front_buffers_allocation);
|
| - } else {
|
| - no_buffers.push_back(stub);
|
| - stub->SetMemoryAllocation(no_buffers_allocation);
|
| - }
|
| + if (stub->surface_state().visible)
|
| + stubs_with_surface_foreground.push_back(stub);
|
| + else if (i < max_surfaces_with_frontbuffer_soft_limit_)
|
| + stubs_with_surface_background.push_back(stub);
|
| + else
|
| + stubs_with_surface_hibernated.push_back(stub);
|
| }
|
| -
|
| - // Now, go through the stubs without surfaces and deduce visibility using the
|
| - // visibility of stubs which are in the same context share group.
|
| for (std::vector<GpuCommandBufferStubBase*>::const_iterator it =
|
| stubs_without_surface.begin(); it != stubs_without_surface.end(); ++it) {
|
| GpuCommandBufferStubBase* stub = *it;
|
| DCHECK(!stub->has_surface_state());
|
| - if (IsInSameContextShareGroupAsAnyOf(stub, all_buffers)) {
|
| - stub->SetMemoryAllocation(all_buffers_allocation);
|
| - } else if (IsInSameContextShareGroupAsAnyOf(stub, front_buffers)) {
|
| - stub->SetMemoryAllocation(front_buffers_allocation);
|
| - } else {
|
| - stub->SetMemoryAllocation(no_buffers_allocation);
|
| - }
|
| +
|
| + // Stubs without surfaces have deduced allocation state using the state
|
| + // of surface stubs which are in the same context share group.
|
| + if (IsInSameContextShareGroupAsAnyOf(stub, stubs_with_surface_foreground))
|
| + stubs_without_surface_foreground.push_back(stub);
|
| + else if (IsInSameContextShareGroupAsAnyOf(
|
| + stub, stubs_with_surface_background))
|
| + stubs_without_surface_background.push_back(stub);
|
| + else
|
| + stubs_without_surface_hibernated.push_back(stub);
|
| }
|
| +
|
| + // Calculate memory allocation size in bytes given to each stub, by sharing
|
| + // global limit equally among those that need it.
|
| + size_t num_stubs_need_mem = stubs_with_surface_foreground.size() +
|
| + stubs_without_surface_foreground.size() +
|
| + stubs_without_surface_background.size();
|
| + size_t base_allocation_size = kMinimumAllocationForTab * num_stubs_need_mem;
|
| + size_t bonus_allocation = 0;
|
| + if (base_allocation_size < kMaximumAllocationForTabs &&
|
| + !stubs_with_surface_foreground.empty())
|
| + bonus_allocation = (kMaximumAllocationForTabs - base_allocation_size) /
|
| + stubs_with_surface_foreground.size();
|
| +
|
| + // Now give out allocations to everyone.
|
| + AssignMemoryAllocations(stubs_with_surface_foreground,
|
| + GpuMemoryAllocation(kMinimumAllocationForTab + bonus_allocation,
|
| + GpuMemoryAllocation::kHasFrontbuffer |
|
| + GpuMemoryAllocation::kHasBackbuffer));
|
| +
|
| + AssignMemoryAllocations(stubs_with_surface_background,
|
| + GpuMemoryAllocation(0, GpuMemoryAllocation::kHasFrontbuffer));
|
| +
|
| + AssignMemoryAllocations(stubs_with_surface_hibernated,
|
| + GpuMemoryAllocation(0, GpuMemoryAllocation::kHasNoBuffers));
|
| +
|
| + AssignMemoryAllocations(stubs_without_surface_foreground,
|
| + GpuMemoryAllocation(kMinimumAllocationForTab,
|
| + GpuMemoryAllocation::kHasNoBuffers));
|
| +
|
| + AssignMemoryAllocations(stubs_without_surface_background,
|
| + GpuMemoryAllocation(kMinimumAllocationForTab,
|
| + GpuMemoryAllocation::kHasNoBuffers));
|
| +
|
| + AssignMemoryAllocations(stubs_without_surface_hibernated,
|
| + GpuMemoryAllocation(0, GpuMemoryAllocation::kHasNoBuffers));
|
| }
|
|
|
| #endif
|
|
|