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

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

Issue 960273003: ozone: dri: add synchronous SwapBuffers support on surfaceless (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Schedule asynchronous flip correctly on flip callback 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
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/hardware_display_controller.h" 5 #include "ui/ozone/platform/dri/hardware_display_controller.h"
6 6
7 #include <drm.h> 7 #include <drm.h>
8 #include <errno.h> 8 #include <errno.h>
9 #include <string.h> 9 #include <string.h>
10 #include <xf86drm.h> 10 #include <xf86drm.h>
11 11
12 #include "base/basictypes.h" 12 #include "base/basictypes.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "third_party/skia/include/core/SkCanvas.h" 15 #include "third_party/skia/include/core/SkCanvas.h"
16 #include "ui/gfx/geometry/point.h" 16 #include "ui/gfx/geometry/point.h"
17 #include "ui/gfx/geometry/size.h" 17 #include "ui/gfx/geometry/size.h"
18 #include "ui/ozone/platform/dri/crtc_controller.h" 18 #include "ui/ozone/platform/dri/crtc_controller.h"
19 #include "ui/ozone/platform/dri/dri_buffer.h" 19 #include "ui/ozone/platform/dri/dri_buffer.h"
20 #include "ui/ozone/platform/dri/dri_wrapper.h" 20 #include "ui/ozone/platform/dri/dri_wrapper.h"
21 #include "ui/ozone/public/native_pixmap.h" 21 #include "ui/ozone/public/native_pixmap.h"
22 22
23 namespace ui { 23 namespace ui {
24 24
25 HardwareDisplayController::PageFlipRequest::PageFlipRequest( 25 HardwareDisplayController::PageFlipRequest::PageFlipRequest(
26 const OverlayPlaneList& planes, 26 const OverlayPlaneList& planes,
27 bool is_sync,
27 const base::Closure& callback) 28 const base::Closure& callback)
28 : planes(planes), callback(callback) { 29 : planes(planes), is_sync(is_sync), callback(callback) {
29 } 30 }
30 31
31 HardwareDisplayController::PageFlipRequest::~PageFlipRequest() { 32 HardwareDisplayController::PageFlipRequest::~PageFlipRequest() {
32 } 33 }
33 34
34 HardwareDisplayController::HardwareDisplayController( 35 HardwareDisplayController::HardwareDisplayController(
35 scoped_ptr<CrtcController> controller) 36 scoped_ptr<CrtcController> controller)
36 : is_disabled_(true) { 37 : is_disabled_(true) {
37 memset(&mode_, 0, sizeof(mode_)); 38 memset(&mode_, 0, sizeof(mode_));
38 AddCrtc(controller.Pass()); 39 AddCrtc(controller.Pass());
(...skipping 17 matching lines...) Expand all
56 mode_ = mode; 57 mode_ = mode;
57 58
58 current_planes_ = std::vector<OverlayPlane>(1, primary); 59 current_planes_ = std::vector<OverlayPlane>(1, primary);
59 pending_planes_.clear(); 60 pending_planes_.clear();
60 ClearPendingRequests(); 61 ClearPendingRequests();
61 62
62 // Because a page flip is pending we need to leave some state for the 63 // Because a page flip is pending we need to leave some state for the
63 // callback. We use the modeset state since it is the only valid state. 64 // callback. We use the modeset state since it is the only valid state.
64 if (HasPendingPageFlips()) 65 if (HasPendingPageFlips())
65 requests_.push_back( 66 requests_.push_back(
66 PageFlipRequest(current_planes_, base::Bind(&base::DoNothing))); 67 PageFlipRequest(current_planes_, false, base::Bind(&base::DoNothing)));
67 68
68 return status; 69 return status;
69 } 70 }
70 71
71 bool HardwareDisplayController::Enable() { 72 bool HardwareDisplayController::Enable() {
72 TRACE_EVENT0("dri", "HDC::Enable"); 73 TRACE_EVENT0("dri", "HDC::Enable");
73 DCHECK(!current_planes_.empty()); 74 DCHECK(!current_planes_.empty());
74 const OverlayPlane* primary = OverlayPlane::GetPrimaryPlane(current_planes_); 75 const OverlayPlane* primary = OverlayPlane::GetPrimaryPlane(current_planes_);
75 76
76 return Modeset(*primary, mode_); 77 return Modeset(*primary, mode_);
77 } 78 }
78 79
79 void HardwareDisplayController::Disable() { 80 void HardwareDisplayController::Disable() {
80 TRACE_EVENT0("dri", "HDC::Disable"); 81 TRACE_EVENT0("dri", "HDC::Disable");
81 for (size_t i = 0; i < crtc_controllers_.size(); ++i) 82 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
82 crtc_controllers_[i]->Disable(); 83 crtc_controllers_[i]->Disable();
83 84
84 is_disabled_ = true; 85 is_disabled_ = true;
85 } 86 }
86 87
87 void HardwareDisplayController::QueueOverlayPlane(const OverlayPlane& plane) { 88 void HardwareDisplayController::QueueOverlayPlane(const OverlayPlane& plane) {
88 pending_planes_.push_back(plane); 89 pending_planes_.push_back(plane);
89 } 90 }
90 91
91 bool HardwareDisplayController::SchedulePageFlip( 92 bool HardwareDisplayController::SchedulePageFlip(
93 bool is_sync,
92 const base::Closure& callback) { 94 const base::Closure& callback) {
93 TRACE_EVENT0("dri", "HDC::SchedulePageFlip"); 95 TRACE_EVENT0("dri", "HDC::SchedulePageFlip");
94 96
95 // Ignore requests with no planes to schedule. 97 // Ignore requests with no planes to schedule.
96 if (pending_planes_.empty()) { 98 if (pending_planes_.empty()) {
97 callback.Run(); 99 callback.Run();
98 return true; 100 return true;
99 } 101 }
100 102
101 requests_.push_back(PageFlipRequest(pending_planes_, callback)); 103 requests_.push_back(PageFlipRequest(pending_planes_, is_sync, callback));
102 pending_planes_.clear(); 104 pending_planes_.clear();
103 105
104 // A request is being serviced right now. 106 // A request is being serviced right now.
105 if (HasPendingPageFlips()) 107 if (HasPendingPageFlips())
106 return true; 108 return true;
107 109
108 bool status = ActualSchedulePageFlip(); 110 bool status = ActualSchedulePageFlip(is_sync);
109 111
110 // No page flip event on failure so discard failed request. 112 // No page flip event on failure so discard failed request.
111 if (!status) 113 if (!status)
112 requests_.pop_front(); 114 requests_.pop_front();
113 115
114 return status; 116 return status;
115 } 117 }
116 118
117 bool HardwareDisplayController::SetCursor( 119 bool HardwareDisplayController::SetCursor(
118 const scoped_refptr<ScanoutBuffer>& buffer) { 120 const scoped_refptr<ScanoutBuffer>& buffer) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 if (HasPendingPageFlips()) 240 if (HasPendingPageFlips())
239 return; 241 return;
240 242
241 if (!requests_.empty()) 243 if (!requests_.empty())
242 ProcessPageFlipRequest(); 244 ProcessPageFlipRequest();
243 245
244 // ProcessPageFlipRequest() consumes a request. 246 // ProcessPageFlipRequest() consumes a request.
245 if (requests_.empty()) 247 if (requests_.empty())
246 return; 248 return;
247 249
250 PageFlipRequest request = requests_.front();
dnicoara 2015/02/27 13:58:44 Move this back in the if-statement.
llandwerlin-old 2015/02/27 14:09:04 Done.
248 // At this point we still have requests pending, so schedule the next request. 251 // At this point we still have requests pending, so schedule the next request.
249 bool status = ActualSchedulePageFlip(); 252 bool status = ActualSchedulePageFlip(request.is_sync);
250 if (!status) { 253 if (!status) {
251 PageFlipRequest request = requests_.front();
252 requests_.pop_front(); 254 requests_.pop_front();
253 255
254 // Normally the caller would handle the error call, but because we're in a 256 // Normally the caller would handle the error call, but because we're in a
255 // delayed schedule the initial SchedulePageFlip() already returned true, 257 // delayed schedule the initial SchedulePageFlip() already returned true,
256 // thus we need to run the callback. 258 // thus we need to run the callback.
257 request.callback.Run(); 259 request.callback.Run();
258 } 260 }
259 } 261 }
260 262
261 scoped_refptr<DriWrapper> HardwareDisplayController::GetAllocationDriWrapper() 263 scoped_refptr<DriWrapper> HardwareDisplayController::GetAllocationDriWrapper()
262 const { 264 const {
263 DCHECK(!crtc_controllers_.empty()); 265 DCHECK(!crtc_controllers_.empty());
264 // TODO(dnicoara) When we support mirroring across DRM devices, figure out 266 // TODO(dnicoara) When we support mirroring across DRM devices, figure out
265 // which device should be used for allocations. 267 // which device should be used for allocations.
266 return crtc_controllers_[0]->drm(); 268 return crtc_controllers_[0]->drm();
267 } 269 }
268 270
269 bool HardwareDisplayController::HasPendingPageFlips() const { 271 bool HardwareDisplayController::HasPendingPageFlips() const {
270 for (size_t i = 0; i < crtc_controllers_.size(); ++i) 272 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
271 if (crtc_controllers_[i]->page_flip_pending()) 273 if (crtc_controllers_[i]->page_flip_pending())
272 return true; 274 return true;
273 275
274 return false; 276 return false;
275 } 277 }
276 278
277 bool HardwareDisplayController::ActualSchedulePageFlip() { 279 bool HardwareDisplayController::ActualSchedulePageFlip(bool is_sync) {
278 TRACE_EVENT0("dri", "HDC::ActualSchedulePageFlip"); 280 TRACE_EVENT0("dri", "HDC::ActualSchedulePageFlip");
279 DCHECK(!requests_.empty()); 281 DCHECK(!requests_.empty());
280 282
281 if (is_disabled_) { 283 if (is_disabled_) {
282 ProcessPageFlipRequest(); 284 ProcessPageFlipRequest();
283 return true; 285 return true;
284 } 286 }
285 287
286 OverlayPlaneList pending_planes = requests_.front().planes; 288 OverlayPlaneList pending_planes = requests_.front().planes;
dnicoara 2015/02/27 13:58:44 You'll want to get the is_sync flag here, from |re
llandwerlin-old 2015/02/27 14:09:04 Ah right, got it.
287 std::sort(pending_planes.begin(), pending_planes.end(), 289 std::sort(pending_planes.begin(), pending_planes.end(),
288 [](const OverlayPlane& l, const OverlayPlane& r) { 290 [](const OverlayPlane& l, const OverlayPlane& r) {
289 return l.z_order < r.z_order; 291 return l.z_order < r.z_order;
290 }); 292 });
291 293
292 bool status = true; 294 bool status = true;
293 for (size_t i = 0; i < crtc_controllers_.size(); ++i) { 295 for (size_t i = 0; i < crtc_controllers_.size(); ++i) {
294 status &= crtc_controllers_[i]->SchedulePageFlip( 296 status &= crtc_controllers_[i]->SchedulePageFlip(
295 owned_hardware_planes_.get(crtc_controllers_[i]->drm().get()), 297 owned_hardware_planes_.get(crtc_controllers_[i]->drm().get()),
296 pending_planes); 298 pending_planes);
297 } 299 }
298 300
299 for (const auto& planes : owned_hardware_planes_) { 301 for (const auto& planes : owned_hardware_planes_) {
300 if (!planes.first->plane_manager()->Commit(planes.second)) { 302 if (!planes.first->plane_manager()->Commit(planes.second, is_sync)) {
301 status = false; 303 status = false;
302 } 304 }
303 } 305 }
304 306
305 return status; 307 return status;
306 } 308 }
307 309
308 void HardwareDisplayController::ProcessPageFlipRequest() { 310 void HardwareDisplayController::ProcessPageFlipRequest() {
309 DCHECK(!requests_.empty()); 311 DCHECK(!requests_.empty());
310 PageFlipRequest request = requests_.front(); 312 PageFlipRequest request = requests_.front();
311 requests_.pop_front(); 313 requests_.pop_front();
312 314
313 current_planes_.swap(request.planes); 315 current_planes_.swap(request.planes);
314 request.callback.Run(); 316 request.callback.Run();
315 } 317 }
316 318
317 void HardwareDisplayController::ClearPendingRequests() { 319 void HardwareDisplayController::ClearPendingRequests() {
318 while (!requests_.empty()) { 320 while (!requests_.empty()) {
319 PageFlipRequest request = requests_.front(); 321 PageFlipRequest request = requests_.front();
320 requests_.pop_front(); 322 requests_.pop_front();
321 request.callback.Run(); 323 request.callback.Run();
322 } 324 }
323 } 325 }
324 326
325 } // namespace ui 327 } // namespace ui
OLDNEW
« no previous file with comments | « ui/ozone/platform/dri/hardware_display_controller.h ('k') | ui/ozone/platform/dri/hardware_display_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698