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

Side by Side Diff: ui/ozone/platform/dri/dri_wrapper.cc

Issue 940903002: video_decode_accelerator_unittest: enable test on ozone surfaceless (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix remaining thumbnail issues Created 5 years, 9 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/dri/dri_wrapper.h ('k') | ui/ozone/platform/dri/gbm_surfaceless.cc » ('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/dri/dri_wrapper.h" 5 #include "ui/ozone/platform/dri/dri_wrapper.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>
11 #include <xf86drmMode.h> 11 #include <xf86drmMode.h>
12 12
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/message_loop/message_loop.h" 14 #include "base/message_loop/message_loop.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/synchronization/waitable_event.h"
16 #include "base/task_runner.h" 17 #include "base/task_runner.h"
17 #include "base/thread_task_runner_handle.h" 18 #include "base/thread_task_runner_handle.h"
18 #include "base/trace_event/trace_event.h" 19 #include "base/trace_event/trace_event.h"
19 #include "third_party/skia/include/core/SkImageInfo.h" 20 #include "third_party/skia/include/core/SkImageInfo.h"
20 #include "ui/ozone/platform/dri/dri_util.h" 21 #include "ui/ozone/platform/dri/dri_util.h"
21 #include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h" 22 #include "ui/ozone/platform/dri/hardware_display_plane_manager_legacy.h"
22 23
23 namespace ui { 24 namespace ui {
24 25
25 namespace { 26 namespace {
26 27
27 struct PageFlipPayload { 28 struct PageFlipPayload {
28 PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner, 29 PageFlipPayload(const scoped_refptr<base::TaskRunner>& task_runner,
29 const DriWrapper::PageFlipCallback& callback) 30 const DriWrapper::PageFlipCallback& callback)
30 : task_runner(task_runner), callback(callback) {} 31 : task_runner(task_runner), callback(callback) {}
31 32
32 // Task runner for the thread scheduling the page flip event. This is used to 33 // Task runner for the thread scheduling the page flip event. This is used to
33 // run the callback on the same thread the callback was created on. 34 // run the callback on the same thread the callback was created on.
34 scoped_refptr<base::TaskRunner> task_runner; 35 scoped_refptr<base::TaskRunner> task_runner;
35 DriWrapper::PageFlipCallback callback; 36 DriWrapper::PageFlipCallback callback;
36 }; 37 };
37 38
39 struct PageFlipSyncPayload {
40 unsigned int frame;
41 unsigned int seconds;
42 unsigned int useconds;
43 };
44
38 bool DrmCreateDumbBuffer(int fd, 45 bool DrmCreateDumbBuffer(int fd,
39 const SkImageInfo& info, 46 const SkImageInfo& info,
40 uint32_t* handle, 47 uint32_t* handle,
41 uint32_t* stride) { 48 uint32_t* stride) {
42 struct drm_mode_create_dumb request; 49 struct drm_mode_create_dumb request;
43 memset(&request, 0, sizeof(request)); 50 memset(&request, 0, sizeof(request));
44 request.width = info.width(); 51 request.width = info.width();
45 request.height = info.height(); 52 request.height = info.height();
46 request.bpp = info.bytesPerPixel() << 3; 53 request.bpp = info.bytesPerPixel() << 3;
47 request.flags = 0; 54 request.flags = 0;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 88
82 void HandlePageFlipEventOnUI(int fd, 89 void HandlePageFlipEventOnUI(int fd,
83 unsigned int frame, 90 unsigned int frame,
84 unsigned int seconds, 91 unsigned int seconds,
85 unsigned int useconds, 92 unsigned int useconds,
86 void* data) { 93 void* data) {
87 scoped_ptr<PageFlipPayload> payload(static_cast<PageFlipPayload*>(data)); 94 scoped_ptr<PageFlipPayload> payload(static_cast<PageFlipPayload*>(data));
88 payload->callback.Run(frame, seconds, useconds); 95 payload->callback.Run(frame, seconds, useconds);
89 } 96 }
90 97
98 void HandlePageFlipEventSync(int fd,
99 unsigned int frame,
100 unsigned int seconds,
101 unsigned int useconds,
102 void* data) {
103 PageFlipSyncPayload* payload = static_cast<PageFlipSyncPayload*>(data);
104 payload->frame = frame;
105 payload->seconds = seconds;
106 payload->useconds = useconds;
107 }
108
91 bool CanQueryForResources(int fd) { 109 bool CanQueryForResources(int fd) {
92 drm_mode_card_res resources; 110 drm_mode_card_res resources;
93 memset(&resources, 0, sizeof(resources)); 111 memset(&resources, 0, sizeof(resources));
94 // If there is no error getting DRM resources then assume this is a 112 // If there is no error getting DRM resources then assume this is a
95 // modesetting device. 113 // modesetting device.
96 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources); 114 return !drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &resources);
97 } 115 }
98 116
99 } // namespace 117 } // namespace
100 118
101 class DriWrapper::IOWatcher 119 class DriWrapper::IOWatcher
102 : public base::RefCountedThreadSafe<DriWrapper::IOWatcher>, 120 : public base::RefCountedThreadSafe<DriWrapper::IOWatcher>,
103 public base::MessagePumpLibevent::Watcher { 121 public base::MessagePumpLibevent::Watcher {
104 public: 122 public:
105 IOWatcher(int fd, 123 IOWatcher(int fd,
106 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner) 124 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
107 : io_task_runner_(io_task_runner) { 125 : io_task_runner_(io_task_runner), paused_(false), fd_(fd) {
108 io_task_runner_->PostTask(FROM_HERE, 126 io_task_runner_->PostTask(FROM_HERE,
109 base::Bind(&IOWatcher::RegisterOnIO, this, fd)); 127 base::Bind(&IOWatcher::RegisterOnIO, this));
128 }
129
130 void SetPaused(bool value) {
131 bool paused = !!value;
132 if (paused_ == paused)
133 return;
134
135 base::WaitableEvent done(false, false);
136 io_task_runner_->PostTask(
137 FROM_HERE, base::Bind(&IOWatcher::SetPausedOnIO, this, paused, &done));
138 paused_ = paused;
110 } 139 }
111 140
112 void Shutdown() { 141 void Shutdown() {
113 io_task_runner_->PostTask(FROM_HERE, 142 io_task_runner_->PostTask(FROM_HERE,
114 base::Bind(&IOWatcher::UnregisterOnIO, this)); 143 base::Bind(&IOWatcher::UnregisterOnIO, this));
115 } 144 }
116 145
117 private: 146 private:
118 friend class base::RefCountedThreadSafe<IOWatcher>; 147 friend class base::RefCountedThreadSafe<IOWatcher>;
119 148
120 ~IOWatcher() override {} 149 ~IOWatcher() override {
150 SetPaused(true);
151 }
121 152
122 void RegisterOnIO(int fd) { 153 void RegisterOnIO() {
123 DCHECK(base::MessageLoopForIO::IsCurrent()); 154 DCHECK(base::MessageLoopForIO::IsCurrent());
124 base::MessageLoopForIO::current()->WatchFileDescriptor( 155 base::MessageLoopForIO::current()->WatchFileDescriptor(
125 fd, true, base::MessageLoopForIO::WATCH_READ, &controller_, this); 156 fd_, true, base::MessageLoopForIO::WATCH_READ, &controller_, this);
126 } 157 }
127 158
128 void UnregisterOnIO() { 159 void UnregisterOnIO() {
129 DCHECK(base::MessageLoopForIO::IsCurrent()); 160 DCHECK(base::MessageLoopForIO::IsCurrent());
130 controller_.StopWatchingFileDescriptor(); 161 controller_.StopWatchingFileDescriptor();
131 } 162 }
132 163
164 void SetPausedOnIO(bool paused, base::WaitableEvent* done) {
165 DCHECK(base::MessageLoopForIO::IsCurrent());
166 if (paused)
167 UnregisterOnIO();
168 else
169 RegisterOnIO();
170 done->Signal();
171 }
172
133 // base::MessagePumpLibevent::Watcher overrides: 173 // base::MessagePumpLibevent::Watcher overrides:
134 void OnFileCanReadWithoutBlocking(int fd) override { 174 void OnFileCanReadWithoutBlocking(int fd) override {
135 DCHECK(base::MessageLoopForIO::IsCurrent()); 175 DCHECK(base::MessageLoopForIO::IsCurrent());
136 TRACE_EVENT1("dri", "OnDrmEvent", "socket", fd); 176 TRACE_EVENT1("dri", "OnDrmEvent", "socket", fd);
137 177
138 drmEventContext event; 178 drmEventContext event;
139 event.version = DRM_EVENT_CONTEXT_VERSION; 179 event.version = DRM_EVENT_CONTEXT_VERSION;
140 event.page_flip_handler = HandlePageFlipEventOnIO; 180 event.page_flip_handler = HandlePageFlipEventOnIO;
141 event.vblank_handler = nullptr; 181 event.vblank_handler = nullptr;
142 182
143 drmHandleEvent(fd, &event); 183 drmHandleEvent(fd, &event);
144 } 184 }
145 185
146 void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); } 186 void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); }
147 187
148 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; 188 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
149 189
150 base::MessagePumpLibevent::FileDescriptorWatcher controller_; 190 base::MessagePumpLibevent::FileDescriptorWatcher controller_;
151 191
192 bool paused_;
193 int fd_;
194
152 DISALLOW_COPY_AND_ASSIGN(IOWatcher); 195 DISALLOW_COPY_AND_ASSIGN(IOWatcher);
153 }; 196 };
154 197
155 DriWrapper::DriWrapper(const base::FilePath& device_path) 198 DriWrapper::DriWrapper(const base::FilePath& device_path)
156 : device_path_(device_path), 199 : device_path_(device_path),
157 file_(device_path, 200 file_(device_path,
158 base::File::FLAG_OPEN | base::File::FLAG_READ | 201 base::File::FLAG_OPEN | base::File::FLAG_READ |
159 base::File::FLAG_WRITE) { 202 base::File::FLAG_WRITE) {
160 LOG_IF(FATAL, !file_.IsValid()) 203 LOG_IF(FATAL, !file_.IsValid())
161 << "Failed to open '" << device_path_.value() 204 << "Failed to open '" << device_path_.value()
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 stride, handle, framebuffer); 304 stride, handle, framebuffer);
262 } 305 }
263 306
264 bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) { 307 bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) {
265 DCHECK(file_.IsValid()); 308 DCHECK(file_.IsValid());
266 TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer", 309 TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer",
267 "framebuffer", framebuffer); 310 "framebuffer", framebuffer);
268 return !drmModeRmFB(file_.GetPlatformFile(), framebuffer); 311 return !drmModeRmFB(file_.GetPlatformFile(), framebuffer);
269 } 312 }
270 313
271 bool DriWrapper::PageFlip(uint32_t crtc_id, 314 bool DriWrapper::PageFlip(uint32_t crtc_id,
dnicoara 2015/02/26 16:52:59 You can pass in an |is_sync| boolean in here and r
llandwerlin-old 2015/02/26 17:37:22 Done. New CL : https://codereview.chromium.org/960
272 uint32_t framebuffer, 315 uint32_t framebuffer,
273 const PageFlipCallback& callback) { 316 const PageFlipCallback& callback) {
274 DCHECK(file_.IsValid()); 317 DCHECK(file_.IsValid());
275 TRACE_EVENT2("dri", "DriWrapper::PageFlip", 318 TRACE_EVENT2("dri", "DriWrapper::PageFlip",
276 "crtc", crtc_id, 319 "crtc", crtc_id,
277 "framebuffer", framebuffer); 320 "framebuffer", framebuffer);
278 321
322 watcher_->SetPaused(false);
323
279 // NOTE: Calling drmModeSetCrtc will immediately update the state, though 324 // NOTE: Calling drmModeSetCrtc will immediately update the state, though
280 // callbacks to already scheduled page flips will be honored by the kernel. 325 // callbacks to already scheduled page flips will be honored by the kernel.
281 scoped_ptr<PageFlipPayload> payload( 326 scoped_ptr<PageFlipPayload> payload(
282 new PageFlipPayload(base::ThreadTaskRunnerHandle::Get(), callback)); 327 new PageFlipPayload(base::ThreadTaskRunnerHandle::Get(), callback));
283 if (!drmModePageFlip(file_.GetPlatformFile(), crtc_id, framebuffer, 328 if (!drmModePageFlip(file_.GetPlatformFile(), crtc_id, framebuffer,
284 DRM_MODE_PAGE_FLIP_EVENT, payload.get())) { 329 DRM_MODE_PAGE_FLIP_EVENT, payload.get())) {
285 // If successful the payload will be removed by a PageFlip event. 330 // If successful the payload will be removed by a PageFlip event.
286 ignore_result(payload.release()); 331 ignore_result(payload.release());
287 332
288 // If a task runner isn't installed then fall back to synchronously handling 333 // If a task runner isn't installed then fall back to synchronously handling
289 // the page flip events. 334 // the page flip events.
290 if (!task_runner_) { 335 if (!task_runner_) {
291 TRACE_EVENT1("dri", "OnDrmEvent", "socket", file_.GetPlatformFile()); 336 TRACE_EVENT1("dri", "OnDrmEvent", "socket", file_.GetPlatformFile());
292 337
293 drmEventContext event; 338 drmEventContext event;
294 event.version = DRM_EVENT_CONTEXT_VERSION; 339 event.version = DRM_EVENT_CONTEXT_VERSION;
295 event.page_flip_handler = HandlePageFlipEventOnUI; 340 event.page_flip_handler = HandlePageFlipEventOnUI;
296 event.vblank_handler = nullptr; 341 event.vblank_handler = nullptr;
297 342
298 drmHandleEvent(file_.GetPlatformFile(), &event); 343 drmHandleEvent(file_.GetPlatformFile(), &event);
299 } 344 }
300 345
301 return true; 346 return true;
302 } 347 }
303 348
304 return false; 349 return false;
305 } 350 }
306 351
352 bool DriWrapper::PageFlipSync(uint32_t crtc_id,
353 uint32_t framebuffer,
354 const PageFlipCallback& callback) {
355 DCHECK(file_.IsValid());
356 TRACE_EVENT2("dri", "DriWrapper::PageFlip", "crtc", crtc_id, "framebuffer",
357 framebuffer);
358
359 watcher_->SetPaused(true);
360
361 PageFlipSyncPayload payload;
362 if (!drmModePageFlip(file_.GetPlatformFile(), crtc_id, framebuffer,
363 DRM_MODE_PAGE_FLIP_EVENT, &payload)) {
364 TRACE_EVENT1("dri", "OnDrmEvent", "socket", file_.GetPlatformFile());
365
366 drmEventContext event;
367 event.version = DRM_EVENT_CONTEXT_VERSION;
368 event.page_flip_handler = HandlePageFlipEventSync;
369 event.vblank_handler = nullptr;
370
371 drmHandleEvent(file_.GetPlatformFile(), &event);
372
373 callback.Run(payload.frame, payload.seconds, payload.useconds);
374 return true;
375 }
376
377 return false;
378 }
379
307 bool DriWrapper::PageFlipOverlay(uint32_t crtc_id, 380 bool DriWrapper::PageFlipOverlay(uint32_t crtc_id,
308 uint32_t framebuffer, 381 uint32_t framebuffer,
309 const gfx::Rect& location, 382 const gfx::Rect& location,
310 const gfx::Rect& source, 383 const gfx::Rect& source,
311 int overlay_plane) { 384 int overlay_plane) {
312 DCHECK(file_.IsValid()); 385 DCHECK(file_.IsValid());
313 TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay", 386 TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay",
314 "crtc", crtc_id, 387 "crtc", crtc_id,
315 "framebuffer", framebuffer); 388 "framebuffer", framebuffer);
316 return !drmModeSetPlane(file_.GetPlatformFile(), overlay_plane, crtc_id, 389 return !drmModeSetPlane(file_.GetPlatformFile(), overlay_plane, crtc_id,
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 DCHECK(file_.IsValid()); 500 DCHECK(file_.IsValid());
428 return (drmSetMaster(file_.GetPlatformFile()) == 0); 501 return (drmSetMaster(file_.GetPlatformFile()) == 0);
429 } 502 }
430 503
431 bool DriWrapper::DropMaster() { 504 bool DriWrapper::DropMaster() {
432 DCHECK(file_.IsValid()); 505 DCHECK(file_.IsValid());
433 return (drmDropMaster(file_.GetPlatformFile()) == 0); 506 return (drmDropMaster(file_.GetPlatformFile()) == 0);
434 } 507 }
435 508
436 } // namespace ui 509 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/dri/dri_wrapper.h ('k') | ui/ozone/platform/dri/gbm_surfaceless.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698