IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / gpu / gpu_process_host_ui_shim.cc
blobb17bc59faae752ffa98445671ceac7261a81bcdb
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
3 // found in the LICENSE file.
5 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
7 #include <algorithm>
9 #include "base/bind.h"
10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h"
12 #include "base/id_map.h"
13 #include "base/lazy_instance.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "content/browser/gpu/gpu_data_manager_impl.h"
16 #include "content/browser/gpu/gpu_process_host.h"
17 #include "content/browser/gpu/gpu_surface_tracker.h"
18 #include "content/browser/renderer_host/render_process_host_impl.h"
19 #include "content/browser/renderer_host/render_view_host_impl.h"
20 #include "content/common/gpu/gpu_messages.h"
21 #include "content/port/browser/render_widget_host_view_port.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "ui/gl/gl_switches.h"
25 // From gl2/gl2ext.h.
26 #ifndef GL_MAILBOX_SIZE_CHROMIUM
27 #define GL_MAILBOX_SIZE_CHROMIUM 64
28 #endif
30 namespace content {
32 namespace {
34 // One of the linux specific headers defines this as a macro.
35 #ifdef DestroyAll
36 #undef DestroyAll
37 #endif
39 base::LazyInstance<IDMap<GpuProcessHostUIShim> > g_hosts_by_id =
40 LAZY_INSTANCE_INITIALIZER;
42 void SendOnIOThreadTask(int host_id, IPC::Message* msg) {
43 GpuProcessHost* host = GpuProcessHost::FromID(host_id);
44 if (host)
45 host->Send(msg);
46 else
47 delete msg;
50 class ScopedSendOnIOThread {
51 public:
52 ScopedSendOnIOThread(int host_id, IPC::Message* msg)
53 : host_id_(host_id),
54 msg_(msg),
55 cancelled_(false) {
58 ~ScopedSendOnIOThread() {
59 if (!cancelled_) {
60 BrowserThread::PostTask(BrowserThread::IO,
61 FROM_HERE,
62 base::Bind(&SendOnIOThreadTask,
63 host_id_,
64 msg_.release()));
68 void Cancel() { cancelled_ = true; }
70 private:
71 int host_id_;
72 scoped_ptr<IPC::Message> msg_;
73 bool cancelled_;
76 RenderWidgetHostViewPort* GetRenderWidgetHostViewFromSurfaceID(
77 int surface_id) {
78 int render_process_id = 0;
79 int render_widget_id = 0;
80 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
81 surface_id, &render_process_id, &render_widget_id))
82 return NULL;
84 RenderWidgetHost* host =
85 RenderWidgetHost::FromID(render_process_id, render_widget_id);
86 return host ? RenderWidgetHostViewPort::FromRWHV(host->GetView()) : NULL;
89 } // namespace
91 void RouteToGpuProcessHostUIShimTask(int host_id, const IPC::Message& msg) {
92 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id);
93 if (ui_shim)
94 ui_shim->OnMessageReceived(msg);
97 GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
98 : host_id_(host_id) {
99 g_hosts_by_id.Pointer()->AddWithID(this, host_id_);
102 // static
103 GpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
104 DCHECK(!FromID(host_id));
105 return new GpuProcessHostUIShim(host_id);
108 // static
109 void GpuProcessHostUIShim::Destroy(int host_id, const std::string& message) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
112 GpuDataManagerImpl::GetInstance()->AddLogMessage(
113 logging::LOG_ERROR, "GpuProcessHostUIShim",
114 message);
116 delete FromID(host_id);
119 // static
120 void GpuProcessHostUIShim::DestroyAll() {
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
122 while (!g_hosts_by_id.Pointer()->IsEmpty()) {
123 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
124 delete it.GetCurrentValue();
128 // static
129 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
130 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
131 return g_hosts_by_id.Pointer()->Lookup(host_id);
134 // static
135 GpuProcessHostUIShim* GpuProcessHostUIShim::GetOneInstance() {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 if (g_hosts_by_id.Pointer()->IsEmpty())
138 return NULL;
139 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
140 return it.GetCurrentValue();
143 bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
144 DCHECK(CalledOnValidThread());
145 return BrowserThread::PostTask(BrowserThread::IO,
146 FROM_HERE,
147 base::Bind(&SendOnIOThreadTask,
148 host_id_,
149 msg));
152 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
153 DCHECK(CalledOnValidThread());
155 if (message.routing_id() != MSG_ROUTING_CONTROL)
156 return false;
158 return OnControlMessageReceived(message);
161 void GpuProcessHostUIShim::SimulateRemoveAllContext() {
162 Send(new GpuMsg_Clean());
165 void GpuProcessHostUIShim::SimulateCrash() {
166 Send(new GpuMsg_Crash());
169 void GpuProcessHostUIShim::SimulateHang() {
170 Send(new GpuMsg_Hang());
173 GpuProcessHostUIShim::~GpuProcessHostUIShim() {
174 DCHECK(CalledOnValidThread());
175 g_hosts_by_id.Pointer()->Remove(host_id_);
178 bool GpuProcessHostUIShim::OnControlMessageReceived(
179 const IPC::Message& message) {
180 DCHECK(CalledOnValidThread());
182 IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
183 IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
184 OnLogMessage)
186 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceInitialized,
187 OnAcceleratedSurfaceInitialized)
188 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
189 OnAcceleratedSurfaceBuffersSwapped)
190 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfacePostSubBuffer,
191 OnAcceleratedSurfacePostSubBuffer)
192 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSuspend,
193 OnAcceleratedSurfaceSuspend)
194 IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
195 OnGraphicsInfoCollected)
196 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease,
197 OnAcceleratedSurfaceRelease)
198 IPC_MESSAGE_HANDLER(GpuHostMsg_VideoMemoryUsageStats,
199 OnVideoMemoryUsageStatsReceived);
200 IPC_MESSAGE_HANDLER(GpuHostMsg_UpdateVSyncParameters,
201 OnUpdateVSyncParameters)
202 IPC_MESSAGE_HANDLER(GpuHostMsg_FrameDrawn, OnFrameDrawn)
204 IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView)
206 IPC_MESSAGE_UNHANDLED_ERROR()
207 IPC_END_MESSAGE_MAP()
209 return true;
212 void GpuProcessHostUIShim::OnUpdateVSyncParameters(int surface_id,
213 base::TimeTicks timebase,
214 base::TimeDelta interval) {
216 int render_process_id = 0;
217 int render_widget_id = 0;
218 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
219 surface_id, &render_process_id, &render_widget_id)) {
220 return;
222 RenderWidgetHost* rwh =
223 RenderWidgetHost::FromID(render_process_id, render_widget_id);
224 if (!rwh)
225 return;
226 RenderWidgetHostImpl::From(rwh)->UpdateVSyncParameters(timebase, interval);
229 void GpuProcessHostUIShim::OnLogMessage(
230 int level,
231 const std::string& header,
232 const std::string& message) {
233 GpuDataManagerImpl::GetInstance()->AddLogMessage(
234 level, header, message);
237 void GpuProcessHostUIShim::OnGraphicsInfoCollected(
238 const gpu::GPUInfo& gpu_info) {
239 // OnGraphicsInfoCollected is sent back after the GPU process successfully
240 // initializes GL.
241 TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected");
243 GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
246 void GpuProcessHostUIShim::OnResizeView(int32 surface_id,
247 int32 route_id,
248 gfx::Size size) {
249 // Always respond even if the window no longer exists. The GPU process cannot
250 // make progress on the resizing command buffer until it receives the
251 // response.
252 ScopedSendOnIOThread delayed_send(
253 host_id_,
254 new AcceleratedSurfaceMsg_ResizeViewACK(route_id));
256 RenderWidgetHostViewPort* view =
257 GetRenderWidgetHostViewFromSurfaceID(surface_id);
258 if (!view)
259 return;
261 view->ResizeCompositingSurface(size);
264 static base::TimeDelta GetSwapDelay() {
265 CommandLine* cmd_line = CommandLine::ForCurrentProcess();
266 int delay = 0;
267 if (cmd_line->HasSwitch(switches::kGpuSwapDelay)) {
268 base::StringToInt(cmd_line->GetSwitchValueNative(
269 switches::kGpuSwapDelay).c_str(), &delay);
271 return base::TimeDelta::FromMilliseconds(delay);
274 void GpuProcessHostUIShim::OnAcceleratedSurfaceInitialized(int32 surface_id,
275 int32 route_id) {
276 RenderWidgetHostViewPort* view =
277 GetRenderWidgetHostViewFromSurfaceID(surface_id);
278 if (!view)
279 return;
280 view->AcceleratedSurfaceInitialized(host_id_, route_id);
283 void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
284 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
285 TRACE_EVENT0("renderer",
286 "GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped");
287 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
288 ack_params.mailbox_name = params.mailbox_name;
289 ack_params.sync_point = 0;
290 ScopedSendOnIOThread delayed_send(
291 host_id_,
292 new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
293 ack_params));
295 if (!params.mailbox_name.empty() &&
296 params.mailbox_name.length() != GL_MAILBOX_SIZE_CHROMIUM)
297 return;
299 RenderWidgetHostViewPort* view = GetRenderWidgetHostViewFromSurfaceID(
300 params.surface_id);
301 if (!view)
302 return;
304 delayed_send.Cancel();
306 static const base::TimeDelta swap_delay = GetSwapDelay();
307 if (swap_delay.ToInternalValue())
308 base::PlatformThread::Sleep(swap_delay);
310 // View must send ACK message after next composite.
311 view->AcceleratedSurfaceBuffersSwapped(params, host_id_);
312 view->DidReceiveRendererFrame();
315 void GpuProcessHostUIShim::OnFrameDrawn(const ui::LatencyInfo& latency_info) {
316 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
319 void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
320 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) {
321 TRACE_EVENT0("renderer",
322 "GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer");
324 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
325 ack_params.mailbox_name = params.mailbox_name;
326 ack_params.sync_point = 0;
327 ScopedSendOnIOThread delayed_send(
328 host_id_,
329 new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
330 ack_params));
332 if (!params.mailbox_name.empty() &&
333 params.mailbox_name.length() != GL_MAILBOX_SIZE_CHROMIUM)
334 return;
336 RenderWidgetHostViewPort* view =
337 GetRenderWidgetHostViewFromSurfaceID(params.surface_id);
338 if (!view)
339 return;
341 delayed_send.Cancel();
343 // View must send ACK message after next composite.
344 view->AcceleratedSurfacePostSubBuffer(params, host_id_);
345 view->DidReceiveRendererFrame();
348 void GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend(int32 surface_id) {
349 TRACE_EVENT0("renderer",
350 "GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend");
352 RenderWidgetHostViewPort* view =
353 GetRenderWidgetHostViewFromSurfaceID(surface_id);
354 if (!view)
355 return;
357 view->AcceleratedSurfaceSuspend();
360 void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
361 const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
362 RenderWidgetHostViewPort* view = GetRenderWidgetHostViewFromSurfaceID(
363 params.surface_id);
364 if (!view)
365 return;
366 view->AcceleratedSurfaceRelease();
369 void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived(
370 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
371 GpuDataManagerImpl::GetInstance()->UpdateVideoMemoryUsageStats(
372 video_memory_usage_stats);
375 } // namespace content