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 |