summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Paul <seanpaul@chromium.org>2016-05-11 16:29:45 -0400
committerSean Paul <seanpaul@chromium.org>2016-05-12 14:20:39 -0400
commitca699be0bcc162c8748abb63cd4f7158733b1466 (patch)
tree5de723fa59113e26fa8b4c3741fa24abcbec32ad
parent39b3784628eb4169b46e71b30c98daf83c93bb8e (diff)
downloaddrm_hwcomposer-ca699be0bcc162c8748abb63cd4f7158733b1466.tar.gz
drm_hwcomposer-ca699be0bcc162c8748abb63cd4f7158733b1466.tar.xz
drm_hwcomposer: Use a vector for composition source_layers
Instead of a 1:1 mapping of layer:plane, use a vector to store source layers for a composition plane. This will allow us to represent squash compositions more easily by adding all source layers to the vector. This should also facilitate hardware which allows multiple fbs per plane. BUG=b/28117135 TEST=Tested on ryu Signed-off-by: Sean Paul <seanpaul@chromium.org> Change-Id: I5d4bfc6e9da022eaab047f948cc874d6a8a25746
-rw-r--r--drmdisplaycomposition.cpp72
-rw-r--r--drmdisplaycomposition.h55
-rw-r--r--drmdisplaycompositor.cpp97
3 files changed, 148 insertions, 76 deletions
diff --git a/drmdisplaycomposition.cpp b/drmdisplaycomposition.cpp
index 2089157..2af9d5a 100644
--- a/drmdisplaycomposition.cpp
+++ b/drmdisplaycomposition.cpp
@@ -113,11 +113,8 @@ int DrmDisplayComposition::SetDisplayMode(const DrmMode &display_mode) {
}
int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) {
- composition_planes_.emplace_back(
- DrmCompositionPlane{.plane = plane,
- .crtc = crtc_,
- .type = DrmCompositionPlaneType::kDisable,
- .source_layer = -1});
+ composition_planes_.emplace_back(DrmCompositionPlaneType::kDisable, plane,
+ crtc_);
return 0;
}
@@ -153,8 +150,7 @@ static DrmPlane *TakePlane(DrmCrtc *crtc,
}
void DrmDisplayComposition::EmplaceCompositionPlane(
- DrmCompositionPlaneType type, int source_layer,
- std::vector<DrmPlane *> *primary_planes,
+ DrmCompositionPlaneType type, std::vector<DrmPlane *> *primary_planes,
std::vector<DrmPlane *> *overlay_planes) {
DrmPlane *plane = TakePlane(crtc_, primary_planes, overlay_planes);
if (plane == NULL) {
@@ -163,11 +159,21 @@ void DrmDisplayComposition::EmplaceCompositionPlane(
"remaining");
return;
}
- composition_planes_.emplace_back(
- DrmCompositionPlane{.plane = plane,
- .crtc = crtc_,
- .type = type,
- .source_layer = source_layer});
+ composition_planes_.emplace_back(type, plane, crtc_);
+}
+
+void DrmDisplayComposition::EmplaceCompositionPlane(
+ size_t source_layer, std::vector<DrmPlane *> *primary_planes,
+ std::vector<DrmPlane *> *overlay_planes) {
+ DrmPlane *plane = TakePlane(crtc_, primary_planes, overlay_planes);
+ if (plane == NULL) {
+ ALOGE(
+ "Failed to add composition plane because there are no planes "
+ "remaining");
+ return;
+ }
+ composition_planes_.emplace_back(DrmCompositionPlaneType::kLayer, plane,
+ crtc_, source_layer);
}
static std::vector<size_t> SetBitsToVector(uint64_t in, size_t *index_map) {
@@ -275,10 +281,12 @@ int DrmDisplayComposition::CreateAndAssignReleaseFences() {
}
for (const DrmCompositionPlane &plane : composition_planes_) {
- if (plane.type == DrmCompositionPlaneType::kLayer) {
- DrmHwcLayer *source_layer = &layers_[plane.source_layer];
- comp_layers.emplace(source_layer);
- pre_comp_layers.erase(source_layer);
+ if (plane.type() == DrmCompositionPlaneType::kLayer) {
+ for (auto i : plane.source_layers()) {
+ DrmHwcLayer *source_layer = &layers_[i];
+ comp_layers.emplace(source_layer);
+ pre_comp_layers.erase(source_layer);
+ }
}
}
@@ -393,8 +401,7 @@ int DrmDisplayComposition::Plan(SquashState *squash,
if (planes_can_use == 0 && layers_remaining.size() > 0) {
for (auto i : protected_layers)
- EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer, i,
- primary_planes, overlay_planes);
+ EmplaceCompositionPlane(i, primary_planes, overlay_planes);
ALOGE("Protected layers consumed all hardware planes");
return CreateAndAssignReleaseFences();
@@ -430,15 +437,13 @@ int DrmDisplayComposition::Plan(SquashState *squash,
// that again.
if (protected_idx < protected_layers.size() &&
idx > protected_layers[protected_idx]) {
- EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer,
- protected_layers[protected_idx], primary_planes,
+ EmplaceCompositionPlane(protected_layers[protected_idx], primary_planes,
overlay_planes);
protected_idx++;
continue;
}
- EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer,
- layers_remaining[last_hw_comp_layer],
+ EmplaceCompositionPlane(layers_remaining[last_hw_comp_layer],
primary_planes, overlay_planes);
last_hw_comp_layer++;
planes_can_use--;
@@ -449,14 +454,13 @@ int DrmDisplayComposition::Plan(SquashState *squash,
// Enqueue the rest of the protected layers (if any) between the hw composited
// overlay layers and the squash/precomp layers.
- for (int i = protected_idx; i < protected_layers.size(); ++i)
- EmplaceCompositionPlane(DrmCompositionPlaneType::kLayer,
- protected_layers[i], primary_planes,
+ for (size_t i = protected_idx; i < protected_layers.size(); ++i)
+ EmplaceCompositionPlane(protected_layers[i], primary_planes,
overlay_planes);
if (layers_remaining.size() > 0) {
- EmplaceCompositionPlane(DrmCompositionPlaneType::kPrecomp, -1,
- primary_planes, overlay_planes);
+ EmplaceCompositionPlane(DrmCompositionPlaneType::kPrecomp, primary_planes,
+ overlay_planes);
SeparateLayers(layers_.data(), layers_remaining.data(),
layers_remaining.size(), protected_layers.data(),
protected_layers.size(), exclude_rects.data(),
@@ -464,8 +468,8 @@ int DrmDisplayComposition::Plan(SquashState *squash,
}
if (use_squash_framebuffer) {
- EmplaceCompositionPlane(DrmCompositionPlaneType::kSquash, -1,
- primary_planes, overlay_planes);
+ EmplaceCompositionPlane(DrmCompositionPlaneType::kSquash, primary_planes,
+ overlay_planes);
}
return CreateAndAssignReleaseFences();
@@ -631,9 +635,9 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const {
for (size_t i = 0; i < composition_planes_.size(); i++) {
const DrmCompositionPlane &comp_plane = composition_planes_[i];
*out << " [" << i << "]"
- << " plane=" << (comp_plane.plane ? comp_plane.plane->id() : -1)
+ << " plane=" << (comp_plane.plane() ? comp_plane.plane()->id() : -1)
<< " type=";
- switch (comp_plane.type) {
+ switch (comp_plane.type()) {
case DrmCompositionPlaneType::kDisable:
*out << "DISABLE";
break;
@@ -651,7 +655,11 @@ void DrmDisplayComposition::Dump(std::ostringstream *out) const {
break;
}
- *out << " source_layer=" << comp_plane.source_layer << "\n";
+ *out << " source_layer=";
+ for (auto i : comp_plane.source_layers()) {
+ *out << i << " ";
+ }
+ *out << "\n";
}
*out << " Squash Regions: count=" << squash_regions_.size() << "\n";
diff --git a/drmdisplaycomposition.h b/drmdisplaycomposition.h
index 0362404..768ccfb 100644
--- a/drmdisplaycomposition.h
+++ b/drmdisplaycomposition.h
@@ -53,11 +53,51 @@ enum class DrmCompositionPlaneType : int32_t {
kSquash,
};
-struct DrmCompositionPlane {
- DrmCompositionPlaneType type;
- DrmPlane *plane;
- DrmCrtc *crtc;
- int source_layer;
+class DrmCompositionPlane {
+ public:
+ DrmCompositionPlane() = default;
+ DrmCompositionPlane(DrmCompositionPlane &&rhs) = default;
+ DrmCompositionPlane &operator=(DrmCompositionPlane &&other) = default;
+ DrmCompositionPlane(DrmCompositionPlaneType type, DrmPlane *plane,
+ DrmCrtc *crtc)
+ : type_(type), plane_(plane), crtc_(crtc) {
+ }
+ DrmCompositionPlane(DrmCompositionPlaneType type, DrmPlane *plane,
+ DrmCrtc *crtc, size_t source_layer)
+ : type_(type),
+ plane_(plane),
+ crtc_(crtc),
+ source_layers_(1, source_layer) {
+ }
+
+ DrmCompositionPlaneType type() const {
+ return type_;
+ }
+
+ DrmPlane *plane() const {
+ return plane_;
+ }
+ void set_plane(DrmPlane *plane) {
+ plane_ = plane;
+ }
+
+ DrmCrtc *crtc() const {
+ return crtc_;
+ }
+
+ std::vector<size_t> &source_layers() {
+ return source_layers_;
+ }
+
+ const std::vector<size_t> &source_layers() const {
+ return source_layers_;
+ }
+
+ private:
+ DrmCompositionPlaneType type_ = DrmCompositionPlaneType::kDisable;
+ DrmPlane *plane_ = NULL;
+ DrmCrtc *crtc_ = NULL;
+ std::vector<size_t> source_layers_;
};
class DrmDisplayComposition {
@@ -139,7 +179,10 @@ class DrmDisplayComposition {
int IncreaseTimelineToPoint(int point);
- void EmplaceCompositionPlane(DrmCompositionPlaneType type, int source_layer,
+ void EmplaceCompositionPlane(DrmCompositionPlaneType type,
+ std::vector<DrmPlane *> *primary_planes,
+ std::vector<DrmPlane *> *overlay_planes);
+ void EmplaceCompositionPlane(size_t source_layer,
std::vector<DrmPlane *> *primary_planes,
std::vector<DrmPlane *> *overlay_planes);
int CreateAndAssignReleaseFences();
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index c9cf40c..fc040dc 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -172,7 +172,7 @@ void SquashState::Dump(std::ostringstream *out) const {
static bool UsesSquash(const std::vector<DrmCompositionPlane> &comp_planes) {
return std::any_of(comp_planes.begin(), comp_planes.end(),
[](const DrmCompositionPlane &plane) {
- return plane.type == DrmCompositionPlaneType::kSquash;
+ return plane.type() == DrmCompositionPlaneType::kSquash;
});
}
@@ -488,7 +488,7 @@ int DrmDisplayCompositor::DisablePlanes(DrmDisplayComposition *display_comp) {
std::vector<DrmCompositionPlane> &comp_planes =
display_comp->composition_planes();
for (DrmCompositionPlane &comp_plane : comp_planes) {
- DrmPlane *plane = comp_plane.plane;
+ DrmPlane *plane = comp_plane.plane();
ret = drmModeAtomicAddProperty(pset, plane->id(),
plane->crtc_property().id(), 0) < 0 ||
drmModeAtomicAddProperty(pset, plane->id(), plane->fb_property().id(),
@@ -572,9 +572,13 @@ int DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) {
}
for (DrmCompositionPlane &comp_plane : comp_planes) {
- switch (comp_plane.type) {
+ std::vector<size_t> &source_layers = comp_plane.source_layers();
+ switch (comp_plane.type()) {
case DrmCompositionPlaneType::kSquash:
- comp_plane.source_layer = squash_layer_index;
+ if (source_layers.size())
+ ALOGE("Squash source_layers is expected to be empty (%zu/%d)",
+ source_layers[0], squash_layer_index);
+ source_layers.push_back(squash_layer_index);
break;
case DrmCompositionPlaneType::kPrecomp:
if (!do_pre_comp) {
@@ -583,7 +587,9 @@ int DrmDisplayCompositor::PrepareFrame(DrmDisplayComposition *display_comp) {
"regions");
return -EINVAL;
}
- comp_plane.source_layer = pre_comp_layer_index;
+ // Replace source_layers with the output of the precomposite
+ source_layers.clear();
+ source_layers.push_back(pre_comp_layer_index);
break;
default:
break;
@@ -636,8 +642,9 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
}
for (DrmCompositionPlane &comp_plane : comp_planes) {
- DrmPlane *plane = comp_plane.plane;
- DrmCrtc *crtc = comp_plane.crtc;
+ DrmPlane *plane = comp_plane.plane();
+ DrmCrtc *crtc = comp_plane.crtc();
+ std::vector<size_t> &source_layers = comp_plane.source_layers();
int fb_id = -1;
DrmHwcRect<int> display_frame;
@@ -645,14 +652,19 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
uint64_t rotation = 0;
uint64_t alpha = 0xFF;
- if (comp_plane.type != DrmCompositionPlaneType::kDisable) {
- if (comp_plane.source_layer < 0 ||
- static_cast<size_t>(comp_plane.source_layer) >= layers.size()) {
- ALOGE("Source layer index %d out of bounds %zu type=%d",
- comp_plane.source_layer, layers.size(), comp_plane.type);
+ if (comp_plane.type() != DrmCompositionPlaneType::kDisable) {
+ if (source_layers.size() > 1) {
+ ALOGE("Can't handle more than one source layer sz=%zu type=%d",
+ source_layers.size(), comp_plane.type());
+ continue;
+ }
+
+ if (source_layers.empty() || source_layers.front() >= layers.size()) {
+ ALOGE("Source layer index %zu out of bounds %zu type=%d",
+ source_layers.front(), layers.size(), comp_plane.type());
break;
}
- DrmHwcLayer &layer = layers[comp_plane.source_layer];
+ DrmHwcLayer &layer = layers[source_layers.front()];
if (!test_only && layer.acquire_fence.get() >= 0) {
int acquire_fence = layer.acquire_fence.get();
int total_fence_timeout = 0;
@@ -1029,7 +1041,7 @@ int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src,
// Make sure there is more than one layer to squash.
size_t src_planes_with_layer = std::count_if(
src_planes.begin(), src_planes.end(), [](DrmCompositionPlane &p) {
- return p.type == DrmCompositionPlaneType::kLayer;
+ return p.type() == DrmCompositionPlaneType::kLayer;
});
if (src_planes_with_layer <= 1)
return -EALREADY;
@@ -1047,35 +1059,36 @@ int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src,
std::vector<DrmHwcLayer> dst_layers;
for (DrmCompositionPlane &comp_plane : src_planes) {
// Composition planes without DRM planes should never happen
- if (comp_plane.plane == NULL) {
+ if (comp_plane.plane() == NULL) {
ALOGE("Skipping squash all because of NULL plane");
ret = -EINVAL;
goto move_layers_back;
}
- if (comp_plane.type == DrmCompositionPlaneType::kDisable ||
- comp_plane.source_layer < 0)
+ if (comp_plane.type() == DrmCompositionPlaneType::kDisable)
continue;
- DrmHwcLayer &layer = src_layers[comp_plane.source_layer];
+ for (auto i : comp_plane.source_layers()) {
+ DrmHwcLayer &layer = src_layers[i];
- // Squashing protected layers is impossible.
- if (layer.protected_usage()) {
- ret = -ENOTSUP;
- goto move_layers_back;
- }
+ // Squashing protected layers is impossible.
+ if (layer.protected_usage()) {
+ ret = -ENOTSUP;
+ goto move_layers_back;
+ }
- // The OutputFds point to freed memory after hwc_set returns. They are
- // returned to the default to prevent DrmDisplayComposition::Plan from
- // filling the OutputFds.
- layer.release_fence = OutputFd();
- dst_layers.emplace_back(std::move(layer));
+ // The OutputFds point to freed memory after hwc_set returns. They are
+ // returned to the default to prevent DrmDisplayComposition::Plan from
+ // filling the OutputFds.
+ layer.release_fence = OutputFd();
+ dst_layers.emplace_back(std::move(layer));
+ }
- if (comp_plane.plane->type() == DRM_PLANE_TYPE_PRIMARY &&
+ if (comp_plane.plane()->type() == DRM_PLANE_TYPE_PRIMARY &&
primary_planes.size() == 0)
- primary_planes.push_back(comp_plane.plane);
+ primary_planes.push_back(comp_plane.plane());
else
- dst->AddPlaneDisable(comp_plane.plane);
+ dst->AddPlaneDisable(comp_plane.plane());
}
ret = dst->SetLayers(dst_layers.data(), dst_layers.size(), false);
@@ -1100,9 +1113,14 @@ int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src,
pre_comp_layer_index = dst->layers().size() - 1;
framebuffer_index_ = (framebuffer_index_ + 1) % DRM_DISPLAY_BUFFERS;
- for (DrmCompositionPlane &plane : dst->composition_planes())
- if (plane.type == DrmCompositionPlaneType::kPrecomp)
- plane.source_layer = pre_comp_layer_index;
+ for (DrmCompositionPlane &plane : dst->composition_planes()) {
+ if (plane.type() == DrmCompositionPlaneType::kPrecomp) {
+ // Replace source_layers with the output of the precomposite
+ plane.source_layers().clear();
+ plane.source_layers().push_back(pre_comp_layer_index);
+ break;
+ }
+ }
return 0;
@@ -1110,10 +1128,13 @@ int DrmDisplayCompositor::SquashFrame(DrmDisplayComposition *src,
// composition.
move_layers_back:
for (size_t plane_index = 0;
- plane_index < src_planes.size() && plane_index < dst_layers.size();
- plane_index++) {
- size_t source_layer_index = src_planes[plane_index].source_layer;
- src_layers[source_layer_index] = std::move(dst_layers[plane_index]);
+ plane_index < src_planes.size() && plane_index < dst_layers.size();) {
+ if (src_planes[plane_index].source_layers().empty()) {
+ plane_index++;
+ continue;
+ }
+ for (auto i : src_planes[plane_index].source_layers())
+ src_layers[i] = std::move(dst_layers[plane_index++]);
}
return ret;