Add remoting and PPAPI tests to GN build
[chromium-blink-merge.git] / content / browser / gpu / gpu_process_host_ui_shim.cc
blobabc53985da04bbb28bd926ec13d35fd9f2a4886d
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/callback_helpers.h"
11 #include "base/id_map.h"
12 #include "base/lazy_instance.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/trace_event/trace_event.h"
15 #include "content/browser/compositor/gpu_process_transport_factory.h"
16 #include "content/browser/gpu/compositor_util.h"
17 #include "content/browser/gpu/gpu_data_manager_impl.h"
18 #include "content/browser/gpu/gpu_process_host.h"
19 #include "content/browser/gpu/gpu_surface_tracker.h"
20 #include "content/browser/renderer_host/render_process_host_impl.h"
21 #include "content/browser/renderer_host/render_view_host_impl.h"
22 #include "content/browser/renderer_host/render_widget_helper.h"
23 #include "content/browser/renderer_host/render_widget_host_view_base.h"
24 #include "content/common/gpu/gpu_messages.h"
25 #include "content/public/browser/browser_thread.h"
27 #if defined(OS_MACOSX)
28 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
29 #endif
31 #if defined(USE_OZONE)
32 #include "ui/ozone/public/gpu_platform_support_host.h"
33 #include "ui/ozone/public/ozone_platform.h"
34 #endif
36 namespace content {
38 namespace {
40 // One of the linux specific headers defines this as a macro.
41 #ifdef DestroyAll
42 #undef DestroyAll
43 #endif
45 #if defined(OS_MACOSX)
46 void OnSurfaceDisplayedCallback(int output_surface_id) {
47 content::ImageTransportFactory::GetInstance()->OnSurfaceDisplayed(
48 output_surface_id);
50 #endif
52 base::LazyInstance<IDMap<GpuProcessHostUIShim> > g_hosts_by_id =
53 LAZY_INSTANCE_INITIALIZER;
55 void SendOnIOThreadTask(int host_id, IPC::Message* msg) {
56 GpuProcessHost* host = GpuProcessHost::FromID(host_id);
57 if (host)
58 host->Send(msg);
59 else
60 delete msg;
63 class ScopedSendOnIOThread {
64 public:
65 ScopedSendOnIOThread(int host_id, IPC::Message* msg)
66 : host_id_(host_id),
67 msg_(msg),
68 cancelled_(false) {
71 ~ScopedSendOnIOThread() {
72 if (!cancelled_) {
73 BrowserThread::PostTask(BrowserThread::IO,
74 FROM_HERE,
75 base::Bind(&SendOnIOThreadTask,
76 host_id_,
77 msg_.release()));
81 void Cancel() { cancelled_ = true; }
83 private:
84 int host_id_;
85 scoped_ptr<IPC::Message> msg_;
86 bool cancelled_;
89 RenderWidgetHostViewBase* GetRenderWidgetHostViewFromSurfaceID(
90 int surface_id) {
91 int render_process_id = 0;
92 int render_widget_id = 0;
93 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
94 surface_id, &render_process_id, &render_widget_id))
95 return NULL;
97 RenderWidgetHost* host =
98 RenderWidgetHost::FromID(render_process_id, render_widget_id);
99 return host ? static_cast<RenderWidgetHostViewBase*>(host->GetView()) : NULL;
102 } // namespace
104 void RouteToGpuProcessHostUIShimTask(int host_id, const IPC::Message& msg) {
105 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id);
106 if (ui_shim)
107 ui_shim->OnMessageReceived(msg);
110 GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
111 : host_id_(host_id) {
112 g_hosts_by_id.Pointer()->AddWithID(this, host_id_);
113 #if defined(USE_OZONE)
114 ui::OzonePlatform::GetInstance()
115 ->GetGpuPlatformSupportHost()
116 ->OnChannelEstablished(
117 host_id,
118 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
119 base::Bind(&SendOnIOThreadTask, host_id_));
120 #endif
123 // static
124 GpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
125 DCHECK(!FromID(host_id));
126 return new GpuProcessHostUIShim(host_id);
129 // static
130 void GpuProcessHostUIShim::Destroy(int host_id, const std::string& message) {
131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
133 GpuDataManagerImpl::GetInstance()->AddLogMessage(
134 logging::LOG_ERROR, "GpuProcessHostUIShim",
135 message);
137 #if defined(USE_OZONE)
138 ui::OzonePlatform::GetInstance()
139 ->GetGpuPlatformSupportHost()
140 ->OnChannelDestroyed(host_id);
141 #endif
143 delete FromID(host_id);
146 // static
147 void GpuProcessHostUIShim::DestroyAll() {
148 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
149 while (!g_hosts_by_id.Pointer()->IsEmpty()) {
150 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
151 delete it.GetCurrentValue();
155 // static
156 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
157 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
158 return g_hosts_by_id.Pointer()->Lookup(host_id);
161 // static
162 GpuProcessHostUIShim* GpuProcessHostUIShim::GetOneInstance() {
163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
164 if (g_hosts_by_id.Pointer()->IsEmpty())
165 return NULL;
166 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
167 return it.GetCurrentValue();
170 bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
171 DCHECK(CalledOnValidThread());
172 return BrowserThread::PostTask(BrowserThread::IO,
173 FROM_HERE,
174 base::Bind(&SendOnIOThreadTask,
175 host_id_,
176 msg));
179 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
180 DCHECK(CalledOnValidThread());
182 #if defined(USE_OZONE)
183 if (ui::OzonePlatform::GetInstance()
184 ->GetGpuPlatformSupportHost()
185 ->OnMessageReceived(message))
186 return true;
187 #endif
189 if (message.routing_id() != MSG_ROUTING_CONTROL)
190 return false;
192 return OnControlMessageReceived(message);
195 void GpuProcessHostUIShim::RelinquishGpuResources(
196 const base::Closure& callback) {
197 DCHECK(relinquish_callback_.is_null());
198 relinquish_callback_ = callback;
199 Send(new GpuMsg_RelinquishResources());
202 void GpuProcessHostUIShim::SimulateRemoveAllContext() {
203 Send(new GpuMsg_Clean());
206 void GpuProcessHostUIShim::SimulateCrash() {
207 Send(new GpuMsg_Crash());
210 void GpuProcessHostUIShim::SimulateHang() {
211 Send(new GpuMsg_Hang());
214 GpuProcessHostUIShim::~GpuProcessHostUIShim() {
215 DCHECK(CalledOnValidThread());
216 g_hosts_by_id.Pointer()->Remove(host_id_);
219 bool GpuProcessHostUIShim::OnControlMessageReceived(
220 const IPC::Message& message) {
221 DCHECK(CalledOnValidThread());
223 IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
224 IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
225 OnLogMessage)
226 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceInitialized,
227 OnAcceleratedSurfaceInitialized)
228 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
229 OnAcceleratedSurfaceBuffersSwapped)
230 IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
231 OnGraphicsInfoCollected)
232 IPC_MESSAGE_HANDLER(GpuHostMsg_VideoMemoryUsageStats,
233 OnVideoMemoryUsageStatsReceived);
234 IPC_MESSAGE_HANDLER(GpuHostMsg_ResourcesRelinquished,
235 OnResourcesRelinquished)
236 IPC_MESSAGE_HANDLER(GpuHostMsg_AddSubscription, OnAddSubscription);
237 IPC_MESSAGE_HANDLER(GpuHostMsg_RemoveSubscription, OnRemoveSubscription);
239 IPC_MESSAGE_UNHANDLED_ERROR()
240 IPC_END_MESSAGE_MAP()
242 return true;
245 void GpuProcessHostUIShim::OnLogMessage(
246 int level,
247 const std::string& header,
248 const std::string& message) {
249 GpuDataManagerImpl::GetInstance()->AddLogMessage(
250 level, header, message);
253 void GpuProcessHostUIShim::OnGraphicsInfoCollected(
254 const gpu::GPUInfo& gpu_info) {
255 // OnGraphicsInfoCollected is sent back after the GPU process successfully
256 // initializes GL.
257 TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected");
259 GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
262 void GpuProcessHostUIShim::OnAcceleratedSurfaceInitialized(int32 surface_id,
263 int32 route_id) {
264 RenderWidgetHostViewBase* view =
265 GetRenderWidgetHostViewFromSurfaceID(surface_id);
266 if (!view)
267 return;
268 view->AcceleratedSurfaceInitialized(route_id);
271 void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
272 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
273 #if defined(OS_MACOSX)
274 TRACE_EVENT0("renderer",
275 "GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped");
276 if (!ui::LatencyInfo::Verify(params.latency_info,
277 "GpuHostMsg_AcceleratedSurfaceBuffersSwapped")) {
278 return;
281 // On Mac with delegated rendering, accelerated surfaces are not necessarily
282 // associated with a RenderWidgetHostViewBase.
283 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
284 DCHECK(IsDelegatedRendererEnabled());
286 // If the frame was intended for an NSView that the gfx::AcceleratedWidget is
287 // no longer attached to, do not pass the frame along to the widget. Just ack
288 // it to the GPU process immediately, so we can proceed to the next frame.
289 bool should_not_show_frame =
290 content::ImageTransportFactory::GetInstance()
291 ->SurfaceShouldNotShowFramesAfterRecycle(params.surface_id);
292 if (should_not_show_frame) {
293 OnSurfaceDisplayedCallback(params.surface_id);
294 } else {
295 gfx::AcceleratedWidget native_widget =
296 content::GpuSurfaceTracker::Get()->AcquireNativeWidget(
297 params.surface_id);
298 ui::AcceleratedWidgetMacGotAcceleratedFrame(
299 native_widget, params.surface_handle, params.latency_info, params.size,
300 params.scale_factor,
301 base::Bind(&OnSurfaceDisplayedCallback, params.surface_id),
302 &ack_params.disable_throttling, &ack_params.renderer_id);
304 Send(new AcceleratedSurfaceMsg_BufferPresented(params.route_id, ack_params));
305 #else
306 NOTREACHED();
307 #endif
310 void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived(
311 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
312 GpuDataManagerImpl::GetInstance()->UpdateVideoMemoryUsageStats(
313 video_memory_usage_stats);
316 void GpuProcessHostUIShim::OnResourcesRelinquished() {
317 if (!relinquish_callback_.is_null()) {
318 base::ResetAndReturn(&relinquish_callback_).Run();
322 void GpuProcessHostUIShim::OnAddSubscription(
323 int32 process_id, unsigned int target) {
324 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
325 if (rph) {
326 rph->OnAddSubscription(target);
330 void GpuProcessHostUIShim::OnRemoveSubscription(
331 int32 process_id, unsigned int target) {
332 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
333 if (rph) {
334 rph->OnRemoveSubscription(target);
338 } // namespace content