Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(24)

Side by Side Diff: content/browser/gpu/browser_gpu_memory_buffer_manager.cc

Issue 1055403010: content: Add GpuMemoryBuffer MemoryDumpProvider implementation. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: move register out of ifdef Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/browser/gpu/browser_gpu_memory_buffer_manager.h" 5 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/lazy_instance.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread_restrictions.h" 11 #include "base/threading/thread_restrictions.h"
12 #include "base/trace_event/process_memory_dump.h"
12 #include "base/trace_event/trace_event.h" 13 #include "base/trace_event/trace_event.h"
13 #include "content/common/gpu/client/gpu_memory_buffer_factory_host.h" 14 #include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
14 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" 15 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
15 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" 16 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
16 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
17 18
18 namespace content { 19 namespace content {
19 namespace { 20 namespace {
20 21
21 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; 22 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr;
22 23
23 // Global atomic to generate gpu memory buffer unique IDs. 24 // Global atomic to generate gpu memory buffer unique IDs.
24 base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id; 25 base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id;
25 26
27 const char kMemoryAllocatorName[] = "gpumemorybuffer";
28
26 } // namespace 29 } // namespace
27 30
28 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest { 31 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
29 AllocateGpuMemoryBufferRequest(const gfx::Size& size, 32 AllocateGpuMemoryBufferRequest(const gfx::Size& size,
30 gfx::GpuMemoryBuffer::Format format, 33 gfx::GpuMemoryBuffer::Format format,
31 gfx::GpuMemoryBuffer::Usage usage, 34 gfx::GpuMemoryBuffer::Usage usage,
32 int client_id, 35 int client_id,
33 int surface_id) 36 int surface_id)
34 : event(true, false), 37 : event(true, false),
35 size(size), 38 size(size),
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 if (!gpu_memory_buffer_factory_host_->IsGpuMemoryBufferConfigurationSupported( 141 if (!gpu_memory_buffer_factory_host_->IsGpuMemoryBufferConfigurationSupported(
139 format, usage)) { 142 format, usage)) {
140 // Early out if we cannot fallback to shared memory buffer. 143 // Early out if we cannot fallback to shared memory buffer.
141 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) || 144 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
142 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format) || 145 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format) ||
143 usage != gfx::GpuMemoryBuffer::MAP) { 146 usage != gfx::GpuMemoryBuffer::MAP) {
144 callback.Run(gfx::GpuMemoryBufferHandle()); 147 callback.Run(gfx::GpuMemoryBufferHandle());
145 return; 148 return;
146 } 149 }
147 150
148 buffers[new_id] = gfx::SHARED_MEMORY_BUFFER; 151 buffers[new_id] = BufferInfo(size, format, gfx::SHARED_MEMORY_BUFFER);
149 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 152 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
150 new_id, size, format, child_process_handle)); 153 new_id, size, format, child_process_handle));
151 return; 154 return;
152 } 155 }
153 156
154 // Note: Handling of cases where the child process is removed before the 157 // Note: Handling of cases where the child process is removed before the
155 // allocation completes is less subtle if we set the buffer type to 158 // allocation completes is less subtle if we set the buffer type to
156 // EMPTY_BUFFER here and verify that this has not changed when allocation 159 // EMPTY_BUFFER here and verify that this has not changed when allocation
157 // completes. 160 // completes.
158 buffers[new_id] = gfx::EMPTY_BUFFER; 161 buffers[new_id] = BufferInfo(size, format, gfx::EMPTY_BUFFER);
159 162
160 gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer( 163 gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer(
161 new_id, size, format, usage, child_client_id, 0, 164 new_id, size, format, usage, child_client_id, 0,
162 base::Bind(&BrowserGpuMemoryBufferManager:: 165 base::Bind(&BrowserGpuMemoryBufferManager::
163 GpuMemoryBufferAllocatedForChildProcess, 166 GpuMemoryBufferAllocatedForChildProcess,
164 weak_ptr_factory_.GetWeakPtr(), child_client_id, callback)); 167 weak_ptr_factory_.GetWeakPtr(), child_client_id, callback));
165 } 168 }
166 169
167 gfx::GpuMemoryBuffer* 170 gfx::GpuMemoryBuffer*
168 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( 171 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
169 ClientBuffer buffer) { 172 ClientBuffer buffer) {
170 return GpuMemoryBufferImpl::FromClientBuffer(buffer); 173 return GpuMemoryBufferImpl::FromClientBuffer(buffer);
171 } 174 }
172 175
173 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint( 176 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
174 gfx::GpuMemoryBuffer* buffer, 177 gfx::GpuMemoryBuffer* buffer,
175 uint32 sync_point) { 178 uint32 sync_point) {
176 static_cast<GpuMemoryBufferImpl*>(buffer) 179 static_cast<GpuMemoryBufferImpl*>(buffer)
177 ->set_destruction_sync_point(sync_point); 180 ->set_destruction_sync_point(sync_point);
178 } 181 }
179 182
183 bool BrowserGpuMemoryBufferManager::OnMemoryDump(
184 base::trace_event::ProcessMemoryDump* pmd) {
185 DCHECK_CURRENTLY_ON(BrowserThread::IO);
186
187 for (const auto& client : clients_) {
188 for (const auto& buffer : client.second) {
189 if (buffer.second.type == gfx::EMPTY_BUFFER)
190 continue;
191
192 base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(
193 base::StringPrintf("%s/%d", kMemoryAllocatorName, buffer.first));
194 if (!dump)
195 return false;
196
197 size_t buffer_size_in_bytes = 0;
198 // Note: BufferSizeInBytes returns an approximated size for the buffer
199 // but the factory can be made to return the exact size if this
200 // approximation is not good enough.
201 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes(
202 buffer.second.size, buffer.second.format, &buffer_size_in_bytes);
203 DCHECK(valid_size);
204
205 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameOuterSize,
206 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
207 buffer_size_in_bytes);
208 }
209 }
210
211 return true;
212 }
213
180 void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer( 214 void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer(
181 gfx::GpuMemoryBufferId id, 215 gfx::GpuMemoryBufferId id,
182 base::ProcessHandle child_process_handle, 216 base::ProcessHandle child_process_handle,
183 int child_client_id, 217 int child_client_id,
184 uint32 sync_point) { 218 uint32 sync_point) {
185 DCHECK_CURRENTLY_ON(BrowserThread::IO); 219 DCHECK_CURRENTLY_ON(BrowserThread::IO);
186 DCHECK(clients_.find(child_client_id) != clients_.end()); 220 DCHECK(clients_.find(child_client_id) != clients_.end());
187 221
188 BufferMap& buffers = clients_[child_client_id]; 222 BufferMap& buffers = clients_[child_client_id];
189 223
190 BufferMap::iterator buffer_it = buffers.find(id); 224 BufferMap::iterator buffer_it = buffers.find(id);
191 if (buffer_it == buffers.end()) { 225 if (buffer_it == buffers.end()) {
192 LOG(ERROR) << "Invalid GpuMemoryBuffer ID for child process."; 226 LOG(ERROR) << "Invalid GpuMemoryBuffer ID for child process.";
193 return; 227 return;
194 } 228 }
195 229
196 // This can happen if a child process managed to trigger a call to this while 230 // This can happen if a child process managed to trigger a call to this while
197 // a buffer is in the process of being allocated. 231 // a buffer is in the process of being allocated.
198 if (buffer_it->second == gfx::EMPTY_BUFFER) { 232 if (buffer_it->second.type == gfx::EMPTY_BUFFER) {
199 LOG(ERROR) << "Invalid GpuMemoryBuffer type."; 233 LOG(ERROR) << "Invalid GpuMemoryBuffer type.";
200 return; 234 return;
201 } 235 }
202 236
203 // Buffers allocated using the factory need to be destroyed through the 237 // Buffers allocated using the factory need to be destroyed through the
204 // factory. 238 // factory.
205 if (buffer_it->second != gfx::SHARED_MEMORY_BUFFER) { 239 if (buffer_it->second.type != gfx::SHARED_MEMORY_BUFFER) {
206 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(id, 240 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(id,
207 child_client_id, 241 child_client_id,
208 sync_point); 242 sync_point);
209 } 243 }
210 244
211 buffers.erase(buffer_it); 245 buffers.erase(buffer_it);
212 } 246 }
213 247
214 void BrowserGpuMemoryBufferManager::ProcessRemoved( 248 void BrowserGpuMemoryBufferManager::ProcessRemoved(
215 base::ProcessHandle process_handle, 249 base::ProcessHandle process_handle,
216 int client_id) { 250 int client_id) {
217 DCHECK_CURRENTLY_ON(BrowserThread::IO); 251 DCHECK_CURRENTLY_ON(BrowserThread::IO);
218 252
219 ClientMap::iterator client_it = clients_.find(client_id); 253 ClientMap::iterator client_it = clients_.find(client_id);
220 if (client_it == clients_.end()) 254 if (client_it == clients_.end())
221 return; 255 return;
222 256
223 for (auto &buffer_it : client_it->second) { 257 for (const auto& buffer : client_it->second) {
224 // This might happen if buffer is currenlty in the process of being 258 // This might happen if buffer is currenlty in the process of being
225 // allocated. The buffer will in that case be cleaned up when allocation 259 // allocated. The buffer will in that case be cleaned up when allocation
226 // completes. 260 // completes.
227 if (buffer_it.second == gfx::EMPTY_BUFFER) 261 if (buffer.second.type == gfx::EMPTY_BUFFER)
228 continue; 262 continue;
229 263
230 // Skip shared memory buffers as they were not allocated using the factory. 264 // Skip shared memory buffers as they were not allocated using the factory.
231 if (buffer_it.second == gfx::SHARED_MEMORY_BUFFER) 265 if (buffer.second.type == gfx::SHARED_MEMORY_BUFFER)
232 continue; 266 continue;
233 267
234 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(buffer_it.first, 268 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(buffer.first,
235 client_id, 269 client_id, 0);
236 0);
237 } 270 }
238 271
239 clients_.erase(client_it); 272 clients_.erase(client_it);
240 } 273 }
241 274
242 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO( 275 void BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferOnIO(
243 AllocateGpuMemoryBufferRequest* request) { 276 AllocateGpuMemoryBufferRequest* request) {
244 // Note: Unretained is safe as this is only used for synchronous allocation 277 // Note: Unretained is safe as this is only used for synchronous allocation
245 // from a non-IO thread. 278 // from a non-IO thread.
246 gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer( 279 gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 handle.id, child_client_id, 0); 331 handle.id, child_client_id, 0);
299 } 332 }
300 callback.Run(gfx::GpuMemoryBufferHandle()); 333 callback.Run(gfx::GpuMemoryBufferHandle());
301 return; 334 return;
302 } 335 }
303 336
304 BufferMap& buffers = client_it->second; 337 BufferMap& buffers = client_it->second;
305 338
306 BufferMap::iterator buffer_it = buffers.find(handle.id); 339 BufferMap::iterator buffer_it = buffers.find(handle.id);
307 DCHECK(buffer_it != buffers.end()); 340 DCHECK(buffer_it != buffers.end());
308 DCHECK_EQ(buffer_it->second, gfx::EMPTY_BUFFER); 341 DCHECK_EQ(buffer_it->second.type, gfx::EMPTY_BUFFER);
309 342
310 if (handle.is_null()) { 343 if (handle.is_null()) {
311 buffers.erase(buffer_it); 344 buffers.erase(buffer_it);
312 callback.Run(gfx::GpuMemoryBufferHandle()); 345 callback.Run(gfx::GpuMemoryBufferHandle());
313 return; 346 return;
314 } 347 }
315 348
316 // The factory should never return a shared memory backed buffer. 349 // The factory should never return a shared memory backed buffer.
317 DCHECK_NE(handle.type, gfx::SHARED_MEMORY_BUFFER); 350 DCHECK_NE(handle.type, gfx::SHARED_MEMORY_BUFFER);
318 351
319 // Store the type of this buffer so it can be cleaned up if the child 352 // Store the type of this buffer so it can be cleaned up if the child
320 // process is removed. 353 // process is removed.
321 buffer_it->second = handle.type; 354 buffer_it->second.type = handle.type;
322 355
323 callback.Run(handle); 356 callback.Run(handle);
324 } 357 }
325 358
326 } // namespace content 359 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gpu/browser_gpu_memory_buffer_manager.h ('k') | content/common/gpu/client/gpu_memory_buffer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698