diff options
author | Lowry Li <lowry.li@arm.com> | 2018-08-28 17:58:21 +0800 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2018-09-04 16:09:55 -0400 |
commit | 9b6cafd4e218556b56ccfa7b5e933a808c5353fd (patch) | |
tree | b604984f55ec34346ae2c58512764cce18dbf86a | |
parent | 088fed0a54a6b338a04b49642a0e382f8687169c (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.cpp | 46 | ||||
-rw-r--r-- | drmplane.cpp | 8 | ||||
-rw-r--r-- | drmplane.h | 2 | ||||
-rw-r--r-- | drmproperty.cpp | 11 | ||||
-rw-r--r-- | drmproperty.h | 1 | ||||
-rw-r--r-- | platform.cpp | 48 | ||||
-rw-r--r-- | platform.h | 11 | ||||
-rw-r--r-- | platformhisi.cpp | 2 |
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_; } @@ -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; @@ -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) |