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/dri/hardware_display_plane_manager_legacy.h"
8 #include "ui/ozone/platform/dri/crtc_controller.h"
9 #include "ui/ozone/platform/dri/dri_wrapper.h"
10 #include "ui/ozone/platform/dri/scanout_buffer.h"
14 HardwareDisplayPlaneManagerLegacy::HardwareDisplayPlaneManagerLegacy() {
17 HardwareDisplayPlaneManagerLegacy::~HardwareDisplayPlaneManagerLegacy() {
20 bool HardwareDisplayPlaneManagerLegacy::Commit(
21 HardwareDisplayPlaneList
* plane_list
) {
22 if (plane_list
->plane_list
.empty()) // No assigned planes, nothing to do.
25 // The order of operations here (set new planes, pageflip, clear old planes)
26 // is designed to minimze the chance of a significant artifact occurring.
27 // The planes must be updated first because the main plane no longer contains
28 // their content. The old planes are removed last because the previous primary
29 // plane used them as overlays and thus didn't contain their content, so we
30 // must first flip to the new primary plane, which does. The error here will
31 // be the delta of (new contents, old contents), but it should be barely
33 for (const auto& flip
: plane_list
->legacy_page_flips
) {
34 // Permission Denied is a legitimate error
35 for (const auto& plane
: flip
.planes
) {
36 if (!drm_
->PageFlipOverlay(flip
.crtc_id
, plane
.framebuffer
, plane
.bounds
,
37 plane
.src_rect
, plane
.plane
)) {
38 LOG(ERROR
) << "Cannot display plane on overlay: error="
39 << strerror(errno
) << "crtc=" << flip
.crtc
40 << " plane=" << plane
.plane
;
42 flip
.crtc
->PageFlipFailed();
46 if (!drm_
->PageFlip(flip
.crtc_id
, flip
.framebuffer
,
47 base::Bind(&CrtcController::OnPageFlipEvent
,
48 flip
.crtc
->AsWeakPtr()))) {
49 if (errno
!= EACCES
) {
50 LOG(ERROR
) << "Cannot page flip: error='" << strerror(errno
) << "'"
51 << " crtc=" << flip
.crtc_id
52 << " framebuffer=" << flip
.framebuffer
;
53 LOG(ERROR
) << "Failed to commit planes";
56 flip
.crtc
->PageFlipFailed();
59 // For each element in |old_plane_list|, if it hasn't been reclaimed (by
60 // this or any other HDPL), clear the overlay contents.
61 for (HardwareDisplayPlane
* plane
: plane_list
->old_plane_list
) {
62 if (!plane
->in_use()) {
63 // This plane is being released, so we need to zero it.
64 if (!drm_
->PageFlipOverlay(plane
->owning_crtc(), 0, gfx::Rect(),
65 gfx::Rect(), plane
->plane_id())) {
66 LOG(ERROR
) << "Cannot free overlay: error=" << strerror(errno
)
67 << "crtc=" << plane
->owning_crtc()
68 << " plane=" << plane
->plane_id();
74 plane_list
->plane_list
.swap(plane_list
->old_plane_list
);
75 plane_list
->plane_list
.clear();
76 plane_list
->legacy_page_flips
.clear();
77 plane_list
->committed
= true;
81 bool HardwareDisplayPlaneManagerLegacy::SetPlaneData(
82 HardwareDisplayPlaneList
* plane_list
,
83 HardwareDisplayPlane
* hw_plane
,
84 const OverlayPlane
& overlay
,
86 const gfx::Rect
& src_rect
,
87 CrtcController
* crtc
) {
88 if (plane_list
->legacy_page_flips
.empty() ||
89 plane_list
->legacy_page_flips
.back().crtc_id
!= crtc_id
) {
90 plane_list
->legacy_page_flips
.push_back(
91 HardwareDisplayPlaneList::PageFlipInfo(
92 crtc_id
, overlay
.buffer
->GetFramebufferId(), hw_plane
->plane_id(),
95 plane_list
->legacy_page_flips
.back().planes
.push_back(
96 HardwareDisplayPlaneList::PageFlipInfo::Plane(
97 hw_plane
->plane_id(), overlay
.buffer
->GetFramebufferId(),
98 overlay
.display_bounds
, src_rect
));