Chromium Code Reviews| Index: ui/ozone/platform/dri/dri_gpu_platform_support.cc |
| diff --git a/ui/ozone/platform/dri/dri_gpu_platform_support.cc b/ui/ozone/platform/dri/dri_gpu_platform_support.cc |
| index 7d01217160606848e0b128a0af98749c47f0644f..5eb45cddad7bcd8749ff9462685ea59830cb90f4 100644 |
| --- a/ui/ozone/platform/dri/dri_gpu_platform_support.cc |
| +++ b/ui/ozone/platform/dri/dri_gpu_platform_support.cc |
| @@ -4,6 +4,7 @@ |
| #include "ui/ozone/platform/dri/dri_gpu_platform_support.h" |
| +#include "base/bind.h" |
| #include "ipc/ipc_message_macros.h" |
| #include "ui/display/types/display_mode.h" |
| #include "ui/display/types/display_snapshot.h" |
| @@ -16,6 +17,109 @@ |
| namespace ui { |
| +namespace { |
| + |
| +class DriGpuPlatformSupportMessageFilter : public IPC::MessageFilter { |
| + public: |
| + DriGpuPlatformSupportMessageFilter(DriWindowDelegateManager* window_manager, |
| + IPC::Listener* main_thread_listener) |
| + : window_manager_(window_manager), |
| + main_thread_listener_(main_thread_listener), |
| + main_thread_task_runner_(base::MessageLoop::current()->task_runner()), |
| + pending_main_thread_operations_(0) {} |
| + |
| + void OnFilterAdded(IPC::Sender* sender) override { |
| + io_thread_task_runner_ = base::MessageLoop::current()->task_runner(); |
|
spang
2015/01/08 18:58:30
I think the preferred spelling of this is:
base
|
| + } |
| + |
| + // This code is meant to be very temporary and only as a special case to fix |
| + // cursor movement jank resulting from slowdowns on the gpu main thread. |
| + // It handles cursor movement on IO thread when display config is stable |
| + // and returns it to main thread during transitions. |
| + bool OnMessageReceived(const IPC::Message& message) override { |
| + // If this message affects the state needed to set cursor, handle it on |
| + // the main thread. If a cursor move message arrives but we haven't |
| + // processed the previous main thread message, keep processing on main |
| + // until nothing is pending. |
| + bool process_move_on_main = pending_main_thread_operations_ && |
| + MessageAffectsCursorPosition(message.type()); |
| + if (MessageAffectsCursorState(message.type()) || process_move_on_main) { |
| + pending_main_thread_operations_++; |
| + |
| + base::Closure main_thread_message_handler = |
| + base::Bind(base::IgnoreResult(&IPC::Listener::OnMessageReceived), |
| + base::Unretained(main_thread_listener_), message); |
| + main_thread_task_runner_->PostTask(FROM_HERE, |
| + main_thread_message_handler); |
| + |
| + // This is an echo from the main thread to decrement pending ops. |
| + // When the main thread is done with the task, it posts back to IO to |
| + // signal completion. |
| + base::Closure message_processed_callback = base::Bind( |
| + &DriGpuPlatformSupportMessageFilter::MessageProcessedOnMain, this); |
| + main_thread_task_runner_->PostTask(FROM_HERE, message_processed_callback); |
| + |
| + return true; |
| + } |
| + |
| + // Otherwise, we are in a steady state and it's safe to move cursor on IO. |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(DriGpuPlatformSupportMessageFilter, message) |
| + IPC_MESSAGE_HANDLER(OzoneGpuMsg_CursorMove, OnCursorMove) |
| + IPC_MESSAGE_UNHANDLED(handled = false); |
| + IPC_END_MESSAGE_MAP() |
| + |
| + return handled; |
| + } |
| + |
| + protected: |
| + ~DriGpuPlatformSupportMessageFilter() override {} |
| + |
| + void OnCursorMove(gfx::AcceleratedWidget widget, const gfx::Point& location) { |
| + window_manager_->GetWindowDelegate(widget)->MoveCursor(location); |
| + } |
| + |
| + void MessageProcessedOnMain() { |
| + io_thread_task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind( |
| + &DriGpuPlatformSupportMessageFilter::DecrementPendingOperationsOnIO, |
| + this)); |
| + } |
| + |
| + void DecrementPendingOperationsOnIO() { pending_main_thread_operations_--; } |
| + |
| + bool MessageAffectsCursorState(uint32 message_type) { |
| + switch (message_type) { |
| + case OzoneGpuMsg_CreateWindowDelegate::ID: |
| + case OzoneGpuMsg_DestroyWindowDelegate::ID: |
| + case OzoneGpuMsg_WindowBoundsChanged::ID: |
| + case OzoneGpuMsg_ConfigureNativeDisplay::ID: |
| + case OzoneGpuMsg_DisableNativeDisplay::ID: |
| + case OzoneGpuMsg_CursorSet::ID: |
| + return true; |
| + default: |
| + return false; |
| + } |
| + } |
| + |
| + bool MessageAffectsCursorPosition(uint32 message_type) { |
| + switch (message_type) { |
| + case OzoneGpuMsg_CursorMove::ID: |
| + return true; |
| + default: |
| + return false; |
| + } |
| + } |
| + |
| + DriWindowDelegateManager* window_manager_; |
| + IPC::Listener* main_thread_listener_; |
| + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; |
| + scoped_refptr<base::SingleThreadTaskRunner> io_thread_task_runner_; |
| + int32 pending_main_thread_operations_; |
| +}; |
| +} |
| + |
| DriGpuPlatformSupport::DriGpuPlatformSupport( |
| DriWrapper* drm, |
| DriWindowDelegateManager* window_manager, |
| @@ -26,6 +130,7 @@ DriGpuPlatformSupport::DriGpuPlatformSupport( |
| window_manager_(window_manager), |
| screen_manager_(screen_manager), |
| ndd_(ndd.Pass()) { |
| + filter_ = new DriGpuPlatformSupportMessageFilter(window_manager, this); |
| } |
| DriGpuPlatformSupport::~DriGpuPlatformSupport() { |
| @@ -203,7 +308,7 @@ void DriGpuPlatformSupport::RelinquishGpuResources( |
| } |
| IPC::MessageFilter* DriGpuPlatformSupport::GetMessageFilter() { |
| - return nullptr; |
| + return filter_.get(); |
| } |
| } // namespace ui |