Chromium Code Reviews| Index: content/child/child_shared_bitmap_manager.cc |
| diff --git a/content/child/child_shared_bitmap_manager.cc b/content/child/child_shared_bitmap_manager.cc |
| index 00b461c7e96baad1d89e7d8717ff523cdaf132b4..62c6ebcf508215a1f553b2732b8fe6d3b2784ceb 100644 |
| --- a/content/child/child_shared_bitmap_manager.cc |
| +++ b/content/child/child_shared_bitmap_manager.cc |
| @@ -15,6 +15,7 @@ |
| #include "build/build_config.h" |
| #include "content/child/child_thread_impl.h" |
| #include "content/common/child_process_messages.h" |
| +#include "mojo/public/cpp/system/platform_handle.h" |
| #include "ui/gfx/geometry/size.h" |
| namespace content { |
| @@ -23,27 +24,30 @@ namespace { |
| class ChildSharedBitmap : public SharedMemoryBitmap { |
| public: |
| - ChildSharedBitmap(scoped_refptr<ThreadSafeSender> sender, |
| + ChildSharedBitmap(const base::WeakPtr<ChildSharedBitmapManager>& manager, |
| + scoped_refptr<ThreadSafeSender> sender, |
| base::SharedMemory* shared_memory, |
| const cc::SharedBitmapId& id) |
| : SharedMemoryBitmap(static_cast<uint8_t*>(shared_memory->memory()), |
| id, |
| shared_memory), |
| - sender_(sender) {} |
| + manager_(manager) {} |
| - ChildSharedBitmap(scoped_refptr<ThreadSafeSender> sender, |
| + ChildSharedBitmap(const base::WeakPtr<ChildSharedBitmapManager>& manager, |
| + scoped_refptr<ThreadSafeSender> sender, |
| std::unique_ptr<base::SharedMemory> shared_memory_holder, |
| const cc::SharedBitmapId& id) |
| - : ChildSharedBitmap(sender, shared_memory_holder.get(), id) { |
| + : ChildSharedBitmap(manager, sender, shared_memory_holder.get(), id) { |
| shared_memory_holder_ = std::move(shared_memory_holder); |
| } |
| ~ChildSharedBitmap() override { |
| - sender_->Send(new ChildProcessHostMsg_DeletedSharedBitmap(id())); |
| + if (manager_) |
| + manager_->OnBitmapDeleted(id()); |
| } |
| private: |
| - scoped_refptr<ThreadSafeSender> sender_; |
| + base::WeakPtr<ChildSharedBitmapManager> manager_; |
| std::unique_ptr<base::SharedMemory> shared_memory_holder_; |
| }; |
| @@ -78,9 +82,16 @@ SharedMemoryBitmap::SharedMemoryBitmap(uint8_t* pixels, |
| base::SharedMemory* shared_memory) |
| : SharedBitmap(pixels, id), shared_memory_(shared_memory) {} |
| +// Store the interface pointer info, as the actual methods are called from a |
| +// different thread (the compositor thread). We'll bind the ptr on the first |
| +// call. |
| ChildSharedBitmapManager::ChildSharedBitmapManager( |
| - scoped_refptr<ThreadSafeSender> sender) |
| - : sender_(sender) { |
| + scoped_refptr<ThreadSafeSender> sender, |
| + mojom::SharedMemoryAllocatorPtr shared_memory_allocator) |
| + : sender_(sender), |
| + shared_memory_allocator_ptr_info_( |
| + shared_memory_allocator.PassInterface()), |
| + weak_factory_(this) { |
| } |
| ChildSharedBitmapManager::~ChildSharedBitmapManager() {} |
| @@ -105,25 +116,10 @@ ChildSharedBitmapManager::AllocateSharedMemoryBitmap(const gfx::Size& size) { |
| if (!cc::SharedBitmap::SizeInBytes(size, &memory_size)) |
| return std::unique_ptr<SharedMemoryBitmap>(); |
| cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); |
| - std::unique_ptr<base::SharedMemory> memory; |
| -#if defined(OS_POSIX) |
| - base::SharedMemoryHandle handle; |
| - bool send_success = |
| - sender_->Send(new ChildProcessHostMsg_SyncAllocateSharedBitmap( |
| - memory_size, id, &handle)); |
| - if (!send_success) { |
| - // Callers of this method are not prepared to handle failures during |
| - // shutdown. Exit immediately. This is expected behavior during the Fast |
| - // Shutdown path, so use EXIT_SUCCESS. https://crbug.com/615121. |
| - exit(EXIT_SUCCESS); |
| - } |
| - memory = base::MakeUnique<base::SharedMemory>(handle, false); |
| - if (!memory->Map(memory_size)) |
| - CollectMemoryUsageAndDie(size, memory_size); |
| -#else |
| - bool out_of_memory; |
| - memory = ChildThreadImpl::AllocateSharedMemory(memory_size, sender_.get(), |
| - &out_of_memory); |
| + bool out_of_memory = false; |
| + std::unique_ptr<base::SharedMemory> memory = |
| + ChildThreadImpl::AllocateSharedMemory(memory_size, sender_.get(), |
| + &out_of_memory); |
| if (!memory) { |
| if (out_of_memory) { |
| CollectMemoryUsageAndDie(size, memory_size); |
| @@ -138,11 +134,10 @@ ChildSharedBitmapManager::AllocateSharedMemoryBitmap(const gfx::Size& size) { |
| if (!memory->Map(memory_size)) |
| CollectMemoryUsageAndDie(size, memory_size); |
| - base::SharedMemoryHandle handle_to_send = memory->handle(); |
| - sender_->Send(new ChildProcessHostMsg_AllocatedSharedBitmap( |
| - memory_size, handle_to_send, id)); |
| -#endif |
| - return base::MakeUnique<ChildSharedBitmap>(sender_, std::move(memory), id); |
| + NotifyAllocatedSharedBitmap(memory.get(), id); |
| + |
| + return base::MakeUnique<ChildSharedBitmap>(weak_factory_.GetWeakPtr(), |
| + sender_, std::move(memory), id); |
| } |
| std::unique_ptr<cc::SharedBitmap> |
| @@ -155,15 +150,44 @@ ChildSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size&, |
| std::unique_ptr<cc::SharedBitmap> |
| ChildSharedBitmapManager::GetBitmapForSharedMemory(base::SharedMemory* mem) { |
| cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); |
| - base::SharedMemoryHandle handle_to_send = mem->handle(); |
| + NotifyAllocatedSharedBitmap(mem, cc::SharedBitmap::GenerateId()); |
| + return base::MakeUnique<ChildSharedBitmap>(weak_factory_.GetWeakPtr(), |
| + sender_, std::move(mem), id); |
| +} |
| + |
| +void ChildSharedBitmapManager::OnBitmapDeleted(const cc::SharedBitmapId& id) { |
| + shared_memory_allocator_->DeletedSharedBitmap(id); |
| +} |
| + |
| +void ChildSharedBitmapManager::FinishInitialization() { |
| + if (shared_memory_allocator_.is_bound()) |
| + return; // Already initialized. |
| + |
| + shared_memory_allocator_.Bind(std::move(shared_memory_allocator_ptr_info_)); |
| +} |
| + |
| +// Notifies the browser process that a shared bitmap with the given ID was |
| +// allocated. Caller keeps ownership of |memory|. |
| +void ChildSharedBitmapManager::NotifyAllocatedSharedBitmap( |
| + base::SharedMemory* memory, |
| + const cc::SharedBitmapId& id) { |
| + // If we have not bound our interface, do it now that we are on the correct |
| + // thread. |
| + FinishInitialization(); |
| + |
| + base::SharedMemoryHandle handle_to_send = memory->handle(); |
| #if defined(OS_POSIX) |
| - if (!mem->ShareToProcess(base::GetCurrentProcessHandle(), &handle_to_send)) |
| - return std::unique_ptr<cc::SharedBitmap>(); |
| + if (!memory->ShareToProcess(base::GetCurrentProcessHandle(), &handle_to_send)) |
| + return; |
| #endif |
| - sender_->Send(new ChildProcessHostMsg_AllocatedSharedBitmap( |
| - mem->mapped_size(), handle_to_send, id)); |
| - return base::MakeUnique<ChildSharedBitmap>(sender_, mem, id); |
| + mojo::ScopedSharedBufferHandle buffer_handle = |
| + mojo::WrapSharedMemoryHandle( |
| + base::SharedMemory::DuplicateHandle(handle_to_send), |
| + memory->mapped_size(), |
| + true /* read_only */); |
|
Jay Civelli
2016/11/09 21:47:11
@jbauman Existing code does not share the memory a
|
| + |
| + shared_memory_allocator_->AllocatedSharedBitmap(std::move(buffer_handle), id); |
| } |
| } // namespace content |