diff options
-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) |