We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / content / common / host_shared_bitmap_manager.cc
blobb95820c2f32c44867d7b3abba5f2b05d70f1d00d
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 HostSharedBitmapManagerClient::HostSharedBitmapManagerClient(
59 HostSharedBitmapManager* manager)
60 : manager_(manager) {
63 HostSharedBitmapManagerClient::~HostSharedBitmapManagerClient() {
64 for (const auto& id : owned_bitmaps_)
65 manager_->ChildDeletedSharedBitmap(id);
68 void HostSharedBitmapManagerClient::AllocateSharedBitmapForChild(
69 base::ProcessHandle process_handle,
70 size_t buffer_size,
71 const cc::SharedBitmapId& id,
72 base::SharedMemoryHandle* shared_memory_handle) {
73 manager_->AllocateSharedBitmapForChild(process_handle, buffer_size, id,
74 shared_memory_handle);
75 owned_bitmaps_.insert(id);
78 void HostSharedBitmapManagerClient::ChildAllocatedSharedBitmap(
79 size_t buffer_size,
80 const base::SharedMemoryHandle& handle,
81 base::ProcessHandle process_handle,
82 const cc::SharedBitmapId& id) {
83 manager_->ChildAllocatedSharedBitmap(buffer_size, handle, process_handle, id);
84 owned_bitmaps_.insert(id);
87 void HostSharedBitmapManagerClient::ChildDeletedSharedBitmap(
88 const cc::SharedBitmapId& id) {
89 manager_->ChildDeletedSharedBitmap(id);
90 owned_bitmaps_.erase(id);
93 HostSharedBitmapManager::HostSharedBitmapManager() {}
94 HostSharedBitmapManager::~HostSharedBitmapManager() {
95 DCHECK(handle_map_.empty());
98 HostSharedBitmapManager* HostSharedBitmapManager::current() {
99 return g_shared_memory_manager.Pointer();
102 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::AllocateSharedBitmap(
103 const gfx::Size& size) {
104 base::AutoLock lock(lock_);
105 size_t bitmap_size;
106 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size))
107 return scoped_ptr<cc::SharedBitmap>();
109 scoped_refptr<BitmapData> data(
110 new BitmapData(base::GetCurrentProcessHandle(),
111 bitmap_size));
112 // Bitmaps allocated in host don't need to be shared to other processes, so
113 // allocate them with new instead.
114 data->pixels = scoped_ptr<uint8[]>(new uint8[bitmap_size]);
116 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
117 handle_map_[id] = data;
118 return make_scoped_ptr(
119 new HostSharedBitmap(data->pixels.get(), data, id, this));
122 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetSharedBitmapFromId(
123 const gfx::Size& size,
124 const cc::SharedBitmapId& id) {
125 base::AutoLock lock(lock_);
126 BitmapMap::iterator it = handle_map_.find(id);
127 if (it == handle_map_.end())
128 return scoped_ptr<cc::SharedBitmap>();
130 BitmapData* data = it->second.get();
132 size_t bitmap_size;
133 if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
134 bitmap_size > data->buffer_size)
135 return scoped_ptr<cc::SharedBitmap>();
137 if (data->pixels) {
138 return make_scoped_ptr(
139 new HostSharedBitmap(data->pixels.get(), data, id, nullptr));
141 if (!data->memory->memory()) {
142 return scoped_ptr<cc::SharedBitmap>();
145 return make_scoped_ptr(new HostSharedBitmap(
146 static_cast<uint8*>(data->memory->memory()), data, id, nullptr));
149 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
150 size_t buffer_size,
151 const base::SharedMemoryHandle& handle,
152 base::ProcessHandle process_handle,
153 const cc::SharedBitmapId& id) {
154 base::AutoLock lock(lock_);
155 if (handle_map_.find(id) != handle_map_.end())
156 return;
157 scoped_refptr<BitmapData> data(
158 new BitmapData(process_handle, buffer_size));
160 handle_map_[id] = data;
161 #if defined(OS_WIN)
162 data->memory = make_scoped_ptr(
163 new base::SharedMemory(handle, false, data->process_handle));
164 #else
165 data->memory =
166 make_scoped_ptr(new base::SharedMemory(handle, false));
167 #endif
168 data->memory->Map(data->buffer_size);
169 data->memory->Close();
172 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
173 base::ProcessHandle process_handle,
174 size_t buffer_size,
175 const cc::SharedBitmapId& id,
176 base::SharedMemoryHandle* shared_memory_handle) {
177 base::AutoLock lock(lock_);
178 if (handle_map_.find(id) != handle_map_.end()) {
179 *shared_memory_handle = base::SharedMemory::NULLHandle();
180 return;
182 scoped_ptr<base::SharedMemory> shared_memory(new base::SharedMemory);
183 if (!shared_memory->CreateAndMapAnonymous(buffer_size)) {
184 LOG(ERROR) << "Cannot create shared memory buffer";
185 *shared_memory_handle = base::SharedMemory::NULLHandle();
186 return;
189 scoped_refptr<BitmapData> data(
190 new BitmapData(process_handle, buffer_size));
191 data->memory = shared_memory.Pass();
193 handle_map_[id] = data;
194 if (!data->memory->ShareToProcess(process_handle, shared_memory_handle)) {
195 LOG(ERROR) << "Cannot share shared memory buffer";
196 *shared_memory_handle = base::SharedMemory::NULLHandle();
197 return;
199 data->memory->Close();
202 void HostSharedBitmapManager::ChildDeletedSharedBitmap(
203 const cc::SharedBitmapId& id) {
204 base::AutoLock lock(lock_);
205 handle_map_.erase(id);
208 size_t HostSharedBitmapManager::AllocatedBitmapCount() const {
209 base::AutoLock lock(lock_);
210 return handle_map_.size();
213 void HostSharedBitmapManager::FreeSharedMemoryFromMap(
214 const cc::SharedBitmapId& id) {
215 base::AutoLock lock(lock_);
216 handle_map_.erase(id);
219 } // namespace content