Commit ab2cd950 authored by Saman Sami's avatar Saman Sami Committed by Commit Bot

Ozone/DRM: Fix cursor remote being rebound on every cursor move

This CL fixes two issues:
- |evdev_bound_| is never set, so we keep rebinding |evdev_cursor_| on
  every cursor move.
- |evdev_cursor_| was initially bound on the UI thread so calling
  Unbind() on the evdev thread for the first time triggers a DCHECK.
  Instead keep the pending remote unbound until it's time to bind it on
  the evdev thread.

Bug: 620927,1039834
Change-Id: Iea19d5e32b0cbc9396f7b5e178e8e4ab6001f8c4
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1997646
Commit-Queue: Saman Sami <samans@chromium.org>
Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Auto-Submit: Saman Sami <samans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#731618}
parent 43079c75
...@@ -16,7 +16,7 @@ HostCursorProxy::HostCursorProxy( ...@@ -16,7 +16,7 @@ HostCursorProxy::HostCursorProxy(
mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor, mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor,
mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor) mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor)
: main_cursor_(std::move(main_cursor)), : main_cursor_(std::move(main_cursor)),
evdev_cursor_(std::move(evdev_cursor)), evdev_cursor_pending_remote_(std::move(evdev_cursor)),
ui_thread_ref_(base::PlatformThread::CurrentRef()) {} ui_thread_ref_(base::PlatformThread::CurrentRef()) {}
HostCursorProxy::~HostCursorProxy() {} HostCursorProxy::~HostCursorProxy() {}
...@@ -25,39 +25,28 @@ void HostCursorProxy::CursorSet(gfx::AcceleratedWidget widget, ...@@ -25,39 +25,28 @@ void HostCursorProxy::CursorSet(gfx::AcceleratedWidget widget,
const std::vector<SkBitmap>& bitmaps, const std::vector<SkBitmap>& bitmaps,
const gfx::Point& location, const gfx::Point& location,
int frame_delay_ms) { int frame_delay_ms) {
InitializeOnEvdevIfNecessary();
if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) { if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) {
main_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms); main_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms);
} else { } else {
InitializeOnEvdevIfNecessary();
evdev_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms); evdev_cursor_->SetCursor(widget, bitmaps, location, frame_delay_ms);
} }
} }
void HostCursorProxy::Move(gfx::AcceleratedWidget widget, void HostCursorProxy::Move(gfx::AcceleratedWidget widget,
const gfx::Point& location) { const gfx::Point& location) {
InitializeOnEvdevIfNecessary();
if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) { if (ui_thread_ref_ == base::PlatformThread::CurrentRef()) {
main_cursor_->MoveCursor(widget, location); main_cursor_->MoveCursor(widget, location);
} else { } else {
InitializeOnEvdevIfNecessary();
evdev_cursor_->MoveCursor(widget, location); evdev_cursor_->MoveCursor(widget, location);
} }
} }
// Evdev runs this method on starting. But if a HostCursorProxy is created long
// after Evdev has started (e.g. if the Viz process crashes (and the
// |HostCursorProxy| self-destructs and then a new |HostCursorProxy| is built
// when the GpuThread/DrmThread pair are once again running), we need to run it
// on cursor motions.
void HostCursorProxy::InitializeOnEvdevIfNecessary() { void HostCursorProxy::InitializeOnEvdevIfNecessary() {
// TODO(rjkroege): Rebind on Viz process restart. if (evdev_cursor_.is_bound())
if (evdev_bound_)
return; return;
evdev_cursor_.Bind(std::move(evdev_cursor_pending_remote_));
if (ui_thread_ref_ != base::PlatformThread::CurrentRef()) {
// Rebind the mojo pipe on the current thread. We expect this to be the
// thread running EVDEV.
evdev_cursor_.Bind(evdev_cursor_.Unbind());
}
} }
} // namespace ui } // namespace ui
...@@ -35,12 +35,15 @@ class HostCursorProxy : public DrmCursorProxy { ...@@ -35,12 +35,15 @@ class HostCursorProxy : public DrmCursorProxy {
void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override; void Move(gfx::AcceleratedWidget window, const gfx::Point& point) override;
void InitializeOnEvdevIfNecessary() override; void InitializeOnEvdevIfNecessary() override;
// Mojo implementation of the DrmCursorProxy. // Accessed from UI thread only.
mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor_; mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> main_cursor_;
// Accessed from evdev thread only.
mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor_; mojo::AssociatedRemote<ui::ozone::mojom::DeviceCursor> evdev_cursor_;
mojo::PendingAssociatedRemote<ui::ozone::mojom::DeviceCursor>
evdev_cursor_pending_remote_;
base::PlatformThreadRef ui_thread_ref_; base::PlatformThreadRef ui_thread_ref_;
bool evdev_bound_ = false;
DISALLOW_COPY_AND_ASSIGN(HostCursorProxy); DISALLOW_COPY_AND_ASSIGN(HostCursorProxy);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment