Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(453)

Unified Diff: ui/ozone/platform/dri/dri_wrapper.cc

Issue 821023003: [Ozone-DRI] Listen for swap events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@async-swap
Patch Set: Added comment Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/ozone/platform/dri/dri_wrapper.h ('k') | ui/ozone/platform/dri/gbm_surface.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 e08fbfc7374aab8e15e4c0fe80e680b741279c13..faf10e231bb97413e722d3a230edef3bfd688834 100644
--- a/ui/ozone/platform/dri/dri_wrapper.cc
+++ b/ui/ozone/platform/dri/dri_wrapper.cc
@@ -12,7 +12,10 @@
#include "base/debug/trace_event.h"
#include "base/logging.h"
+#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
+#include "base/task_runner.h"
+#include "base/thread_task_runner_handle.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "ui/ozone/platform/dri/dri_util.h"
#include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h"
@@ -21,6 +24,17 @@ namespace ui {
namespace {
+struct PageFlipPayload {
+ PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner,
+ const DriWrapper::PageFlipCallback& callback)
+ : task_runner(task_runner), callback(callback) {}
+
+ // Task runner for the thread scheduling the page flip event. This is used to
+ // run the callback on the same thread the callback was created on.
+ scoped_refptr<base::TaskRunner> task_runner;
+ DriWrapper::PageFlipCallback callback;
+};
+
bool DrmCreateDumbBuffer(int fd,
const SkImageInfo& info,
uint32_t* handle,
@@ -55,16 +69,95 @@ void DrmDestroyDumbBuffer(int fd, uint32_t handle) {
drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
}
+void HandlePageFlipEventOnIO(int fd,
+ unsigned int frame,
+ unsigned int seconds,
+ unsigned int useconds,
+ void* data) {
+ scoped_ptr<PageFlipPayload> payload(static_cast<PageFlipPayload*>(data));
+ payload->task_runner->PostTask(
+ FROM_HERE, base::Bind(payload->callback, frame, seconds, useconds));
+}
+
+void HandlePageFlipEventOnUI(int fd,
+ unsigned int frame,
+ unsigned int seconds,
+ unsigned int useconds,
+ void* data) {
+ scoped_ptr<PageFlipPayload> payload(static_cast<PageFlipPayload*>(data));
+ payload->callback.Run(frame, seconds, useconds);
+}
+
} // namespace
-DriWrapper::DriWrapper(const char* device_path)
- : fd_(-1), device_path_(device_path) {
+class DriWrapper::IOWatcher
+ : public base::RefCountedThreadSafe<DriWrapper::IOWatcher>,
+ public base::MessagePumpLibevent::Watcher {
+ 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));
+ }
+
+ void Shutdown() {
+ io_task_runner_->PostTask(FROM_HERE,
+ base::Bind(&IOWatcher::UnregisterOnIO, this));
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<IOWatcher>;
+
+ ~IOWatcher() override {}
+
+ void RegisterOnIO(int fd) {
+ DCHECK(base::MessageLoopForIO::IsCurrent());
+ base::MessageLoopForIO::current()->WatchFileDescriptor(
+ fd, true, base::MessageLoopForIO::WATCH_READ, &controller_, this);
+ }
+
+ void UnregisterOnIO() {
+ DCHECK(base::MessageLoopForIO::IsCurrent());
+ controller_.StopWatchingFileDescriptor();
+ }
+
+ // base::MessagePumpLibevent::Watcher overrides:
+ void OnFileCanReadWithoutBlocking(int fd) override {
+ DCHECK(base::MessageLoopForIO::IsCurrent());
+ TRACE_EVENT1("dri", "OnDrmEvent", "socket", fd);
+
+ drmEventContext event;
+ event.version = DRM_EVENT_CONTEXT_VERSION;
+ event.page_flip_handler = HandlePageFlipEventOnIO;
+ event.vblank_handler = nullptr;
+
+ drmHandleEvent(fd, &event);
+ }
+
+ void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
+
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+
+ base::MessagePumpLibevent::FileDescriptorWatcher controller_;
+
+ DISALLOW_COPY_AND_ASSIGN(IOWatcher);
+};
+
+DriWrapper::DriWrapper(const char* device_path, bool software_mode)
+ : fd_(-1),
+ software_mode_(software_mode),
+ device_path_(device_path),
+ io_thread_("DriIOThread") {
plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
}
DriWrapper::~DriWrapper() {
if (fd_ >= 0)
close(fd_);
+
+ if (watcher_)
+ watcher_->Shutdown();
}
void DriWrapper::Initialize() {
@@ -75,6 +168,16 @@ void DriWrapper::Initialize() {
LOG(ERROR) << "Failed to initialize the plane manager";
}
+void DriWrapper::InitializeIOWatcher() {
+ if (!software_mode_ && !watcher_) {
+ if (!io_thread_.StartWithOptions(
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0)))
+ LOG(FATAL) << "Failed to start the IO helper thread";
+
+ watcher_ = new IOWatcher(fd_, io_thread_.task_runner());
+ }
+}
+
ScopedDrmCrtcPtr DriWrapper::GetCrtc(uint32_t crtc_id) {
DCHECK(fd_ >= 0);
return ScopedDrmCrtcPtr(drmModeGetCrtc(fd_, crtc_id));
@@ -161,16 +264,37 @@ bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) {
bool DriWrapper::PageFlip(uint32_t crtc_id,
uint32_t framebuffer,
- void* data) {
+ const PageFlipCallback& callback) {
DCHECK(fd_ >= 0);
TRACE_EVENT2("dri", "DriWrapper::PageFlip",
"crtc", crtc_id,
"framebuffer", framebuffer);
- return !drmModePageFlip(fd_,
- crtc_id,
- framebuffer,
- DRM_MODE_PAGE_FLIP_EVENT,
- data);
+
+ // 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(
+ new PageFlipPayload(base::ThreadTaskRunnerHandle::Get(), callback));
+ if (!drmModePageFlip(fd_, crtc_id, framebuffer, DRM_MODE_PAGE_FLIP_EVENT,
+ payload.get())) {
+ // If successful the payload will be removed by a PageFlip event.
+ ignore_result(payload.release());
+ if (software_mode_) {
+ TRACE_EVENT1("dri", "OnDrmEvent", "socket", fd_);
+
+ drmEventContext event;
+ event.version = DRM_EVENT_CONTEXT_VERSION;
+ event.page_flip_handler = HandlePageFlipEventOnUI;
+ event.vblank_handler = nullptr;
+
+ drmHandleEvent(fd_, &event);
+ } else {
+ InitializeIOWatcher();
+ }
+
+ return true;
+ }
+
+ return false;
}
bool DriWrapper::PageFlipOverlay(uint32_t crtc_id,
@@ -257,12 +381,6 @@ bool DriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) {
return !drmModeMoveCursor(fd_, crtc_id, point.x(), point.y());
}
-void DriWrapper::HandleEvent(drmEventContext& event) {
- DCHECK(fd_ >= 0);
- TRACE_EVENT0("dri", "DriWrapper::HandleEvent");
- drmHandleEvent(fd_, &event);
-}
-
bool DriWrapper::CreateDumbBuffer(const SkImageInfo& info,
uint32_t* handle,
uint32_t* stride,
« no previous file with comments | « ui/ozone/platform/dri/dri_wrapper.h ('k') | ui/ozone/platform/dri/gbm_surface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698