#include "content/common/child_process_host_impl.h"
#include "content/common/gpu/gpu_messages.h"
#include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/render_widget_host_view_frame_subscriber.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
+#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "gpu/command_buffer/service/gpu_switches.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_switches.h"
+#include "ipc/message_filter.h"
#include "ui/events/latency_info.h"
#include "ui/gl/gl_switches.h"
#if defined(OS_WIN)
#include "base/win/windows_version.h"
#include "content/common/sandbox_win.h"
-#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "sandbox/win/src/sandbox_policy.h"
#include "ui/gfx/switches.h"
#endif
-#if defined(OS_CHROMEOS)
-#include "chromeos/chromeos_switches.h"
-#endif
-
#if defined(USE_OZONE)
#include "ui/ozone/ozone_switches.h"
#endif
}
}
-void AcceleratedSurfaceBuffersSwappedCompletedForGPU(
- int host_id,
- int route_id,
- bool alive,
- base::TimeTicks vsync_timebase,
- base::TimeDelta vsync_interval) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForGPU,
- host_id,
- route_id,
- alive,
- vsync_timebase,
- vsync_interval));
- return;
- }
-
- GpuProcessHost* host = GpuProcessHost::FromID(host_id);
- if (host) {
- if (alive) {
- AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
- ack_params.sync_point = 0;
-#if defined(OS_WIN)
- ack_params.vsync_timebase = vsync_timebase;
- ack_params.vsync_interval = vsync_interval;
-#endif
- host->Send(
- new AcceleratedSurfaceMsg_BufferPresented(route_id, ack_params));
- } else {
- host->ForceShutdown();
- }
- }
-}
-
-#if defined(OS_WIN)
-// This sends a ViewMsg_SwapBuffers_ACK directly to the renderer process
-// (RenderWidget).
-void AcceleratedSurfaceBuffersSwappedCompletedForRenderer(
- int surface_id,
- base::TimeTicks timebase,
- base::TimeDelta interval,
- const std::vector<ui::LatencyInfo>& latency_info) {
- if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForRenderer,
- surface_id, timebase, interval, latency_info));
- return;
- }
-
- int render_process_id = 0;
- int render_widget_id = 0;
- if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
- surface_id, &render_process_id, &render_widget_id)) {
- RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
- return;
- }
- RenderWidgetHost* rwh =
- RenderWidgetHost::FromID(render_process_id, render_widget_id);
- if (!rwh)
- return;
- RenderWidgetHostImpl::From(rwh)->AcknowledgeSwapBuffersToRenderer();
- if (interval != base::TimeDelta())
- RenderWidgetHostImpl::From(rwh)->UpdateVSyncParameters(timebase, interval);
- for (size_t i = 0; i < latency_info.size(); i++)
- RenderWidgetHostImpl::From(rwh)->FrameSwapped(latency_info[i]);
- RenderWidgetHostImpl::From(rwh)->DidReceiveRendererFrame();
-}
-
-void AcceleratedSurfaceBuffersSwappedCompleted(
- int host_id,
- int route_id,
- int surface_id,
- bool alive,
- base::TimeTicks timebase,
- base::TimeDelta interval,
- const std::vector<ui::LatencyInfo>& latency_info) {
- AcceleratedSurfaceBuffersSwappedCompletedForGPU(
- host_id, route_id, alive, timebase, interval);
- AcceleratedSurfaceBuffersSwappedCompletedForRenderer(
- surface_id, timebase, interval, latency_info);
-}
-
// NOTE: changes to this class need to be reviewed by the security team.
class GpuSandboxedProcessLauncherDelegate
: public SandboxedProcessLauncherDelegate {
public:
- explicit GpuSandboxedProcessLauncherDelegate(CommandLine* cmd_line)
+ GpuSandboxedProcessLauncherDelegate(CommandLine* cmd_line,
+ ChildProcessHost* host)
+#if defined(OS_WIN)
: cmd_line_(cmd_line) {}
+#elif defined(OS_POSIX)
+ : ipc_fd_(host->TakeClientFileDescriptor()) {}
+#endif
+
virtual ~GpuSandboxedProcessLauncherDelegate() {}
- virtual void ShouldSandbox(bool* in_sandbox) OVERRIDE {
- if (cmd_line_->HasSwitch(switches::kDisableGpuSandbox)) {
- *in_sandbox = false;
+#if defined(OS_WIN)
+ virtual bool ShouldSandbox() OVERRIDE {
+ bool sandbox = !cmd_line_->HasSwitch(switches::kDisableGpuSandbox);
+ if(! sandbox) {
DVLOG(1) << "GPU sandbox is disabled";
}
+ return sandbox;
}
virtual void PreSandbox(bool* disable_default_policy,
}
}
}
+#elif defined(OS_POSIX)
+
+ virtual int GetIpcFd() OVERRIDE {
+ return ipc_fd_;
+ }
+#endif // OS_WIN
private:
+#if defined(OS_WIN)
CommandLine* cmd_line_;
+#elif defined(OS_POSIX)
+ int ipc_fd_;
+#endif // OS_WIN
};
-#endif // defined(OS_WIN)
} // anonymous namespace
// static
bool GpuProcessHost::ValidateHost(GpuProcessHost* host) {
- if (!host)
- return false;
-
// The Gpu process is invalid if it's not using SwiftShader, the card is
// blacklisted, and we can kill it and start over.
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess) ||
return result;
}
-void GpuProcessHost::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
+void GpuProcessHost::AddFilter(IPC::MessageFilter* filter) {
DCHECK(CalledOnValidThread());
process_->GetHost()->AddFilter(filter);
}
IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
OnAcceleratedSurfaceBuffersSwapped)
#endif
-#if defined(OS_WIN)
- IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
- OnAcceleratedSurfaceBuffersSwapped)
- IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfacePostSubBuffer,
- OnAcceleratedSurfacePostSubBuffer)
- IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSuspend,
- OnAcceleratedSurfaceSuspend)
- IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease,
- OnAcceleratedSurfaceRelease)
-#endif
IPC_MESSAGE_HANDLER(GpuHostMsg_DestroyChannel,
OnDestroyChannel)
IPC_MESSAGE_HANDLER(GpuHostMsg_CacheShader,
// If GPU features are already blacklisted, no need to establish the channel.
if (!GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL)) {
+ DVLOG(1) << "GPU blacklisted, refusing to open a GPU channel.";
callback.Run(IPC::ChannelHandle(), gpu::GPUInfo());
return;
}
if (Send(new GpuMsg_EstablishChannel(client_id, share_context))) {
channel_requests_.push(callback);
} else {
+ DVLOG(1) << "Failed to send GpuMsg_EstablishChannel.";
callback.Run(IPC::ChannelHandle(), gpu::GPUInfo());
}
int surface_id,
int client_id,
const GPUCreateCommandBufferConfig& init_params,
+ int route_id,
const CreateCommandBufferCallback& callback) {
TRACE_EVENT0("gpu", "GpuProcessHost::CreateViewCommandBuffer");
if (!compositing_surface.is_null() &&
Send(new GpuMsg_CreateViewCommandBuffer(
- compositing_surface, surface_id, client_id, init_params))) {
+ compositing_surface, surface_id, client_id, init_params, route_id))) {
create_command_buffer_requests_.push(callback);
surface_refs_.insert(std::make_pair(surface_id,
GpuSurfaceTracker::GetInstance()->GetSurfaceRefForSurface(surface_id)));
} else {
- callback.Run(MSG_ROUTING_NONE);
+ callback.Run(false);
}
}
if (!initialized_)
GpuDataManagerImpl::GetInstance()->OnGpuProcessInitFailure();
+ else if (!in_process_)
+ GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
}
void GpuProcessHost::OnChannelEstablished(
GpuDataManagerImpl::GetInstance()->GetGPUInfo());
}
-void GpuProcessHost::OnCommandBufferCreated(const int32 route_id) {
+void GpuProcessHost::OnCommandBufferCreated(bool succeeded) {
TRACE_EVENT0("gpu", "GpuProcessHost::OnCommandBufferCreated");
if (create_command_buffer_requests_.empty())
CreateCommandBufferCallback callback =
create_command_buffer_requests_.front();
create_command_buffer_requests_.pop();
- callback.Run(route_id);
+ callback.Run(succeeded);
}
void GpuProcessHost::OnDestroyCommandBuffer(int32 surface_id) {
return;
}
- base::ScopedClosureRunner scoped_completion_runner(
- base::Bind(&AcceleratedSurfaceBuffersSwappedCompletedForGPU,
- host_id_, params.route_id,
- true /* alive */, base::TimeTicks(), base::TimeDelta()));
+ AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
+ ack_params.sync_point = 0;
int render_process_id = 0;
int render_widget_id = 0;
if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
params.surface_id, &render_process_id, &render_widget_id)) {
+ Send(new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
+ ack_params));
return;
}
RenderWidgetHelper* helper =
RenderWidgetHelper::FromProcessHostID(render_process_id);
- if (!helper)
+ if (!helper) {
+ Send(new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
+ ack_params));
return;
+ }
// Pass the SwapBuffers on to the RenderWidgetHelper to wake up the UI thread
// if the browser is waiting for a new frame. Otherwise the RenderWidgetHelper
// will forward to the RenderWidgetHostView via RenderProcessHostImpl and
// RenderWidgetHostImpl.
- ignore_result(scoped_completion_runner.Release());
-
ViewHostMsg_CompositorSurfaceBuffersSwapped_Params view_params;
view_params.surface_id = params.surface_id;
view_params.surface_handle = params.surface_handle;
}
#endif // OS_MACOSX
-#if defined(OS_WIN)
-void GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped(
- const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
- TRACE_EVENT0("gpu", "GpuProcessHost::OnAcceleratedSurfaceBuffersSwapped");
-
- if (!ui::LatencyInfo::Verify(params.latency_info,
- "GpuHostMsg_AcceleratedSurfaceBuffersSwapped"))
- return;
-
- base::ScopedClosureRunner scoped_completion_runner(
- base::Bind(&AcceleratedSurfaceBuffersSwappedCompleted,
- host_id_, params.route_id, params.surface_id,
- true, base::TimeTicks(), base::TimeDelta(),
- std::vector<ui::LatencyInfo>()));
-
- gfx::GLSurfaceHandle handle =
- GpuSurfaceTracker::Get()->GetSurfaceHandle(params.surface_id);
-
- if (handle.is_null())
- return;
-
- if (handle.transport_type == gfx::TEXTURE_TRANSPORT) {
- TRACE_EVENT1("gpu", "SurfaceIDNotFound_RoutingToUI",
- "surface_id", params.surface_id);
- // This is a content area swap, send it on to the UI thread.
- ignore_result(scoped_completion_runner.Release());
- RouteOnUIThread(GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
- return;
- }
-
- TRACE_EVENT1("gpu",
- "EarlyOut_NativeWindowNotFound",
- "handle",
- handle.handle);
- ignore_result(scoped_completion_runner.Release());
- AcceleratedSurfaceBuffersSwappedCompleted(host_id_,
- params.route_id,
- params.surface_id,
- true,
- base::TimeTicks(),
- base::TimeDelta(),
- params.latency_info);
-}
-
-void GpuProcessHost::OnAcceleratedSurfacePostSubBuffer(
- const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) {
- TRACE_EVENT0("gpu", "GpuProcessHost::OnAcceleratedSurfacePostSubBuffer");
-
- if (!ui::LatencyInfo::Verify(params.latency_info,
- "GpuHostMsg_AcceleratedSurfacePostSubBuffer"))
- return;
-
- NOTIMPLEMENTED();
-}
-
-void GpuProcessHost::OnAcceleratedSurfaceSuspend(int32 surface_id) {
- TRACE_EVENT0("gpu", "GpuProcessHost::OnAcceleratedSurfaceSuspend");
-
- gfx::PluginWindowHandle handle =
- GpuSurfaceTracker::Get()->GetSurfaceHandle(surface_id).handle;
-
- if (!handle) {
-#if defined(USE_AURA)
- RouteOnUIThread(GpuHostMsg_AcceleratedSurfaceSuspend(surface_id));
-#endif
- return;
- }
-}
-
-void GpuProcessHost::OnAcceleratedSurfaceRelease(
- const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
- TRACE_EVENT0("gpu", "GpuProcessHost::OnAcceleratedSurfaceRelease");
-
- gfx::PluginWindowHandle handle =
- GpuSurfaceTracker::Get()->GetSurfaceHandle(params.surface_id).handle;
- if (!handle) {
-#if defined(USE_AURA)
- RouteOnUIThread(GpuHostMsg_AcceleratedSurfaceRelease(params));
- return;
-#endif
- }
-}
-
-#endif // OS_WIN
-
void GpuProcessHost::OnProcessLaunched() {
UMA_HISTOGRAM_TIMES("GPU.GPUProcessLaunchTime",
base::TimeTicks::Now() - init_start_time_);
static const char* const kSwitchNames[] = {
switches::kDisableAcceleratedVideoDecode,
switches::kDisableBreakpad,
- switches::kDisableGLDrawingForTests,
switches::kDisableGpuSandbox,
switches::kDisableGpuWatchdog,
switches::kDisableLogging,
switches::kEnableShareGroupAsyncTextureUpload,
switches::kGpuStartupDialog,
switches::kGpuSandboxAllowSysVShm,
+ switches::kGpuSandboxFailuresFatal,
+ switches::kGpuSandboxStartAfterInitialization,
switches::kLoggingLevel,
switches::kNoSandbox,
switches::kTestGLLib,
#if defined(OS_MACOSX)
switches::kEnableSandboxLogging,
#endif
-#if defined(OS_CHROMEOS)
- chromeos::switches::kGpuSandboxFailuresNonfatal,
-#endif
#if defined(USE_AURA)
switches::kUIPrioritizeInGpuProcess,
#endif
cmd_line->PrependWrapper(gpu_launcher);
process_->Launch(
-#if defined(OS_WIN)
- new GpuSandboxedProcessLauncherDelegate(cmd_line),
- false,
-#elif defined(OS_POSIX)
- false,
- base::EnvironmentMap(),
-#endif
+ new GpuSandboxedProcessLauncherDelegate(cmd_line,
+ process_->GetHost()),
cmd_line);
process_launched_ = true;
CreateCommandBufferCallback callback =
create_command_buffer_requests_.front();
create_command_buffer_requests_.pop();
- callback.Run(MSG_ROUTING_NONE);
+ callback.Run(false);
}
}