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

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: . 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
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..948a2ab91173442de5aa1e05704ded11efe5998b 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,15 @@ namespace ui {
namespace {
+struct PageFlipPayload {
+ PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner,
alexst (slow to review) 2015/01/09 03:55:46 You should mention which thread this task runner b
dnicoara 2015/01/09 15:08:24 Added some comments. In principle it doesn't matte
+ const DriWrapper::PageFlipCallback& callback)
+ : task_runner(task_runner), callback(callback) {}
+
+ scoped_refptr<base::TaskRunner> task_runner;
+ DriWrapper::PageFlipCallback callback;
+};
+
bool DrmCreateDumbBuffer(int fd,
const SkImageInfo& info,
uint32_t* handle,
@@ -55,10 +67,84 @@ 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));
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<IOWatcher>;
+
+ ~IOWatcher() override {
+ io_task_runner_->PostTask(FROM_HERE,
+ base::Bind(&IOWatcher::UnregisterOnIO, this));
alexst (slow to review) 2015/01/09 03:55:46 I am pretty sure this is not safe, we are in the d
dnicoara 2015/01/09 15:08:24 Doh! You are right, move the post in a Shutdown()
+ }
+
+ 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());
alexst (slow to review) 2015/01/09 03:55:46 Is this checking that an IO type thread is current
dnicoara 2015/01/09 15:08:24 Yes. It would be hard to check which IO message lo
+ 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());
}
@@ -75,6 +161,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 +257,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 +374,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,

Powered by Google App Engine
This is Rietveld 408576698