Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / browser / gpu / gpu_process_host_ui_shim.cc
blob741368f0ff909941b2946307ffd7682c8edbc22b
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/debug/trace_event.h"
11 #include "base/id_map.h"
12 #include "base/lazy_instance.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "content/browser/gpu/compositor_util.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_helper.h"
21 #include "content/browser/renderer_host/render_widget_host_view_base.h"
22 #include "content/common/gpu/gpu_messages.h"
23 #include "content/public/browser/browser_thread.h"
25 #if defined(OS_MACOSX)
26 #include "content/browser/compositor/browser_compositor_view_mac.h"
27 #endif
29 #if defined(USE_OZONE)
30 #include "ui/ozone/public/gpu_platform_support_host.h"
31 #include "ui/ozone/public/ozone_platform.h"
32 #endif
34 namespace content {
36 namespace {
38 // One of the linux specific headers defines this as a macro.
39 #ifdef DestroyAll
40 #undef DestroyAll
41 #endif
43 base::LazyInstance<IDMap<GpuProcessHostUIShim> > g_hosts_by_id =
44 LAZY_INSTANCE_INITIALIZER;
46 void SendOnIOThreadTask(int host_id, IPC::Message* msg) {
47 GpuProcessHost* host = GpuProcessHost::FromID(host_id);
48 if (host)
49 host->Send(msg);
50 else
51 delete msg;
54 class ScopedSendOnIOThread {
55 public:
56 ScopedSendOnIOThread(int host_id, IPC::Message* msg)
57 : host_id_(host_id),
58 msg_(msg),
59 cancelled_(false) {
62 ~ScopedSendOnIOThread() {
63 if (!cancelled_) {
64 BrowserThread::PostTask(BrowserThread::IO,
65 FROM_HERE,
66 base::Bind(&SendOnIOThreadTask,
67 host_id_,
68 msg_.release()));
72 void Cancel() { cancelled_ = true; }
74 private:
75 int host_id_;
76 scoped_ptr<IPC::Message> msg_;
77 bool cancelled_;
80 RenderWidgetHostViewBase* GetRenderWidgetHostViewFromSurfaceID(
81 int surface_id) {
82 int render_process_id = 0;
83 int render_widget_id = 0;
84 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
85 surface_id, &render_process_id, &render_widget_id))
86 return NULL;
88 RenderWidgetHost* host =
89 RenderWidgetHost::FromID(render_process_id, render_widget_id);
90 return host ? static_cast<RenderWidgetHostViewBase*>(host->GetView()) : NULL;
93 } // namespace
95 void RouteToGpuProcessHostUIShimTask(int host_id, const IPC::Message& msg) {
96 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id);
97 if (ui_shim)
98 ui_shim->OnMessageReceived(msg);
101 GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
102 : host_id_(host_id) {
103 g_hosts_by_id.Pointer()->AddWithID(this, host_id_);
104 #if defined(USE_OZONE)
105 ui::OzonePlatform::GetInstance()
106 ->GetGpuPlatformSupportHost()
107 ->OnChannelEstablished(host_id, this);
108 #endif
111 // static
112 GpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
113 DCHECK(!FromID(host_id));
114 return new GpuProcessHostUIShim(host_id);
117 // static
118 void GpuProcessHostUIShim::Destroy(int host_id, const std::string& message) {
119 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
121 GpuDataManagerImpl::GetInstance()->AddLogMessage(
122 logging::LOG_ERROR, "GpuProcessHostUIShim",
123 message);
125 #if defined(USE_OZONE)
126 ui::OzonePlatform::GetInstance()
127 ->GetGpuPlatformSupportHost()
128 ->OnChannelDestroyed(host_id);
129 #endif
131 delete FromID(host_id);
134 // static
135 void GpuProcessHostUIShim::DestroyAll() {
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137 while (!g_hosts_by_id.Pointer()->IsEmpty()) {
138 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
139 delete it.GetCurrentValue();
143 // static
144 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
146 return g_hosts_by_id.Pointer()->Lookup(host_id);
149 // static
150 GpuProcessHostUIShim* GpuProcessHostUIShim::GetOneInstance() {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 if (g_hosts_by_id.Pointer()->IsEmpty())
153 return NULL;
154 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
155 return it.GetCurrentValue();
158 bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
159 DCHECK(CalledOnValidThread());
160 return BrowserThread::PostTask(BrowserThread::IO,
161 FROM_HERE,
162 base::Bind(&SendOnIOThreadTask,
163 host_id_,
164 msg));
167 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
168 DCHECK(CalledOnValidThread());
170 #if defined(USE_OZONE)
171 if (ui::OzonePlatform::GetInstance()
172 ->GetGpuPlatformSupportHost()
173 ->OnMessageReceived(message))
174 return true;
175 #endif
177 if (message.routing_id() != MSG_ROUTING_CONTROL)
178 return false;
180 return OnControlMessageReceived(message);
183 void GpuProcessHostUIShim::SimulateRemoveAllContext() {
184 Send(new GpuMsg_Clean());
187 void GpuProcessHostUIShim::SimulateCrash() {
188 Send(new GpuMsg_Crash());
191 void GpuProcessHostUIShim::SimulateHang() {
192 Send(new GpuMsg_Hang());
195 GpuProcessHostUIShim::~GpuProcessHostUIShim() {
196 DCHECK(CalledOnValidThread());
197 g_hosts_by_id.Pointer()->Remove(host_id_);
200 bool GpuProcessHostUIShim::OnControlMessageReceived(
201 const IPC::Message& message) {
202 DCHECK(CalledOnValidThread());
204 IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
205 IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
206 OnLogMessage)
208 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceInitialized,
209 OnAcceleratedSurfaceInitialized)
210 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
211 OnAcceleratedSurfaceBuffersSwapped)
212 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfacePostSubBuffer,
213 OnAcceleratedSurfacePostSubBuffer)
214 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSuspend,
215 OnAcceleratedSurfaceSuspend)
216 IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
217 OnGraphicsInfoCollected)
218 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceRelease,
219 OnAcceleratedSurfaceRelease)
220 IPC_MESSAGE_HANDLER(GpuHostMsg_VideoMemoryUsageStats,
221 OnVideoMemoryUsageStatsReceived);
222 IPC_MESSAGE_HANDLER(GpuHostMsg_FrameDrawn, OnFrameDrawn)
224 IPC_MESSAGE_UNHANDLED_ERROR()
225 IPC_END_MESSAGE_MAP()
227 return true;
230 void GpuProcessHostUIShim::OnLogMessage(
231 int level,
232 const std::string& header,
233 const std::string& message) {
234 GpuDataManagerImpl::GetInstance()->AddLogMessage(
235 level, header, message);
238 void GpuProcessHostUIShim::OnGraphicsInfoCollected(
239 const gpu::GPUInfo& gpu_info) {
240 // OnGraphicsInfoCollected is sent back after the GPU process successfully
241 // initializes GL.
242 TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected");
244 GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
247 void GpuProcessHostUIShim::OnAcceleratedSurfaceInitialized(int32 surface_id,
248 int32 route_id) {
249 RenderWidgetHostViewBase* view =
250 GetRenderWidgetHostViewFromSurfaceID(surface_id);
251 if (!view)
252 return;
253 view->AcceleratedSurfaceInitialized(host_id_, route_id);
256 void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
257 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
258 TRACE_EVENT0("renderer",
259 "GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped");
260 if (!ui::LatencyInfo::Verify(params.latency_info,
261 "GpuHostMsg_AcceleratedSurfaceBuffersSwapped"))
262 return;
264 #if defined(OS_MACOSX)
265 // On Mac with delegated rendering, accelerated surfaces are not necessarily
266 // associated with a RenderWidgetHostViewBase.
267 if (IsDelegatedRendererEnabled()) {
268 gfx::AcceleratedWidget native_widget =
269 content::GpuSurfaceTracker::Get()->AcquireNativeWidget(
270 params.surface_id);
271 BrowserCompositorViewMac::GotAcceleratedFrame(
272 native_widget, params.surface_handle, params.surface_id,
273 params.latency_info, params.size, params.scale_factor,
274 host_id_, params.route_id);
275 return;
277 #endif
279 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
280 ack_params.mailbox = params.mailbox;
281 ack_params.sync_point = 0;
282 ScopedSendOnIOThread delayed_send(
283 host_id_,
284 new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
285 ack_params));
287 RenderWidgetHostViewBase* view = GetRenderWidgetHostViewFromSurfaceID(
288 params.surface_id);
289 if (!view)
290 return;
292 delayed_send.Cancel();
294 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params view_params = params;
296 RenderWidgetHostImpl* impl =
297 RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
298 for (size_t i = 0; i < view_params.latency_info.size(); i++)
299 impl->AddLatencyInfoComponentIds(&view_params.latency_info[i]);
301 // View must send ACK message after next composite.
302 view->AcceleratedSurfaceBuffersSwapped(view_params, host_id_);
303 view->DidReceiveRendererFrame();
306 void GpuProcessHostUIShim::OnFrameDrawn(
307 const std::vector<ui::LatencyInfo>& latency_info) {
308 if (!ui::LatencyInfo::Verify(latency_info,
309 "GpuProcessHostUIShim::OnFrameDrawn"))
310 return;
311 RenderWidgetHostImpl::CompositorFrameDrawn(latency_info);
314 void GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer(
315 const GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params& params) {
316 TRACE_EVENT0("renderer",
317 "GpuProcessHostUIShim::OnAcceleratedSurfacePostSubBuffer");
318 if (!ui::LatencyInfo::Verify(params.latency_info,
319 "GpuHostMsg_AcceleratedSurfacePostSubBuffer"))
320 return;
321 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
322 ack_params.mailbox = params.mailbox;
323 ack_params.sync_point = 0;
324 ScopedSendOnIOThread delayed_send(
325 host_id_,
326 new AcceleratedSurfaceMsg_BufferPresented(params.route_id,
327 ack_params));
329 RenderWidgetHostViewBase* view =
330 GetRenderWidgetHostViewFromSurfaceID(params.surface_id);
331 if (!view)
332 return;
334 delayed_send.Cancel();
336 GpuHostMsg_AcceleratedSurfacePostSubBuffer_Params view_params = params;
338 RenderWidgetHostImpl* impl =
339 RenderWidgetHostImpl::From(view->GetRenderWidgetHost());
340 for (size_t i = 0; i < view_params.latency_info.size(); i++)
341 impl->AddLatencyInfoComponentIds(&view_params.latency_info[i]);
343 // View must send ACK message after next composite.
344 view->AcceleratedSurfacePostSubBuffer(view_params, host_id_);
345 view->DidReceiveRendererFrame();
348 void GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend(int32 surface_id) {
349 TRACE_EVENT0("renderer",
350 "GpuProcessHostUIShim::OnAcceleratedSurfaceSuspend");
352 RenderWidgetHostViewBase* view =
353 GetRenderWidgetHostViewFromSurfaceID(surface_id);
354 if (!view)
355 return;
357 view->AcceleratedSurfaceSuspend();
360 void GpuProcessHostUIShim::OnAcceleratedSurfaceRelease(
361 const GpuHostMsg_AcceleratedSurfaceRelease_Params& params) {
362 RenderWidgetHostViewBase* 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