Record MTU discovery packets in net-internals log.
[chromium-blink-merge.git] / content / common / host_shared_bitmap_manager.cc
blob07241f2a2ce2f05bb0f6fb63909c50180b253ea9
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/host_shared_bitmap_manager.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/strings/string_number_conversions.h"
10 #include "base/trace_event/process_memory_dump.h"
11 #include "content/common/view_messages.h"
12 #include "ui/gfx/geometry/size.h"
14 namespace content {
16 class BitmapData : public base::RefCountedThreadSafe<BitmapData> {
17 public:
18 BitmapData(base::ProcessHandle process_handle,
19 size_t buffer_size)
20 : process_handle(process_handle),
21 buffer_size(buffer_size) {}
22 base::ProcessHandle process_handle;
23 scoped_ptr<base::SharedMemory> memory;
24 scoped_ptr<uint8[]> pixels;
25 size_t buffer_size;
27 private:
28 friend class base::RefCountedThreadSafe<BitmapData>;
29 ~BitmapData() {}
30 DISALLOW_COPY_AND_ASSIGN(BitmapData);
33 namespace {
35 class HostSharedBitmap : public cc::SharedBitmap {
36 public:
37 HostSharedBitmap(uint8* pixels,
38 scoped_refptr<BitmapData> bitmap_data,
39 const cc::SharedBitmapId& id,
40 HostSharedBitmapManager* manager)
41 : SharedBitmap(pixels, id),
42 bitmap_data_(bitmap_data),
43 manager_(manager) {}
45 ~HostSharedBitmap() override {
46 if (manager_)
47 manager_->FreeSharedMemoryFromMap(id());
50 private:
51 scoped_refptr<BitmapData> bitmap_data_;
52 HostSharedBitmapManager* manager_;
55 const char kMemoryAllocatorName[] = "sharedbitmap";
57 } // namespace
59 base::LazyInstance<HostSharedBitmapManager> g_shared_memory_manager =
60 LAZY_INSTANCE_INITIALIZER;
62 HostSharedBitmapManagerClient::HostSharedBitmapManagerClient(
63 HostSharedBitmapManager* manager)
64 : manager_(manager) {
67 HostSharedBitmapManagerClient::~HostSharedBitmapManagerClient() {
68 for (const auto& id : owned_bitmaps_)
69 manager_->ChildDeletedSharedBitmap(id);
72 void HostSharedBitmapManagerClient::AllocateSharedBitmapForChild(
73 base::ProcessHandle process_handle,
74 size_t buffer_size,
75 const cc::SharedBitmapId& id,
76 base::SharedMemoryHandle* shared_memory_handle) {
77 manager_->AllocateSharedBitmapForChild(process_handle, buffer_size, id,
78 shared_memory_handle);
79 owned_bitmaps_.insert(id);
82 void HostSharedBitmapManagerClient::ChildAllocatedSharedBitmap(
83 size_t buffer_size,
84 const base::SharedMemoryHandle& handle,
85 base::ProcessHandle process_handle,
86 const cc::SharedBitmapId& id) {
87 manager_->ChildAllocatedSharedBitmap(buffer_size, handle, process_handle, id);
88 owned_bitmaps_.insert(id);
91 void HostSharedBitmapManagerClient::ChildDeletedSharedBitmap(
92 const cc::SharedBitmapId& id) {
93 manager_->ChildDeletedSharedBitmap(id);
94 owned_bitmaps_.erase(id);
97 HostSharedBitmapManager::HostSharedBitmapManager() {}
98 HostSharedBitmapManager::~HostSharedBitmapManager() {
99 DCHECK(handle_map_.empty());
102 HostSharedBitmapManager* HostSharedBitmapManager::current() {
103 return g_shared_memory_manager.Pointer();
106 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap(
107 const gfx::Size& size) {
108 base::AutoLock lock(lock_);
109 size_t bitmap_size;
110 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size))
111 return scoped_ptr<cc::SharedBitmap>();
113 scoped_refptr<BitmapData> data(
114 new BitmapData(base::GetCurrentProcessHandle(),
115 bitmap_size));
116 // Bitmaps allocated in host don't need to be shared to other processes, so
117 // allocate them with new instead.
118 data->pixels = scoped_ptr<uint8[]>(new uint8[bitmap_size]);
120 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
121 handle_map_[id] = data;
122 return make_scoped_ptr(
123 new HostSharedBitmap(data->pixels.get(), data, id, this));
126 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetSharedBitmapFromId(
127 const gfx::Size& size,
128 const cc::SharedBitmapId& id) {
129 base::AutoLock lock(lock_);
130 BitmapMap::iterator it = handle_map_.find(id);
131 if (it == handle_map_.end())
132 return scoped_ptr<cc::SharedBitmap>();
134 BitmapData* data = it->second.get();
136 size_t bitmap_size;
137 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
138 bitmap_size > data->buffer_size)
139 return scoped_ptr<cc::SharedBitmap>();
141 if (data->pixels) {
142 return make_scoped_ptr(
143 new HostSharedBitmap(data->pixels.get(), data, id, nullptr));
145 if (!data->memory->memory()) {
146 return scoped_ptr<cc::SharedBitmap>();
149 return make_scoped_ptr(new HostSharedBitmap(
150 static_cast<uint8*>(data->memory->memory()), data, id, nullptr));
153 bool HostSharedBitmapManager::OnMemoryDump(
154 base::trace_event::ProcessMemoryDump* pmd) {
155 base::AutoLock lock(lock_);
157 for (const auto& bitmap : handle_map_) {
158 base::trace_event::MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(
159 base::StringPrintf("%s/%s", kMemoryAllocatorName,
160 base::HexEncode(bitmap.first.name,
161 sizeof(bitmap.first.name)).c_str()));
162 if (!dump)
163 return false;
165 dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
166 base::trace_event::MemoryAllocatorDump::kUnitsBytes,
167 bitmap.second->buffer_size);
170 return true;
173 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
174 size_t buffer_size,
175 const base::SharedMemoryHandle& handle,
176 base::ProcessHandle process_handle,
177 const cc::SharedBitmapId& id) {
178 base::AutoLock lock(lock_);
179 if (handle_map_.find(id) != handle_map_.end())
180 return;
181 scoped_refptr<BitmapData> data(
182 new BitmapData(process_handle, buffer_size));
184 handle_map_[id] = data;
185 #if defined(OS_WIN)
186 data->memory = make_scoped_ptr(
187 new base::SharedMemory(handle, false, data->process_handle));
188 #else
189 data->memory =
190 make_scoped_ptr(new base::SharedMemory(handle, false));
191 #endif
192 data->memory->Map(data->buffer_size);
193 data->memory->Close();
196 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
197 base::ProcessHandle process_handle,
198 size_t buffer_size,
199 const cc::SharedBitmapId& id,
200 base::SharedMemoryHandle* shared_memory_handle) {
201 base::AutoLock lock(lock_);
202 if (handle_map_.find(id) != handle_map_.end()) {
203 *shared_memory_handle = base::SharedMemory::NULLHandle();
204 return;
206 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
207 if (!shared_memory->CreateAndMapAnonymous(buffer_size)) {
208 LOG(ERROR) << "Cannot create shared memory buffer";
209 *shared_memory_handle = base::SharedMemory::NULLHandle();
210 return;
213 scoped_refptr<BitmapData> data(
214 new BitmapData(process_handle, buffer_size));
215 data->memory = shared_memory.Pass();
217 handle_map_[id] = data;
218 if (!data->memory->ShareToProcess(process_handle, shared_memory_handle)) {
219 LOG(ERROR) << "Cannot share shared memory buffer";
220 *shared_memory_handle = base::SharedMemory::NULLHandle();
221 return;
223 data->memory->Close();
226 void HostSharedBitmapManager::ChildDeletedSharedBitmap(
227 const cc::SharedBitmapId& id) {
228 base::AutoLock lock(lock_);
229 handle_map_.erase(id);
232 size_t HostSharedBitmapManager::AllocatedBitmapCount() const {
233 base::AutoLock lock(lock_);
234 return handle_map_.size();
237 void HostSharedBitmapManager::FreeSharedMemoryFromMap(
238 const cc::SharedBitmapId& id) {
239 base::AutoLock lock(lock_);
240 handle_map_.erase(id);
243 } // namespace content