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_plane_manager_legacy.h"
8 #include "ui/ozone/platform/drm/gpu/crtc_controller.h"
9 #include "ui/ozone/platform/drm/gpu/drm_device.h"
10 #include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
14 HardwareDisplayPlaneManagerLegacy::HardwareDisplayPlaneManagerLegacy() {
17 HardwareDisplayPlaneManagerLegacy::~HardwareDisplayPlaneManagerLegacy() {
20 bool HardwareDisplayPlaneManagerLegacy::Commit(
21 HardwareDisplayPlaneList
* plane_list
,
25 for (HardwareDisplayPlane
* plane
: plane_list
->plane_list
) {
26 plane
->set_in_use(false);
28 plane_list
->plane_list
.clear();
29 plane_list
->legacy_page_flips
.clear();
32 if (plane_list
->plane_list
.empty()) // No assigned planes, nothing to do.
35 // The order of operations here (set new planes, pageflip, clear old planes)
36 // is designed to minimze the chance of a significant artifact occurring.
37 // The planes must be updated first because the main plane no longer contains
38 // their content. The old planes are removed last because the previous primary
39 // plane used them as overlays and thus didn't contain their content, so we
40 // must first flip to the new primary plane, which does. The error here will
41 // be the delta of (new contents, old contents), but it should be barely
43 for (const auto& flip
: plane_list
->legacy_page_flips
) {
44 // Permission Denied is a legitimate error
45 for (const auto& plane
: flip
.planes
) {
46 if (!drm_
->PageFlipOverlay(flip
.crtc_id
, plane
.framebuffer
, plane
.bounds
,
47 plane
.src_rect
, plane
.plane
)) {
48 PLOG(ERROR
) << "Cannot display plane on overlay: crtc=" << flip
.crtc
49 << " plane=" << plane
.plane
;
51 flip
.crtc
->PageFlipFailed();
55 if (!drm_
->PageFlip(flip
.crtc_id
, flip
.framebuffer
, is_sync
,
56 base::Bind(&CrtcController::OnPageFlipEvent
,
57 flip
.crtc
->AsWeakPtr()))) {
58 if (errno
!= EACCES
) {
59 PLOG(ERROR
) << "Cannot page flip: crtc=" << flip
.crtc_id
60 << " framebuffer=" << flip
.framebuffer
61 << " is_sync=" << is_sync
;
64 flip
.crtc
->PageFlipFailed();
67 // For each element in |old_plane_list|, if it hasn't been reclaimed (by
68 // this or any other HDPL), clear the overlay contents.
69 for (HardwareDisplayPlane
* plane
: plane_list
->old_plane_list
) {
70 if (!plane
->in_use() && !plane
->is_dummy()) {
71 // This plane is being released, so we need to zero it.
72 if (!drm_
->PageFlipOverlay(plane
->owning_crtc(), 0, gfx::Rect(),
73 gfx::Rect(), plane
->plane_id())) {
74 PLOG(ERROR
) << "Cannot free overlay: crtc=" << plane
->owning_crtc()
75 << " plane=" << plane
->plane_id();
81 plane_list
->plane_list
.swap(plane_list
->old_plane_list
);
82 plane_list
->plane_list
.clear();
83 plane_list
->legacy_page_flips
.clear();
87 bool HardwareDisplayPlaneManagerLegacy::SetPlaneData(
88 HardwareDisplayPlaneList
* plane_list
,
89 HardwareDisplayPlane
* hw_plane
,
90 const OverlayPlane
& overlay
,
92 const gfx::Rect
& src_rect
,
93 CrtcController
* crtc
) {
94 if (hw_plane
->is_dummy() || plane_list
->legacy_page_flips
.empty() ||
95 plane_list
->legacy_page_flips
.back().crtc_id
!= crtc_id
) {
96 plane_list
->legacy_page_flips
.push_back(
97 HardwareDisplayPlaneList::PageFlipInfo(
98 crtc_id
, overlay
.buffer
->GetFramebufferId(), crtc
));
100 plane_list
->legacy_page_flips
.back().planes
.push_back(
101 HardwareDisplayPlaneList::PageFlipInfo::Plane(
102 hw_plane
->plane_id(), overlay
.buffer
->GetFramebufferId(),
103 overlay
.display_bounds
, src_rect
));