15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_process_impl.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <objidl.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mlang.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
189ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/sys_info.h"
21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/child/child_thread.h"
22ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/plugin_instance.h"
23ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/child/npapi/plugin_lib.h"
2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/child/site_isolation_policy.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/content_renderer_client.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_channel.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message_utils.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
31bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "third_party/WebKit/public/web/WebFrame.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/surface/transport_dib.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/glue/webkit_glue.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/mac/mac_util.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_ANDROID)
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/android/sys_utils.h"
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderProcessImpl::RenderProcessImpl()
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : shared_mem_cache_cleaner_(
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          FROM_HERE, base::TimeDelta::FromSeconds(5),
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          this, &RenderProcessImpl::ClearTransportDIBCache),
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      transport_dib_next_sequence_number_(0),
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      enabled_bindings_(0) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  in_process_plugins_ = InProcessPlugins();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_mem_cache_[i] = NULL;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // HACK:  See http://b/issue?id=1024307 for rationale.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetModuleHandle(L"LPK.DLL") == NULL) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // when buffering into a EMF buffer for printing.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GdiInitializeLanguagePack gdi_init_lpk =
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            GetModuleHandle(L"GDI32.DLL"),
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "GdiInitializeLanguagePack"));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(gdi_init_lpk);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (gdi_init_lpk) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdi_init_lpk(0);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Out of process dev tools rely upon auto break behavior.
73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  webkit_glue::SetJavaScriptFlags("--debugger-auto-break");
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_ANDROID)
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (base::android::SysUtils::IsLowEndDevice())
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    webkit_glue::SetJavaScriptFlags("--optimize-for-size");
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kJavaScriptFlags)) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    webkit_glue::SetJavaScriptFlags(
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line.GetSwitchValueASCII(switches::kJavaScriptFlags));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
8658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Turn on cross-site document blocking for renderer processes.
8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  SiteIsolationPolicy::SetPolicyEnabled(
8858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      GetContentClient()->renderer()->ShouldEnableSiteIsolationPolicy());
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)RenderProcessImpl::~RenderProcessImpl() {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int count = blink::WebFrame::instanceCount();
94bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch  if (count)
95bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch    DLOG(ERROR) << "WebFrame LEAKED " << count << " TIMES";
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetShutDownEvent()->Signal();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearTransportDIBCache();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderProcessImpl::InProcessPlugins() {
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_OPENBSD)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Plugin processes require a UI message loop, and the Linux message loop
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implementation only allows one UI loop per process.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line.HasSwitch(switches::kInProcessPlugins))
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NOTIMPLEMENTED() << ": in process plugins not supported on Linux";
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command_line.HasSwitch(switches::kInProcessPlugins);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return command_line.HasSwitch(switches::kInProcessPlugins) ||
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         command_line.HasSwitch(switches::kSingleProcess);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderProcessImpl::AddBindings(int bindings) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enabled_bindings_ |= bindings;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RenderProcessImpl::GetEnabledBindings() const {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return enabled_bindings_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Platform specific code for dealing with bitmap transport...
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TransportDIB* RenderProcessImpl::CreateTransportDIB(size_t size) {
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // POSIX creates transport DIBs in the browser, so we need to do a sync IPC to
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // get one.  The TransportDIB is cached in the browser.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TransportDIB::Handle handle;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Message* msg = new ViewHostMsg_AllocTransportDIB(size, true, &handle);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!main_thread()->Send(msg))
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (handle.fd < 0)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TransportDIB::Map(handle);
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Windows, legacy GTK and Android create transport DIBs inside the
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // renderer.
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return TransportDIB::Create(size, transport_dib_next_sequence_number_++);
14290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderProcessImpl::FreeTransportDIB(TransportDIB* dib) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dib)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_POSIX) && !defined(TOOLKIT_GTK) && !defined(OS_ANDROID)
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // On POSIX we need to tell the browser that it can drop a reference to the
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shared memory.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Message* msg = new ViewHostMsg_FreeTransportDIB(dib->id());
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  main_thread()->Send(msg);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete dib;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -----------------------------------------------------------------------------
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skia::PlatformCanvas* RenderProcessImpl::GetDrawingCanvas(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TransportDIB** memory, const gfx::Rect& rect) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int width = rect.width();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = rect.height();
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t stride = skia::PlatformCanvasStrideForWidth(rect.width());
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_OPENBSD)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t max_size = base::SysInfo::MaxSharedMemorySize();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t max_size = 0;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the requested size is too big, reduce the height. Ideally we might like
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to reduce the width as well to make the size reduction more "balanced", but
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it rarely comes up in practice.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((max_size != 0) && (height * stride > max_size))
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    height = max_size / stride;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t size = height * stride;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetTransportDIBFromCache(memory, size)) {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *memory = CreateTransportDIB(size);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!*memory)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return NULL;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (*memory)->GetPlatformCanvas(width, height);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderProcessImpl::ReleaseTransportDIB(TransportDIB* mem) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PutSharedMemInCache(mem)) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_mem_cache_cleaner_.Reset();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FreeTransportDIB(mem);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderProcessImpl::UseInProcessPlugins() const {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return in_process_plugins_;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderProcessImpl::GetTransportDIBFromCache(TransportDIB** mem,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             size_t size) {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // look for a cached object that is suitable for the requested size.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shared_mem_cache_[i] &&
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        size <= shared_mem_cache_[i]->size()) {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *mem = shared_mem_cache_[i];
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shared_mem_cache_[i] = NULL;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int RenderProcessImpl::FindFreeCacheSlot(size_t size) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // simple algorithm:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - look for an empty slot to store mem, or
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - if full, then replace smallest entry which is smaller than |size|
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shared_mem_cache_[i] == NULL)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return i;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t smallest_size = size;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int smallest_index = -1;
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 1; i < arraysize(shared_mem_cache_); ++i) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const size_t entry_size = shared_mem_cache_[i]->size();
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (entry_size < smallest_size) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      smallest_size = entry_size;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      smallest_index = i;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (smallest_index != -1) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FreeTransportDIB(shared_mem_cache_[smallest_index]);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shared_mem_cache_[smallest_index] = NULL;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return smallest_index;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RenderProcessImpl::PutSharedMemInCache(TransportDIB* mem) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int slot = FindFreeCacheSlot(mem->size());
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slot == -1)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shared_mem_cache_[slot] = mem;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RenderProcessImpl::ClearTransportDIBCache() {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(shared_mem_cache_); ++i) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shared_mem_cache_[i]) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FreeTransportDIB(shared_mem_cache_[i]);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shared_mem_cache_[i] = NULL;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
265