diff options
author | Rob Herring <robh@kernel.org> | 2018-05-17 14:33:02 -0500 |
---|---|---|
committer | Sean Paul <seanpaul@chromium.org> | 2018-05-30 13:31:41 -0400 |
commit | 4f6c62e978a02c78c6ae4e9707f0cb0a174f5721 (patch) | |
tree | cb55d34a7d41d5ed1bad2ab0f0371b1fe9a40046 | |
parent | cff7b1e829c3ee3608146144148b6602e218fbae (diff) | |
download | drm_hwcomposer-4f6c62e978a02c78c6ae4e9707f0cb0a174f5721.tar.gz |
drm_hwcomposer: Support assigning planes in ValidateDisplay
In order to assign planes to layers in ValidateDisplay, testing
compositing with a DRM atomic modeset test is needed as PresentDisplay
is too late. This means most of PresentDisplay needs to be run from
ValidateDisplay, so refactor PresentDisplay to a common function adding
a test only option.
Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r-- | drmdisplaycompositor.cpp | 4 | ||||
-rw-r--r-- | drmdisplaycompositor.h | 1 | ||||
-rw-r--r-- | drmhwctwo.cpp | 78 | ||||
-rw-r--r-- | drmhwctwo.h | 1 |
4 files changed, 74 insertions, 10 deletions
diff --git a/drmdisplaycompositor.cpp b/drmdisplaycompositor.cpp index 2f9f6c6..defede6 100644 --- a/drmdisplaycompositor.cpp +++ b/drmdisplaycompositor.cpp @@ -510,6 +510,10 @@ int DrmDisplayCompositor::ApplyComposition( return ret; } +int DrmDisplayCompositor::TestComposition(DrmDisplayComposition *composition) { + return CommitFrame(composition, true); +} + void DrmDisplayCompositor::Dump(std::ostringstream *out) const { int ret = pthread_mutex_lock(&lock_); if (ret) diff --git a/drmdisplaycompositor.h b/drmdisplaycompositor.h index ed46873..0d85949 100644 --- a/drmdisplaycompositor.h +++ b/drmdisplaycompositor.h @@ -44,6 +44,7 @@ class DrmDisplayCompositor { std::unique_ptr<DrmDisplayComposition> CreateComposition() const; int ApplyComposition(std::unique_ptr<DrmDisplayComposition> composition); + int TestComposition(DrmDisplayComposition *composition); int Composite(); void Dump(std::ostringstream *out) const; diff --git a/drmhwctwo.cpp b/drmhwctwo.cpp index 3c22484..cbe6df7 100644 --- a/drmhwctwo.cpp +++ b/drmhwctwo.cpp @@ -467,8 +467,7 @@ void DrmHwcTwo::HwcDisplay::AddFenceToRetireFence(int fd) { } } -HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { - supported(__func__); +HWC2::Error DrmHwcTwo::HwcDisplay::CreateComposition(bool test) { std::vector<DrmCompositionDisplayLayersMap> layers_map; layers_map.emplace_back(); DrmCompositionDisplayLayersMap &map = layers_map.back(); @@ -481,7 +480,13 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { uint32_t client_z_order = 0; std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map; for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { - switch (l.second.validated_type()) { + HWC2::Composition comp_type; + if (test) + comp_type = l.second.sf_type(); + else + comp_type = l.second.validated_type(); + + switch (comp_type) { case HWC2::Composition::Device: z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); break; @@ -497,6 +502,9 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { if (use_client_layer) z_map.emplace(std::make_pair(client_z_order, &client_layer_)); + if (z_map.empty()) + return HWC2::Error::BadLayer; + // now that they're ordered by z, add them to the composition for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { DrmHwcLayer layer; @@ -508,10 +516,6 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { } map.layers.emplace_back(std::move(layer)); } - if (map.layers.empty()) { - *retire_fence = -1; - return HWC2::Error::None; - } std::unique_ptr<DrmDisplayComposition> composition = compositor_.CreateComposition(); @@ -542,13 +546,31 @@ HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { i = overlay_planes.erase(i); } - AddFenceToRetireFence(composition->take_out_fence()); - - ret = compositor_.ApplyComposition(std::move(composition)); + if (test) { + ret = compositor_.TestComposition(composition.get()); + } else { + AddFenceToRetireFence(composition->take_out_fence()); + ret = compositor_.ApplyComposition(std::move(composition)); + } if (ret) { ALOGE("Failed to apply the frame composition ret=%d", ret); return HWC2::Error::BadParameter; } + return HWC2::Error::None; +} + +HWC2::Error DrmHwcTwo::HwcDisplay::PresentDisplay(int32_t *retire_fence) { + supported(__func__); + HWC2::Error ret; + + ret = CreateComposition(false); + if (ret == HWC2::Error::BadLayer) { + // Can we really have no client or device layers? + *retire_fence = -1; + return HWC2::Error::None; + } + if (ret != HWC2::Error::None) + return ret; // The retire fence returned here is for the last frame, so return it and // promote the next retire fence @@ -670,11 +692,47 @@ HWC2::Error DrmHwcTwo::HwcDisplay::SetVsyncEnabled(int32_t enabled) { HWC2::Error DrmHwcTwo::HwcDisplay::ValidateDisplay(uint32_t *num_types, uint32_t *num_requests) { supported(__func__); + size_t plane_count = 0; *num_types = 0; *num_requests = 0; + size_t avail_planes = primary_planes_.size() + overlay_planes_.size(); + + HWC2::Error ret; + + for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) + l.second.set_validated_type(HWC2::Composition::Invalid); + + ret = CreateComposition(true); + if (ret != HWC2::Error::None) + // Assume the test failed due to overlay planes + avail_planes = 1; + + std::map<uint32_t, DrmHwcTwo::HwcLayer *> z_map; + for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { + if (l.second.sf_type() == HWC2::Composition::Device) + z_map.emplace(std::make_pair(l.second.z_order(), &l.second)); + } + + /* + * If more layers then planes, save one plane + * for client composited layers + */ + if (avail_planes < layers_.size()) + avail_planes--; + + for (std::pair<const uint32_t, DrmHwcTwo::HwcLayer *> &l : z_map) { + if (!avail_planes--) + break; + l.second->set_validated_type(HWC2::Composition::Device); + } + for (std::pair<const hwc2_layer_t, DrmHwcTwo::HwcLayer> &l : layers_) { DrmHwcTwo::HwcLayer &layer = l.second; switch (layer.sf_type()) { + case HWC2::Composition::Device: + if (layer.validated_type() == HWC2::Composition::Device) + break; + // fall thru case HWC2::Composition::SolidColor: case HWC2::Composition::Cursor: case HWC2::Composition::Sideband: diff --git a/drmhwctwo.h b/drmhwctwo.h index aa9de3f..82a9768 100644 --- a/drmhwctwo.h +++ b/drmhwctwo.h @@ -185,6 +185,7 @@ class DrmHwcTwo : public hwc2_device_t { } private: + HWC2::Error CreateComposition(bool test); void AddFenceToRetireFence(int fd); DrmResources *drm_; |