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

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

Issue 1091253003: [ozone] Keep the queue of surfaceless buffers inside gl_surface_ozone (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: 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 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/hardware_display_controller.h" 5 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
6 6
7 #include <drm.h> 7 #include <drm.h>
8 #include <string.h> 8 #include <string.h>
9 #include <xf86drm.h> 9 #include <xf86drm.h>
10 10
(...skipping 15 matching lines...) Expand all
26 bool is_sync, 26 bool is_sync,
27 const base::Closure& callback) 27 const base::Closure& callback)
28 : planes(planes), is_sync(is_sync), callback(callback) { 28 : planes(planes), is_sync(is_sync), callback(callback) {
29 } 29 }
30 30
31 HardwareDisplayController::PageFlipRequest::~PageFlipRequest() { 31 HardwareDisplayController::PageFlipRequest::~PageFlipRequest() {
32 } 32 }
33 33
34 HardwareDisplayController::HardwareDisplayController( 34 HardwareDisplayController::HardwareDisplayController(
35 scoped_ptr<CrtcController> controller) 35 scoped_ptr<CrtcController> controller)
36 : is_disabled_(true) { 36 : is_disabled_(true), ignore_page_flip_event_(false) {
37 memset(&mode_, 0, sizeof(mode_)); 37 memset(&mode_, 0, sizeof(mode_));
38 AddCrtc(controller.Pass()); 38 AddCrtc(controller.Pass());
39 } 39 }
40 40
41 HardwareDisplayController::~HardwareDisplayController() { 41 HardwareDisplayController::~HardwareDisplayController() {
42 // Reset the cursor. 42 // Reset the cursor.
43 UnsetCursor(); 43 UnsetCursor();
44 ClearPendingRequests(); 44 ProcessPageFlipRequest();
45 } 45 }
46 46
47 bool HardwareDisplayController::Modeset(const OverlayPlane& primary, 47 bool HardwareDisplayController::Modeset(const OverlayPlane& primary,
48 drmModeModeInfo mode) { 48 drmModeModeInfo mode) {
49 TRACE_EVENT0("drm", "HDC::Modeset"); 49 TRACE_EVENT0("drm", "HDC::Modeset");
50 DCHECK(primary.buffer.get()); 50 DCHECK(primary.buffer.get());
51 bool status = true; 51 bool status = true;
52 for (size_t i = 0; i < crtc_controllers_.size(); ++i) 52 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
53 status &= crtc_controllers_[i]->Modeset(primary, mode); 53 status &= crtc_controllers_[i]->Modeset(primary, mode);
54 54
55 is_disabled_ = false; 55 is_disabled_ = false;
56 mode_ = mode; 56 mode_ = mode;
57 57
58 current_planes_ = std::vector<OverlayPlane>(1, primary); 58 ProcessPageFlipRequest();
59 ClearPendingRequests();
60 59
61 // Because a page flip is pending we need to leave some state for the 60 // Because a page flip is pending we need to leave some state for the
dnicoara 2015/04/21 18:50:42 Could you please update the comment.
62 // callback. We use the modeset state since it is the only valid state. 61 // callback.
63 if (HasPendingPageFlips()) 62 if (HasPendingPageFlips())
64 requests_.push_back( 63 ignore_page_flip_event_ = true;
dnicoara 2015/04/21 18:50:42 nit: Simplity it to 'ignore_page_flip_event_ = Has
alexst (slow to review) 2015/04/21 19:19:55 Done.
spang 2015/04/21 19:39:36 This is funky. Could we pass a callback w/ weak p
alexst (slow to review) 2015/04/21 19:46:17 Yes, that's a good idea.
65 PageFlipRequest(current_planes_, false, base::Bind(&base::DoNothing)));
66 64
67 return status; 65 return status;
68 } 66 }
69 67
70 void HardwareDisplayController::Disable() { 68 void HardwareDisplayController::Disable() {
71 TRACE_EVENT0("drm", "HDC::Disable"); 69 TRACE_EVENT0("drm", "HDC::Disable");
72 for (size_t i = 0; i < crtc_controllers_.size(); ++i) 70 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
73 crtc_controllers_[i]->Disable(); 71 crtc_controllers_[i]->Disable();
74 72
75 // Don't hold onto any requests because we don't track fron buffer while 73 // Don't hold onto any requests because we don't track fron buffer while
76 // disabled. 74 // disabled.
77 while (requests_.size()) 75 ProcessPageFlipRequest();
78 ProcessPageFlipRequest();
79
80 current_planes_.clear();
81 76
82 is_disabled_ = true; 77 is_disabled_ = true;
83 } 78 }
84 79
85 bool HardwareDisplayController::SchedulePageFlip( 80 bool HardwareDisplayController::SchedulePageFlip(
86 const OverlayPlaneList& plane_list, 81 const OverlayPlaneList& plane_list,
87 bool is_sync, 82 bool is_sync,
88 const base::Closure& callback) { 83 const base::Closure& callback) {
89 TRACE_EVENT0("drm", "HDC::SchedulePageFlip"); 84 TRACE_EVENT0("drm", "HDC::SchedulePageFlip");
90 85
86 // A request is being serviced right now.
dnicoara 2015/04/21 18:50:42 Shouldn't this be reversed? When we schedule the p
alexst (slow to review) 2015/04/21 19:19:55 of course!
87 DCHECK(HasPendingPageFlips());
88 DCHECK(page_flip_request_.get());
89
91 // Ignore requests with no planes to schedule. 90 // Ignore requests with no planes to schedule.
92 if (plane_list.empty()) { 91 if (plane_list.empty()) {
93 callback.Run(); 92 callback.Run();
94 return true; 93 return true;
95 } 94 }
96 95
97 requests_.push_back(PageFlipRequest(plane_list, is_sync, callback)); 96 page_flip_request_.reset(new PageFlipRequest(plane_list, is_sync, callback));
98 97
99 // A request is being serviced right now. 98 return ActualSchedulePageFlip();
100 if (HasPendingPageFlips())
101 return true;
102
103 bool status = ActualSchedulePageFlip();
104
105 // No page flip event on failure so discard failed request.
106 if (!status)
107 requests_.pop_front();
108
109 return status;
110 } 99 }
111 100
112 bool HardwareDisplayController::SetCursor( 101 bool HardwareDisplayController::SetCursor(
113 const scoped_refptr<ScanoutBuffer>& buffer) { 102 const scoped_refptr<ScanoutBuffer>& buffer) {
114 bool status = true; 103 bool status = true;
115 104
116 if (is_disabled_) 105 if (is_disabled_)
117 return true; 106 return true;
118 107
119 for (size_t i = 0; i < crtc_controllers_.size(); ++i) 108 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 // for the next request. In this case we expect that |requests_| isn't 215 // for the next request. In this case we expect that |requests_| isn't
227 // empty. 216 // empty.
228 // 2) A CRTC was added while it was page flipping. In this case a modeset 217 // 2) A CRTC was added while it was page flipping. In this case a modeset
229 // must be performed. Modesetting clears all pending requests, however the 218 // must be performed. Modesetting clears all pending requests, however the
230 // CRTCs will honor the scheduled page flip. Thus we need to handle page 219 // CRTCs will honor the scheduled page flip. Thus we need to handle page
231 // flip events with no requests. 220 // flip events with no requests.
232 221
233 if (HasPendingPageFlips()) 222 if (HasPendingPageFlips())
234 return; 223 return;
235 224
236 if (!requests_.empty()) 225 if (ignore_page_flip_event_) {
237 ProcessPageFlipRequest(); 226 ignore_page_flip_event_ = false;
227 return;
228 }
238 229
239 // ProcessPageFlipRequest() consumes a request. 230 ProcessPageFlipRequest();
240 if (requests_.empty())
241 return;
242
243 // At this point we still have requests pending, so schedule the next request.
244 bool status = ActualSchedulePageFlip();
245 if (!status) {
246 PageFlipRequest request = requests_.front();
247 requests_.pop_front();
248
249 // Normally the caller would handle the error call, but because we're in a
250 // delayed schedule the initial SchedulePageFlip() already returned true,
251 // thus we need to run the callback.
252 request.callback.Run();
253 }
254 } 231 }
255 232
256 scoped_refptr<DrmDevice> HardwareDisplayController::GetAllocationDrmDevice() 233 scoped_refptr<DrmDevice> HardwareDisplayController::GetAllocationDrmDevice()
257 const { 234 const {
258 DCHECK(!crtc_controllers_.empty()); 235 DCHECK(!crtc_controllers_.empty());
259 // TODO(dnicoara) When we support mirroring across DRM devices, figure out 236 // TODO(dnicoara) When we support mirroring across DRM devices, figure out
260 // which device should be used for allocations. 237 // which device should be used for allocations.
261 return crtc_controllers_[0]->drm(); 238 return crtc_controllers_[0]->drm();
262 } 239 }
263 240
264 bool HardwareDisplayController::HasPendingPageFlips() const { 241 bool HardwareDisplayController::HasPendingPageFlips() const {
265 for (size_t i = 0; i < crtc_controllers_.size(); ++i) 242 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
266 if (crtc_controllers_[i]->page_flip_pending()) 243 if (crtc_controllers_[i]->page_flip_pending())
267 return true; 244 return true;
268 245
269 return false; 246 return false;
270 } 247 }
271 248
272 bool HardwareDisplayController::ActualSchedulePageFlip() { 249 bool HardwareDisplayController::ActualSchedulePageFlip() {
273 TRACE_EVENT0("drm", "HDC::ActualSchedulePageFlip"); 250 TRACE_EVENT0("drm", "HDC::ActualSchedulePageFlip");
274 DCHECK(!requests_.empty()); 251 DCHECK(page_flip_request_.get());
252 DCHECK(!is_disabled_);
275 253
276 if (is_disabled_) { 254 OverlayPlaneList& pending_planes = page_flip_request_->planes;
277 ProcessPageFlipRequest();
278 return true;
279 }
280
281 OverlayPlaneList pending_planes = requests_.front().planes;
282 std::sort(pending_planes.begin(), pending_planes.end(), 255 std::sort(pending_planes.begin(), pending_planes.end(),
283 [](const OverlayPlane& l, const OverlayPlane& r) { 256 [](const OverlayPlane& l, const OverlayPlane& r) {
284 return l.z_order < r.z_order; 257 return l.z_order < r.z_order;
285 }); 258 });
286 259
287 bool status = true; 260 bool status = true;
288 for (size_t i = 0; i < crtc_controllers_.size(); ++i) { 261 for (size_t i = 0; i < crtc_controllers_.size(); ++i) {
289 status &= crtc_controllers_[i]->SchedulePageFlip( 262 status &= crtc_controllers_[i]->SchedulePageFlip(
290 owned_hardware_planes_.get(crtc_controllers_[i]->drm().get()), 263 owned_hardware_planes_.get(crtc_controllers_[i]->drm().get()),
291 pending_planes); 264 pending_planes);
292 } 265 }
293 266
294 bool is_sync = requests_.front().is_sync; 267 bool is_sync = page_flip_request_->is_sync;
295 for (const auto& planes : owned_hardware_planes_) { 268 for (const auto& planes : owned_hardware_planes_) {
296 if (!planes.first->plane_manager()->Commit(planes.second, is_sync)) { 269 if (!planes.first->plane_manager()->Commit(planes.second, is_sync)) {
297 status = false; 270 status = false;
298 } 271 }
299 } 272 }
300 273
301 return status; 274 return status;
302 } 275 }
303 276
304 void HardwareDisplayController::ProcessPageFlipRequest() { 277 void HardwareDisplayController::ProcessPageFlipRequest() {
305 DCHECK(!requests_.empty()); 278 if (page_flip_request_.get()) {
306 PageFlipRequest request = requests_.front(); 279 scoped_ptr<PageFlipRequest> last_request;
307 requests_.pop_front(); 280 // We are done with the last request, so clear it before we execute the
308 281 // callback since it may schedule a new frame.
309 current_planes_.swap(request.planes); 282 swap(last_request, page_flip_request_);
310 request.callback.Run(); 283 last_request->callback.Run();
311 }
312
313 void HardwareDisplayController::ClearPendingRequests() {
314 while (!requests_.empty()) {
315 PageFlipRequest request = requests_.front();
316 requests_.pop_front();
317 request.callback.Run();
318 } 284 }
319 } 285 }
320 286
321 } // namespace ui 287 } // namespace ui
OLDNEW
« ui/gl/gl_surface_ozone.cc ('K') | « ui/ozone/platform/drm/gpu/hardware_display_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698