Change next_proto member type.
[chromium-blink-merge.git] / content / common / host_shared_bitmap_manager.cc
bloba086dfd9af1c1ce9ccae42311f28d53792d8d9c4
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 "content/common/view_messages.h"
10 #include "ui/gfx/size.h"
12 namespace content {
14 class BitmapData : public base::RefCountedThreadSafe<BitmapData> {
15 public:
16 BitmapData(base::ProcessHandle process_handle,
17 size_t buffer_size)
18 : process_handle(process_handle),
19 buffer_size(buffer_size) {}
20 base::ProcessHandle process_handle;
21 scoped_ptr<base::SharedMemory> memory;
22 scoped_ptr<uint8[]> pixels;
23 size_t buffer_size;
25 private:
26 friend class base::RefCountedThreadSafe<BitmapData>;
27 ~BitmapData() {}
28 DISALLOW_COPY_AND_ASSIGN(BitmapData);
31 namespace {
33 class HostSharedBitmap : public cc::SharedBitmap {
34 public:
35 HostSharedBitmap(uint8* pixels,
36 scoped_refptr<BitmapData> bitmap_data,
37 const cc::SharedBitmapId& id,
38 HostSharedBitmapManager* manager)
39 : SharedBitmap(pixels, id),
40 bitmap_data_(bitmap_data),
41 manager_(manager) {}
43 ~HostSharedBitmap() override {
44 if (manager_)
45 manager_->FreeSharedMemoryFromMap(id());
48 base::SharedMemory* memory() override { return bitmap_data_->memory.get(); }
50 private:
51 scoped_refptr<BitmapData> bitmap_data_;
52 HostSharedBitmapManager* manager_;
55 } // namespace
57 base::LazyInstance<HostSharedBitmapManager> g_shared_memory_manager =
58 LAZY_INSTANCE_INITIALIZER;
60 HostSharedBitmapManager::HostSharedBitmapManager() {}
61 HostSharedBitmapManager::~HostSharedBitmapManager() {
62 DCHECK(handle_map_.empty());
65 HostSharedBitmapManager* HostSharedBitmapManager::current() {
66 return g_shared_memory_manager.Pointer();
69 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap(
70 const gfx::Size& size) {
71 base::AutoLock lock(lock_);
72 size_t bitmap_size;
73 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size))
74 return scoped_ptr<cc::SharedBitmap>();
76 scoped_refptr<BitmapData> data(
77 new BitmapData(base::GetCurrentProcessHandle(),
78 bitmap_size));
79 // Bitmaps allocated in host don't need to be shared to other processes, so
80 // allocate them with new instead.
81 data->pixels = scoped_ptr<uint8[]>(new uint8[bitmap_size]);
83 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
84 handle_map_[id] = data;
85 return make_scoped_ptr(
86 new HostSharedBitmap(data->pixels.get(), data, id, this));
89 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetSharedBitmapFromId(
90 const gfx::Size& size,
91 const cc::SharedBitmapId& id) {
92 base::AutoLock lock(lock_);
93 BitmapMap::iterator it = handle_map_.find(id);
94 if (it == handle_map_.end())
95 return scoped_ptr<cc::SharedBitmap>();
97 BitmapData* data = it->second.get();
99 size_t bitmap_size;
100 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
101 bitmap_size > data->buffer_size)
102 return scoped_ptr<cc::SharedBitmap>();
104 if (data->pixels) {
105 return make_scoped_ptr(
106 new HostSharedBitmap(data->pixels.get(), data, id, nullptr));
108 if (!data->memory->memory()) {
109 return scoped_ptr<cc::SharedBitmap>();
112 return make_scoped_ptr(new HostSharedBitmap(
113 static_cast<uint8*>(data->memory->memory()), data, id, nullptr));
116 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetBitmapForSharedMemory(
117 base::SharedMemory*) {
118 return scoped_ptr<cc::SharedBitmap>();
121 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
122 size_t buffer_size,
123 const base::SharedMemoryHandle& handle,
124 base::ProcessHandle process_handle,
125 const cc::SharedBitmapId& id) {
126 base::AutoLock lock(lock_);
127 if (handle_map_.find(id) != handle_map_.end())
128 return;
129 scoped_refptr<BitmapData> data(
130 new BitmapData(process_handle, buffer_size));
132 handle_map_[id] = data;
133 process_map_[process_handle].insert(id);
134 #if defined(OS_WIN)
135 data->memory = make_scoped_ptr(
136 new base::SharedMemory(handle, false, data->process_handle));
137 #else
138 data->memory =
139 make_scoped_ptr(new base::SharedMemory(handle, false));
140 #endif
141 data->memory->Map(data->buffer_size);
142 data->memory->Close();
145 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
146 base::ProcessHandle process_handle,
147 size_t buffer_size,
148 const cc::SharedBitmapId& id,
149 base::SharedMemoryHandle* shared_memory_handle) {
150 base::AutoLock lock(lock_);
151 if (handle_map_.find(id) != handle_map_.end()) {
152 *shared_memory_handle = base::SharedMemory::NULLHandle();
153 return;
155 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
156 if (!shared_memory->CreateAndMapAnonymous(buffer_size)) {
157 LOG(ERROR) << "Cannot create shared memory buffer";
158 *shared_memory_handle = base::SharedMemory::NULLHandle();
159 return;
162 scoped_refptr<BitmapData> data(
163 new BitmapData(process_handle, buffer_size));
164 data->memory = shared_memory.Pass();
166 handle_map_[id] = data;
167 process_map_[process_handle].insert(id);
168 if (!data->memory->ShareToProcess(process_handle, shared_memory_handle)) {
169 LOG(ERROR) << "Cannot share shared memory buffer";
170 *shared_memory_handle = base::SharedMemory::NULLHandle();
171 return;
173 data->memory->Close();
176 void HostSharedBitmapManager::ChildDeletedSharedBitmap(
177 const cc::SharedBitmapId& id) {
178 base::AutoLock lock(lock_);
179 BitmapMap::iterator it = handle_map_.find(id);
180 if (it == handle_map_.end())
181 return;
182 base::hash_set<cc::SharedBitmapId>& res =
183 process_map_[it->second->process_handle];
184 res.erase(id);
185 handle_map_.erase(it);
188 void HostSharedBitmapManager::ProcessRemoved(
189 base::ProcessHandle process_handle) {
190 base::AutoLock lock(lock_);
191 ProcessMap::iterator proc_it = process_map_.find(process_handle);
192 if (proc_it == process_map_.end())
193 return;
194 base::hash_set<cc::SharedBitmapId>& res = proc_it->second;
196 for (base::hash_set<cc::SharedBitmapId>::iterator it = res.begin();
197 it != res.end();
198 ++it) {
199 handle_map_.erase(*it);
201 process_map_.erase(proc_it);
204 size_t HostSharedBitmapManager::AllocatedBitmapCount() const {
205 base::AutoLock lock(lock_);
206 return handle_map_.size();
209 void HostSharedBitmapManager::FreeSharedMemoryFromMap(
210 const cc::SharedBitmapId& id) {
211 base::AutoLock lock(lock_);
212 handle_map_.erase(id);
215 } // namespace content