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

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: register/unregister 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/lazy_instance.h"
10 #include "base/strings/stringprintf.h"
10 #include "base/synchronization/waitable_event.h" 11 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread_restrictions.h" 12 #include "base/threading/thread_restrictions.h"
13 #include "base/trace_event/process_memory_dump.h"
12 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
13 #include "content/common/gpu/client/gpu_memory_buffer_factory_host.h" 15 #include "content/common/gpu/client/gpu_memory_buffer_factory_host.h"
14 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" 16 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
15 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h" 17 #include "content/common/gpu/client/gpu_memory_buffer_impl_shared_memory.h"
16 #include "content/public/browser/browser_thread.h" 18 #include "content/public/browser/browser_thread.h"
17 19
18 namespace content { 20 namespace content {
19 namespace { 21 namespace {
20 22
21 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr; 23 BrowserGpuMemoryBufferManager* g_gpu_memory_buffer_manager = nullptr;
22 24
23 // Global atomic to generate gpu memory buffer unique IDs. 25 // Global atomic to generate gpu memory buffer unique IDs.
24 base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id; 26 base::StaticAtomicSequenceNumber g_next_gpu_memory_buffer_id;
25 27
28 const char kMemoryAllocatorName[] = "gpumemorybuffer";
29
26 } // namespace 30 } // namespace
27 31
28 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest { 32 struct BrowserGpuMemoryBufferManager::AllocateGpuMemoryBufferRequest {
29 AllocateGpuMemoryBufferRequest(const gfx::Size& size, 33 AllocateGpuMemoryBufferRequest(const gfx::Size& size,
30 gfx::GpuMemoryBuffer::Format format, 34 gfx::GpuMemoryBuffer::Format format,
31 gfx::GpuMemoryBuffer::Usage usage, 35 gfx::GpuMemoryBuffer::Usage usage,
32 int client_id, 36 int client_id,
33 int surface_id) 37 int surface_id)
34 : event(true, false), 38 : event(true, false),
35 size(size), 39 size(size),
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 if (!gpu_memory_buffer_factory_host_->IsGpuMemoryBufferConfigurationSupported( 142 if (!gpu_memory_buffer_factory_host_->IsGpuMemoryBufferConfigurationSupported(
139 format, usage)) { 143 format, usage)) {
140 // Early out if we cannot fallback to shared memory buffer. 144 // Early out if we cannot fallback to shared memory buffer.
141 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) || 145 if (!GpuMemoryBufferImplSharedMemory::IsFormatSupported(format) ||
142 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format) || 146 !GpuMemoryBufferImplSharedMemory::IsSizeValidForFormat(size, format) ||
143 usage != gfx::GpuMemoryBuffer::MAP) { 147 usage != gfx::GpuMemoryBuffer::MAP) {
144 callback.Run(gfx::GpuMemoryBufferHandle()); 148 callback.Run(gfx::GpuMemoryBufferHandle());
145 return; 149 return;
146 } 150 }
147 151
148 buffers[new_id] = gfx::SHARED_MEMORY_BUFFER; 152 buffers[new_id] = BufferInfo(size, format, gfx::SHARED_MEMORY_BUFFER);
149 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess( 153 callback.Run(GpuMemoryBufferImplSharedMemory::AllocateForChildProcess(
150 new_id, size, format, child_process_handle)); 154 new_id, size, format, child_process_handle));
151 return; 155 return;
152 } 156 }
153 157
154 // Note: Handling of cases where the child process is removed before the 158 // 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 159 // 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 160 // EMPTY_BUFFER here and verify that this has not changed when allocation
157 // completes. 161 // completes.
158 buffers[new_id] = gfx::EMPTY_BUFFER; 162 buffers[new_id] = BufferInfo(size, format, gfx::EMPTY_BUFFER);
159 163
160 gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer( 164 gpu_memory_buffer_factory_host_->CreateGpuMemoryBuffer(
161 new_id, size, format, usage, child_client_id, 0, 165 new_id, size, format, usage, child_client_id, 0,
162 base::Bind(&BrowserGpuMemoryBufferManager:: 166 base::Bind(&BrowserGpuMemoryBufferManager::
163 GpuMemoryBufferAllocatedForChildProcess, 167 GpuMemoryBufferAllocatedForChildProcess,
164 weak_ptr_factory_.GetWeakPtr(), child_client_id, callback)); 168 weak_ptr_factory_.GetWeakPtr(), child_client_id, callback));
165 } 169 }
166 170
167 gfx::GpuMemoryBuffer* 171 gfx::GpuMemoryBuffer*
168 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer( 172 BrowserGpuMemoryBufferManager::GpuMemoryBufferFromClientBuffer(
169 ClientBuffer buffer) { 173 ClientBuffer buffer) {
170 return GpuMemoryBufferImpl::FromClientBuffer(buffer); 174 return GpuMemoryBufferImpl::FromClientBuffer(buffer);
171 } 175 }
172 176
173 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint( 177 void BrowserGpuMemoryBufferManager::SetDestructionSyncPoint(
174 gfx::GpuMemoryBuffer* buffer, 178 gfx::GpuMemoryBuffer* buffer,
175 uint32 sync_point) { 179 uint32 sync_point) {
176 static_cast<GpuMemoryBufferImpl*>(buffer) 180 static_cast<GpuMemoryBufferImpl*>(buffer)
177 ->set_destruction_sync_point(sync_point); 181 ->set_destruction_sync_point(sync_point);
178 } 182 }
179 183
184 bool BrowserGpuMemoryBufferManager::OnMemoryDump(
185 base::trace_event::ProcessMemoryDump* pmd) {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO);
187
188 for (auto& client_it : clients_) {
Primiano Tucci (use gerrit) 2015/04/28 20:13:08 Maybe these two could be "const" auto& (or is ther
reveman 2015/04/28 20:52:25 Done.
189 for (auto& buffer_it : client_it.second) {
190 if (buffer_it.second.type == gfx::EMPTY_BUFFER)
191 continue;
192
193 base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(
194 base::StringPrintf("%s/%d", kMemoryAllocatorName, buffer_it.first));
195 if (!dump)
196 return false;
197
198 size_t buffer_size_in_bytes = 0;
199 // Note: BufferSizeInBytes returns an approximated size for the buffer
200 // but the factory can be made to return the exact size if this
201 // approximation is not good enough.
202 bool valid_size = GpuMemoryBufferImpl::BufferSizeInBytes(
203 buffer_it.second.size, buffer_it.second.format,
204 &buffer_size_in_bytes);
205 DCHECK(valid_size);
206
207 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameInnerSize,
Primiano Tucci (use gerrit) 2015/04/28 20:13:08 Is it this really intending to be InnerSize (As op
reveman 2015/04/28 20:52:25 I used InnerSize as we don't know what the interna
208 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
209 buffer_size_in_bytes);
210 }
211 }
212
213 return true;
214 }
215
180 void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer( 216 void BrowserGpuMemoryBufferManager::ChildProcessDeletedGpuMemoryBuffer(
181 gfx::GpuMemoryBufferId id, 217 gfx::GpuMemoryBufferId id,
182 base::ProcessHandle child_process_handle, 218 base::ProcessHandle child_process_handle,
183 int child_client_id, 219 int child_client_id,
184 uint32 sync_point) { 220 uint32 sync_point) {
185 DCHECK_CURRENTLY_ON(BrowserThread::IO); 221 DCHECK_CURRENTLY_ON(BrowserThread::IO);
186 DCHECK(clients_.find(child_client_id) != clients_.end()); 222 DCHECK(clients_.find(child_client_id) != clients_.end());
187 223
188 BufferMap& buffers = clients_[child_client_id]; 224 BufferMap& buffers = clients_[child_client_id];
189 225
190 BufferMap::iterator buffer_it = buffers.find(id); 226 BufferMap::iterator buffer_it = buffers.find(id);
191 if (buffer_it == buffers.end()) { 227 if (buffer_it == buffers.end()) {
192 LOG(ERROR) << "Invalid GpuMemoryBuffer ID for child process."; 228 LOG(ERROR) << "Invalid GpuMemoryBuffer ID for child process.";
193 return; 229 return;
194 } 230 }
195 231
196 // This can happen if a child process managed to trigger a call to this while 232 // 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. 233 // a buffer is in the process of being allocated.
198 if (buffer_it->second == gfx::EMPTY_BUFFER) { 234 if (buffer_it->second.type == gfx::EMPTY_BUFFER) {
199 LOG(ERROR) << "Invalid GpuMemoryBuffer type."; 235 LOG(ERROR) << "Invalid GpuMemoryBuffer type.";
200 return; 236 return;
201 } 237 }
202 238
203 // Buffers allocated using the factory need to be destroyed through the 239 // Buffers allocated using the factory need to be destroyed through the
204 // factory. 240 // factory.
205 if (buffer_it->second != gfx::SHARED_MEMORY_BUFFER) { 241 if (buffer_it->second.type != gfx::SHARED_MEMORY_BUFFER) {
206 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(id, 242 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(id,
207 child_client_id, 243 child_client_id,
208 sync_point); 244 sync_point);
209 } 245 }
210 246
211 buffers.erase(buffer_it); 247 buffers.erase(buffer_it);
212 } 248 }
213 249
214 void BrowserGpuMemoryBufferManager::ProcessRemoved( 250 void BrowserGpuMemoryBufferManager::ProcessRemoved(
215 base::ProcessHandle process_handle, 251 base::ProcessHandle process_handle,
216 int client_id) { 252 int client_id) {
217 DCHECK_CURRENTLY_ON(BrowserThread::IO); 253 DCHECK_CURRENTLY_ON(BrowserThread::IO);
218 254
219 ClientMap::iterator client_it = clients_.find(client_id); 255 ClientMap::iterator client_it = clients_.find(client_id);
220 if (client_it == clients_.end()) 256 if (client_it == clients_.end())
221 return; 257 return;
222 258
223 for (auto &buffer_it : client_it->second) { 259 for (auto &buffer_it : client_it->second) {
224 // This might happen if buffer is currenlty in the process of being 260 // 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 261 // allocated. The buffer will in that case be cleaned up when allocation
226 // completes. 262 // completes.
227 if (buffer_it.second == gfx::EMPTY_BUFFER) 263 if (buffer_it.second.type == gfx::EMPTY_BUFFER)
228 continue; 264 continue;
229 265
230 // Skip shared memory buffers as they were not allocated using the factory. 266 // Skip shared memory buffers as they were not allocated using the factory.
231 if (buffer_it.second == gfx::SHARED_MEMORY_BUFFER) 267 if (buffer_it.second.type == gfx::SHARED_MEMORY_BUFFER)
232 continue; 268 continue;
233 269
234 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(buffer_it.first, 270 gpu_memory_buffer_factory_host_->DestroyGpuMemoryBuffer(buffer_it.first,
235 client_id, 271 client_id,
236 0); 272 0);
237 } 273 }
238 274
239 clients_.erase(client_it); 275 clients_.erase(client_it);
240 } 276 }
241 277
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 handle.id, child_client_id, 0); 334 handle.id, child_client_id, 0);
299 } 335 }
300 callback.Run(gfx::GpuMemoryBufferHandle()); 336 callback.Run(gfx::GpuMemoryBufferHandle());
301 return; 337 return;
302 } 338 }
303 339
304 BufferMap& buffers = client_it->second; 340 BufferMap& buffers = client_it->second;
305 341
306 BufferMap::iterator buffer_it = buffers.find(handle.id); 342 BufferMap::iterator buffer_it = buffers.find(handle.id);
307 DCHECK(buffer_it != buffers.end()); 343 DCHECK(buffer_it != buffers.end());
308 DCHECK_EQ(buffer_it->second, gfx::EMPTY_BUFFER); 344 DCHECK_EQ(buffer_it->second.type, gfx::EMPTY_BUFFER);
309 345
310 if (handle.is_null()) { 346 if (handle.is_null()) {
311 buffers.erase(buffer_it); 347 buffers.erase(buffer_it);
312 callback.Run(gfx::GpuMemoryBufferHandle()); 348 callback.Run(gfx::GpuMemoryBufferHandle());
313 return; 349 return;
314 } 350 }
315 351
316 // The factory should never return a shared memory backed buffer. 352 // The factory should never return a shared memory backed buffer.
317 DCHECK_NE(handle.type, gfx::SHARED_MEMORY_BUFFER); 353 DCHECK_NE(handle.type, gfx::SHARED_MEMORY_BUFFER);
318 354
319 // Store the type of this buffer so it can be cleaned up if the child 355 // Store the type of this buffer so it can be cleaned up if the child
320 // process is removed. 356 // process is removed.
321 buffer_it->second = handle.type; 357 buffer_it->second.type = handle.type;
322 358
323 callback.Run(handle); 359 callback.Run(handle);
324 } 360 }
325 361
326 } // namespace content 362 } // 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