| Index: ui/ozone/platform/dri/dri_wrapper.cc
|
| diff --git a/ui/ozone/platform/dri/dri_wrapper.cc b/ui/ozone/platform/dri/dri_wrapper.cc
|
| index a2b333f16e762f6d5ce2d67e762e7f9fb730ff80..b08d8265e557d2224537ae64158b2d1d3c87ec8b 100644
|
| --- a/ui/ozone/platform/dri/dri_wrapper.cc
|
| +++ b/ui/ozone/platform/dri/dri_wrapper.cc
|
| @@ -13,6 +13,7 @@
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/stl_util.h"
|
| +#include "base/synchronization/waitable_event.h"
|
| #include "base/task_runner.h"
|
| #include "base/thread_task_runner_handle.h"
|
| #include "base/trace_event/trace_event.h"
|
| @@ -104,25 +105,36 @@ class DriWrapper::IOWatcher
|
| public:
|
| IOWatcher(int fd,
|
| const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
|
| - : io_task_runner_(io_task_runner) {
|
| - io_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&IOWatcher::RegisterOnIO, this, fd));
|
| + : io_task_runner_(io_task_runner), paused_(true), fd_(fd) {
|
| + }
|
| +
|
| + void SetPaused(bool paused) {
|
| + if (paused_ == paused)
|
| + return;
|
| +
|
| + paused_ = paused;
|
| + base::WaitableEvent done(false, false);
|
| + io_task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(&IOWatcher::SetPausedOnIO, this, &done));
|
| }
|
|
|
| void Shutdown() {
|
| - io_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&IOWatcher::UnregisterOnIO, this));
|
| + if (!paused_)
|
| + io_task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(&IOWatcher::UnregisterOnIO, this));
|
| }
|
|
|
| private:
|
| friend class base::RefCountedThreadSafe<IOWatcher>;
|
|
|
| - ~IOWatcher() override {}
|
| + ~IOWatcher() override {
|
| + SetPaused(true);
|
| + }
|
|
|
| - void RegisterOnIO(int fd) {
|
| + void RegisterOnIO() {
|
| DCHECK(base::MessageLoopForIO::IsCurrent());
|
| base::MessageLoopForIO::current()->WatchFileDescriptor(
|
| - fd, true, base::MessageLoopForIO::WATCH_READ, &controller_, this);
|
| + fd_, true, base::MessageLoopForIO::WATCH_READ, &controller_, this);
|
| }
|
|
|
| void UnregisterOnIO() {
|
| @@ -130,6 +142,15 @@ class DriWrapper::IOWatcher
|
| controller_.StopWatchingFileDescriptor();
|
| }
|
|
|
| + void SetPausedOnIO(base::WaitableEvent* done) {
|
| + DCHECK(base::MessageLoopForIO::IsCurrent());
|
| + if (paused_)
|
| + UnregisterOnIO();
|
| + else
|
| + RegisterOnIO();
|
| + done->Signal();
|
| + }
|
| +
|
| // base::MessagePumpLibevent::Watcher overrides:
|
| void OnFileCanReadWithoutBlocking(int fd) override {
|
| DCHECK(base::MessageLoopForIO::IsCurrent());
|
| @@ -149,6 +170,9 @@ class DriWrapper::IOWatcher
|
|
|
| base::MessagePumpLibevent::FileDescriptorWatcher controller_;
|
|
|
| + bool paused_;
|
| + int fd_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(IOWatcher);
|
| };
|
|
|
| @@ -270,12 +294,16 @@ bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) {
|
|
|
| bool DriWrapper::PageFlip(uint32_t crtc_id,
|
| uint32_t framebuffer,
|
| + bool is_sync,
|
| const PageFlipCallback& callback) {
|
| DCHECK(file_.IsValid());
|
| TRACE_EVENT2("dri", "DriWrapper::PageFlip",
|
| "crtc", crtc_id,
|
| "framebuffer", framebuffer);
|
|
|
| + if (watcher_)
|
| + watcher_->SetPaused(is_sync);
|
| +
|
| // NOTE: Calling drmModeSetCrtc will immediately update the state, though
|
| // callbacks to already scheduled page flips will be honored by the kernel.
|
| scoped_ptr<PageFlipPayload> payload(
|
| @@ -285,9 +313,9 @@ bool DriWrapper::PageFlip(uint32_t crtc_id,
|
| // If successful the payload will be removed by a PageFlip event.
|
| ignore_result(payload.release());
|
|
|
| - // If a task runner isn't installed then fall back to synchronously handling
|
| - // the page flip events.
|
| - if (!task_runner_) {
|
| + // If the flip was requested synchronous or if no watcher has been installed
|
| + // yet, then synchronously handle the page flip events.
|
| + if (is_sync || !watcher_) {
|
| TRACE_EVENT1("dri", "OnDrmEvent", "socket", file_.GetPlatformFile());
|
|
|
| drmEventContext event;
|
|
|