| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/render_process_impl.h" | 5 #include "content/renderer/render_process_impl.h" |
| 6 | 6 |
| 7 #include "build/build_config.h" | 7 #include "build/build_config.h" |
| 8 | 8 |
| 9 #if defined(OS_WIN) | 9 #if defined(OS_WIN) |
| 10 #include <windows.h> | 10 #include <windows.h> |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 #include "base/mac/mac_util.h" | 36 #include "base/mac/mac_util.h" |
| 37 #endif | 37 #endif |
| 38 | 38 |
| 39 #if defined(OS_ANDROID) | 39 #if defined(OS_ANDROID) |
| 40 #include "base/android/sys_utils.h" | 40 #include "base/android/sys_utils.h" |
| 41 #endif | 41 #endif |
| 42 | 42 |
| 43 namespace content { | 43 namespace content { |
| 44 | 44 |
| 45 RenderProcessImpl::RenderProcessImpl() | 45 RenderProcessImpl::RenderProcessImpl() |
| 46 : shared_mem_cache_cleaner_( | 46 : enabled_bindings_(0) { |
| 47 FROM_HERE, base::TimeDelta::FromSeconds(5), | |
| 48 this, &RenderProcessImpl::ClearTransportDIBCache), | |
| 49 transport_dib_next_sequence_number_(0), | |
| 50 enabled_bindings_(0) { | |
| 51 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) | |
| 52 shared_mem_cache_[i] = NULL; | |
| 53 | |
| 54 #if defined(OS_WIN) | 47 #if defined(OS_WIN) |
| 55 // HACK: See http://b/issue?id=1024307 for rationale. | 48 // HACK: See http://b/issue?id=1024307 for rationale. |
| 56 if (GetModuleHandle(L"LPK.DLL") == NULL) { | 49 if (GetModuleHandle(L"LPK.DLL") == NULL) { |
| 57 // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works | 50 // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works |
| 58 // when buffering into a EMF buffer for printing. | 51 // when buffering into a EMF buffer for printing. |
| 59 typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs); | 52 typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs); |
| 60 GdiInitializeLanguagePack gdi_init_lpk = | 53 GdiInitializeLanguagePack gdi_init_lpk = |
| 61 reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress( | 54 reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress( |
| 62 GetModuleHandle(L"GDI32.DLL"), | 55 GetModuleHandle(L"GDI32.DLL"), |
| 63 "GdiInitializeLanguagePack")); | 56 "GdiInitializeLanguagePack")); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 89 } | 82 } |
| 90 | 83 |
| 91 RenderProcessImpl::~RenderProcessImpl() { | 84 RenderProcessImpl::~RenderProcessImpl() { |
| 92 #ifndef NDEBUG | 85 #ifndef NDEBUG |
| 93 int count = blink::WebFrame::instanceCount(); | 86 int count = blink::WebFrame::instanceCount(); |
| 94 if (count) | 87 if (count) |
| 95 DLOG(ERROR) << "WebFrame LEAKED " << count << " TIMES"; | 88 DLOG(ERROR) << "WebFrame LEAKED " << count << " TIMES"; |
| 96 #endif | 89 #endif |
| 97 | 90 |
| 98 GetShutDownEvent()->Signal(); | 91 GetShutDownEvent()->Signal(); |
| 99 ClearTransportDIBCache(); | |
| 100 } | 92 } |
| 101 | 93 |
| 102 void RenderProcessImpl::AddBindings(int bindings) { | 94 void RenderProcessImpl::AddBindings(int bindings) { |
| 103 enabled_bindings_ |= bindings; | 95 enabled_bindings_ |= bindings; |
| 104 } | 96 } |
| 105 | 97 |
| 106 int RenderProcessImpl::GetEnabledBindings() const { | 98 int RenderProcessImpl::GetEnabledBindings() const { |
| 107 return enabled_bindings_; | 99 return enabled_bindings_; |
| 108 } | 100 } |
| 109 | 101 |
| 110 // ----------------------------------------------------------------------------- | |
| 111 // Platform specific code for dealing with bitmap transport... | |
| 112 | |
| 113 TransportDIB* RenderProcessImpl::CreateTransportDIB(size_t size) { | |
| 114 #if defined(OS_POSIX) && !defined(OS_ANDROID) | |
| 115 // POSIX creates transport DIBs in the browser, so we need to do a sync IPC to | |
| 116 // get one. The TransportDIB is cached in the browser. | |
| 117 TransportDIB::Handle handle; | |
| 118 IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, true, &handle); | |
| 119 if (!main_thread()->Send(msg)) | |
| 120 return NULL; | |
| 121 if (handle.fd < 0) | |
| 122 return NULL; | |
| 123 return TransportDIB::Map(handle); | |
| 124 #else | |
| 125 // Windows and Android create transport DIBs inside the renderer. | |
| 126 return TransportDIB::Create(size, transport_dib_next_sequence_number_++); | |
| 127 #endif | |
| 128 } | |
| 129 | |
| 130 void RenderProcessImpl::FreeTransportDIB(TransportDIB* dib) { | |
| 131 if (!dib) | |
| 132 return; | |
| 133 | |
| 134 #if defined(OS_POSIX) && !defined(OS_ANDROID) | |
| 135 // On POSIX we need to tell the browser that it can drop a reference to the | |
| 136 // shared memory. | |
| 137 IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id()); | |
| 138 main_thread()->Send(msg); | |
| 139 #endif | |
| 140 | |
| 141 delete dib; | |
| 142 } | |
| 143 | |
| 144 // ----------------------------------------------------------------------------- | |
| 145 | |
| 146 | |
| 147 skia::PlatformCanvas* RenderProcessImpl::GetDrawingCanvas( | |
| 148 TransportDIB** memory, const gfx::Rect& rect) { | |
| 149 int width = rect.width(); | |
| 150 int height = rect.height(); | |
| 151 const size_t stride = skia::PlatformCanvasStrideForWidth(rect.width()); | |
| 152 #if defined(OS_LINUX) || defined(OS_OPENBSD) | |
| 153 const size_t max_size = base::SysInfo::MaxSharedMemorySize(); | |
| 154 #else | |
| 155 const size_t max_size = 0; | |
| 156 #endif | |
| 157 | |
| 158 // If the requested size is too big, reduce the height. Ideally we might like | |
| 159 // to reduce the width as well to make the size reduction more "balanced", but | |
| 160 // it rarely comes up in practice. | |
| 161 if ((max_size != 0) && (height * stride > max_size)) | |
| 162 height = max_size / stride; | |
| 163 | |
| 164 const size_t size = height * stride; | |
| 165 | |
| 166 if (!GetTransportDIBFromCache(memory, size)) { | |
| 167 *memory = CreateTransportDIB(size); | |
| 168 if (!*memory) | |
| 169 return NULL; | |
| 170 } | |
| 171 | |
| 172 return (*memory)->GetPlatformCanvas(width, height); | |
| 173 } | |
| 174 | |
| 175 void RenderProcessImpl::ReleaseTransportDIB(TransportDIB* mem) { | |
| 176 if (PutSharedMemInCache(mem)) { | |
| 177 shared_mem_cache_cleaner_.Reset(); | |
| 178 return; | |
| 179 } | |
| 180 | |
| 181 FreeTransportDIB(mem); | |
| 182 } | |
| 183 | |
| 184 bool RenderProcessImpl::GetTransportDIBFromCache(TransportDIB** mem, | |
| 185 size_t size) { | |
| 186 // look for a cached object that is suitable for the requested size. | |
| 187 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) { | |
| 188 if (shared_mem_cache_[i] && | |
| 189 size <= shared_mem_cache_[i]->size()) { | |
| 190 *mem = shared_mem_cache_[i]; | |
| 191 shared_mem_cache_[i] = NULL; | |
| 192 return true; | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 return false; | |
| 197 } | |
| 198 | |
| 199 int RenderProcessImpl::FindFreeCacheSlot(size_t size) { | |
| 200 // simple algorithm: | |
| 201 // - look for an empty slot to store mem, or | |
| 202 // - if full, then replace smallest entry which is smaller than |size| | |
| 203 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) { | |
| 204 if (shared_mem_cache_[i] == NULL) | |
| 205 return i; | |
| 206 } | |
| 207 | |
| 208 size_t smallest_size = size; | |
| 209 int smallest_index = -1; | |
| 210 | |
| 211 for (size_t i = 1; i < arraysize(shared_mem_cache_); ++i) { | |
| 212 const size_t entry_size = shared_mem_cache_[i]->size(); | |
| 213 if (entry_size < smallest_size) { | |
| 214 smallest_size = entry_size; | |
| 215 smallest_index = i; | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 if (smallest_index != -1) { | |
| 220 FreeTransportDIB(shared_mem_cache_[smallest_index]); | |
| 221 shared_mem_cache_[smallest_index] = NULL; | |
| 222 } | |
| 223 | |
| 224 return smallest_index; | |
| 225 } | |
| 226 | |
| 227 bool RenderProcessImpl::PutSharedMemInCache(TransportDIB* mem) { | |
| 228 const int slot = FindFreeCacheSlot(mem->size()); | |
| 229 if (slot == -1) | |
| 230 return false; | |
| 231 | |
| 232 shared_mem_cache_[slot] = mem; | |
| 233 return true; | |
| 234 } | |
| 235 | |
| 236 void RenderProcessImpl::ClearTransportDIBCache() { | |
| 237 for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) { | |
| 238 if (shared_mem_cache_[i]) { | |
| 239 FreeTransportDIB(shared_mem_cache_[i]); | |
| 240 shared_mem_cache_[i] = NULL; | |
| 241 } | |
| 242 } | |
| 243 } | |
| 244 | |
| 245 } // namespace content | 102 } // namespace content |
| OLD | NEW |