Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / ozone / platform / drm / gpu / hardware_display_controller.cc
blob5ee481931ff3c6f6626260e922775ba847cb378a
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
3 // found in the LICENSE file.
5 #include "ui/ozone/platform/drm/gpu/hardware_display_controller.h"
7 #include <drm.h>
8 #include <string.h>
9 #include <xf86drm.h>
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/trace_event/trace_event.h"
14 #include "third_party/skia/include/core/SkCanvas.h"
15 #include "ui/gfx/geometry/point.h"
16 #include "ui/gfx/geometry/size.h"
17 #include "ui/gfx/swap_result.h"
18 #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
19 #include "ui/ozone/platform/drm/gpu/drm_buffer.h"
20 #include "ui/ozone/platform/drm/gpu/drm_device.h"
21 #include "ui/ozone/platform/drm/gpu/page_flip_request.h"
22 #include "ui/ozone/public/native_pixmap.h"
24 namespace ui {
26 HardwareDisplayController::HardwareDisplayController(
27 scoped_ptr<CrtcController> controller,
28 const gfx::Point& origin)
29 : origin_(origin),
30 mode_(controller->mode()),
31 is_disabled_(controller->is_disabled()) {
32 AddCrtc(controller.Pass());
35 HardwareDisplayController::~HardwareDisplayController() {
36 // Reset the cursor.
37 UnsetCursor();
40 bool HardwareDisplayController::Modeset(const OverlayPlane& primary,
41 drmModeModeInfo mode) {
42 TRACE_EVENT0("drm", "HDC::Modeset");
43 DCHECK(primary.buffer.get());
44 bool status = true;
45 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
46 status &= crtc_controllers_[i]->Modeset(primary, mode);
48 is_disabled_ = false;
49 mode_ = mode;
51 return status;
54 void HardwareDisplayController::Disable() {
55 TRACE_EVENT0("drm", "HDC::Disable");
56 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
57 crtc_controllers_[i]->Disable();
60 is_disabled_ = true;
63 bool HardwareDisplayController::SchedulePageFlip(
64 const OverlayPlaneList& plane_list,
65 bool is_sync,
66 bool test_only,
67 const PageFlipCallback& callback) {
68 TRACE_EVENT0("drm", "HDC::SchedulePageFlip");
70 DCHECK(!is_disabled_);
72 // Ignore requests with no planes to schedule.
73 if (plane_list.empty()) {
74 callback.Run(gfx::SwapResult::SWAP_ACK);
75 return true;
78 scoped_refptr<PageFlipRequest> page_flip_request =
79 new PageFlipRequest(crtc_controllers_.size(), callback);
81 OverlayPlaneList pending_planes = plane_list;
82 std::sort(pending_planes.begin(), pending_planes.end(),
83 [](const OverlayPlane& l, const OverlayPlane& r) {
84 return l.z_order < r.z_order;
85 });
86 if (pending_planes.front().z_order != 0)
87 return false;
89 for (const auto& planes : owned_hardware_planes_)
90 planes.first->plane_manager()->BeginFrame(planes.second);
92 bool status = true;
93 for (size_t i = 0; i < crtc_controllers_.size(); ++i) {
94 status &= crtc_controllers_[i]->SchedulePageFlip(
95 owned_hardware_planes_.get(crtc_controllers_[i]->drm().get()),
96 pending_planes, test_only, page_flip_request);
99 for (const auto& planes : owned_hardware_planes_) {
100 if (!planes.first->plane_manager()->Commit(planes.second, is_sync,
101 test_only)) {
102 status = false;
106 return status;
109 bool HardwareDisplayController::SetCursor(
110 const scoped_refptr<ScanoutBuffer>& buffer) {
111 bool status = true;
113 if (is_disabled_)
114 return true;
116 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
117 status &= crtc_controllers_[i]->SetCursor(buffer);
119 return status;
122 bool HardwareDisplayController::UnsetCursor() {
123 bool status = true;
124 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
125 status &= crtc_controllers_[i]->SetCursor(nullptr);
127 return status;
130 bool HardwareDisplayController::MoveCursor(const gfx::Point& location) {
131 if (is_disabled_)
132 return true;
134 bool status = true;
135 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
136 status &= crtc_controllers_[i]->MoveCursor(location);
138 return status;
141 void HardwareDisplayController::AddCrtc(scoped_ptr<CrtcController> controller) {
142 owned_hardware_planes_.add(
143 controller->drm().get(),
144 scoped_ptr<HardwareDisplayPlaneList>(new HardwareDisplayPlaneList()));
145 crtc_controllers_.push_back(controller.Pass());
148 scoped_ptr<CrtcController> HardwareDisplayController::RemoveCrtc(
149 const scoped_refptr<DrmDevice>& drm,
150 uint32_t crtc) {
151 for (ScopedVector<CrtcController>::iterator it = crtc_controllers_.begin();
152 it != crtc_controllers_.end(); ++it) {
153 if ((*it)->drm() == drm && (*it)->crtc() == crtc) {
154 scoped_ptr<CrtcController> controller(*it);
155 crtc_controllers_.weak_erase(it);
156 // Remove entry from |owned_hardware_planes_| iff no other crtcs share it.
157 bool found = false;
158 for (ScopedVector<CrtcController>::iterator it =
159 crtc_controllers_.begin();
160 it != crtc_controllers_.end(); ++it) {
161 if ((*it)->drm() == controller->drm()) {
162 found = true;
163 break;
166 if (!found)
167 owned_hardware_planes_.erase(controller->drm().get());
169 return controller.Pass();
173 return nullptr;
176 bool HardwareDisplayController::HasCrtc(const scoped_refptr<DrmDevice>& drm,
177 uint32_t crtc) const {
178 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
179 if (crtc_controllers_[i]->drm() == drm &&
180 crtc_controllers_[i]->crtc() == crtc)
181 return true;
183 return false;
186 bool HardwareDisplayController::IsMirrored() const {
187 return crtc_controllers_.size() > 1;
190 bool HardwareDisplayController::IsDisabled() const {
191 return is_disabled_;
194 gfx::Size HardwareDisplayController::GetModeSize() const {
195 return gfx::Size(mode_.hdisplay, mode_.vdisplay);
198 uint64_t HardwareDisplayController::GetTimeOfLastFlip() const {
199 uint64_t time = 0;
200 for (size_t i = 0; i < crtc_controllers_.size(); ++i)
201 if (time < crtc_controllers_[i]->time_of_last_flip())
202 time = crtc_controllers_[i]->time_of_last_flip();
204 return time;
207 scoped_refptr<DrmDevice> HardwareDisplayController::GetAllocationDrmDevice()
208 const {
209 DCHECK(!crtc_controllers_.empty());
210 // TODO(dnicoara) When we support mirroring across DRM devices, figure out
211 // which device should be used for allocations.
212 return crtc_controllers_[0]->drm();
215 } // namespace ui