| OLD | NEW | 
|---|
|  | (Empty) | 
| 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. |  | 
| 4 |  | 
| 5 #include "content/child/child_shared_bitmap_manager.h" |  | 
| 6 |  | 
| 7 #include <stddef.h> |  | 
| 8 |  | 
| 9 #include <utility> |  | 
| 10 |  | 
| 11 #include "base/debug/alias.h" |  | 
| 12 #include "base/memory/ptr_util.h" |  | 
| 13 #include "base/process/memory.h" |  | 
| 14 #include "base/process/process_metrics.h" |  | 
| 15 #include "build/build_config.h" |  | 
| 16 #include "content/child/child_thread_impl.h" |  | 
| 17 #include "content/common/child_process_messages.h" |  | 
| 18 #include "mojo/public/cpp/system/platform_handle.h" |  | 
| 19 #include "ui/gfx/geometry/size.h" |  | 
| 20 |  | 
| 21 namespace content { |  | 
| 22 |  | 
| 23 namespace { |  | 
| 24 |  | 
| 25 class ChildSharedBitmap : public cc::SharedBitmap { |  | 
| 26  public: |  | 
| 27   ChildSharedBitmap( |  | 
| 28       const scoped_refptr<mojom::ThreadSafeRenderMessageFilterAssociatedPtr>& |  | 
| 29           render_message_filter_ptr, |  | 
| 30       base::SharedMemory* shared_memory, |  | 
| 31       const cc::SharedBitmapId& id) |  | 
| 32       : cc::SharedBitmap(static_cast<uint8_t*>(shared_memory->memory()), id), |  | 
| 33         render_message_filter_ptr_(render_message_filter_ptr) {} |  | 
| 34 |  | 
| 35   ChildSharedBitmap( |  | 
| 36       const scoped_refptr<mojom::ThreadSafeRenderMessageFilterAssociatedPtr>& |  | 
| 37           render_message_filter_ptr, |  | 
| 38       std::unique_ptr<base::SharedMemory> shared_memory_holder, |  | 
| 39       const cc::SharedBitmapId& id) |  | 
| 40       : ChildSharedBitmap(render_message_filter_ptr, |  | 
| 41                           shared_memory_holder.get(), |  | 
| 42                           id) { |  | 
| 43     shared_memory_holder_ = std::move(shared_memory_holder); |  | 
| 44   } |  | 
| 45 |  | 
| 46   ~ChildSharedBitmap() override { |  | 
| 47     (*render_message_filter_ptr_)->DeletedSharedBitmap(id()); |  | 
| 48   } |  | 
| 49 |  | 
| 50  private: |  | 
| 51   scoped_refptr<mojom::ThreadSafeRenderMessageFilterAssociatedPtr> |  | 
| 52       render_message_filter_ptr_; |  | 
| 53   std::unique_ptr<base::SharedMemory> shared_memory_holder_; |  | 
| 54 }; |  | 
| 55 |  | 
| 56 // Collect extra information for debugging bitmap creation failures. |  | 
| 57 void CollectMemoryUsageAndDie(const gfx::Size& size, size_t alloc_size) { |  | 
| 58 #if defined(OS_WIN) |  | 
| 59   int width = size.width(); |  | 
| 60   int height = size.height(); |  | 
| 61   DWORD last_error = GetLastError(); |  | 
| 62 |  | 
| 63   std::unique_ptr<base::ProcessMetrics> metrics( |  | 
| 64       base::ProcessMetrics::CreateProcessMetrics( |  | 
| 65           base::GetCurrentProcessHandle())); |  | 
| 66 |  | 
| 67   size_t private_bytes = 0; |  | 
| 68   size_t shared_bytes = 0; |  | 
| 69   metrics->GetMemoryBytes(&private_bytes, &shared_bytes); |  | 
| 70 |  | 
| 71   base::debug::Alias(&width); |  | 
| 72   base::debug::Alias(&height); |  | 
| 73   base::debug::Alias(&last_error); |  | 
| 74   base::debug::Alias(&private_bytes); |  | 
| 75   base::debug::Alias(&shared_bytes); |  | 
| 76 #endif |  | 
| 77   base::TerminateBecauseOutOfMemory(alloc_size); |  | 
| 78 } |  | 
| 79 |  | 
| 80 }  // namespace |  | 
| 81 |  | 
| 82 ChildSharedBitmapManager::ChildSharedBitmapManager( |  | 
| 83     const scoped_refptr<mojom::ThreadSafeRenderMessageFilterAssociatedPtr>& |  | 
| 84         render_message_filter_ptr) |  | 
| 85     : render_message_filter_ptr_(render_message_filter_ptr) {} |  | 
| 86 |  | 
| 87 ChildSharedBitmapManager::~ChildSharedBitmapManager() {} |  | 
| 88 |  | 
| 89 std::unique_ptr<cc::SharedBitmap> |  | 
| 90 ChildSharedBitmapManager::AllocateSharedBitmap(const gfx::Size& size) { |  | 
| 91   TRACE_EVENT2("renderer", "ChildSharedBitmapManager::AllocateSharedBitmap", |  | 
| 92                "width", size.width(), "height", size.height()); |  | 
| 93   size_t memory_size; |  | 
| 94   if (!cc::SharedBitmap::SizeInBytes(size, &memory_size)) |  | 
| 95     return nullptr; |  | 
| 96   cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); |  | 
| 97   std::unique_ptr<base::SharedMemory> memory = |  | 
| 98       ChildThreadImpl::AllocateSharedMemory(memory_size); |  | 
| 99   if (!memory || !memory->Map(memory_size)) |  | 
| 100     CollectMemoryUsageAndDie(size, memory_size); |  | 
| 101 |  | 
| 102   NotifyAllocatedSharedBitmap(memory.get(), id); |  | 
| 103 |  | 
| 104   // Close the associated FD to save resources, the previously mapped memory |  | 
| 105   // remains available. |  | 
| 106   memory->Close(); |  | 
| 107 |  | 
| 108   return base::MakeUnique<ChildSharedBitmap>(render_message_filter_ptr_, |  | 
| 109                                              std::move(memory), id); |  | 
| 110 } |  | 
| 111 |  | 
| 112 std::unique_ptr<cc::SharedBitmap> |  | 
| 113 ChildSharedBitmapManager::GetSharedBitmapFromId(const gfx::Size&, |  | 
| 114                                                 const cc::SharedBitmapId&) { |  | 
| 115   NOTREACHED(); |  | 
| 116   return nullptr; |  | 
| 117 } |  | 
| 118 |  | 
| 119 std::unique_ptr<cc::SharedBitmap> |  | 
| 120 ChildSharedBitmapManager::GetBitmapForSharedMemory(base::SharedMemory* mem) { |  | 
| 121   cc::SharedBitmapId id = cc::SharedBitmap::GenerateId(); |  | 
| 122   NotifyAllocatedSharedBitmap(mem, cc::SharedBitmap::GenerateId()); |  | 
| 123   return base::MakeUnique<ChildSharedBitmap>(render_message_filter_ptr_, |  | 
| 124                                              std::move(mem), id); |  | 
| 125 } |  | 
| 126 |  | 
| 127 // Notifies the browser process that a shared bitmap with the given ID was |  | 
| 128 // allocated. Caller keeps ownership of |memory|. |  | 
| 129 void ChildSharedBitmapManager::NotifyAllocatedSharedBitmap( |  | 
| 130     base::SharedMemory* memory, |  | 
| 131     const cc::SharedBitmapId& id) { |  | 
| 132   base::SharedMemoryHandle handle_to_send = |  | 
| 133       base::SharedMemory::DuplicateHandle(memory->handle()); |  | 
| 134   if (!base::SharedMemory::IsHandleValid(handle_to_send)) { |  | 
| 135     LOG(ERROR) << "Failed to duplicate shared memory handle for bitmap."; |  | 
| 136     return; |  | 
| 137   } |  | 
| 138 |  | 
| 139   mojo::ScopedSharedBufferHandle buffer_handle = mojo::WrapSharedMemoryHandle( |  | 
| 140       handle_to_send, memory->mapped_size(), true /* read_only */); |  | 
| 141 |  | 
| 142   (*render_message_filter_ptr_) |  | 
| 143       ->AllocatedSharedBitmap(std::move(buffer_handle), id); |  | 
| 144 } |  | 
| 145 |  | 
| 146 }  // namespace content |  | 
| OLD | NEW | 
|---|