| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 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 "content/common/gpu/gpu_memory_manager.h" | 5 #include "content/common/gpu/gpu_memory_manager.h" |
| 6 | 6 |
| 7 #if defined(ENABLE_GPU) | 7 #if defined(ENABLE_GPU) |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 componentsPerPixel * bytesPerComponent; | 41 componentsPerPixel * bytesPerComponent; |
| 42 if (limit < GpuMemoryManager::kMinimumAllocationForTab) | 42 if (limit < GpuMemoryManager::kMinimumAllocationForTab) |
| 43 limit = GpuMemoryManager::kMinimumAllocationForTab; | 43 limit = GpuMemoryManager::kMinimumAllocationForTab; |
| 44 else if (limit > GpuMemoryManager::kMaximumAllocationForTabs) | 44 else if (limit > GpuMemoryManager::kMaximumAllocationForTabs) |
| 45 limit = GpuMemoryManager::kMaximumAllocationForTabs; | 45 limit = GpuMemoryManager::kMaximumAllocationForTabs; |
| 46 return limit - GpuMemoryManager::kMinimumAllocationForTab; | 46 return limit - GpuMemoryManager::kMinimumAllocationForTab; |
| 47 } | 47 } |
| 48 #endif | 48 #endif |
| 49 | 49 |
| 50 void AssignMemoryAllocations( | 50 void AssignMemoryAllocations( |
| 51 std::vector<GpuCommandBufferStubBase*>& stubs, | 51 GpuMemoryManager::StubMemoryStatMap* stub_memory_stats, |
| 52 GpuMemoryAllocation allocation) { | 52 const std::vector<GpuCommandBufferStubBase*>& stubs, |
| 53 for (std::vector<GpuCommandBufferStubBase*>::iterator it = stubs.begin(); | 53 GpuMemoryAllocation allocation, |
| 54 it != stubs.end(); ++it) { | 54 bool visible) { |
| 55 for (std::vector<GpuCommandBufferStubBase*>::const_iterator it = |
| 56 stubs.begin(); |
| 57 it != stubs.end(); |
| 58 ++it) { |
| 55 (*it)->SetMemoryAllocation(allocation); | 59 (*it)->SetMemoryAllocation(allocation); |
| 60 (*stub_memory_stats)[*it].allocation = allocation; |
| 61 (*stub_memory_stats)[*it].visible = visible; |
| 56 } | 62 } |
| 57 } | 63 } |
| 58 | 64 |
| 59 } | 65 } |
| 60 | 66 |
| 61 GpuMemoryManager::GpuMemoryManager(GpuMemoryManagerClient* client, | 67 GpuMemoryManager::GpuMemoryManager(GpuMemoryManagerClient* client, |
| 62 size_t max_surfaces_with_frontbuffer_soft_limit) | 68 size_t max_surfaces_with_frontbuffer_soft_limit) |
| 63 : client_(client), | 69 : client_(client), |
| 64 manage_immediate_scheduled_(false), | 70 manage_immediate_scheduled_(false), |
| 65 max_surfaces_with_frontbuffer_soft_limit_( | 71 max_surfaces_with_frontbuffer_soft_limit_( |
| 66 max_surfaces_with_frontbuffer_soft_limit) { | 72 max_surfaces_with_frontbuffer_soft_limit), |
| 73 peak_assigned_allocation_sum_(0) { |
| 67 } | 74 } |
| 68 | 75 |
| 69 GpuMemoryManager::~GpuMemoryManager() { | 76 GpuMemoryManager::~GpuMemoryManager() { |
| 70 } | 77 } |
| 71 | 78 |
| 72 bool GpuMemoryManager::StubWithSurfaceComparator::operator()( | 79 bool GpuMemoryManager::StubWithSurfaceComparator::operator()( |
| 73 GpuCommandBufferStubBase* lhs, | 80 GpuCommandBufferStubBase* lhs, |
| 74 GpuCommandBufferStubBase* rhs) { | 81 GpuCommandBufferStubBase* rhs) { |
| 75 DCHECK(lhs->has_surface_state() && rhs->has_surface_state()); | 82 DCHECK(lhs->has_surface_state() && rhs->has_surface_state()); |
| 76 const GpuCommandBufferStubBase::SurfaceState& lhs_ss = lhs->surface_state(); | 83 const GpuCommandBufferStubBase::SurfaceState& lhs_ss = lhs->surface_state(); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 96 return; | 103 return; |
| 97 delayed_manage_callback_.Reset(base::Bind(&GpuMemoryManager::Manage, | 104 delayed_manage_callback_.Reset(base::Bind(&GpuMemoryManager::Manage, |
| 98 AsWeakPtr())); | 105 AsWeakPtr())); |
| 99 MessageLoop::current()->PostDelayedTask( | 106 MessageLoop::current()->PostDelayedTask( |
| 100 FROM_HERE, | 107 FROM_HERE, |
| 101 delayed_manage_callback_.callback(), | 108 delayed_manage_callback_.callback(), |
| 102 base::TimeDelta::FromMilliseconds(kDelayedScheduleManageTimeoutMs)); | 109 base::TimeDelta::FromMilliseconds(kDelayedScheduleManageTimeoutMs)); |
| 103 } | 110 } |
| 104 } | 111 } |
| 105 | 112 |
| 113 size_t GpuMemoryManager::GetAvailableGpuMemory() const { |
| 114 // TODO(mmocny): Implement this with real system figures. |
| 115 return kMaximumAllocationForTabs; |
| 116 } |
| 117 |
| 106 // The current Manage algorithm simply classifies contexts (stubs) into | 118 // The current Manage algorithm simply classifies contexts (stubs) into |
| 107 // "foreground", "background", or "hibernated" categories. | 119 // "foreground", "background", or "hibernated" categories. |
| 108 // For each of these three categories, there are predefined memory allocation | 120 // For each of these three categories, there are predefined memory allocation |
| 109 // limits and front/backbuffer states. | 121 // limits and front/backbuffer states. |
| 110 // | 122 // |
| 111 // Stubs may or may not have a surfaces, and the rules are different for each. | 123 // Stubs may or may not have a surfaces, and the rules are different for each. |
| 112 // | 124 // |
| 113 // The rules for categorizing contexts with a surface are: | 125 // The rules for categorizing contexts with a surface are: |
| 114 // 1. Foreground: All visible surfaces. | 126 // 1. Foreground: All visible surfaces. |
| 115 // * Must have both front and back buffer. | 127 // * Must have both front and back buffer. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 !stubs_with_surface_foreground.empty()) | 221 !stubs_with_surface_foreground.empty()) |
| 210 bonus_allocation = (kMaximumAllocationForTabs - base_allocation_size) / | 222 bonus_allocation = (kMaximumAllocationForTabs - base_allocation_size) / |
| 211 stubs_with_surface_foreground.size(); | 223 stubs_with_surface_foreground.size(); |
| 212 #else | 224 #else |
| 213 // On android, calculate bonus allocation based on surface size. | 225 // On android, calculate bonus allocation based on surface size. |
| 214 if (!stubs_with_surface_foreground.empty()) | 226 if (!stubs_with_surface_foreground.empty()) |
| 215 bonus_allocation = CalculateBonusMemoryAllocationBasedOnSize( | 227 bonus_allocation = CalculateBonusMemoryAllocationBasedOnSize( |
| 216 stubs_with_surface_foreground[0]->GetSurfaceSize()); | 228 stubs_with_surface_foreground[0]->GetSurfaceSize()); |
| 217 #endif | 229 #endif |
| 218 | 230 |
| 231 stub_memory_stats_for_last_manage_.clear(); |
| 232 |
| 219 // Now give out allocations to everyone. | 233 // Now give out allocations to everyone. |
| 220 AssignMemoryAllocations(stubs_with_surface_foreground, | 234 AssignMemoryAllocations( |
| 235 &stub_memory_stats_for_last_manage_, |
| 236 stubs_with_surface_foreground, |
| 221 GpuMemoryAllocation(kMinimumAllocationForTab + bonus_allocation, | 237 GpuMemoryAllocation(kMinimumAllocationForTab + bonus_allocation, |
| 222 GpuMemoryAllocation::kHasFrontbuffer | | 238 GpuMemoryAllocation::kHasFrontbuffer | |
| 223 GpuMemoryAllocation::kHasBackbuffer)); | 239 GpuMemoryAllocation::kHasBackbuffer), |
| 240 true); |
| 224 | 241 |
| 225 AssignMemoryAllocations(stubs_with_surface_background, | 242 AssignMemoryAllocations( |
| 226 GpuMemoryAllocation(0, GpuMemoryAllocation::kHasFrontbuffer)); | 243 &stub_memory_stats_for_last_manage_, |
| 244 stubs_with_surface_background, |
| 245 GpuMemoryAllocation(0, GpuMemoryAllocation::kHasFrontbuffer), |
| 246 false); |
| 227 | 247 |
| 228 AssignMemoryAllocations(stubs_with_surface_hibernated, | 248 AssignMemoryAllocations( |
| 229 GpuMemoryAllocation(0, GpuMemoryAllocation::kHasNoBuffers)); | 249 &stub_memory_stats_for_last_manage_, |
| 250 stubs_with_surface_hibernated, |
| 251 GpuMemoryAllocation(0, GpuMemoryAllocation::kHasNoBuffers), |
| 252 false); |
| 230 | 253 |
| 231 AssignMemoryAllocations(stubs_without_surface_foreground, | 254 AssignMemoryAllocations( |
| 255 &stub_memory_stats_for_last_manage_, |
| 256 stubs_without_surface_foreground, |
| 232 GpuMemoryAllocation(kMinimumAllocationForTab, | 257 GpuMemoryAllocation(kMinimumAllocationForTab, |
| 233 GpuMemoryAllocation::kHasNoBuffers)); | 258 GpuMemoryAllocation::kHasNoBuffers), |
| 259 true); |
| 234 | 260 |
| 235 AssignMemoryAllocations(stubs_without_surface_background, | 261 AssignMemoryAllocations( |
| 262 &stub_memory_stats_for_last_manage_, |
| 263 stubs_without_surface_background, |
| 236 GpuMemoryAllocation(kMinimumAllocationForTab, | 264 GpuMemoryAllocation(kMinimumAllocationForTab, |
| 237 GpuMemoryAllocation::kHasNoBuffers)); | 265 GpuMemoryAllocation::kHasNoBuffers), |
| 266 false); |
| 238 | 267 |
| 239 AssignMemoryAllocations(stubs_without_surface_hibernated, | 268 AssignMemoryAllocations( |
| 240 GpuMemoryAllocation(0, GpuMemoryAllocation::kHasNoBuffers)); | 269 &stub_memory_stats_for_last_manage_, |
| 270 stubs_without_surface_hibernated, |
| 271 GpuMemoryAllocation(0, GpuMemoryAllocation::kHasNoBuffers), |
| 272 false); |
| 273 |
| 274 size_t assigned_allocation_sum = 0; |
| 275 for (StubMemoryStatMap::iterator it = |
| 276 stub_memory_stats_for_last_manage_.begin(); |
| 277 it != stub_memory_stats_for_last_manage_.end(); |
| 278 ++it) { |
| 279 assigned_allocation_sum += it->second.allocation.gpu_resource_size_in_bytes; |
| 280 } |
| 281 |
| 282 if (assigned_allocation_sum > peak_assigned_allocation_sum_) |
| 283 peak_assigned_allocation_sum_ = assigned_allocation_sum; |
| 241 } | 284 } |
| 242 | 285 |
| 243 #endif | 286 #endif |
| OLD | NEW |