1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/ozone/platform/drm/gpu/hardware_display_plane_manager_legacy.h"
#include "base/bind.h"
#include "ui/ozone/platform/drm/gpu/crtc_controller.h"
#include "ui/ozone/platform/drm/gpu/drm_device.h"
#include "ui/ozone/platform/drm/gpu/scanout_buffer.h"
namespace ui {
HardwareDisplayPlaneManagerLegacy::HardwareDisplayPlaneManagerLegacy() {
}
HardwareDisplayPlaneManagerLegacy::~HardwareDisplayPlaneManagerLegacy() {
}
bool HardwareDisplayPlaneManagerLegacy::Commit(
HardwareDisplayPlaneList* plane_list,
bool is_sync,
bool test_only) {
if (test_only) {
for (HardwareDisplayPlane* plane : plane_list->plane_list) {
plane->set_in_use(false);
}
plane_list->plane_list.clear();
plane_list->legacy_page_flips.clear();
return true;
}
if (plane_list->plane_list.empty()) // No assigned planes, nothing to do.
return true;
bool ret = true;
// The order of operations here (set new planes, pageflip, clear old planes)
// is designed to minimze the chance of a significant artifact occurring.
// The planes must be updated first because the main plane no longer contains
// their content. The old planes are removed last because the previous primary
// plane used them as overlays and thus didn't contain their content, so we
// must first flip to the new primary plane, which does. The error here will
// be the delta of (new contents, old contents), but it should be barely
// noticeable.
for (const auto& flip : plane_list->legacy_page_flips) {
// Permission Denied is a legitimate error
for (const auto& plane : flip.planes) {
if (!drm_->PageFlipOverlay(flip.crtc_id, plane.framebuffer, plane.bounds,
plane.src_rect, plane.plane)) {
PLOG(ERROR) << "Cannot display plane on overlay: crtc=" << flip.crtc
<< " plane=" << plane.plane;
ret = false;
flip.crtc->PageFlipFailed();
break;
}
}
if (!drm_->PageFlip(flip.crtc_id, flip.framebuffer, is_sync,
base::Bind(&CrtcController::OnPageFlipEvent,
flip.crtc->AsWeakPtr()))) {
if (errno != EACCES) {
PLOG(ERROR) << "Cannot page flip: crtc=" << flip.crtc_id
<< " framebuffer=" << flip.framebuffer
<< " is_sync=" << is_sync;
ret = false;
}
flip.crtc->PageFlipFailed();
}
}
// For each element in |old_plane_list|, if it hasn't been reclaimed (by
// this or any other HDPL), clear the overlay contents.
for (HardwareDisplayPlane* plane : plane_list->old_plane_list) {
if (!plane->in_use() && !plane->is_dummy()) {
// This plane is being released, so we need to zero it.
if (!drm_->PageFlipOverlay(plane->owning_crtc(), 0, gfx::Rect(),
gfx::Rect(), plane->plane_id())) {
PLOG(ERROR) << "Cannot free overlay: crtc=" << plane->owning_crtc()
<< " plane=" << plane->plane_id();
ret = false;
break;
}
}
}
plane_list->plane_list.swap(plane_list->old_plane_list);
plane_list->plane_list.clear();
plane_list->legacy_page_flips.clear();
return ret;
}
bool HardwareDisplayPlaneManagerLegacy::SetPlaneData(
HardwareDisplayPlaneList* plane_list,
HardwareDisplayPlane* hw_plane,
const OverlayPlane& overlay,
uint32_t crtc_id,
const gfx::Rect& src_rect,
CrtcController* crtc) {
if (hw_plane->is_dummy() || plane_list->legacy_page_flips.empty() ||
plane_list->legacy_page_flips.back().crtc_id != crtc_id) {
plane_list->legacy_page_flips.push_back(
HardwareDisplayPlaneList::PageFlipInfo(
crtc_id, overlay.buffer->GetFramebufferId(), crtc));
} else {
plane_list->legacy_page_flips.back().planes.push_back(
HardwareDisplayPlaneList::PageFlipInfo::Plane(
hw_plane->plane_id(), overlay.buffer->GetFramebufferId(),
overlay.display_bounds, src_rect));
}
return true;
}
} // namespace ui
|