Make USB permissions work in the new permission message system
[chromium-blink-merge.git] / content / browser / gpu / gpu_process_host_ui_shim.cc
blobad1f64724334affa0579a561471bb0047e71a906
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 void StopGpuProcessOnIO(int host_id) {
64 GpuProcessHost* host = GpuProcessHost::FromID(host_id);
65 if (host)
66 host->StopGpuProcess();
69 class ScopedSendOnIOThread {
70 public:
71 ScopedSendOnIOThread(int host_id, IPC::Message* msg)
72 : host_id_(host_id),
73 msg_(msg),
74 cancelled_(false) {
77 ~ScopedSendOnIOThread() {
78 if (!cancelled_) {
79 BrowserThread::PostTask(BrowserThread::IO,
80 FROM_HERE,
81 base::Bind(&SendOnIOThreadTask,
82 host_id_,
83 msg_.release()));
87 void Cancel() { cancelled_ = true; }
89 private:
90 int host_id_;
91 scoped_ptr<IPC::Message> msg_;
92 bool cancelled_;
95 RenderWidgetHostViewBase* GetRenderWidgetHostViewFromSurfaceID(
96 int surface_id) {
97 int render_process_id = 0;
98 int render_widget_id = 0;
99 if (!GpuSurfaceTracker::Get()->GetRenderWidgetIDForSurface(
100 surface_id, &render_process_id, &render_widget_id))
101 return NULL;
103 RenderWidgetHost* host =
104 RenderWidgetHost::FromID(render_process_id, render_widget_id);
105 return host ? static_cast<RenderWidgetHostViewBase*>(host->GetView()) : NULL;
108 } // namespace
110 void RouteToGpuProcessHostUIShimTask(int host_id, const IPC::Message& msg) {
111 GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id);
112 if (ui_shim)
113 ui_shim->OnMessageReceived(msg);
116 GpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
117 : host_id_(host_id) {
118 g_hosts_by_id.Pointer()->AddWithID(this, host_id_);
119 #if defined(USE_OZONE)
120 ui::OzonePlatform::GetInstance()
121 ->GetGpuPlatformSupportHost()
122 ->OnChannelEstablished(
123 host_id,
124 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
125 base::Bind(&SendOnIOThreadTask, host_id_));
126 #endif
129 // static
130 GpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
131 DCHECK(!FromID(host_id));
132 return new GpuProcessHostUIShim(host_id);
135 // static
136 void GpuProcessHostUIShim::Destroy(int host_id, const std::string& message) {
137 DCHECK_CURRENTLY_ON(BrowserThread::UI);
139 GpuDataManagerImpl::GetInstance()->AddLogMessage(
140 logging::LOG_ERROR, "GpuProcessHostUIShim",
141 message);
143 #if defined(USE_OZONE)
144 ui::OzonePlatform::GetInstance()
145 ->GetGpuPlatformSupportHost()
146 ->OnChannelDestroyed(host_id);
147 #endif
149 delete FromID(host_id);
152 // static
153 void GpuProcessHostUIShim::DestroyAll() {
154 DCHECK_CURRENTLY_ON(BrowserThread::UI);
155 while (!g_hosts_by_id.Pointer()->IsEmpty()) {
156 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
157 delete it.GetCurrentValue();
161 // static
162 GpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
163 DCHECK_CURRENTLY_ON(BrowserThread::UI);
164 return g_hosts_by_id.Pointer()->Lookup(host_id);
167 // static
168 GpuProcessHostUIShim* GpuProcessHostUIShim::GetOneInstance() {
169 DCHECK_CURRENTLY_ON(BrowserThread::UI);
170 if (g_hosts_by_id.Pointer()->IsEmpty())
171 return NULL;
172 IDMap<GpuProcessHostUIShim>::iterator it(g_hosts_by_id.Pointer());
173 return it.GetCurrentValue();
176 bool GpuProcessHostUIShim::Send(IPC::Message* msg) {
177 DCHECK(CalledOnValidThread());
178 return BrowserThread::PostTask(BrowserThread::IO,
179 FROM_HERE,
180 base::Bind(&SendOnIOThreadTask,
181 host_id_,
182 msg));
185 bool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
186 DCHECK(CalledOnValidThread());
188 #if defined(USE_OZONE)
189 if (ui::OzonePlatform::GetInstance()
190 ->GetGpuPlatformSupportHost()
191 ->OnMessageReceived(message))
192 return true;
193 #endif
195 if (message.routing_id() != MSG_ROUTING_CONTROL)
196 return false;
198 return OnControlMessageReceived(message);
201 void GpuProcessHostUIShim::StopGpuProcess(const base::Closure& callback) {
202 close_callback_ = callback;
204 BrowserThread::PostTask(
205 BrowserThread::IO, FROM_HERE, base::Bind(&StopGpuProcessOnIO, host_id_));
208 void GpuProcessHostUIShim::SimulateRemoveAllContext() {
209 Send(new GpuMsg_Clean());
212 void GpuProcessHostUIShim::SimulateCrash() {
213 Send(new GpuMsg_Crash());
216 void GpuProcessHostUIShim::SimulateHang() {
217 Send(new GpuMsg_Hang());
220 GpuProcessHostUIShim::~GpuProcessHostUIShim() {
221 DCHECK(CalledOnValidThread());
222 if (!close_callback_.is_null())
223 base::ResetAndReturn(&close_callback_).Run();
224 g_hosts_by_id.Pointer()->Remove(host_id_);
227 bool GpuProcessHostUIShim::OnControlMessageReceived(
228 const IPC::Message& message) {
229 DCHECK(CalledOnValidThread());
231 IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
232 IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
233 OnLogMessage)
234 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceInitialized,
235 OnAcceleratedSurfaceInitialized)
236 #if defined(OS_MACOSX)
237 IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
238 OnAcceleratedSurfaceBuffersSwapped)
239 #endif
240 IPC_MESSAGE_HANDLER(GpuHostMsg_GraphicsInfoCollected,
241 OnGraphicsInfoCollected)
242 IPC_MESSAGE_HANDLER(GpuHostMsg_VideoMemoryUsageStats,
243 OnVideoMemoryUsageStatsReceived);
244 IPC_MESSAGE_HANDLER(GpuHostMsg_AddSubscription, OnAddSubscription);
245 IPC_MESSAGE_HANDLER(GpuHostMsg_RemoveSubscription, OnRemoveSubscription);
247 IPC_MESSAGE_UNHANDLED_ERROR()
248 IPC_END_MESSAGE_MAP()
250 return true;
253 void GpuProcessHostUIShim::OnLogMessage(
254 int level,
255 const std::string& header,
256 const std::string& message) {
257 GpuDataManagerImpl::GetInstance()->AddLogMessage(
258 level, header, message);
261 void GpuProcessHostUIShim::OnGraphicsInfoCollected(
262 const gpu::GPUInfo& gpu_info) {
263 // OnGraphicsInfoCollected is sent back after the GPU process successfully
264 // initializes GL.
265 TRACE_EVENT0("test_gpu", "OnGraphicsInfoCollected");
267 GpuDataManagerImpl::GetInstance()->UpdateGpuInfo(gpu_info);
270 void GpuProcessHostUIShim::OnAcceleratedSurfaceInitialized(int32 surface_id,
271 int32 route_id) {
272 RenderWidgetHostViewBase* view =
273 GetRenderWidgetHostViewFromSurfaceID(surface_id);
274 if (!view)
275 return;
276 view->AcceleratedSurfaceInitialized(route_id);
279 #if defined(OS_MACOSX)
280 void GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
281 const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
282 TRACE_EVENT0("renderer",
283 "GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped");
284 if (!ui::LatencyInfo::Verify(params.latency_info,
285 "GpuHostMsg_AcceleratedSurfaceBuffersSwapped")) {
286 return;
289 // On Mac with delegated rendering, accelerated surfaces are not necessarily
290 // associated with a RenderWidgetHostViewBase.
291 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
292 DCHECK(IsDelegatedRendererEnabled());
294 // If the frame was intended for an NSView that the gfx::AcceleratedWidget is
295 // no longer attached to, do not pass the frame along to the widget. Just ack
296 // it to the GPU process immediately, so we can proceed to the next frame.
297 bool should_not_show_frame =
298 content::ImageTransportFactory::GetInstance()
299 ->SurfaceShouldNotShowFramesAfterSuspendForRecycle(params.surface_id);
300 if (should_not_show_frame) {
301 OnSurfaceDisplayedCallback(params.surface_id);
302 } else {
303 gfx::AcceleratedWidget native_widget =
304 content::GpuSurfaceTracker::Get()->AcquireNativeWidget(
305 params.surface_id);
306 ui::AcceleratedWidgetMacGotAcceleratedFrame(
307 native_widget, params.surface_handle, params.latency_info, params.size,
308 params.scale_factor,
309 params.damage_rect,
310 base::Bind(&OnSurfaceDisplayedCallback, params.surface_id),
311 &ack_params.disable_throttling, &ack_params.renderer_id,
312 &ack_params.vsync_timebase, &ack_params.vsync_interval);
314 Send(new AcceleratedSurfaceMsg_BufferPresented(params.route_id, ack_params));
316 #endif
318 void GpuProcessHostUIShim::OnVideoMemoryUsageStatsReceived(
319 const GPUVideoMemoryUsageStats& video_memory_usage_stats) {
320 GpuDataManagerImpl::GetInstance()->UpdateVideoMemoryUsageStats(
321 video_memory_usage_stats);
324 void GpuProcessHostUIShim::OnAddSubscription(
325 int32 process_id, unsigned int target) {
326 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
327 if (rph) {
328 rph->OnAddSubscription(target);
332 void GpuProcessHostUIShim::OnRemoveSubscription(
333 int32 process_id, unsigned int target) {
334 RenderProcessHost* rph = RenderProcessHost::FromID(process_id);
335 if (rph) {
336 rph->OnRemoveSubscription(target);
340 } // namespace content