Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / common / host_shared_bitmap_manager.cc
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.
4
5 #include "content/common/host_shared_bitmap_manager.h"
6
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"
11
12 namespace content {
13
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   size_t buffer_size;
26
27  private:
28   friend class base::RefCountedThreadSafe<BitmapData>;
29   ~BitmapData() {}
30   DISALLOW_COPY_AND_ASSIGN(BitmapData);
31 };
32
33 // Holds a reference on the memory to keep it alive.
34 void FreeSharedMemory(scoped_refptr<BitmapData> data,
35                       cc::SharedBitmap* bitmap) {}
36
37 base::LazyInstance<HostSharedBitmapManager> g_shared_memory_manager =
38     LAZY_INSTANCE_INITIALIZER;
39
40 HostSharedBitmapManager::HostSharedBitmapManager() {}
41 HostSharedBitmapManager::~HostSharedBitmapManager() {}
42
43 HostSharedBitmapManager* HostSharedBitmapManager::current() {
44   return g_shared_memory_manager.Pointer();
45 }
46
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>();
52 }
53
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>();
61
62   BitmapData* data = it->second.get();
63
64   size_t bitmap_size;
65   if (!cc::SharedBitmap::SizeInBytes(size, &bitmap_size) ||
66       bitmap_size > data->buffer_size)
67     return scoped_ptr<cc::SharedBitmap>();
68
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>();
74     }
75   }
76
77   scoped_ptr<cc::SharedBitmap> bitmap(new cc::SharedBitmap(
78       data->memory.get(), id, base::Bind(&FreeSharedMemory, it->second)));
79
80   return bitmap.Pass();
81 }
82
83 scoped_ptr<cc::SharedBitmap> HostSharedBitmapManager::GetBitmapForSharedMemory(
84     base::SharedMemory*) {
85   return scoped_ptr<cc::SharedBitmap>();
86 }
87
88 void HostSharedBitmapManager::ChildAllocatedSharedBitmap(
89     size_t buffer_size,
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())
95     return;
96   scoped_refptr<BitmapData> data(
97       new BitmapData(process_handle, handle, buffer_size));
98
99   handle_map_[id] = data;
100   process_map_[process_handle].insert(id);
101 #if defined(OS_WIN)
102   data->memory = make_scoped_ptr(
103       new base::SharedMemory(data->memory_handle, false, data->process_handle));
104 #else
105   data->memory =
106       make_scoped_ptr(new base::SharedMemory(data->memory_handle, false));
107 #endif
108 }
109
110 void HostSharedBitmapManager::AllocateSharedBitmapForChild(
111     base::ProcessHandle process_handle,
112     size_t buffer_size,
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();
118     return;
119   }
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();
124     return;
125   }
126
127   scoped_refptr<BitmapData> data(
128       new BitmapData(process_handle, shared_memory->handle(), buffer_size));
129   data->memory = shared_memory.Pass();
130
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();
136     return;
137   }
138 }
139
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())
145     return;
146   base::hash_set<cc::SharedBitmapId>& res =
147       process_map_[it->second->process_handle];
148   res.erase(id);
149   handle_map_.erase(it);
150 }
151
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())
157     return;
158   base::hash_set<cc::SharedBitmapId>& res = proc_it->second;
159
160   for (base::hash_set<cc::SharedBitmapId>::iterator it = res.begin();
161        it != res.end();
162        ++it) {
163     handle_map_.erase(*it);
164   }
165   process_map_.erase(proc_it);
166 }
167
168 }  // namespace content