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

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: update & fix clang Created 5 years, 2 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
« no previous file with comments | « ui/ozone/platform/drm/gpu/drm_device.h ('k') | ui/ozone/platform/drm/gpu/drm_device_manager.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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, 215 DrmDevice::DrmDevice(const base::FilePath& device_path,
247 base::File file, 216 base::File file,
248 bool is_primary_device) 217 bool is_primary_device)
249 : device_path_(device_path), 218 : device_path_(device_path),
250 file_(file.Pass()), 219 file_(file.Pass()),
251 page_flip_manager_(new PageFlipManager()), 220 page_flip_manager_(new PageFlipManager()),
252 is_primary_device_(is_primary_device) {} 221 is_primary_device_(is_primary_device) {}
253 222
254 DrmDevice::~DrmDevice() { 223 DrmDevice::~DrmDevice() {}
255 if (watcher_)
256 watcher_->Shutdown();
257 }
258 224
259 bool DrmDevice::Initialize(bool use_atomic) { 225 bool DrmDevice::Initialize(bool use_atomic) {
260 // Ignore devices that cannot perform modesetting. 226 // Ignore devices that cannot perform modesetting.
261 if (!CanQueryForResources(file_.GetPlatformFile())) { 227 if (!CanQueryForResources(file_.GetPlatformFile())) {
262 VLOG(2) << "Cannot query for resources for '" << device_path_.value() 228 VLOG(2) << "Cannot query for resources for '" << device_path_.value()
263 << "'"; 229 << "'";
264 return false; 230 return false;
265 } 231 }
266 232
267 #if defined(USE_DRM_ATOMIC) 233 #if defined(USE_DRM_ATOMIC)
268 // Use atomic only if the build, kernel & flags all allow it. 234 // Use atomic only if the build, kernel & flags all allow it.
269 if (use_atomic && SetCapability(DRM_CLIENT_CAP_ATOMIC, 1)) 235 if (use_atomic && SetCapability(DRM_CLIENT_CAP_ATOMIC, 1))
270 plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic()); 236 plane_manager_.reset(new HardwareDisplayPlaneManagerAtomic());
271 #endif // defined(USE_DRM_ATOMIC) 237 #endif // defined(USE_DRM_ATOMIC)
272 238
273 if (!plane_manager_) 239 if (!plane_manager_)
274 plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy()); 240 plane_manager_.reset(new HardwareDisplayPlaneManagerLegacy());
275 if (!plane_manager_->Initialize(this)) { 241 if (!plane_manager_->Initialize(this)) {
276 LOG(ERROR) << "Failed to initialize the plane manager for " 242 LOG(ERROR) << "Failed to initialize the plane manager for "
277 << device_path_.value(); 243 << device_path_.value();
278 plane_manager_.reset(); 244 plane_manager_.reset();
279 return false; 245 return false;
280 } 246 }
281 247
248 watcher_.reset(
249 new IOWatcher(file_.GetPlatformFile(), page_flip_manager_.get()));
250
282 return true; 251 return true;
283 } 252 }
284 253
285 void DrmDevice::InitializeTaskRunner(
286 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
287 DCHECK(!task_runner_);
288 task_runner_ = task_runner;
289 watcher_ =
290 new IOWatcher(file_.GetPlatformFile(), task_runner_, page_flip_manager_);
291 }
292
293 ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) { 254 ScopedDrmCrtcPtr DrmDevice::GetCrtc(uint32_t crtc_id) {
294 DCHECK(file_.IsValid()); 255 DCHECK(file_.IsValid());
295 return ScopedDrmCrtcPtr(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id)); 256 return ScopedDrmCrtcPtr(drmModeGetCrtc(file_.GetPlatformFile(), crtc_id));
296 } 257 }
297 258
298 bool DrmDevice::SetCrtc(uint32_t crtc_id, 259 bool DrmDevice::SetCrtc(uint32_t crtc_id,
299 uint32_t framebuffer, 260 uint32_t framebuffer,
300 std::vector<uint32_t> connectors, 261 std::vector<uint32_t> connectors,
301 drmModeModeInfo* mode) { 262 drmModeModeInfo* mode) {
302 DCHECK(file_.IsValid()); 263 DCHECK(file_.IsValid());
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 b.push_back(lut[i].b); 535 b.push_back(lut[i].b);
575 } 536 }
576 537
577 DCHECK(file_.IsValid()); 538 DCHECK(file_.IsValid());
578 TRACE_EVENT0("drm", "DrmDevice::SetGamma"); 539 TRACE_EVENT0("drm", "DrmDevice::SetGamma");
579 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0], 540 return (drmModeCrtcSetGamma(file_.GetPlatformFile(), crtc_id, r.size(), &r[0],
580 &g[0], &b[0]) == 0); 541 &g[0], &b[0]) == 0);
581 } 542 }
582 543
583 } // namespace ui 544 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/drm/gpu/drm_device.h ('k') | ui/ozone/platform/drm/gpu/drm_device_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698