Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / content / child / child_shared_bitmap_manager.cc
blob334a7ea8e4f705a47ed2ab30a19a94e3853f04ea
1 // Copyright (c) 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/child/child_shared_bitmap_manager.h"
7 #include "base/debug/alias.h"
8 #include "base/process/memory.h"
9 #include "base/process/process_metrics.h"
10 #include "content/child/child_thread_impl.h"
11 #include "content/common/child_process_messages.h"
12 #include "ui/gfx/geometry/size.h"
14 namespace content {
16 namespace {
18 class ChildSharedBitmap : public SharedMemoryBitmap {
19 public:
20 ChildSharedBitmap(scoped_refptr<ThreadSafeSender> sender,
21 base::SharedMemory* shared_memory,
22 const cc::SharedBitmapId& id)
23 : SharedMemoryBitmap(static_cast<uint8*>(shared_memory->memory()),
24 id,
25 shared_memory),
26 sender_(sender) {}
28 ChildSharedBitmap(scoped_refptr<ThreadSafeSender> sender,
29 scoped_ptr<base::SharedMemory> shared_memory_holder,
30 const cc::SharedBitmapId& id)
31 : ChildSharedBitmap(sender, shared_memory_holder.get(), id) {
32 shared_memory_holder_ = shared_memory_holder.Pass();
35 ~ChildSharedBitmap() override {
36 sender_->Send(new ChildProcessHostMsg_DeletedSharedBitmap(id()));
39 private:
40 scoped_refptr<ThreadSafeSender> sender_;
41 scoped_ptr<base::SharedMemory> shared_memory_holder_;
44 // Collect extra information for debugging bitmap creation failures.
45 void CollectMemoryUsageAndDie(const gfx::Size& size, size_t alloc_size) {
46 #if defined(OS_WIN)
47 int width = size.width();
48 int height = size.height();
49 DWORD last_error = GetLastError();
51 scoped_ptr<base::ProcessMetrics> metrics(
52 base::ProcessMetrics::CreateProcessMetrics(
53 base::GetCurrentProcessHandle()));
55 size_t private_bytes = 0;
56 size_t shared_bytes = 0;
57 metrics->GetMemoryBytes(&private_bytes, &shared_bytes);
59 base::debug::Alias(&width);
60 base::debug::Alias(&height);
61 base::debug::Alias(&last_error);
62 base::debug::Alias(&private_bytes);
63 base::debug::Alias(&shared_bytes);
64 #endif
65 base::TerminateBecauseOutOfMemory(alloc_size);
68 } // namespace
70 SharedMemoryBitmap::SharedMemoryBitmap(uint8* pixels,
71 const cc::SharedBitmapId& id,
72 base::SharedMemory* shared_memory)
73 : SharedBitmap(pixels, id), shared_memory_(shared_memory) {
76 ChildSharedBitmapManager::ChildSharedBitmapManager(
77 scoped_refptr<ThreadSafeSender> sender)
78 : sender_(sender) {
81 ChildSharedBitmapManager::~ChildSharedBitmapManager() {}
83 scoped_ptr<cc::SharedBitmap> ChildSharedBitmapManager::AllocateSharedBitmap(
84 const gfx::Size& size) {
85 scoped_ptr<SharedMemoryBitmap> bitmap = AllocateSharedMemoryBitmap(size);
86 #if defined(OS_POSIX)
87 // Close file descriptor to avoid running out.
88 if (bitmap)
89 bitmap->shared_memory()->Close();
90 #endif
91 return bitmap.Pass();
94 scoped_ptr<SharedMemoryBitmap>
95 ChildSharedBitmapManager::AllocateSharedMemoryBitmap(const gfx::Size& size) {
96 TRACE_EVENT2("renderer",
97 "ChildSharedBitmapManager::AllocateSharedMemoryBitmap", "width",
98 size.width(), "height", size.height());
99 size_t memory_size;
100 if (!cc::SharedBitmap::SizeInBytes(size, &memory_size))
101 return scoped_ptr<SharedMemoryBitmap>();
102 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
103 scoped_ptr<base::SharedMemory> memory;
104 #if defined(OS_POSIX)
105 base::SharedMemoryHandle handle;
106 sender_->Send(new ChildProcessHostMsg_SyncAllocateSharedBitmap(
107 memory_size, id, &handle));
108 memory = make_scoped_ptr(new base::SharedMemory(handle, false));
109 if (!memory->Map(memory_size))
110 CollectMemoryUsageAndDie(size, memory_size);
111 #else
112 memory = ChildThreadImpl::AllocateSharedMemory(memory_size, sender_.get());
113 if (!memory)
114 CollectMemoryUsageAndDie(size, memory_size);
116 if (!memory->Map(memory_size))
117 CollectMemoryUsageAndDie(size, memory_size);
119 base::SharedMemoryHandle handle_to_send = memory->handle();
120 sender_->Send(new ChildProcessHostMsg_AllocatedSharedBitmap(
121 memory_size, handle_to_send, id));
122 #endif
123 return make_scoped_ptr(new ChildSharedBitmap(sender_, memory.Pass(), id));
126 scoped_ptr<cc::SharedBitmap> ChildSharedBitmapManager::GetSharedBitmapFromId(
127 const gfx::Size&,
128 const cc::SharedBitmapId&) {
129 NOTREACHED();
130 return scoped_ptr<cc::SharedBitmap>();
133 scoped_ptr<cc::SharedBitmap> ChildSharedBitmapManager::GetBitmapForSharedMemory(
134 base::SharedMemory* mem) {
135 cc::SharedBitmapId id = cc::SharedBitmap::GenerateId();
136 base::SharedMemoryHandle handle_to_send = mem->handle();
137 #if defined(OS_POSIX)
138 if (!mem->ShareToProcess(base::GetCurrentProcessHandle(), &handle_to_send))
139 return scoped_ptr<cc::SharedBitmap>();
140 #endif
141 sender_->Send(new ChildProcessHostMsg_AllocatedSharedBitmap(
142 mem->mapped_size(), handle_to_send, id));
144 return make_scoped_ptr(new ChildSharedBitmap(sender_, mem, id));
147 } // namespace content