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"
14 class BitmapData
: public base::RefCountedThreadSafe
<BitmapData
> {
16 BitmapData(base::ProcessHandle process_handle
,
17 base::SharedMemoryHandle memory_handle
,
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
;
28 friend class base::RefCountedThreadSafe
<BitmapData
>;
30 DISALLOW_COPY_AND_ASSIGN(BitmapData
);
33 // Holds a reference on the memory to keep it alive.
34 void FreeSharedMemory(scoped_refptr
<BitmapData
> data
,
35 cc::SharedBitmap
* bitmap
) {}
37 base::LazyInstance
<HostSharedBitmapManager
> g_shared_memory_manager
=
38 LAZY_INSTANCE_INITIALIZER
;
40 HostSharedBitmapManager::HostSharedBitmapManager() {}
41 HostSharedBitmapManager::~HostSharedBitmapManager() {}
43 HostSharedBitmapManager
* HostSharedBitmapManager::current() {
44 return g_shared_memory_manager
.Pointer();
47 scoped_ptr
<cc::SharedBitmap
> HostSharedBitmapManager::AllocateSharedBitmap(
48 const gfx::Size
& size
) {
49 // Bitmaps allocated in host don't need to be shared to other processes, so
50 // allocate them with new instead.
51 return scoped_ptr
<cc::SharedBitmap
>();
54 scoped_ptr
<cc::SharedBitmap
> HostSharedBitmapManager::GetSharedBitmapFromId(
55 const gfx::Size
& size
,
56 const cc::SharedBitmapId
& id
) {
57 base::AutoLock
lock(lock_
);
58 BitmapMap::iterator it
= handle_map_
.find(id
);
59 if (it
== handle_map_
.end())
60 return scoped_ptr
<cc::SharedBitmap
>();
62 BitmapData
* data
= it
->second
.get();
65 if (!cc::SharedBitmap::SizeInBytes(size
, &bitmap_size
) ||
66 bitmap_size
> data
->buffer_size
)
67 return scoped_ptr
<cc::SharedBitmap
>();
69 if (!data
->memory
->memory()) {
70 TRACE_EVENT0("renderer_host",
71 "HostSharedBitmapManager::GetSharedBitmapFromId");
72 if (!data
->memory
->Map(data
->buffer_size
)) {
73 return scoped_ptr
<cc::SharedBitmap
>();
77 scoped_ptr
<cc::SharedBitmap
> bitmap(new cc::SharedBitmap(
78 data
->memory
.get(), id
, base::Bind(&FreeSharedMemory
, it
->second
)));
83 scoped_ptr
<cc::SharedBitmap
> HostSharedBitmapManager::GetBitmapForSharedMemory(
84 base::SharedMemory
*) {
85 return scoped_ptr
<cc::SharedBitmap
>();
88 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
90 const base::SharedMemoryHandle
& handle
,
91 base::ProcessHandle process_handle
,
92 const cc::SharedBitmapId
& id
) {
93 base::AutoLock
lock(lock_
);
94 if (handle_map_
.find(id
) != handle_map_
.end())
96 scoped_refptr
<BitmapData
> data(
97 new BitmapData(process_handle
, handle
, buffer_size
));
99 handle_map_
[id
] = data
;
100 process_map_
[process_handle
].insert(id
);
102 data
->memory
= make_scoped_ptr(
103 new base::SharedMemory(data
->memory_handle
, false, data
->process_handle
));
106 make_scoped_ptr(new base::SharedMemory(data
->memory_handle
, false));
110 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
111 base::ProcessHandle process_handle
,
113 const cc::SharedBitmapId
& id
,
114 base::SharedMemoryHandle
* shared_memory_handle
) {
115 base::AutoLock
lock(lock_
);
116 if (handle_map_
.find(id
) != handle_map_
.end()) {
117 *shared_memory_handle
= base::SharedMemory::NULLHandle();
120 scoped_ptr
<base::SharedMemory
> shared_memory(new base::SharedMemory
);
121 if (!shared_memory
->CreateAndMapAnonymous(buffer_size
)) {
122 LOG(ERROR
) << "Cannot create shared memory buffer";
123 *shared_memory_handle
= base::SharedMemory::NULLHandle();
127 scoped_refptr
<BitmapData
> data(
128 new BitmapData(process_handle
, shared_memory
->handle(), buffer_size
));
129 data
->memory
= shared_memory
.Pass();
131 handle_map_
[id
] = data
;
132 process_map_
[process_handle
].insert(id
);
133 if (!data
->memory
->ShareToProcess(process_handle
, shared_memory_handle
)) {
134 LOG(ERROR
) << "Cannot share shared memory buffer";
135 *shared_memory_handle
= base::SharedMemory::NULLHandle();
140 void HostSharedBitmapManager::ChildDeletedSharedBitmap(
141 const cc::SharedBitmapId
& id
) {
142 base::AutoLock
lock(lock_
);
143 BitmapMap::iterator it
= handle_map_
.find(id
);
144 if (it
== handle_map_
.end())
146 base::hash_set
<cc::SharedBitmapId
>& res
=
147 process_map_
[it
->second
->process_handle
];
149 handle_map_
.erase(it
);
152 void HostSharedBitmapManager::ProcessRemoved(
153 base::ProcessHandle process_handle
) {
154 base::AutoLock
lock(lock_
);
155 ProcessMap::iterator proc_it
= process_map_
.find(process_handle
);
156 if (proc_it
== process_map_
.end())
158 base::hash_set
<cc::SharedBitmapId
>& res
= proc_it
->second
;
160 for (base::hash_set
<cc::SharedBitmapId
>::iterator it
= res
.begin();
163 handle_map_
.erase(*it
);
165 process_map_
.erase(proc_it
);
168 } // namespace content