Chromium Code Reviews| 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 |
| + |