summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLowry Li <lowry.li@arm.com>2018-08-28 17:58:21 +0800
committerSean Paul <seanpaul@chromium.org>2018-09-04 16:09:55 -0400
commit9b6cafd4e218556b56ccfa7b5e933a808c5353fd (patch)
treeb604984f55ec34346ae2c58512764cce18dbf86a
parent088fed0a54a6b338a04b49642a0e382f8687169c (diff)
drm_hwcomposer: Add support for pixel blend mode property
The upstream version of pixel blend mode property will be added to the DRM core. So added support for pixel blend mode property to the DrmPlane. Created ValidatePlane() function in Planner to do the blend check, and also moved rotation and plane alpha property check there. Fixed the Emplace() call in platformhisi.cpp as was done with the other planner implementations. Change-Id: I7e6714699cf7c222a83de472060d4625e1e6945a Reviewed-by: Sean Paul <seanpaul@chromium.org> Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Signed-off-by: Lowry Li <lowry.li@arm.com> Tested-by: John Stultz <john.stultz@linaro.org>
-rw-r--r--drmdisplaycompositor.cpp46
-rw-r--r--drmplane.cpp8
-rw-r--r--drmplane.h2
-rw-r--r--drmproperty.cpp11
-rw-r--r--drmproperty.h1
-rw-r--r--platform.cpp48
-rw-r--r--platform.h11
-rw-r--r--platformhisi.cpp2
8 files changed, 108 insertions, 21 deletions
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index f479f10..cd6d4b2 100644
--- a/drmdisplaycompositor.cpp
+++ b/drmdisplaycompositor.cpp
@@ -316,6 +316,7 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
hwc_frect_t source_crop;
uint64_t rotation = 0;
uint64_t alpha = 0xFFFF;
+ uint64_t blend;
if (comp_plane.type() != DrmCompositionPlane::Type::kDisable) {
if (source_layers.size() > 1) {
@@ -338,8 +339,25 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
fence_fd = layer.acquire_fence.get();
display_frame = layer.display_frame;
source_crop = layer.source_crop;
- if (layer.blending == DrmHwcBlending::kPreMult)
- alpha = layer.alpha;
+ alpha = layer.alpha;
+
+ if (plane->blend_property().id()) {
+ switch (layer.blending) {
+ case DrmHwcBlending::kPreMult:
+ std::tie(blend, ret) = plane->blend_property().GetEnumValueWithName(
+ "Pre-multiplied");
+ break;
+ case DrmHwcBlending::kCoverage:
+ std::tie(blend, ret) = plane->blend_property().GetEnumValueWithName(
+ "Coverage");
+ break;
+ case DrmHwcBlending::kNone:
+ default:
+ std::tie(blend, ret) = plane->blend_property().GetEnumValueWithName(
+ "None");
+ break;
+ }
+ }
rotation = 0;
if (layer.transform & DrmHwcTransform::kFlipH)
@@ -382,20 +400,6 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
continue;
}
- // TODO: Once we have atomic test, this should fall back to GL
- if (rotation != DRM_MODE_ROTATE_0 && plane->rotation_property().id() == 0) {
- ALOGV("Rotation is not supported on plane %d", plane->id());
- ret = -EINVAL;
- break;
- }
-
- // TODO: Once we have atomic test, this should fall back to GL
- if (alpha != 0xFFFF && plane->alpha_property().id() == 0) {
- ALOGV("Alpha is not supported on plane %d", plane->id());
- ret = -EINVAL;
- break;
- }
-
ret = drmModeAtomicAddProperty(pset, plane->id(),
plane->crtc_property().id(), crtc->id()) < 0;
ret |= drmModeAtomicAddProperty(pset, plane->id(),
@@ -453,6 +457,16 @@ int DrmDisplayCompositor::CommitFrame(DrmDisplayComposition *display_comp,
break;
}
}
+
+ if (plane->blend_property().id()) {
+ ret = drmModeAtomicAddProperty(pset, plane->id(),
+ plane->blend_property().id(), blend) < 0;
+ if (ret) {
+ ALOGE("Failed to add pixel blend mode property %d to plane %d",
+ plane->blend_property().id(), plane->id());
+ break;
+ }
+ }
}
if (!ret) {
diff --git a/drmplane.cpp b/drmplane.cpp
index 2603e16..6747621 100644
--- a/drmplane.cpp
+++ b/drmplane.cpp
@@ -126,6 +126,10 @@ int DrmPlane::Init() {
if (ret)
ALOGI("Could not get alpha property");
+ ret = drm_->GetPlaneProperty(*this, "pixel blend mode", &blend_property_);
+ if (ret)
+ ALOGI("Could not get pixel blend mode property");
+
ret = drm_->GetPlaneProperty(*this, "IN_FENCE_FD", &in_fence_fd_property_);
if (ret)
ALOGI("Could not get IN_FENCE_FD property");
@@ -193,6 +197,10 @@ const DrmProperty &DrmPlane::alpha_property() const {
return alpha_property_;
}
+const DrmProperty &DrmPlane::blend_property() const {
+ return blend_property_;
+}
+
const DrmProperty &DrmPlane::in_fence_fd_property() const {
return in_fence_fd_property_;
}
diff --git a/drmplane.h b/drmplane.h
index 46dbc94..b7607ff 100644
--- a/drmplane.h
+++ b/drmplane.h
@@ -54,6 +54,7 @@ class DrmPlane {
const DrmProperty &src_h_property() const;
const DrmProperty &rotation_property() const;
const DrmProperty &alpha_property() const;
+ const DrmProperty &blend_property() const;
const DrmProperty &in_fence_fd_property() const;
private:
@@ -76,6 +77,7 @@ class DrmPlane {
DrmProperty src_h_property_;
DrmProperty rotation_property_;
DrmProperty alpha_property_;
+ DrmProperty blend_property_;
DrmProperty in_fence_fd_property_;
};
} // namespace android
diff --git a/drmproperty.cpp b/drmproperty.cpp
index e71c159..dcab05e 100644
--- a/drmproperty.cpp
+++ b/drmproperty.cpp
@@ -99,4 +99,15 @@ int DrmProperty::value(uint64_t *value) const {
return -EINVAL;
}
}
+
+std::tuple<uint64_t, int> DrmProperty::GetEnumValueWithName(
+ std::string name) const {
+ for (auto it : enums_) {
+ if (it.name_.compare(name) == 0) {
+ return std::make_tuple(it.value_, 0);
+ }
+ }
+
+ return std::make_tuple(UINT64_MAX, -EINVAL);
+}
} // namespace android
diff --git a/drmproperty.h b/drmproperty.h
index dc01c88..5e358be 100644
--- a/drmproperty.h
+++ b/drmproperty.h
@@ -40,6 +40,7 @@ class DrmProperty {
DrmProperty &operator=(const DrmProperty &) = delete;
void Init(drmModePropertyPtr p, uint64_t value);
+ std::tuple<uint64_t, int> GetEnumValueWithName(std::string name) const;
uint32_t id() const;
std::string name() const;
diff --git a/platform.cpp b/platform.cpp
index af18124..9e0eb45 100644
--- a/platform.cpp
+++ b/platform.cpp
@@ -36,6 +36,50 @@ std::vector<DrmPlane *> Planner::GetUsablePlanes(
return usable_planes;
}
+int Planner::PlanStage::ValidatePlane(DrmPlane *plane, DrmHwcLayer *layer) {
+ int ret = 0;
+ uint64_t blend;
+
+ if ((plane->rotation_property().id() == 0) &&
+ layer->transform != DrmHwcTransform::kIdentity) {
+ ALOGE("Rotation is not supported on plane %d", plane->id());
+ return -EINVAL;
+ }
+
+ if (plane->alpha_property().id() == 0 && layer->alpha != 0xffff) {
+ ALOGE("Alpha is not supported on plane %d", plane->id());
+ return -EINVAL;
+ }
+
+ if (plane->blend_property().id() == 0) {
+ if ((layer->blending != DrmHwcBlending::kNone) &&
+ (layer->blending != DrmHwcBlending::kPreMult)) {
+ ALOGE("Blending is not supported on plane %d", plane->id());
+ return -EINVAL;
+ }
+ } else {
+ switch (layer->blending) {
+ case DrmHwcBlending::kPreMult:
+ std::tie(blend, ret) = plane->blend_property().GetEnumValueWithName(
+ "Pre-multiplied");
+ break;
+ case DrmHwcBlending::kCoverage:
+ std::tie(blend, ret) = plane->blend_property().GetEnumValueWithName(
+ "Coverage");
+ break;
+ case DrmHwcBlending::kNone:
+ default:
+ std::tie(blend,
+ ret) = plane->blend_property().GetEnumValueWithName("None");
+ break;
+ }
+ if (ret)
+ ALOGE("Expected a valid blend mode on plane %d", plane->id());
+ }
+
+ return ret;
+}
+
std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes(
std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
std::vector<DrmPlane *> *primary_planes,
@@ -73,7 +117,7 @@ int PlanStageProtected::ProvisionPlanes(
}
ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer, crtc,
- i->first);
+ std::make_pair(i->first, i->second));
if (ret)
ALOGE("Failed to dedicate protected layer! Dropping it.");
@@ -91,7 +135,7 @@ int PlanStageGreedy::ProvisionPlanes(
// Fill up the remaining planes
for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i)) {
int ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer,
- crtc, i->first);
+ crtc, std::make_pair(i->first, i->second));
// We don't have any planes left
if (ret == -ENOENT)
break;
diff --git a/platform.h b/platform.h
index 37c4647..6c12fe9 100644
--- a/platform.h
+++ b/platform.h
@@ -73,16 +73,23 @@ class Planner {
return plane;
}
+ static int ValidatePlane(DrmPlane *plane, DrmHwcLayer *layer);
+
// Inserts the given layer:plane in the composition at the back
static int Emplace(std::vector<DrmCompositionPlane> *composition,
std::vector<DrmPlane *> *planes,
DrmCompositionPlane::Type type, DrmCrtc *crtc,
- size_t source_layer) {
+ std::pair<size_t, DrmHwcLayer *> layer) {
DrmPlane *plane = PopPlane(planes);
+ int ret;
if (!plane)
return -ENOENT;
- composition->emplace_back(type, plane, crtc, source_layer);
+ ret = ValidatePlane(plane, layer.second);
+ if (ret)
+ return -EINVAL;
+
+ composition->emplace_back(type, plane, crtc, layer.first);
return 0;
}
};
diff --git a/platformhisi.cpp b/platformhisi.cpp
index 68bb5a7..0e12ef1 100644
--- a/platformhisi.cpp
+++ b/platformhisi.cpp
@@ -153,7 +153,7 @@ class PlanStageHiSi : public Planner::PlanStage {
continue;
int ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer,
- crtc, i->first);
+ crtc, std::make_pair(i->first, i->second));
layers_added++;
// We don't have any planes left
if (ret == -ENOENT)