Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / gpu / gpu_process_host_ui_shim.cc
blob0ef8439fb0cf3625b2036a30bdb2f4c3295a365a
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/browser/renderer_host/render_widget_host_view_base.h"
21 #include "content/common/gpu/gpu_messages.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "ui/gl/gl_switches.h"
25 namespace content {
27 namespace {
29 // One of the linux specific headers defines this as a macro.
30 #ifdef DestroyAll
31 #undef DestroyAll
32 #endif
34 base::LazyInstance<IDMap<GpuProcessHostUIShim> > g_hosts_by_id =
35 LAZY_INSTANCE_INITIALIZER;
37 void SendOnIOThreadTask(int host_id, IPC::Message* msg) {
38 GpuProcessHost* host = GpuProcessHost::FromID(host_id);
39 if (host)
40 host->Send(msg);
41 else
42 delete msg;
45 class ScopedSendOnIOThread {
46 public:
47 ScopedSendOnIOThread(int host_id, IPC::Message* msg)
48 : host_id_(host_id),
49 msg_(msg),
50 cancelled_(false) {
53 ~ScopedSendOnIOThread() {
54 if (!cancelled_) {
55 BrowserThread::PostTask(BrowserThread::IO,
56 FROM_HERE,
57 base::Bind(&SendOnIOThreadTask,
58 host_id_,
59 msg_.release()));
63 void Cancel() { cancelled_ = true; }
65 private:
66 int host_id_;
67 scoped_ptr<IPC::Message> msg_;
68 bool cancelled_;
71 RenderWidgetHostViewBase* GetRenderWidgetHostViewFromSurfaceID(
72 int surface_id) {
73 int render_process_id = 0;
74 int render_widget_id = 0;
75 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
76 surface_id, &render_process_id, &render_widget_id))
77 return NULL;
79 RenderWidgetHost* host =
80 RenderWidgetHost::FromID(render_process_id, render_widget_id);
81 return host ? static_cast<RenderWidgetHostViewBase*>(host->GetView()) : NULL;
84 } // namespace
86 void RouteToGpuProcessHostUIShimTask(int host_id, const IPC::Message& msg) {
87 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id);
88 if (ui_shim)
89 ui_shim->OnMessageReceived(msg);
92 GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
93 : host_id_(host_id) {
94 g_hosts_by_id.Pointer()->AddWithID(this, host_id_);
97 // static
98 GpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
99 DCHECK(!FromID(host_id));
100 return new GpuProcessHostUIShim(host_id);
103 // static
104 void GpuProcessHostUIShim::Destroy(int host_id, const std::string& message) {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
107 GpuDataManagerImpl::GetInstance()->AddLogMessage(
108 logging::LOG_ERROR, "GpuProcessHostUIShim",
109 message);
111 delete FromID(host_id);
114 // static
115 void GpuProcessHostUIShim::DestroyAll() {
116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
117 while (!g_hosts_by_id.Pointer()->IsEmpty()) {
118 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
119 delete it.GetCurrentValue();
123 // static
124 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126 return g_hosts_by_id.Pointer()->Lookup(host_id);
129 // static
130 GpuProcessHostUIShim* GpuProcessHostUIShim::GetOneInstance() {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
132 if (g_hosts_by_id.Pointer()->IsEmpty())
133 return NULL;
134 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
135 return it.GetCurrentValue();
138 bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
139 DCHECK(CalledOnValidThread());
140 return BrowserThread::PostTask(BrowserThread::IO,
141 FROM_HERE,
142 base::Bind(&SendOnIOThreadTask,
143 host_id_,
144 msg));
147 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
148 DCHECK(CalledOnValidThread());
150 if (message.routing_id() != MSG_ROUTING_CONTROL)
151 return false;
153 return OnControlMessageReceived(message);
156 void GpuProcessHostUIShim::SimulateRemoveAllContext() {
157 Send(new GpuMsg_Clean());
160 void GpuProcessHostUIShim::SimulateCrash() {
161 Send(new GpuMsg_Crash());
164 void GpuProcessHostUIShim::SimulateHang() {
165 Send(new GpuMsg_Hang());
168 GpuProcessHostUIShim::~GpuProcessHostUIShim() {
169 DCHECK(CalledOnValidThread());
170 g_hosts_by_id.Pointer()->Remove(host_id_);
173 bool GpuProcessHostUIShim::OnControlMessageReceived(
174 const IPC::Message& message) {
175 DCHECK(CalledOnValidThread());
177 IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
178 IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
179 OnLogMessage)
181 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceInitialized,
182 OnAcceleratedSurfaceInitialized)
183 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
184 OnAcceleratedSurfaceBuffersSwapped)
185 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfacePostSubBuffer,
186 OnAcceleratedSurfacePostSubBuffer)
187 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSuspend,
188 OnAcceleratedSurfaceSuspend)
189 IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
190 OnGraphicsInfoCollected)
191 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease,
192 OnAcceleratedSurfaceRelease)
193 IPC_MESSAGE_HANDLER(GpuHostMsg_VideoMemoryUsageStats,
194 OnVideoMemoryUsageStatsReceived);
195 IPC_MESSAGE_HANDLER(GpuHostMsg_UpdateVSyncParameters,
196 OnUpdateVSyncParameters)
197 IPC_MESSAGE_HANDLER(GpuHostMsg_FrameDrawn, OnFrameDrawn)
199 IPC_MESSAGE_UNHANDLED_ERROR()
200 IPC_END_MESSAGE_MAP()
202 return true;
205 void GpuProcessHostUIShim::OnUpdateVSyncParameters(int surface_id,
206 base::TimeTicks timebase,
207 base::TimeDelta interval) {
209 int render_process_id = 0;
210 int render_widget_id = 0;
211 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
212 surface_id, &render_process_id, &render_widget_id)) {
213 return;
215 RenderWidgetHost* rwh =
216 RenderWidgetHost::FromID(render_process_id, render_widget_id);
217 if (!rwh)
218 return;
219 RenderWidgetHostImpl::From(rwh)->UpdateVSyncParameters(timebase, interval);
222 void GpuProcessHostUIShim::OnLogMessage(
223 int level,
224 const std::string& header,
225 const std::string& message) {
226 GpuDataManagerImpl::GetInstance()->AddLogMessage(
227 level, header, message);
230 void GpuProcessHostUIShim::OnGraphicsInfoCollected(
231 const gpu::GPUInfo& gpu_info) {
232 // OnGraphicsInfoCollected is sent back after the GPU process successfully
233 // initializes GL.
234 TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected");
236 GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
239 void GpuProcessHostUIShim::OnAcceleratedSurfaceInitialized(int32 surface_id,
240 int32 route_id) {
241 RenderWidgetHostViewBase* view =
242 GetRenderWidgetHostViewFromSurfaceID(surface_id);
243 if (!view)
244 return;
245 view->AcceleratedSurfaceInitialized(host_id_, route_id);
248 void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
249 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
250 TRACE_EVENT0("renderer",
251 "GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped");
252 if (!ui::LatencyInfo::Verify(params.latency_info,
253 "GpuHostMsg_AcceleratedSurfaceBuffersSwapped"))
254 return;
255 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
256 ack_params.mailbox = params.mailbox;
257 ack_params.sync_point = 0;
258 ScopedSendOnIOThread delayed_send(
259 host_id_,
260 new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
261 ack_params));
263 RenderWidgetHostViewBase* view = GetRenderWidgetHostViewFromSurfaceID(
264 params.surface_id);
265 if (!view)
266 return;
268 delayed_send.Cancel();
270 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params view_params = params;
272 RenderWidgetHostImpl* impl =
273 RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
274 for (size_t i = 0; i < view_params.latency_info.size(); i++)
275 impl->AddLatencyInfoComponentIds(&view_params.latency_info[i]);
277 // View must send ACK message after next composite.
278 view->AcceleratedSurfaceBuffersSwapped(view_params, host_id_);
279 view->DidReceiveRendererFrame();
282 void GpuProcessHostUIShim::OnFrameDrawn(
283 const std::vector<ui::LatencyInfo>& latency_info) {
284 if (!ui::LatencyInfo::Verify(latency_info,
285 "GpuProcessHostUIShim::OnFrameDrawn"))
286 return;
287 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
290 void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
291 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) {
292 TRACE_EVENT0("renderer",
293 "GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer");
294 if (!ui::LatencyInfo::Verify(params.latency_info,
295 "GpuHostMsg_AcceleratedSurfacePostSubBuffer"))
296 return;
297 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
298 ack_params.mailbox = params.mailbox;
299 ack_params.sync_point = 0;
300 ScopedSendOnIOThread delayed_send(
301 host_id_,
302 new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
303 ack_params));
305 RenderWidgetHostViewBase* view =
306 GetRenderWidgetHostViewFromSurfaceID(params.surface_id);
307 if (!view)
308 return;
310 delayed_send.Cancel();
312 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params view_params = params;
314 RenderWidgetHostImpl* impl =
315 RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
316 for (size_t i = 0; i < view_params.latency_info.size(); i++)
317 impl->AddLatencyInfoComponentIds(&view_params.latency_info[i]);
319 // View must send ACK message after next composite.
320 view->AcceleratedSurfacePostSubBuffer(view_params, host_id_);
321 view->DidReceiveRendererFrame();
324 void GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend(int32 surface_id) {
325 TRACE_EVENT0("renderer",
326 "GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend");
328 RenderWidgetHostViewBase* view =
329 GetRenderWidgetHostViewFromSurfaceID(surface_id);
330 if (!view)
331 return;
333 view->AcceleratedSurfaceSuspend();
336 void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
337 const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
338 RenderWidgetHostViewBase* view = GetRenderWidgetHostViewFromSurfaceID(
339 params.surface_id);
340 if (!view)
341 return;
342 view->AcceleratedSurfaceRelease();
345 void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived(
346 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
347 GpuDataManagerImpl::GetInstance()->UpdateVideoMemoryUsageStats(
348 video_memory_usage_stats);
351 } // namespace content