ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / content / common / host_shared_bitmap_manager.cc
blob778260b0f7ef96d4b76b5ce99b74ca92cc46f900
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/geometry/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 private:
49 scoped_refptr<BitmapData> bitmap_data_;
50 HostSharedBitmapManager* manager_;
53 } // namespace
55 base::LazyInstance<HostSharedBitmapManager> g_shared_memory_manager =
56 LAZY_INSTANCE_INITIALIZER;
58 HostSharedBitmapManager::HostSharedBitmapManager() {}
59 HostSharedBitmapManager::~HostSharedBitmapManager() {
60 DCHECK(handle_map_.empty());
63 HostSharedBitmapManager* HostSharedBitmapManager::current() {
64 return g_shared_memory_manager.Pointer();
67 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap(
68 const gfx::Size& size) {
69 base::AutoLock lock(lock_);
70 size_t bitmap_size;
71 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size))
72 return scoped_ptr<cc::SharedBitmap>();
74 scoped_refptr<BitmapData> data(
75 new BitmapData(base::GetCurrentProcessHandle(),
76 bitmap_size));
77 // Bitmaps allocated in host don't need to be shared to other processes, so
78 // allocate them with new instead.
79 data->pixels = scoped_ptr<uint8[]>(new uint8[bitmap_size]);
81 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
82 handle_map_[id] = data;
83 return make_scoped_ptr(
84 new HostSharedBitmap(data->pixels.get(), data, id, this));
87 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetSharedBitmapFromId(
88 const gfx::Size& size,
89 const cc::SharedBitmapId& id) {
90 base::AutoLock lock(lock_);
91 BitmapMap::iterator it = handle_map_.find(id);
92 if (it == handle_map_.end())
93 return scoped_ptr<cc::SharedBitmap>();
95 BitmapData* data = it->second.get();
97 size_t bitmap_size;
98 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
99 bitmap_size > data->buffer_size)
100 return scoped_ptr<cc::SharedBitmap>();
102 if (data->pixels) {
103 return make_scoped_ptr(
104 new HostSharedBitmap(data->pixels.get(), data, id, nullptr));
106 if (!data->memory->memory()) {
107 return scoped_ptr<cc::SharedBitmap>();
110 return make_scoped_ptr(new HostSharedBitmap(
111 static_cast<uint8*>(data->memory->memory()), data, id, nullptr));
114 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
115 size_t buffer_size,
116 const base::SharedMemoryHandle& handle,
117 base::ProcessHandle process_handle,
118 const cc::SharedBitmapId& id) {
119 base::AutoLock lock(lock_);
120 if (handle_map_.find(id) != handle_map_.end())
121 return;
122 scoped_refptr<BitmapData> data(
123 new BitmapData(process_handle, buffer_size));
125 handle_map_[id] = data;
126 process_map_[process_handle].insert(id);
127 #if defined(OS_WIN)
128 data->memory = make_scoped_ptr(
129 new base::SharedMemory(handle, false, data->process_handle));
130 #else
131 data->memory =
132 make_scoped_ptr(new base::SharedMemory(handle, false));
133 #endif
134 data->memory->Map(data->buffer_size);
135 data->memory->Close();
138 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
139 base::ProcessHandle process_handle,
140 size_t buffer_size,
141 const cc::SharedBitmapId& id,
142 base::SharedMemoryHandle* shared_memory_handle) {
143 base::AutoLock lock(lock_);
144 if (handle_map_.find(id) != handle_map_.end()) {
145 *shared_memory_handle = base::SharedMemory::NULLHandle();
146 return;
148 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
149 if (!shared_memory->CreateAndMapAnonymous(buffer_size)) {
150 LOG(ERROR) << "Cannot create shared memory buffer";
151 *shared_memory_handle = base::SharedMemory::NULLHandle();
152 return;
155 scoped_refptr<BitmapData> data(
156 new BitmapData(process_handle, buffer_size));
157 data->memory = shared_memory.Pass();
159 handle_map_[id] = data;
160 process_map_[process_handle].insert(id);
161 if (!data->memory->ShareToProcess(process_handle, shared_memory_handle)) {
162 LOG(ERROR) << "Cannot share shared memory buffer";
163 *shared_memory_handle = base::SharedMemory::NULLHandle();
164 return;
166 data->memory->Close();
169 void HostSharedBitmapManager::ChildDeletedSharedBitmap(
170 const cc::SharedBitmapId& id) {
171 base::AutoLock lock(lock_);
172 BitmapMap::iterator it = handle_map_.find(id);
173 if (it == handle_map_.end())
174 return;
175 base::hash_set<cc::SharedBitmapId>& res =
176 process_map_[it->second->process_handle];
177 res.erase(id);
178 handle_map_.erase(it);
181 void HostSharedBitmapManager::ProcessRemoved(
182 base::ProcessHandle process_handle) {
183 base::AutoLock lock(lock_);
184 ProcessMap::iterator proc_it = process_map_.find(process_handle);
185 if (proc_it == process_map_.end())
186 return;
187 base::hash_set<cc::SharedBitmapId>& res = proc_it->second;
189 for (base::hash_set<cc::SharedBitmapId>::iterator it = res.begin();
190 it != res.end();
191 ++it) {
192 handle_map_.erase(*it);
194 process_map_.erase(proc_it);
197 size_t HostSharedBitmapManager::AllocatedBitmapCount() const {
198 base::AutoLock lock(lock_);
199 return handle_map_.size();
202 void HostSharedBitmapManager::FreeSharedMemoryFromMap(
203 const cc::SharedBitmapId& id) {
204 base::AutoLock lock(lock_);
205 handle_map_.erase(id);
208 } // namespace content