Index: content/browser/renderer_host/render_widget_resize_helper_mac.cc |
diff --git a/content/browser/renderer_host/render_widget_resize_helper_mac.cc b/content/browser/renderer_host/render_widget_resize_helper_mac.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..906fb0b21281fa5a92854554ca9e93f251c82508 |
--- /dev/null |
+++ b/content/browser/renderer_host/render_widget_resize_helper_mac.cc |
@@ -0,0 +1,150 @@ |
+#include "content/browser/renderer_host/render_widget_resize_helper_mac.h" |
piman
2014/07/15 19:56:00
nit: copyright header needed.
ccameron
2014/07/15 20:36:24
Done.
|
+ |
+#include "content/browser/gpu/gpu_process_host_ui_shim.h" |
+#include "content/browser/renderer_host/render_process_host_impl.h" |
+#include "content/public/browser/browser_thread.h" |
+ |
+namespace content { |
+namespace { |
+base::LazyInstance<RenderWidgetResizeHelper> g_render_widget_task_runner; |
+} // namespace |
+ |
+// A helper used with DidReceiveBackingStoreMsg that we hold a pointer to in |
+// pending_paints_. |
piman
2014/07/15 19:56:00
nit: fix comment.
ccameron
2014/07/15 20:36:24
Done.
|
+class RenderWidgetResizeHelper::EnqueuedTask { |
+ public: |
+ enum Type { |
+ RENDERER_IPC, |
+ GPU_IPC, |
+ }; |
+ EnqueuedTask(Type type, int process_id, const IPC::Message& m); |
+ ~EnqueuedTask(); |
+ void Run(); |
+ |
+ private: |
+ Type type_; |
+ int process_id_; |
+ IPC::Message message_; |
+ bool has_run_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(EnqueuedTask); |
+}; |
+ |
+RenderWidgetResizeHelper::EnqueuedTask::EnqueuedTask( |
+ Type type, |
+ int process_id, |
+ const IPC::Message& m) |
+ : type_(type), |
+ process_id_(process_id), |
+ message_(m), |
+ has_run_(false) { |
+} |
+ |
+RenderWidgetResizeHelper::EnqueuedTask::~EnqueuedTask() { |
+} |
+ |
+void RenderWidgetResizeHelper::EnqueuedTask::Run() { |
+ if (has_run_) |
+ return; |
+ |
+ RenderWidgetResizeHelper::Get()->WillRunEnqueuedTask(this); |
+ has_run_ = true; |
+ |
+ switch (type_) { |
+ case RENDERER_IPC: { |
+ RenderProcessHost* host = RenderProcessHost::FromID(process_id_); |
+ if (host) |
+ host->OnMessageReceived(message_); |
+ } break; |
piman
2014/07/15 19:56:00
nit: break inside the {}
ccameron
2014/07/15 20:36:24
Done.
|
+ case GPU_IPC: { |
+ GpuProcessHostUIShim* host = GpuProcessHostUIShim::FromID(process_id_); |
+ if (host) |
+ host->OnMessageReceived(message_); |
+ } break; |
piman
2014/07/15 19:56:00
nit: here too.
ccameron
2014/07/15 20:36:24
Done.
|
+ } |
+} |
+ |
+// static |
+RenderWidgetResizeHelper* RenderWidgetResizeHelper::Get() { |
+ return g_render_widget_task_runner.Pointer(); |
+} |
+ |
+bool RenderWidgetResizeHelper::WaitForSingleTaskToRun( |
+ const base::TimeDelta& max_delay) { |
+ base::TimeTicks time_start = base::TimeTicks::Now(); |
+ |
+ for (;;) { |
+ // Peek at the message from the front of the queue. Running it will remove |
+ // it from the queue. |
+ EnqueuedTask* task = NULL; |
+ { |
+ base::AutoLock lock(task_queue_lock_); |
+ if (!task_queue_.empty()) |
+ task = task_queue_.front(); |
+ } |
+ |
+ if (task) { |
+ task->Run(); |
+ return true; |
+ } |
+ |
+ // Calculate the maximum amount of time that we are willing to sleep. |
+ base::TimeDelta max_sleep_time = |
+ max_delay - (base::TimeTicks::Now() - time_start); |
+ if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) |
+ break; |
+ |
+ base::ThreadRestrictions::ScopedAllowWait allow_wait; |
+ event_.TimedWait(max_sleep_time); |
+ } |
+ |
+ return false; |
+} |
+ |
+void RenderWidgetResizeHelper::PostEnqueuedTask(EnqueuedTask* task) { |
+ { |
+ base::AutoLock lock(task_queue_lock_); |
+ task_queue_.push_back(task); |
+ } |
+ |
+ // Notify anyone waiting on the UI thread that there is a new entry in the |
+ // task map. If they don't find the entry they are looking for, then they |
+ // will just continue waiting. |
+ event_.Signal(); |
+ |
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
+ base::Bind(&EnqueuedTask::Run, base::Owned(task))); |
+} |
+ |
+void RenderWidgetResizeHelper::WillRunEnqueuedTask(EnqueuedTask* task) { |
+ base::AutoLock lock(task_queue_lock_); |
+ DCHECK(task_queue_.front() == task); |
+ task_queue_.pop_front(); |
+} |
+ |
+void RenderWidgetResizeHelper::PostRendererProcessMsg( |
+ int render_process_id, const IPC::Message& msg) { |
+ PostEnqueuedTask(new EnqueuedTask( |
+ EnqueuedTask::RENDERER_IPC, render_process_id, msg)); |
+} |
+ |
+void RenderWidgetResizeHelper::PostGpuProcessMsg( |
+ int gpu_host_id, const IPC::Message& msg) { |
+ PostEnqueuedTask(new EnqueuedTask(EnqueuedTask::GPU_IPC, gpu_host_id, msg)); |
+} |
+ |
+RenderWidgetResizeHelper::RenderWidgetResizeHelper() |
+#if defined(OS_WIN) |
+ : event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)) {} |
+#elif defined(OS_POSIX) |
+ : event_(false /* auto-reset */, false) {} |
piman
2014/07/15 19:56:00
nit: why not always this path on all platforms? It
ccameron
2014/07/15 20:36:25
This is from the earlier versions of the code -- n
piman
2014/07/15 22:49:36
This probably predates some API unification.
Readi
|
+#endif |
+ |
+RenderWidgetResizeHelper::~RenderWidgetResizeHelper() { |
+ // The elements of task_queue_ will call back into this object, so we |
+ // should not be destroyed unless task_queue_ is empty! |
+ DCHECK(task_queue_.empty()); |
+} |
+ |
+} // namespace content |
+ |