aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Stultz <john.stultz@linaro.org>2018-12-18 16:54:15 -0800
committerandroid-build-merger <android-build-merger@google.com>2018-12-18 16:54:15 -0800
commit0b75bdf64158a21f977234290908c2df23aafccc (patch)
tree2ecce016531f184292a8fa23020527a15125cd6c
parent8e5a222be6344795af748cdf20481dc88a877b35 (diff)
parentcfef6ba6f095abe8bdeacf19b980791b831d8fd9 (diff)
downloaddrm_hwcomposer-0b75bdf64158a21f977234290908c2df23aafccc.tar.gz
Merge remote-tracking branch 'aosp/upstream-master' into HEAD am: 8345f0a664
am: cfef6ba6f0 Change-Id: Id3f5b666330d1f98581b744f4c6d5a343fe652b7
-rwxr-xr-x.gitlab-ci-checkcommit.sh37
-rw-r--r--.gitlab-ci.yml10
-rw-r--r--README.md2
-rw-r--r--drmdisplaycompositor.cpp57
-rw-r--r--drmhwctwo.cpp11
-rw-r--r--drmplane.cpp16
-rw-r--r--drmplane.h4
-rw-r--r--drmproperty.cpp15
-rw-r--r--drmproperty.h2
-rw-r--r--platform.cpp56
-rw-r--r--platform.h30
-rw-r--r--platformdrmgeneric.cpp6
-rw-r--r--platformdrmgeneric.h1
-rw-r--r--platformhisi.cpp35
-rw-r--r--platformhisi.h2
15 files changed, 231 insertions, 53 deletions
diff --git a/.gitlab-ci-checkcommit.sh b/.gitlab-ci-checkcommit.sh
new file mode 100755
index 0000000..fc8963a
--- /dev/null
+++ b/.gitlab-ci-checkcommit.sh
@@ -0,0 +1,37 @@
+#! /usr/bin/env bash
+
+echoerr() {
+ printf "ERROR: %s\n" "$*" >&2
+}
+
+git fetch https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer.git
+
+git log --pretty='%h' FETCH_HEAD..HEAD | while read h; do
+ subject=$(git show -s --pretty='%s' "$h")
+ if [[ $subject != drm_hwcomposer:* ]]; then
+ echoerr "Invalid subject prefix: $subject"
+ exit 1
+ fi
+
+ commit_body=$(git show -s --pretty=%b "$h")
+
+ author=$(git show -s --format='%an <%ae>')
+ sob=$(echo "$commit_body" | grep "Signed-off-by: $author")
+ if [ -z "$sob" ] ; then
+ echoerr "Author SoB tag is missing from commit $h"
+ exit 1
+ fi
+
+ committer=$(git show -s --format='%cn <%ce>')
+ sob=$(echo "$commit_body" | grep "Signed-off-by: $committer")
+ if [ -z "$sob" ] ; then
+ echoerr "Committer SoB tag is missing from commit $h"
+ exit 1
+ fi
+
+ git show "$h" -- | clang-format-diff-5.0 -p 1 -style=file > format-fixup.patch
+ if [ -s format-fixup.patch ]; then
+ cat format-fixup.patch >&2
+ exit 1
+ fi
+done
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 24c4a0a..c97f4ff 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,13 +7,9 @@ before_script:
stages:
- style
-clang-format:
+checkstyle:
stage: style
- script:
- - git fetch https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer.git
- - git diff -U0 --no-color FETCH_HEAD...HEAD -- | clang-format-diff-5.0 -p 1 -style=file > format-fixup.patch
- - if [ -s format-fixup.patch ]; then cat format-fixup.patch && exit 1; fi
+ script: "./.gitlab-ci-checkcommit.sh"
artifacts:
when: on_failure
- paths:
- - format-fixup.patch
+ untracked: true
diff --git a/README.md b/README.md
index 260ac9b..05f1364 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ A short list of contribution guidelines:
* drm_hwcomposer is Apache 2.0 Licensed and we require contributions to follow the developer's certificate of origin: http://developercertificate.org/
* When submitting new code please follow the naming conventions documented in the generated documentation. Also please make full use of all the helpers and convenience macros provided by drm_hwcomposer. The below command can help you with formatting of your patches:
- `git diff | clang-format-diff-3.5 -p 1 -style=file`
+ `git diff | clang-format-diff-5.0 -p 1 -style=file`
* Hardware specific changes should be tested on relevant platforms before committing.
If you need inspiration, please checkout our [TODO issues](https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer/issues?label_name%5B%5D=TODO)
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp
index f479f10..a1ccdc7 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,36 @@ 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;
+ }
+ }
+
+ 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)
@@ -382,20 +411,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 +468,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/drmhwctwo.cpp b/drmhwctwo.cpp
index c801f2e..cd79e7b 100644
--- a/drmhwctwo.cpp
+++ b/drmhwctwo.cpp
@@ -491,9 +491,13 @@ HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) {
std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map;
for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
HWC2::Composition comp_type;
- if (test)
+ if (test) {
comp_type = l.second.sf_type();
- else
+ if (comp_type == HWC2::Composition::Device) {
+ if (!importer_->CanImportBuffer(l.second.buffer()))
+ comp_type = HWC2::Composition::Client;
+ }
+ } else
comp_type = l.second.validated_type();
switch (comp_type) {
@@ -735,7 +739,8 @@ HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types,
for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) {
if (comp_failed || !avail_planes--)
break;
- l.second->set_validated_type(HWC2::Composition::Device);
+ if (importer_->CanImportBuffer(l.second->buffer()))
+ l.second->set_validated_type(HWC2::Composition::Device);
}
for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) {
diff --git a/drmplane.cpp b/drmplane.cpp
index 2603e16..35f91b4 100644
--- a/drmplane.cpp
+++ b/drmplane.cpp
@@ -118,6 +118,10 @@ int DrmPlane::Init() {
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");
@@ -126,6 +130,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");
@@ -185,6 +193,10 @@ const DrmProperty &DrmPlane::src_h_property() const {
return src_h_property_;
}
+const DrmProperty &DrmPlane::zpos_property() const {
+ return zpos_property_;
+}
+
const DrmProperty &DrmPlane::rotation_property() const {
return rotation_property_;
}
@@ -193,6 +205,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..43e0e8a 100644
--- a/drmplane.h
+++ b/drmplane.h
@@ -52,8 +52,10 @@ class DrmPlane {
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;
const DrmProperty &in_fence_fd_property() const;
private:
@@ -74,8 +76,10 @@ class DrmPlane {
DrmProperty src_y_property_;
DrmProperty src_w_property_;
DrmProperty src_h_property_;
+ DrmProperty zpos_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..9faa37e 100644
--- a/drmproperty.cpp
+++ b/drmproperty.cpp
@@ -99,4 +99,19 @@ int DrmProperty::value(uint64_t *value) const {
return -EINVAL;
}
}
+
+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_) {
+ 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..f1328fe 100644
--- a/drmproperty.h
+++ b/drmproperty.h
@@ -40,11 +40,13 @@ 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;
int value(uint64_t *value) const;
+ bool immutable() const;
private:
class DrmPropertyEnum {
diff --git a/platform.cpp b/platform.cpp
index af18124..b7a47c7 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,9 +117,11 @@ int PlanStageProtected::ProvisionPlanes(
}
ret = Emplace(composition, planes, DrmCompositionPlane::Type::kLayer, crtc,
- i->first);
- if (ret)
+ std::make_pair(i->first, i->second));
+ if (ret) {
ALOGE("Failed to dedicate protected layer! Dropping it.");
+ return ret;
+ }
protected_zorder = i->first;
i = layers.erase(i);
@@ -91,12 +137,14 @@ 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;
- else if (ret)
+ else if (ret) {
ALOGE("Failed to emplace layer %zu, dropping it", i->first);
+ return ret;
+ }
}
return 0;
diff --git a/platform.h b/platform.h
index 37c4647..a58d62e 100644
--- a/platform.h
+++ b/platform.h
@@ -49,6 +49,9 @@ class Importer {
// Note: This can be called from a different thread than ImportBuffer. The
// implementation is responsible for ensuring thread safety.
virtual int ReleaseBuffer(hwc_drm_bo_t *bo) = 0;
+
+ // Checks if importer can import the buffer.
+ virtual bool CanImportBuffer(buffer_handle_t handle) = 0;
};
class Planner {
@@ -73,17 +76,32 @@ 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);
- if (!plane)
- return -ENOENT;
-
- composition->emplace_back(type, plane, crtc, source_layer);
- return 0;
+ 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);
+ }
+
+ if (!ret) {
+ composition->emplace_back(type, plane, crtc, layer.first);
+ planes->insert(planes->begin(), unused_planes.begin(),
+ unused_planes.end());
+ }
+
+ return ret;
}
};
diff --git a/platformdrmgeneric.cpp b/platformdrmgeneric.cpp
index 24d0650..503c04a 100644
--- a/platformdrmgeneric.cpp
+++ b/platformdrmgeneric.cpp
@@ -161,6 +161,12 @@ int DrmGenericImporter::ReleaseBuffer(hwc_drm_bo_t *bo) {
return 0;
}
+bool DrmGenericImporter::CanImportBuffer(buffer_handle_t handle) {
+ if (handle == NULL)
+ return false;
+ return true;
+}
+
#ifdef USE_DRM_GENERIC_IMPORTER
std::unique_ptr<Planner> Planner::CreateInstance(DrmDevice *) {
std::unique_ptr<Planner> planner(new Planner);
diff --git a/platformdrmgeneric.h b/platformdrmgeneric.h
index d46e8b0..233ba55 100644
--- a/platformdrmgeneric.h
+++ b/platformdrmgeneric.h
@@ -33,6 +33,7 @@ class DrmGenericImporter : public Importer {
int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
int ReleaseBuffer(hwc_drm_bo_t *bo) override;
+ bool CanImportBuffer(buffer_handle_t handle) override;
uint32_t ConvertHalFormatToDrm(uint32_t hal_format);
uint32_t DrmFormatToBitsPerPixel(uint32_t drm_format);
diff --git a/platformhisi.cpp b/platformhisi.cpp
index 68bb5a7..76fe1e7 100644
--- a/platformhisi.cpp
+++ b/platformhisi.cpp
@@ -78,10 +78,10 @@ int HisiImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
if (!hnd)
return -EINVAL;
- // We can't import these types of buffers, so pretend we did and rely on the
- // planner to skip them when choosing layers for planes
+ // We can't import these types of buffers.
+ // These buffers should have been filtered out with CanImportBuffer()
if (!(hnd->usage & GRALLOC_USAGE_HW_FB))
- return 0;
+ return -EINVAL;
uint32_t gem_handle;
int ret = drmPrimeFDToHandle(drm_->fd(), hnd->share_fd, &gem_handle);
@@ -139,36 +139,39 @@ int HisiImporter::ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) {
return ret;
}
+bool HisiImporter::CanImportBuffer(buffer_handle_t handle) {
+ private_handle_t const *hnd = reinterpret_cast<private_handle_t const *>(
+ handle);
+ return hnd && (hnd->usage & GRALLOC_USAGE_HW_FB);
+}
+
class PlanStageHiSi : public Planner::PlanStage {
public:
int ProvisionPlanes(std::vector<DrmCompositionPlane> *composition,
std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
std::vector<DrmPlane *> *planes) {
int layers_added = 0;
- int initial_layers = layers.size();
- // Fill up as many planes as we can with buffers that do not have HW_FB
- // usage
+ // Fill up as many DRM planes as we can with buffers that have HW_FB usage.
+ // Buffers without HW_FB should have been filtered out with
+ // CanImportBuffer(), if we meet one here, just skip it.
for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i)) {
if (!(i->second->gralloc_buffer_usage & GRALLOC_USAGE_HW_FB))
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)
break;
- else if (ret)
+ else if (ret) {
ALOGE("Failed to emplace layer %zu, dropping it", i->first);
+ return ret;
+ }
}
- /*
- * If we only have one layer, but we didn't emplace anything, we
- * can run into trouble, as we might try to device composite a
- * buffer we fake-imported, which can cause things to jamb up.
- * So return an error in this case to ensure we force client
- * compositing.
- */
- if (!layers_added && (initial_layers <= 1))
+ // If we didn't emplace anything, return an error to ensure we force client
+ // compositing.
+ if (!layers_added)
return -EINVAL;
return 0;
diff --git a/platformhisi.h b/platformhisi.h
index 2b2d439..927da17 100644
--- a/platformhisi.h
+++ b/platformhisi.h
@@ -36,6 +36,8 @@ class HisiImporter : public DrmGenericImporter {
int ImportBuffer(buffer_handle_t handle, hwc_drm_bo_t *bo) override;
+ bool CanImportBuffer(buffer_handle_t handle) override;
+
private:
DrmDevice *drm_;