Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / common / host_shared_bitmap_manager.cc
blobac1478fe5ea07dc244ff178382418e611bfcd95d
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 base::SharedMemoryHandle memory_handle,
18 size_t buffer_size)
19 : process_handle(process_handle),
20 memory_handle(memory_handle),
21 buffer_size(buffer_size) {}
22 base::ProcessHandle process_handle;
23 base::SharedMemoryHandle memory_handle;
24 scoped_ptr<base::SharedMemory> memory;
25 scoped_ptr<uint8[]> pixels;
26 size_t buffer_size;
28 private:
29 friend class base::RefCountedThreadSafe<BitmapData>;
30 ~BitmapData() {}
31 DISALLOW_COPY_AND_ASSIGN(BitmapData);
34 // Holds a reference on the memory to keep it alive.
35 void FreeSharedMemory(scoped_refptr<BitmapData> data,
36 cc::SharedBitmap* bitmap) {}
38 base::LazyInstance<HostSharedBitmapManager> g_shared_memory_manager =
39 LAZY_INSTANCE_INITIALIZER;
41 HostSharedBitmapManager::HostSharedBitmapManager() {}
42 HostSharedBitmapManager::~HostSharedBitmapManager() {}
44 HostSharedBitmapManager* HostSharedBitmapManager::current() {
45 return g_shared_memory_manager.Pointer();
48 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap(
49 const gfx::Size& size) {
50 base::AutoLock lock(lock_);
51 size_t bitmap_size;
52 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size))
53 return scoped_ptr<cc::SharedBitmap>();
55 scoped_refptr<BitmapData> data(
56 new BitmapData(base::GetCurrentProcessHandle(),
57 base::SharedMemory::NULLHandle(),
58 bitmap_size));
59 // Bitmaps allocated in host don't need to be shared to other processes, so
60 // allocate them with new instead.
61 data->pixels = scoped_ptr<uint8[]>(new uint8[bitmap_size]);
63 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
64 handle_map_[id] = data;
65 return make_scoped_ptr(new cc::SharedBitmap(
66 data->pixels.get(),
67 id,
68 base::Bind(&HostSharedBitmapManager::FreeSharedMemoryFromMap,
69 base::Unretained(this))));
72 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetSharedBitmapFromId(
73 const gfx::Size& size,
74 const cc::SharedBitmapId& id) {
75 base::AutoLock lock(lock_);
76 BitmapMap::iterator it = handle_map_.find(id);
77 if (it == handle_map_.end())
78 return scoped_ptr<cc::SharedBitmap>();
80 BitmapData* data = it->second.get();
82 size_t bitmap_size;
83 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
84 bitmap_size > data->buffer_size)
85 return scoped_ptr<cc::SharedBitmap>();
87 if (data->pixels) {
88 return make_scoped_ptr(new cc::SharedBitmap(
89 data->pixels.get(), id, base::Bind(&FreeSharedMemory, it->second)));
91 if (!data->memory->memory()) {
92 TRACE_EVENT0("renderer_host",
93 "HostSharedBitmapManager::GetSharedBitmapFromId");
94 if (!data->memory->Map(data->buffer_size)) {
95 return scoped_ptr<cc::SharedBitmap>();
99 scoped_ptr<cc::SharedBitmap> bitmap(new cc::SharedBitmap(
100 data->memory.get(), id, base::Bind(&FreeSharedMemory, it->second)));
102 return bitmap.Pass();
105 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetBitmapForSharedMemory(
106 base::SharedMemory*) {
107 return scoped_ptr<cc::SharedBitmap>();
110 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
111 size_t buffer_size,
112 const base::SharedMemoryHandle& handle,
113 base::ProcessHandle process_handle,
114 const cc::SharedBitmapId& id) {
115 base::AutoLock lock(lock_);
116 if (handle_map_.find(id) != handle_map_.end())
117 return;
118 scoped_refptr<BitmapData> data(
119 new BitmapData(process_handle, handle, buffer_size));
121 handle_map_[id] = data;
122 process_map_[process_handle].insert(id);
123 #if defined(OS_WIN)
124 data->memory = make_scoped_ptr(
125 new base::SharedMemory(data->memory_handle, false, data->process_handle));
126 #else
127 data->memory =
128 make_scoped_ptr(new base::SharedMemory(data->memory_handle, false));
129 #endif
132 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
133 base::ProcessHandle process_handle,
134 size_t buffer_size,
135 const cc::SharedBitmapId& id,
136 base::SharedMemoryHandle* shared_memory_handle) {
137 base::AutoLock lock(lock_);
138 if (handle_map_.find(id) != handle_map_.end()) {
139 *shared_memory_handle = base::SharedMemory::NULLHandle();
140 return;
142 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
143 if (!shared_memory->CreateAndMapAnonymous(buffer_size)) {
144 LOG(ERROR) << "Cannot create shared memory buffer";
145 *shared_memory_handle = base::SharedMemory::NULLHandle();
146 return;
149 scoped_refptr<BitmapData> data(
150 new BitmapData(process_handle, shared_memory->handle(), buffer_size));
151 data->memory = shared_memory.Pass();
153 handle_map_[id] = data;
154 process_map_[process_handle].insert(id);
155 if (!data->memory->ShareToProcess(process_handle, shared_memory_handle)) {
156 LOG(ERROR) << "Cannot share shared memory buffer";
157 *shared_memory_handle = base::SharedMemory::NULLHandle();
158 return;
162 void HostSharedBitmapManager::ChildDeletedSharedBitmap(
163 const cc::SharedBitmapId& id) {
164 base::AutoLock lock(lock_);
165 BitmapMap::iterator it = handle_map_.find(id);
166 if (it == handle_map_.end())
167 return;
168 base::hash_set<cc::SharedBitmapId>& res =
169 process_map_[it->second->process_handle];
170 res.erase(id);
171 handle_map_.erase(it);
174 void HostSharedBitmapManager::ProcessRemoved(
175 base::ProcessHandle process_handle) {
176 base::AutoLock lock(lock_);
177 ProcessMap::iterator proc_it = process_map_.find(process_handle);
178 if (proc_it == process_map_.end())
179 return;
180 base::hash_set<cc::SharedBitmapId>& res = proc_it->second;
182 for (base::hash_set<cc::SharedBitmapId>::iterator it = res.begin();
183 it != res.end();
184 ++it) {
185 handle_map_.erase(*it);
187 process_map_.erase(proc_it);
190 void HostSharedBitmapManager::FreeSharedMemoryFromMap(
191 cc::SharedBitmap* bitmap) {
192 base::AutoLock lock(lock_);
193 handle_map_.erase(bitmap->id());
196 } // namespace content