drm_hwcomposer: Add z order support
Currently, the planner just pops the first available drm plane and if
that can't be used for the DrmHwcLayer it just returns error.
This proposes a slighlty smarter way to do that by trying to see if
any of the DrmPlane can be used for the DrmHwcLayer in question.
More, if the drm_plane doesn't have a fix zorder then we could re-add
him to the list of unused planes, so it could be used for hosting
other less demanding DrmHwcLayers.
Signed-off-by: Alexandru Gheorghe <alexandru-cosmin.gheorghe@arm.com>
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index cd6d4b2..a1ccdc7 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -359,6 +359,17 @@
}
}
+ if (plane->zpos_property().id() && !plane->zpos_property().immutable()) {
+ ret = drmModeAtomicAddProperty(pset, plane->id(),
+ plane->zpos_property().id(),
+ source_layers.front()) < 0;
+ if (ret) {
+ ALOGE("Failed to add zpos property %d to plane %d",
+ plane->zpos_property().id(), plane->id());
+ break;
+ }
+ }
+
rotation = 0;
if (layer.transform & DrmHwcTransform::kFlipH)
rotation |= DRM_MODE_REFLECT_X;
diff --git a/drmplane.cpp b/drmplane.cpp
index 6747621..35f91b4 100644
--- a/drmplane.cpp
+++ b/drmplane.cpp
@@ -118,6 +118,10 @@
return ret;
}
+ ret = drm_->GetPlaneProperty(*this, "zpos", &zpos_property_);
+ if (ret)
+ ALOGE("Could not get zpos property for plane %u", id());
+
ret = drm_->GetPlaneProperty(*this, "rotation", &rotation_property_);
if (ret)
ALOGE("Could not get rotation property");
@@ -189,6 +193,10 @@
return src_h_property_;
}
+const DrmProperty &DrmPlane::zpos_property() const {
+ return zpos_property_;
+}
+
const DrmProperty &DrmPlane::rotation_property() const {
return rotation_property_;
}
diff --git a/drmplane.h b/drmplane.h
index b7607ff..43e0e8a 100644
--- a/drmplane.h
+++ b/drmplane.h
@@ -52,6 +52,7 @@
const DrmProperty &src_y_property() const;
const DrmProperty &src_w_property() const;
const DrmProperty &src_h_property() const;
+ const DrmProperty &zpos_property() const;
const DrmProperty &rotation_property() const;
const DrmProperty &alpha_property() const;
const DrmProperty &blend_property() const;
@@ -75,6 +76,7 @@
DrmProperty src_y_property_;
DrmProperty src_w_property_;
DrmProperty src_h_property_;
+ DrmProperty zpos_property_;
DrmProperty rotation_property_;
DrmProperty alpha_property_;
DrmProperty blend_property_;
diff --git a/drmproperty.cpp b/drmproperty.cpp
index dcab05e..9faa37e 100644
--- a/drmproperty.cpp
+++ b/drmproperty.cpp
@@ -100,6 +100,10 @@
}
}
+bool DrmProperty::immutable() const {
+ return id_ && (flags_ & DRM_MODE_PROP_IMMUTABLE);
+}
+
std::tuple<uint64_t, int> DrmProperty::GetEnumValueWithName(
std::string name) const {
for (auto it : enums_) {
diff --git a/drmproperty.h b/drmproperty.h
index 5e358be..f1328fe 100644
--- a/drmproperty.h
+++ b/drmproperty.h
@@ -46,6 +46,7 @@
std::string name() const;
int value(uint64_t *value) const;
+ bool immutable() const;
private:
class DrmPropertyEnum {
diff --git a/platform.h b/platform.h
index 6c12fe9..547a297 100644
--- a/platform.h
+++ b/platform.h
@@ -81,16 +81,24 @@
DrmCompositionPlane::Type type, DrmCrtc *crtc,
std::pair<size_t, DrmHwcLayer *> layer) {
DrmPlane *plane = PopPlane(planes);
- int ret;
- if (!plane)
- return -ENOENT;
+ std::vector<DrmPlane *> unused_planes;
+ int ret = -ENOENT;
+ while (plane) {
+ ret = ValidatePlane(plane, layer.second);
+ if (!ret)
+ break;
+ if (!plane->zpos_property().immutable())
+ unused_planes.push_back(plane);
+ plane = PopPlane(planes);
+ }
- ret = ValidatePlane(plane, layer.second);
- if (ret)
- return -EINVAL;
+ if (!ret) {
+ composition->emplace_back(type, plane, crtc, layer.first);
+ planes->insert(planes->begin(), unused_planes.begin(),
+ unused_planes.end());
+ }
- composition->emplace_back(type, plane, crtc, layer.first);
- return 0;
+ return ret;
}
};