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

Side by Side Diff: ui/ozone/platform/drm/gpu/drm_device.cc

Issue 1311043016: Switch DRM platform to using a separate thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@mv-drm-calls-on-thread2
Patch Set: . Created 5 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/ozone/platform/drm/gpu/drm_device.h" 5 #include "ui/ozone/platform/drm/gpu/drm_device.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/mman.h> 8 #include <sys/mman.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 #include <xf86drm.h> 10 #include <xf86drm.h>
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 bool CanQueryForResources(int fd) { 107 bool CanQueryForResources(int fd) {
108 drm_mode_card_res resources; 108 drm_mode_card_res resources;
109 memset(&resources, 0, sizeof(resources)); 109 memset(&resources, 0, sizeof(resources));
110 // If there is no error getting DRM resources then assume this is a 110 // If there is no error getting DRM resources then assume this is a
111 // modesetting device. 111 // modesetting device.
112 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources); 112 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
113 } 113 }
114 114
115 } // namespace 115 } // namespace
116 116
117 class DrmDevice::PageFlipManager 117 class DrmDevice::PageFlipManager {
118 : public base::RefCountedThreadSafe<DrmDevice::PageFlipManager> {
119 public: 118 public:
120 PageFlipManager() : next_id_(0) {} 119 PageFlipManager() : next_id_(0) {}
120 ~PageFlipManager() {}
121 121
122 void OnPageFlip(uint32_t frame, 122 void OnPageFlip(uint32_t frame,
123 uint32_t seconds, 123 uint32_t seconds,
124 uint32_t useconds, 124 uint32_t useconds,
125 uint64_t id) { 125 uint64_t id) {
126 auto it = 126 auto it =
127 std::find_if(callbacks_.begin(), callbacks_.end(), FindCallback(id)); 127 std::find_if(callbacks_.begin(), callbacks_.end(), FindCallback(id));
128 if (it == callbacks_.end()) { 128 if (it == callbacks_.end()) {
129 LOG(WARNING) << "Could not find callback for page flip id=" << id; 129 LOG(WARNING) << "Could not find callback for page flip id=" << id;
130 return; 130 return;
(...skipping 11 matching lines...) Expand all
142 142
143 uint64_t GetNextId() { return next_id_++; } 143 uint64_t GetNextId() { return next_id_++; }
144 144
145 void RegisterCallback(uint64_t id, 145 void RegisterCallback(uint64_t id,
146 uint64_t pending_calls, 146 uint64_t pending_calls,
147 const DrmDevice::PageFlipCallback& callback) { 147 const DrmDevice::PageFlipCallback& callback) {
148 callbacks_.push_back({id, pending_calls, callback}); 148 callbacks_.push_back({id, pending_calls, callback});
149 } 149 }
150 150
151 private: 151 private:
152 friend class base::RefCountedThreadSafe<DrmDevice::PageFlipManager>;
153 ~PageFlipManager() {}
154
155 struct PageFlip { 152 struct PageFlip {
156 uint64_t id; 153 uint64_t id;
157 uint32_t pending_calls; 154 uint32_t pending_calls;
158 DrmDevice::PageFlipCallback callback; 155 DrmDevice::PageFlipCallback callback;
159 }; 156 };
160 157
161 struct FindCallback { 158 struct FindCallback {
162 FindCallback(uint64_t id) : id(id) {} 159 FindCallback(uint64_t id) : id(id) {}
163 160
164 bool operator()(const PageFlip& flip) const { return flip.id == id; } 161 bool operator()(const PageFlip& flip) const { return flip.id == id; }
165 162
166 uint64_t id; 163 uint64_t id;
167 }; 164 };
168 165
169 uint64_t next_id_; 166 uint64_t next_id_;
170 167
171 std::vector<PageFlip> callbacks_; 168 std::vector<PageFlip> callbacks_;
172 169
173 DISALLOW_COPY_AND_ASSIGN(PageFlipManager); 170 DISALLOW_COPY_AND_ASSIGN(PageFlipManager);
174 }; 171 };
175 172
176 class DrmDevice::IOWatcher 173 class DrmDevice::IOWatcher : public base::MessagePumpLibevent::Watcher {
177 : public base::RefCountedThreadSafe<DrmDevice::IOWatcher>,
178 public base::MessagePumpLibevent::Watcher {
179 public: 174 public:
180 IOWatcher(int fd, 175 IOWatcher(int fd, DrmDevice::PageFlipManager* page_flip_manager)
181 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, 176 : page_flip_manager_(page_flip_manager), fd_(fd) {
182 const scoped_refptr<DrmDevice::PageFlipManager>& page_flip_manager) 177 Register();
183 : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
184 io_task_runner_(io_task_runner),
185 page_flip_manager_(page_flip_manager),
186 fd_(fd) {
187 io_task_runner_->PostTask(FROM_HERE,
188 base::Bind(&IOWatcher::RegisterOnIO, this));
189 } 178 }
190 179
191 void Shutdown() { 180 ~IOWatcher() override { Unregister(); }
192 io_task_runner_->PostTask(FROM_HERE,
193 base::Bind(&IOWatcher::UnregisterOnIO, this));
194 }
195 181
196 private: 182 private:
197 friend class base::RefCountedThreadSafe<IOWatcher>; 183 void Register() {
198
199 ~IOWatcher() override {}
200
201 void RegisterOnIO() {
202 DCHECK(base::MessageLoopForIO::IsCurrent()); 184 DCHECK(base::MessageLoopForIO::IsCurrent());
203 base::MessageLoopForIO::current()->WatchFileDescriptor( 185 base::MessageLoopForIO::current()->WatchFileDescriptor(
204 fd_, true, base::MessageLoopForIO::WATCH_READ, &controller_, this); 186 fd_, true, base::MessageLoopForIO::WATCH_READ, &controller_, this);
205 } 187 }
206 188
207 void UnregisterOnIO() { 189 void Unregister() {
208 DCHECK(base::MessageLoopForIO::IsCurrent()); 190 DCHECK(base::MessageLoopForIO::IsCurrent());
209 controller_.StopWatchingFileDescriptor(); 191 controller_.StopWatchingFileDescriptor();
210 } 192 }
211 193
212 void OnPageFlipOnIO(uint32_t frame,
213 uint32_t seconds,
214 uint32_t useconds,
215 uint64_t id) {
216 main_task_runner_->PostTask(
217 FROM_HERE,
218 base::Bind(&DrmDevice::PageFlipManager::OnPageFlip, page_flip_manager_,
219 frame, seconds, useconds, id));
220 }
221
222 // base::MessagePumpLibevent::Watcher overrides: 194 // base::MessagePumpLibevent::Watcher overrides:
223 void OnFileCanReadWithoutBlocking(int fd) override { 195 void OnFileCanReadWithoutBlocking(int fd) override {
224 DCHECK(base::MessageLoopForIO::IsCurrent()); 196 DCHECK(base::MessageLoopForIO::IsCurrent());
225 TRACE_EVENT1("drm", "OnDrmEvent", "socket", fd); 197 TRACE_EVENT1("drm", "OnDrmEvent", "socket", fd);
226 198
227 if (!ProcessDrmEvent( 199 if (!ProcessDrmEvent(fd, base::Bind(&DrmDevice::PageFlipManager::OnPageFlip,
228 fd, base::Bind(&DrmDevice::IOWatcher::OnPageFlipOnIO, this))) 200 base::Unretained(page_flip_manager_))))
229 UnregisterOnIO(); 201 Unregister();
230 } 202 }
231 203
232 void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); } 204 void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
233 205
234 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; 206 DrmDevice::PageFlipManager* page_flip_manager_;
235 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
236
237 scoped_refptr<DrmDevice::PageFlipManager> page_flip_manager_;
238 207
239 base::MessagePumpLibevent::FileDescriptorWatcher controller_; 208 base::MessagePumpLibevent::FileDescriptorWatcher controller_;
240 209
241 int fd_; 210 int fd_;
242 211
243 DISALLOW_COPY_AND_ASSIGN(IOWatcher); 212 DISALLOW_COPY_AND_ASSIGN(IOWatcher);
244 }; 213 };
245 214
246 DrmDevice::DrmDevice(const base::FilePath& device_path, base::File file) 215 DrmDevice::DrmDevice(const base::FilePath& device_path, base::File file)
247 : device_path_(device_path), 216 : device_path_(device_path),
248 file_(file.Pass()), 217 file_(file.Pass()),
249 page_flip_manager_(new PageFlipManager()) { 218 page_flip_manager_(new PageFlipManager()) {}
250 }
251 219
252 DrmDevice::~DrmDevice() { 220 DrmDevice::~DrmDevice() {}
253 if (watcher_)
254 watcher_->Shutdown();
255 }
256 221
257 bool DrmDevice::Initialize(bool use_atomic) { 222 bool DrmDevice::Initialize(bool use_atomic) {
258 // Ignore devices that cannot perform modesetting. 223 // Ignore devices that cannot perform modesetting.
259 if (!CanQueryForResources(file_.GetPlatformFile())) { 224 if (!CanQueryForResources(file_.GetPlatformFile())) {
260 VLOG(2) << "Cannot query for resources for '" << device_path_.value() 225 VLOG(2) << "Cannot query for resources for '" << device_path_.value()
261 << "'"; 226 << "'";
262 return false; 227 return false;
263 } 228 }
264 229
265 #if defined(USE_DRM_ATOMIC) 230 #if defined(USE_DRM_ATOMIC)
266 // Use atomic only if the build, kernel & flags all allow it. 231 // Use atomic only if the build, kernel & flags all allow it.
267 if (use_atomic && SetCapability(DRM_CLIENT_CAP_ATOMIC, 1)) 232 if (use_atomic && SetCapability(DRM_CLIENT_CAP_ATOMIC, 1))
268 plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic()); 233 plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic());
269 #endif // defined(USE_DRM_ATOMIC) 234 #endif // defined(USE_DRM_ATOMIC)
270 235
271 if (!plane_manager_) 236 if (!plane_manager_)
272 plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); 237 plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
273 if (!plane_manager_->Initialize(this)) { 238 if (!plane_manager_->Initialize(this)) {
274 LOG(ERROR) << "Failed to initialize the plane manager for " 239 LOG(ERROR) << "Failed to initialize the plane manager for "
275 << device_path_.value(); 240 << device_path_.value();
276 plane_manager_.reset(); 241 plane_manager_.reset();
277 return false; 242 return false;
278 } 243 }
279 244
245 watcher_.reset(
246 new IOWatcher(file_.GetPlatformFile(), page_flip_manager_.get()));
247
280 return true; 248 return true;
281 } 249 }
282 250
283 void DrmDevice::InitializeTaskRunner(
284 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
285 DCHECK(!task_runner_);
286 task_runner_ = task_runner;
287 watcher_ =
288 new IOWatcher(file_.GetPlatformFile(), task_runner_, page_flip_manager_);
289 }
290
291 ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) { 251 ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) {
292 DCHECK(file_.IsValid()); 252 DCHECK(file_.IsValid());
293 return ScopedDrmCrtcPtr(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id)); 253 return ScopedDrmCrtcPtr(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id));
294 } 254 }
295 255
296 bool DrmDevice::SetCrtc(uint32_t crtc_id, 256 bool DrmDevice::SetCrtc(uint32_t crtc_id,
297 uint32_t framebuffer, 257 uint32_t framebuffer,
298 std::vector<uint32_t> connectors, 258 std::vector<uint32_t> connectors,
299 drmModeModeInfo* mode) { 259 drmModeModeInfo* mode) {
300 DCHECK(file_.IsValid()); 260 DCHECK(file_.IsValid());
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 b.push_back(lut[i].b); 527 b.push_back(lut[i].b);
568 } 528 }
569 529
570 DCHECK(file_.IsValid()); 530 DCHECK(file_.IsValid());
571 TRACE_EVENT0("drm", "DrmDevice::SetGamma"); 531 TRACE_EVENT0("drm", "DrmDevice::SetGamma");
572 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0], 532 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0],
573 &g[0], &b[0]) == 0); 533 &g[0], &b[0]) == 0);
574 } 534 }
575 535
576 } // namespace ui 536 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698