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

Unified Diff: ui/ozone/platform/drm/gpu/drm_device.cc

Issue 1056793007: [3/4][Ozone-Drm] Use numeric ID to map to callback (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@move-all-hotplug
Patch Set: Use std::vector Created 5 years, 8 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/drm/gpu/drm_device.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/ozone/platform/drm/gpu/drm_device.cc
diff --git a/ui/ozone/platform/drm/gpu/drm_device.cc b/ui/ozone/platform/drm/gpu/drm_device.cc
index ed38a2c88a30fcf4277d598524d29a6962004e8d..77e119640e4a60913680032ba940a63587dac4d9 100644
--- a/ui/ozone/platform/drm/gpu/drm_device.cc
+++ b/ui/ozone/platform/drm/gpu/drm_device.cc
@@ -29,6 +29,11 @@ namespace ui {
namespace {
+typedef base::Callback<void(uint32_t /* frame */,
+ uint32_t /* seconds */,
+ uint32_t /* useconds */,
+ uint64_t /* id */)> DrmEventHandler;
+
struct PageFlipPayload {
PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner,
const DrmDevice::PageFlipCallback& callback)
@@ -73,23 +78,41 @@ bool DrmDestroyDumbBuffer(int fd, uint32_t handle) {
return !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));
-}
+bool ProcessDrmEvent(int fd, const DrmEventHandler& callback) {
+ char buffer[1024];
+ int len = read(fd, buffer, sizeof(buffer));
+ if (len == 0)
+ return false;
+
+ if (len < static_cast<int>(sizeof(drm_event))) {
+ PLOG(ERROR) << "Failed to read DRM event";
+ return false;
+ }
+
+ int idx = 0;
+ while (idx < len) {
+ DCHECK_LT(static_cast<int>(sizeof(drm_event)), len - idx);
+ drm_event event;
+ memcpy(&event, &buffer[idx], sizeof(event));
+ switch (event.type) {
+ case DRM_EVENT_FLIP_COMPLETE: {
+ DCHECK_LT(static_cast<int>(sizeof(drm_event_vblank)), len - idx);
+ drm_event_vblank vblank;
+ memcpy(&vblank, &buffer[idx], sizeof(vblank));
+ callback.Run(vblank.sequence, vblank.tv_sec, vblank.tv_usec,
+ vblank.user_data);
+ } break;
+ case DRM_EVENT_VBLANK:
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ idx += event.length;
+ }
-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);
+ return true;
}
bool CanQueryForResources(int fd) {
@@ -102,13 +125,70 @@ bool CanQueryForResources(int fd) {
} // namespace
+class DrmDevice::PageFlipManager
+ : public base::RefCountedThreadSafe<DrmDevice::PageFlipManager> {
+ public:
+ PageFlipManager() : next_id_(0) {}
+
+ void OnPageFlip(uint32_t frame,
+ uint32_t seconds,
+ uint32_t useconds,
+ uint64_t id) {
+ auto it =
+ std::find_if(callbacks_.begin(), callbacks_.end(), FindCallback(id));
+ if (it == callbacks_.end()) {
+ LOG(WARNING) << "Could not find callback for page flip id=" << id;
+ return;
+ }
+
+ DrmDevice::PageFlipCallback callback = it->callback;
+ callbacks_.erase(it);
+ callback.Run(frame, seconds, useconds);
+ }
+
+ uint64_t GetNextId() { return next_id_++; }
+
+ void RegisterCallback(uint64_t id,
+ const DrmDevice::PageFlipCallback& callback) {
+ callbacks_.push_back({id, callback});
+ }
+
+ private:
+ friend class base::RefCountedThreadSafe<DrmDevice::PageFlipManager>;
+ ~PageFlipManager() {}
+
+ struct PageFlip {
+ uint64_t id;
+ DrmDevice::PageFlipCallback callback;
+ };
+
+ struct FindCallback {
+ FindCallback(uint64_t id) : id(id) {}
+
+ bool operator()(const PageFlip& flip) const { return flip.id == id; }
+
+ uint64_t id;
+ };
+
+ uint64_t next_id_;
+
+ std::vector<PageFlip> callbacks_;
+
+ DISALLOW_COPY_AND_ASSIGN(PageFlipManager);
+};
+
class DrmDevice::IOWatcher
: public base::RefCountedThreadSafe<DrmDevice::IOWatcher>,
public base::MessagePumpLibevent::Watcher {
public:
IOWatcher(int fd,
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
- : io_task_runner_(io_task_runner), paused_(true), fd_(fd) {}
+ const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner,
+ const scoped_refptr<DrmDevice::PageFlipManager>& page_flip_manager)
+ : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ io_task_runner_(io_task_runner),
+ page_flip_manager_(page_flip_manager),
+ paused_(true),
+ fd_(fd) {}
void SetPaused(bool paused) {
if (paused_ == paused)
@@ -152,23 +232,33 @@ class DrmDevice::IOWatcher
done->Signal();
}
+ void OnPageFlipOnIO(uint32_t frame,
+ uint32_t seconds,
+ uint32_t useconds,
+ uint64_t id) {
+ main_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&DrmDevice::PageFlipManager::OnPageFlip, page_flip_manager_,
+ frame, seconds, useconds, id));
+ }
+
// base::MessagePumpLibevent::Watcher overrides:
void OnFileCanReadWithoutBlocking(int fd) override {
DCHECK(base::MessageLoopForIO::IsCurrent());
TRACE_EVENT1("drm", "OnDrmEvent", "socket", fd);
- drmEventContext event;
- event.version = DRM_EVENT_CONTEXT_VERSION;
- event.page_flip_handler = HandlePageFlipEventOnIO;
- event.vblank_handler = nullptr;
-
- drmHandleEvent(fd, &event);
+ if (!ProcessDrmEvent(
+ fd, base::Bind(&DrmDevice::IOWatcher::OnPageFlipOnIO, this)))
+ UnregisterOnIO();
dnicoara 2015/04/28 14:42:49 Also, since it was a trivial change, unregistered
}
void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
+ scoped_refptr<DrmDevice::PageFlipManager> page_flip_manager_;
+
base::MessagePumpLibevent::FileDescriptorWatcher controller_;
bool paused_;
@@ -181,14 +271,17 @@ DrmDevice::DrmDevice(const base::FilePath& device_path)
: device_path_(device_path),
file_(device_path,
base::File::FLAG_OPEN | base::File::FLAG_READ |
- base::File::FLAG_WRITE) {
+ base::File::FLAG_WRITE),
+ page_flip_manager_(new PageFlipManager()) {
LOG_IF(FATAL, !file_.IsValid())
<< "Failed to open '" << device_path_.value()
<< "': " << base::File::ErrorToString(file_.error_details());
}
DrmDevice::DrmDevice(const base::FilePath& device_path, base::File file)
- : device_path_(device_path), file_(file.Pass()) {
+ : device_path_(device_path),
+ file_(file.Pass()),
+ page_flip_manager_(new PageFlipManager()) {
}
DrmDevice::~DrmDevice() {
@@ -223,7 +316,8 @@ void DrmDevice::InitializeTaskRunner(
const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
DCHECK(!task_runner_);
task_runner_ = task_runner;
- watcher_ = new IOWatcher(file_.GetPlatformFile(), task_runner_);
+ watcher_ =
+ new IOWatcher(file_.GetPlatformFile(), task_runner_, page_flip_manager_);
}
ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) {
@@ -307,24 +401,20 @@ bool DrmDevice::PageFlip(uint32_t crtc_id,
// 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));
+ uint64_t id = page_flip_manager_->GetNextId();
if (!drmModePageFlip(file_.GetPlatformFile(), crtc_id, framebuffer,
- DRM_MODE_PAGE_FLIP_EVENT, payload.get())) {
+ DRM_MODE_PAGE_FLIP_EVENT, reinterpret_cast<void*>(id))) {
// If successful the payload will be removed by a PageFlip event.
- ignore_result(payload.release());
+ page_flip_manager_->RegisterCallback(id, callback);
// 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("drm", "OnDrmEvent", "socket", file_.GetPlatformFile());
- drmEventContext event;
- event.version = DRM_EVENT_CONTEXT_VERSION;
- event.page_flip_handler = HandlePageFlipEventOnUI;
- event.vblank_handler = nullptr;
-
- drmHandleEvent(file_.GetPlatformFile(), &event);
+ ProcessDrmEvent(
+ file_.GetPlatformFile(),
+ base::Bind(&PageFlipManager::OnPageFlip, page_flip_manager_));
}
return true;
« no previous file with comments | « ui/ozone/platform/drm/gpu/drm_device.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698