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/process_metrics.h"
9 #include "content/child/child_thread_impl.h"
10 #include "content/common/child_process_messages.h"
11 #include "ui/gfx/geometry/size.h"
17 class ChildSharedBitmap
: public SharedMemoryBitmap
{
19 ChildSharedBitmap(scoped_refptr
<ThreadSafeSender
> sender
,
20 base::SharedMemory
* shared_memory
,
21 const cc::SharedBitmapId
& id
)
22 : SharedMemoryBitmap(static_cast<uint8
*>(shared_memory
->memory()),
27 ChildSharedBitmap(scoped_refptr
<ThreadSafeSender
> sender
,
28 scoped_ptr
<base::SharedMemory
> shared_memory_holder
,
29 const cc::SharedBitmapId
& id
)
30 : ChildSharedBitmap(sender
, shared_memory_holder
.get(), id
) {
31 shared_memory_holder_
= shared_memory_holder
.Pass();
34 ~ChildSharedBitmap() override
{
35 sender_
->Send(new ChildProcessHostMsg_DeletedSharedBitmap(id()));
39 scoped_refptr
<ThreadSafeSender
> sender_
;
40 scoped_ptr
<base::SharedMemory
> shared_memory_holder_
;
45 // Collect extra information for debugging bitmap creation failures.
46 void CollectMemoryUsageAndDie(const gfx::Size
& size
) {
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
);
72 SharedMemoryBitmap::SharedMemoryBitmap(uint8
* pixels
,
73 const cc::SharedBitmapId
& id
,
74 base::SharedMemory
* shared_memory
)
75 : SharedBitmap(pixels
, id
), shared_memory_(shared_memory
) {
78 ChildSharedBitmapManager::ChildSharedBitmapManager(
79 scoped_refptr
<ThreadSafeSender
> sender
)
83 ChildSharedBitmapManager::~ChildSharedBitmapManager() {}
85 scoped_ptr
<cc::SharedBitmap
> ChildSharedBitmapManager::AllocateSharedBitmap(
86 const gfx::Size
& size
) {
87 scoped_ptr
<SharedMemoryBitmap
> bitmap
= AllocateSharedMemoryBitmap(size
);
89 // Close file descriptor to avoid running out.
91 bitmap
->shared_memory()->Close();
96 scoped_ptr
<SharedMemoryBitmap
>
97 ChildSharedBitmapManager::AllocateSharedMemoryBitmap(const gfx::Size
& size
) {
98 TRACE_EVENT2("renderer",
99 "ChildSharedBitmapManager::AllocateSharedMemoryBitmap", "width",
100 size
.width(), "height", size
.height());
102 if (!cc::SharedBitmap::SizeInBytes(size
, &memory_size
))
103 return scoped_ptr
<SharedMemoryBitmap
>();
104 cc::SharedBitmapId id
= cc::SharedBitmap::GenerateId();
105 scoped_ptr
<base::SharedMemory
> memory
;
106 #if defined(OS_POSIX)
107 base::SharedMemoryHandle handle
;
108 sender_
->Send(new ChildProcessHostMsg_SyncAllocateSharedBitmap(
109 memory_size
, id
, &handle
));
110 memory
= make_scoped_ptr(new base::SharedMemory(handle
, false));
111 if (!memory
->Map(memory_size
))
114 memory
= ChildThreadImpl::AllocateSharedMemory(memory_size
, sender_
.get());
117 CollectMemoryUsageAndDie(size
);
121 if (!memory
->Map(memory_size
)) {
123 CollectMemoryUsageAndDie(size
);
127 base::SharedMemoryHandle handle_to_send
= memory
->handle();
128 sender_
->Send(new ChildProcessHostMsg_AllocatedSharedBitmap(
129 memory_size
, handle_to_send
, id
));
131 return make_scoped_ptr(new ChildSharedBitmap(sender_
, memory
.Pass(), id
));
134 scoped_ptr
<cc::SharedBitmap
> ChildSharedBitmapManager::GetSharedBitmapFromId(
136 const cc::SharedBitmapId
&) {
138 return scoped_ptr
<cc::SharedBitmap
>();
141 scoped_ptr
<cc::SharedBitmap
> ChildSharedBitmapManager::GetBitmapForSharedMemory(
142 base::SharedMemory
* mem
) {
143 cc::SharedBitmapId id
= cc::SharedBitmap::GenerateId();
144 base::SharedMemoryHandle handle_to_send
= mem
->handle();
145 #if defined(OS_POSIX)
146 if (!mem
->ShareToProcess(base::GetCurrentProcessHandle(), &handle_to_send
))
147 return scoped_ptr
<cc::SharedBitmap
>();
149 sender_
->Send(new ChildProcessHostMsg_AllocatedSharedBitmap(
150 mem
->mapped_size(), handle_to_send
, id
));
152 return make_scoped_ptr(new ChildSharedBitmap(sender_
, mem
, id
));
155 } // namespace content