1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// TODO(jam): move this file to src/content once we have an interface that the
2dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// embedder provides.  We can then use it to get the resource and resize the
3dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// window.
4dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/gpu_process_host_ui_shim.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/command_line.h"
11dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/id_map.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/process_util.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/browser_process.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/gpu_data_manager.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/io_thread.h"
16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/gpu_process_host.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_widget_host_view.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/content_switches.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/gpu_messages.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "gpu/common/gpu_trace_event.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_LINUX)
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// These two #includes need to come after gpu_messages.h.
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <gdk/gdkwindow.h>  // NOLINT
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <gdk/gdkx.h>  // NOLINT
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/x/x11_util.h"
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_native_view_id_manager.h"
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/size.h"
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif  // defined(OS_LINUX)
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// One of the linux specific headers defines this as a macro.
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef DestroyAll
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef DestroyAll
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
40dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenIDMap<GpuProcessHostUIShim> g_hosts_by_id;
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass SendOnIOThreadTask : public Task {
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  SendOnIOThreadTask(int host_id, IPC::Message* msg)
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      : host_id_(host_id),
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        msg_(msg) {
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void Run() {
51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    GpuProcessHost* host = GpuProcessHost::FromID(host_id_);
52dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    if (host)
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      host->Send(msg_.release());
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
55dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
56dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  int host_id_;
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_ptr<IPC::Message> msg_;
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass UIThreadSender : public IPC::Channel::Sender {
61dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen public:
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual bool Send(IPC::Message* msg) {
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The GPU process must never send a synchronous IPC message to the browser
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // process. This could result in deadlock. Unfortunately linux does this for
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // GpuHostMsg_ResizeXID. TODO(apatrick): fix this before issuing any GL calls
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // on the browser process' GPU thread.
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if !defined(OS_LINUX)
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(!msg->is_sync());
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // When the GpuChannelManager sends an IPC, post it to the UI thread without
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // using IPC.
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool success = BrowserThread::PostTask(
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::UI,
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        FROM_HERE,
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new RouteToGpuProcessHostUIShimTask(0, *msg));
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete msg;
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return success;
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen};
82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ForwardMessageToGpuThread(GpuChannelManager* gpu_channel_manager,
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                               IPC::Message* msg) {
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool success = gpu_channel_manager->OnMessageReceived(*msg);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If the message was not handled, it is likely it was intended for the
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // GpuChildThread, which does not exist in single process and in process GPU
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // mode.
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(success);
91dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delete msg;
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
96dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenRouteToGpuProcessHostUIShimTask::RouteToGpuProcessHostUIShimTask(
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int host_id,
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const IPC::Message& msg)
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  : host_id_(host_id),
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    msg_(msg) {
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenRouteToGpuProcessHostUIShimTask::~RouteToGpuProcessHostUIShimTask() {
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid RouteToGpuProcessHostUIShimTask::Run() {
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GpuProcessHostUIShim* ui_shim = GpuProcessHostUIShim::FromID(host_id_);
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (ui_shim)
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui_shim->OnMessageReceived(msg_);
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
112dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenGpuProcessHostUIShim::GpuProcessHostUIShim(int host_id)
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : host_id_(host_id),
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      gpu_channel_manager_(NULL),
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ui_thread_sender_(NULL) {
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  g_hosts_by_id.AddWithID(this, host_id_);
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (host_id == 0) {
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui_thread_sender_ = new UIThreadSender;
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    gpu_channel_manager_ = new GpuChannelManager(
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        ui_thread_sender_,
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NULL,
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        g_browser_process->io_thread()->message_loop(),
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        g_browser_process->shutdown_event());
125dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
127dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenGpuProcessHostUIShim* GpuProcessHostUIShim::Create(int host_id) {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(!FromID(host_id));
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new GpuProcessHostUIShim(host_id);
132dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
133dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
134dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static
135dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid GpuProcessHostUIShim::Destroy(int host_id) {
136dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
137dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  delete FromID(host_id);
138dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
139dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
140dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GpuProcessHostUIShim::DestroyAll() {
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  while (!g_hosts_by_id.IsEmpty()) {
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IDMap<GpuProcessHostUIShim>::iterator it(&g_hosts_by_id);
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    delete it.GetCurrentValue();
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
147dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
148dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// static
150dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenGpuProcessHostUIShim* GpuProcessHostUIShim::FromID(int host_id) {
151dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return g_hosts_by_id.Lookup(host_id);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool GpuProcessHostUIShim::Send(IPC::Message* msg) {
1564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK(CalledOnValidThread());
15772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool success;
15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (host_id_ == 0) {
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    success = BrowserThread::PostTask(
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::GPU,
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        FROM_HERE,
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableFunction(ForwardMessageToGpuThread,
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            gpu_channel_manager_,
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            msg));
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    success = BrowserThread::PostTask(
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::IO,
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        FROM_HERE,
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        new SendOnIOThreadTask(host_id_, msg));
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return success;
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbool GpuProcessHostUIShim::OnMessageReceived(const IPC::Message& message) {
1784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  DCHECK(CalledOnValidThread());
1794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  if (message.routing_id() != MSG_ROUTING_CONTROL)
181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return false;
18221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return OnControlMessageReceived(message);
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#if defined(OS_MACOSX)
187dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
188dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenvoid GpuProcessHostUIShim::DidDestroyAcceleratedSurface(int renderer_id,
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                        int render_view_id) {
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Destroy the command buffer that owns the accelerated surface.
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Send(new GpuMsg_DestroyCommandBuffer(renderer_id, render_view_id));
192dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GpuProcessHostUIShim::SendToGpuHost(int host_id, IPC::Message* msg) {
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GpuProcessHostUIShim* ui_shim = FromID(host_id);
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!ui_shim)
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    return;
198513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ui_shim->Send(msg);
200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
203dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
204dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenGpuProcessHostUIShim::~GpuProcessHostUIShim() {
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK(CalledOnValidThread());
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  g_hosts_by_id.Remove(host_id_);
207dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Ensure these are destroyed on the GPU thread.
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (gpu_channel_manager_) {
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::DeleteSoon(BrowserThread::GPU,
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              FROM_HERE,
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              gpu_channel_manager_);
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    gpu_channel_manager_ = NULL;
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (ui_thread_sender_) {
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BrowserThread::DeleteSoon(BrowserThread::GPU,
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              FROM_HERE,
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              ui_thread_sender_);
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ui_thread_sender_ = NULL;
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool GpuProcessHostUIShim::OnControlMessageReceived(
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const IPC::Message& message) {
22572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(CalledOnValidThread());
22672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  IPC_BEGIN_MESSAGE_MAP(GpuProcessHostUIShim, message)
22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC_MESSAGE_HANDLER(GpuHostMsg_OnLogMessage,
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        OnLogMessage)
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_LINUX) && !defined(TOUCH_UI) || defined(OS_WIN)
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC_MESSAGE_HANDLER(GpuHostMsg_ResizeView, OnResizeView)
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#elif defined(OS_MACOSX)
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceSetIOSurface,
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        OnAcceleratedSurfaceSetIOSurface)
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC_MESSAGE_HANDLER(GpuHostMsg_AcceleratedSurfaceBuffersSwapped,
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        OnAcceleratedSurfaceBuffersSwapped)
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#elif defined(OS_WIN)
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC_MESSAGE_HANDLER(GpuHostMsg_ScheduleComposite, OnScheduleComposite);
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    IPC_MESSAGE_UNHANDLED_ERROR()
24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  IPC_END_MESSAGE_MAP()
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return true;
24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GpuProcessHostUIShim::OnLogMessage(
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int level,
24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& header,
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& message) {
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DictionaryValue* dict = new DictionaryValue();
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  dict->SetInteger("level", level);
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  dict->SetString("header", header);
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  dict->SetString("message", message);
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GpuDataManager::GetInstance()->AddLogMessage(dict);
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_LINUX) && !defined(TOUCH_UI) || defined(OS_WIN)
25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid GpuProcessHostUIShim::OnResizeView(int32 renderer_id,
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        int32 render_view_id,
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        int32 command_buffer_route_id,
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        gfx::Size size) {
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderViewHost* host = RenderViewHost::FromID(renderer_id, render_view_id);
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (host) {
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RenderWidgetHostView* view = host->view();
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (view) {
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      gfx::PluginWindowHandle handle = view->GetCompositingSurface();
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Resize the window synchronously. The GPU process must not issue GL
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // calls on the command buffer until the window is the size it expects it
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // to be.
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_LINUX) && !defined(TOUCH_UI)
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GdkWindow* window = reinterpret_cast<GdkWindow*>(
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          gdk_xid_table_lookup(handle));
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (window) {
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        Display* display = GDK_WINDOW_XDISPLAY(window);
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        gdk_window_resize(window, size.width(), size.height());
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        XSync(display, False);
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#elif defined(OS_WIN)
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SetWindowPos(handle,
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          NULL,
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          0, 0,
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          size.width(),
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          size.height(),
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER |
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              SWP_NOACTIVATE | SWP_DEFERERASE);
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Always respond even if the window no longer exists. The GPU process cannot
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // make progress on the resizing command buffer until it receives the
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // response.
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Send(new GpuMsg_ResizeViewACK(renderer_id, command_buffer_route_id));
29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
29772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
29872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#elif defined(OS_MACOSX)
29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid GpuProcessHostUIShim::OnAcceleratedSurfaceSetIOSurface(
30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params& params) {
30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RenderViewHost* host = RenderViewHost::FromID(params.renderer_id,
30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                params.render_view_id);
30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!host)
30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RenderWidgetHostView* view = host->view();
30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!view)
30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  view->AcceleratedSurfaceSetIOSurface(params.window,
31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       params.width,
31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       params.height,
31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                       params.identifier);
31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid GpuProcessHostUIShim::OnAcceleratedSurfaceBuffersSwapped(
31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params& params) {
31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RenderViewHost* host = RenderViewHost::FromID(params.renderer_id,
31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                                params.render_view_id);
31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!host)
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  RenderWidgetHostView* view = host->view();
32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!view)
32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  view->AcceleratedSurfaceBuffersSwapped(
32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // Parameters needed to swap the IOSurface.
32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      params.window,
32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      params.surface_id,
32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // Parameters needed to formulate an acknowledgment.
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      params.renderer_id,
33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      params.route_id,
331dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen      host_id_,
33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      params.swap_buffers_count);
33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_WIN)
33872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid GpuProcessHostUIShim::OnScheduleComposite(int renderer_id,
340201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    int render_view_id) {
341201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  RenderViewHost* host = RenderViewHost::FromID(renderer_id,
342201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                render_view_id);
343201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (!host) {
344201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
345201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
346201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  host->ScheduleComposite();
347201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
349201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#endif
350