aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Stratiienko <roman.o.stratiienko@globallogic.com>2022-02-02 09:53:50 +0200
committerRoman Stratiienko <roman.o.stratiienko@globallogic.com>2022-02-04 11:19:40 +0200
commit9362cef4c34b9d23018d75be0cbb6ef0486bf75b (patch)
tree26e2c98e3a18d93ad165398f6d60377265b9ec5d
parentd0c035b44a844af5017c0c3b2507af2f3907c36c (diff)
downloaddrm-hwcomposer-9362cef4c34b9d23018d75be0cbb6ef0486bf75b.tar.gz
drm-hwcomposer-9362cef4c34b9d23018d75be0cbb6ef0486bf75b.tar.bz2
drm-hwcomposer-9362cef4c34b9d23018d75be0cbb6ef0486bf75b.zip
drm_hwcomposer: Rework KMS composition planner + plane sharing support
Rewrite Layer-to-Plane planner. Get rid of ~200 redundant lines of code + added plane sharing functionality. Closes: https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer/-/issues/11 Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
-rw-r--r--.ci/Makefile2
-rw-r--r--Android.bp3
-rw-r--r--backend/Backend.cpp4
-rw-r--r--compositor/DrmDisplayComposition.cpp92
-rw-r--r--compositor/DrmDisplayComposition.h90
-rw-r--r--compositor/DrmDisplayCompositor.cpp27
-rw-r--r--compositor/DrmDisplayCompositor.h9
-rw-r--r--compositor/DrmKmsPlan.cpp59
-rw-r--r--compositor/DrmKmsPlan.h44
-rw-r--r--compositor/Planner.cpp81
-rw-r--r--compositor/Planner.h95
-rw-r--r--drm/DrmDisplayPipeline.cpp47
-rw-r--r--drm/DrmDisplayPipeline.h4
-rw-r--r--hwc2_device/HwcDisplay.cpp34
-rw-r--r--hwc2_device/HwcDisplay.h2
15 files changed, 166 insertions, 427 deletions
diff --git a/.ci/Makefile b/.ci/Makefile
index bca785c..a9b96d3 100644
--- a/.ci/Makefile
+++ b/.ci/Makefile
@@ -21,8 +21,6 @@ TIDY_FILES_OVERRIDE := \
bufferinfo/legacy/BufferInfoMaliMediatek.cpp:COARSE \
bufferinfo/legacy/BufferInfoMaliMeson.cpp:COARSE \
bufferinfo/legacy/BufferInfoMinigbm.cpp:COARSE \
- compositor/DrmDisplayComposition.cpp:COARSE \
- compositor/DrmDisplayComposition.h:COARSE \
compositor/DrmDisplayCompositor.cpp:COARSE \
drm/DrmFbImporter.h:FINE \
drm/DrmMode.h:COARSE \
diff --git a/Android.bp b/Android.bp
index 9236b3e..2323c47 100644
--- a/Android.bp
+++ b/Android.bp
@@ -84,9 +84,8 @@ filegroup {
"bufferinfo/BufferInfoGetter.cpp",
"bufferinfo/BufferInfoMapperMetadata.cpp",
- "compositor/DrmDisplayComposition.cpp",
"compositor/DrmDisplayCompositor.cpp",
- "compositor/Planner.cpp",
+ "compositor/DrmKmsPlan.cpp",
"drm/DrmConnector.cpp",
"drm/DrmCrtc.cpp",
diff --git a/backend/Backend.cpp b/backend/Backend.cpp
index d707192..f6d9c18 100644
--- a/backend/Backend.cpp
+++ b/backend/Backend.cpp
@@ -119,8 +119,8 @@ void Backend::MarkValidated(std::vector<HwcLayer *> &layers,
std::tuple<int, int> Backend::GetExtraClientRange(
HwcDisplay *display, const std::vector<HwcLayer *> &layers,
int client_start, size_t client_size) {
- size_t avail_planes = 1 /* primary planes count*/ +
- display->GetPipe().overlay_planes.size();
+ auto planes = display->GetPipe().GetUsablePlanes();
+ size_t avail_planes = planes.size();
/*
* If more layers then planes, save one plane
diff --git a/compositor/DrmDisplayComposition.cpp b/compositor/DrmDisplayComposition.cpp
deleted file mode 100644
index e571b26..0000000
--- a/compositor/DrmDisplayComposition.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwc-drm-display-composition"
-
-#include "DrmDisplayComposition.h"
-
-#include <sync/sync.h>
-#include <xf86drmMode.h>
-
-#include <algorithm>
-#include <cstdlib>
-#include <unordered_set>
-
-#include "DrmDisplayCompositor.h"
-#include "Planner.h"
-#include "drm/DrmDevice.h"
-#include "utils/log.h"
-
-namespace android {
-
-DrmDisplayComposition::DrmDisplayComposition(DrmCrtc *crtc)
- : crtc_(crtc) // Can be NULL if we haven't modeset yet
-{
-}
-
-int DrmDisplayComposition::SetLayers(DrmHwcLayer *layers, size_t num_layers) {
- for (size_t layer_index = 0; layer_index < num_layers; layer_index++) {
- layers_.emplace_back(std::move(layers[layer_index]));
- }
-
- return 0;
-}
-
-int DrmDisplayComposition::AddPlaneComposition(DrmCompositionPlane plane) {
- composition_planes_.emplace_back(std::move(plane));
- return 0;
-}
-
-int DrmDisplayComposition::Plan(std::vector<DrmPlane *> *primary_planes,
- std::vector<DrmPlane *> *overlay_planes) {
- std::map<size_t, DrmHwcLayer *> to_composite;
-
- for (size_t i = 0; i < layers_.size(); ++i)
- to_composite.emplace(std::make_pair(i, &layers_[i]));
-
- int ret = 0;
- std::tie(ret, composition_planes_) = Planner::ProvisionPlanes(to_composite,
- crtc_,
- primary_planes,
- overlay_planes);
- if (ret) {
- ALOGV("Planner failed provisioning planes ret=%d", ret);
- return ret;
- }
-
- // Remove the planes we used from the pool before returning. This ensures they
- // won't be reused by another display in the composition.
- for (auto &i : composition_planes_) {
- if (!i.plane())
- continue;
-
- std::vector<DrmPlane *> *container = nullptr;
- if (i.plane()->GetType() == DRM_PLANE_TYPE_PRIMARY)
- container = primary_planes;
- else
- container = overlay_planes;
- for (auto j = container->begin(); j != container->end(); ++j) {
- if (*j == i.plane()) {
- container->erase(j);
- break;
- }
- }
- }
-
- return 0;
-}
-
-} // namespace android
diff --git a/compositor/DrmDisplayComposition.h b/compositor/DrmDisplayComposition.h
deleted file mode 100644
index dcfd96e..0000000
--- a/compositor/DrmDisplayComposition.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_DRM_DISPLAY_COMPOSITION_H_
-#define ANDROID_DRM_DISPLAY_COMPOSITION_H_
-
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-#include <sstream>
-#include <vector>
-
-#include "drm/DrmCrtc.h"
-#include "drm/DrmPlane.h"
-#include "drmhwcomposer.h"
-
-namespace android {
-
-class Importer;
-
-constexpr size_t kUndefinedSourceLayer = UINT16_MAX;
-
-class DrmCompositionPlane {
- public:
- DrmCompositionPlane() = default;
- DrmCompositionPlane(DrmCompositionPlane &&rhs) = default;
- DrmCompositionPlane &operator=(DrmCompositionPlane &&other) = default;
- DrmCompositionPlane(DrmPlane *plane, size_t source_layer)
- : plane_(plane), source_layer_(source_layer) {
- }
-
- DrmPlane *plane() const {
- return plane_;
- }
-
- size_t source_layer() const {
- return source_layer_;
- }
-
- private:
- DrmPlane *plane_ = nullptr;
- size_t source_layer_ = kUndefinedSourceLayer;
-};
-
-class DrmDisplayComposition {
- public:
- DrmDisplayComposition(const DrmDisplayComposition &) = delete;
- explicit DrmDisplayComposition(DrmCrtc *crtc);
- ~DrmDisplayComposition() = default;
-
- int SetLayers(DrmHwcLayer *layers, size_t num_layers);
- int AddPlaneComposition(DrmCompositionPlane plane);
-
- int Plan(std::vector<DrmPlane *> *primary_planes,
- std::vector<DrmPlane *> *overlay_planes);
-
- std::vector<DrmHwcLayer> &layers() {
- return layers_;
- }
-
- std::vector<DrmCompositionPlane> &composition_planes() {
- return composition_planes_;
- }
-
- DrmCrtc *crtc() const {
- return crtc_;
- }
-
- private:
- DrmCrtc *crtc_ = nullptr;
-
- std::vector<DrmHwcLayer> layers_;
- std::vector<DrmCompositionPlane> composition_planes_;
-};
-} // namespace android
-
-#endif // ANDROID_DRM_DISPLAY_COMPOSITION_H_
diff --git a/compositor/DrmDisplayCompositor.cpp b/compositor/DrmDisplayCompositor.cpp
index bd0247d..5be2941 100644
--- a/compositor/DrmDisplayCompositor.cpp
+++ b/compositor/DrmDisplayCompositor.cpp
@@ -108,29 +108,18 @@ auto DrmDisplayCompositor::CommitFrame(AtomicCommitArgs &args) -> int {
new_frame_state.used_framebuffers.clear();
new_frame_state.used_planes.clear();
- std::vector<DrmHwcLayer> &layers = args.composition->layers();
- std::vector<DrmCompositionPlane> &comp_planes = args.composition
- ->composition_planes();
-
- for (DrmCompositionPlane &comp_plane : comp_planes) {
- DrmPlane *plane = comp_plane.plane();
- size_t source_layer = comp_plane.source_layer();
-
- if (source_layer >= layers.size()) {
- ALOGE("Source layer index %zu out of bounds %zu", source_layer,
- layers.size());
- return -EINVAL;
- }
- DrmHwcLayer &layer = layers[source_layer];
+ for (auto &joining : args.composition->plan) {
+ DrmPlane *plane = joining.plane->Get();
+ DrmHwcLayer &layer = joining.layer;
new_frame_state.used_framebuffers.emplace_back(layer.fb_id_handle);
- new_frame_state.used_planes.emplace_back(plane);
+ new_frame_state.used_planes.emplace_back(joining.plane);
/* Remove from 'unused' list, since plane is re-used */
auto &v = unused_planes;
- v.erase(std::remove(v.begin(), v.end(), plane), v.end());
+ v.erase(std::remove(v.begin(), v.end(), joining.plane), v.end());
- if (plane->AtomicSetState(*pset, layer, source_layer, crtc->GetId()) !=
+ if (plane->AtomicSetState(*pset, layer, joining.z_pos, crtc->GetId()) !=
0) {
return -EINVAL;
}
@@ -143,8 +132,8 @@ auto DrmDisplayCompositor::CommitFrame(AtomicCommitArgs &args) -> int {
}
if (args.clear_active_composition || args.composition) {
- for (auto *plane : unused_planes) {
- if (plane->AtomicDisablePlane(*pset) != 0) {
+ for (auto &plane : unused_planes) {
+ if (plane->Get()->AtomicDisablePlane(*pset) != 0) {
return -EINVAL;
}
}
diff --git a/compositor/DrmDisplayCompositor.h b/compositor/DrmDisplayCompositor.h
index bff3de7..b556268 100644
--- a/compositor/DrmDisplayCompositor.h
+++ b/compositor/DrmDisplayCompositor.h
@@ -17,8 +17,6 @@
#ifndef ANDROID_DRM_DISPLAY_COMPOSITOR_H_
#define ANDROID_DRM_DISPLAY_COMPOSITOR_H_
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
#include <pthread.h>
#include <functional>
@@ -27,7 +25,8 @@
#include <sstream>
#include <tuple>
-#include "DrmDisplayComposition.h"
+#include "DrmKmsPlan.h"
+#include "drm/DrmPlane.h"
#include "drm/ResourceManager.h"
#include "drm/VSyncWorker.h"
#include "drmhwcomposer.h"
@@ -39,7 +38,7 @@ struct AtomicCommitArgs {
bool test_only = false;
std::optional<DrmMode> display_mode;
std::optional<bool> active;
- std::shared_ptr<DrmDisplayComposition> composition;
+ std::shared_ptr<DrmKmsPlan> composition;
/* 'clear' should never be used together with 'composition' */
bool clear_active_composition = false;
@@ -68,7 +67,7 @@ class DrmDisplayCompositor {
struct KmsState {
/* Required to cleanup unused planes */
- std::vector<DrmPlane *> used_planes;
+ std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> used_planes;
/* We have to hold a reference to framebuffer while displaying it ,
* otherwise picture will blink */
std::vector<std::shared_ptr<DrmFbIdHandle>> used_framebuffers;
diff --git a/compositor/DrmKmsPlan.cpp b/compositor/DrmKmsPlan.cpp
new file mode 100644
index 0000000..966bd4e
--- /dev/null
+++ b/compositor/DrmKmsPlan.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "hwc-composition-drm-kms-plan"
+
+#include "DrmKmsPlan.h"
+
+#include "drm/DrmDevice.h"
+#include "drm/DrmPlane.h"
+#include "utils/log.h"
+
+namespace android {
+auto DrmKmsPlan::CreateDrmKmsPlan(DrmDisplayPipeline &pipe,
+ std::vector<DrmHwcLayer> composition)
+ -> std::unique_ptr<DrmKmsPlan> {
+ auto plan = std::make_unique<DrmKmsPlan>();
+
+ auto avail_planes = pipe.GetUsablePlanes();
+
+ int z_pos = 0;
+ for (auto &dhl : composition) {
+ std::shared_ptr<BindingOwner<DrmPlane>> plane;
+
+ /* Skip unsupported planes */
+ do {
+ if (avail_planes.empty()) {
+ return {};
+ }
+
+ plane = *avail_planes.begin();
+ avail_planes.erase(avail_planes.begin());
+ } while (!plane->Get()->IsValidForLayer(&dhl));
+
+ LayerToPlaneJoining joining = {
+ .layer = std::move(dhl),
+ .plane = plane,
+ .z_pos = z_pos++,
+ };
+
+ plan->plan.emplace_back(std::move(joining));
+ }
+
+ return plan;
+}
+
+} // namespace android
diff --git a/compositor/DrmKmsPlan.h b/compositor/DrmKmsPlan.h
new file mode 100644
index 0000000..35e66e9
--- /dev/null
+++ b/compositor/DrmKmsPlan.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_DRM_KMS_PLAN_H_
+#define ANDROID_DRM_KMS_PLAN_H_
+
+#include <memory>
+#include <vector>
+
+#include "drmhwcomposer.h"
+
+namespace android {
+
+class DrmDevice;
+
+struct DrmKmsPlan {
+ struct LayerToPlaneJoining {
+ DrmHwcLayer layer;
+ std::shared_ptr<BindingOwner<DrmPlane>> plane;
+ int z_pos;
+ };
+
+ std::vector<LayerToPlaneJoining> plan;
+
+ static auto CreateDrmKmsPlan(DrmDisplayPipeline &pipe,
+ std::vector<DrmHwcLayer> composition)
+ -> std::unique_ptr<DrmKmsPlan>;
+};
+
+} // namespace android
+#endif
diff --git a/compositor/Planner.cpp b/compositor/Planner.cpp
deleted file mode 100644
index d875b4b..0000000
--- a/compositor/Planner.cpp
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "hwc-platform"
-
-#include "Planner.h"
-
-#include <algorithm>
-
-#include "drm/DrmDevice.h"
-#include "utils/log.h"
-
-namespace android {
-
-std::vector<DrmPlane *> Planner::GetUsablePlanes(
- DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
- std::vector<DrmPlane *> *overlay_planes) {
- std::vector<DrmPlane *> usable_planes;
- std::copy_if(primary_planes->begin(), primary_planes->end(),
- std::back_inserter(usable_planes),
- [=](DrmPlane *plane) { return plane->IsCrtcSupported(*crtc); });
- std::copy_if(overlay_planes->begin(), overlay_planes->end(),
- std::back_inserter(usable_planes),
- [=](DrmPlane *plane) { return plane->IsCrtcSupported(*crtc); });
- return usable_planes;
-}
-
-std::tuple<int, std::vector<DrmCompositionPlane>> Planner::ProvisionPlanes(
- std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
- std::vector<DrmPlane *> *primary_planes,
- std::vector<DrmPlane *> *overlay_planes) {
- std::vector<DrmCompositionPlane> composition;
- std::vector<DrmPlane *> planes = GetUsablePlanes(crtc, primary_planes,
- overlay_planes);
- if (planes.empty()) {
- ALOGE("Crtc %d has no usable planes", crtc->GetId());
- return std::make_tuple(-ENODEV, std::vector<DrmCompositionPlane>());
- }
-
- // Go through the provisioning stages and provision planes
- int ret = ProvisionPlanesInternal(&composition, layers, &planes);
- if (ret != 0) {
- ALOGV("Failed provision stage with ret %d", ret);
- return std::make_tuple(ret, std::vector<DrmCompositionPlane>());
- }
-
- return std::make_tuple(0, std::move(composition));
-}
-
-int Planner::ProvisionPlanesInternal(
- std::vector<DrmCompositionPlane> *composition,
- std::map<size_t, DrmHwcLayer *> &layers, std::vector<DrmPlane *> *planes) {
- // Fill up the remaining planes
- for (auto i = layers.begin(); i != layers.end(); i = layers.erase(i)) {
- int ret = Emplace(composition, planes, std::make_pair(i->first, i->second));
- // We don't have any planes left
- if (ret == -ENOENT)
- break;
-
- if (ret != 0) {
- ALOGV("Failed to emplace layer %zu, dropping it", i->first);
- return ret;
- }
- }
-
- return 0;
-}
-} // namespace android
diff --git a/compositor/Planner.h b/compositor/Planner.h
deleted file mode 100644
index 7802d0c..0000000
--- a/compositor/Planner.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_DRM_PLATFORM_H_
-#define ANDROID_DRM_PLATFORM_H_
-
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "compositor/DrmDisplayComposition.h"
-#include "drmhwcomposer.h"
-
-namespace android {
-
-class DrmDevice;
-
-class Planner {
- private:
- // Removes and returns the next available plane from planes
- static DrmPlane *PopPlane(std::vector<DrmPlane *> *planes) {
- if (planes->empty())
- return nullptr;
- DrmPlane *plane = planes->front();
- planes->erase(planes->begin());
- return plane;
- }
-
- // Inserts the given layer:plane in the composition at the back
- static int Emplace(std::vector<DrmCompositionPlane> *composition,
- std::vector<DrmPlane *> *planes,
- std::pair<size_t, DrmHwcLayer *> layer) {
- DrmPlane *plane = PopPlane(planes);
- std::vector<DrmPlane *> unused_planes;
- int ret = -ENOENT;
- while (plane != nullptr) {
- ret = plane->IsValidForLayer(layer.second) ? 0 : -EINVAL;
- if (ret == 0)
- break;
- if (!plane->GetZPosProperty().is_immutable())
- unused_planes.push_back(plane);
- plane = PopPlane(planes);
- }
-
- if (ret == 0) {
- composition->emplace_back(plane, layer.first);
- planes->insert(planes->begin(), unused_planes.begin(),
- unused_planes.end());
- }
-
- return ret;
- }
-
- static int ProvisionPlanesInternal(
- std::vector<DrmCompositionPlane> *composition,
- std::map<size_t, DrmHwcLayer *> &layers, std::vector<DrmPlane *> *planes);
-
- public:
- // Takes a stack of layers and provisions hardware planes for them. If the
- // entire stack can't fit in hardware, FIXME
- //
- // @layers: a map of index:layer of layers to composite
- // @primary_planes: a vector of primary planes available for this frame
- // @overlay_planes: a vector of overlay planes available for this frame
- //
- // Returns: A tuple with the status of the operation (0 for success) and
- // a vector of the resulting plan (ie: layer->plane mapping).
- static std::tuple<int, std::vector<DrmCompositionPlane>> ProvisionPlanes(
- std::map<size_t, DrmHwcLayer *> &layers, DrmCrtc *crtc,
- std::vector<DrmPlane *> *primary_planes,
- std::vector<DrmPlane *> *overlay_planes);
-
- private:
- static std::vector<DrmPlane *> GetUsablePlanes(
- DrmCrtc *crtc, std::vector<DrmPlane *> *primary_planes,
- std::vector<DrmPlane *> *overlay_planes);
-};
-} // namespace android
-#endif
diff --git a/drm/DrmDisplayPipeline.cpp b/drm/DrmDisplayPipeline.cpp
index 0ce1afc..31bc764 100644
--- a/drm/DrmDisplayPipeline.cpp
+++ b/drm/DrmDisplayPipeline.cpp
@@ -98,22 +98,6 @@ static auto TryCreatePipeline(DrmDevice &dev, DrmConnector &connector,
return {};
}
- char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
- property_get("vendor.hwc.drm.use_overlay_planes", use_overlay_planes_prop,
- "1");
- constexpr int kStrtolBase = 10;
- bool use_overlay_planes = strtol(use_overlay_planes_prop, nullptr,
- kStrtolBase) != 0;
-
- if (use_overlay_planes) {
- for (auto *plane : overlay_planes) {
- auto op = plane->BindPipeline(pipe.get());
- if (op) {
- pipe->overlay_planes.emplace_back(op);
- }
- }
- }
-
pipe->compositor = std::make_unique<DrmDisplayCompositor>(pipe.get());
return pipe;
@@ -173,4 +157,35 @@ auto DrmDisplayPipeline::CreatePipeline(DrmConnector &connector)
return {};
}
+static bool ReadUseOverlayProperty() {
+ char use_overlay_planes_prop[PROPERTY_VALUE_MAX];
+ property_get("vendor.hwc.drm.use_overlay_planes", use_overlay_planes_prop,
+ "1");
+ constexpr int kStrtolBase = 10;
+ return strtol(use_overlay_planes_prop, nullptr, kStrtolBase) != 0;
+}
+
+auto DrmDisplayPipeline::GetUsablePlanes()
+ -> std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> {
+ std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> planes;
+ planes.emplace_back(primary_plane);
+
+ static bool use_overlay_planes = ReadUseOverlayProperty();
+
+ if (use_overlay_planes) {
+ for (const auto &plane : device->GetPlanes()) {
+ if (plane->IsCrtcSupported(*crtc->Get())) {
+ if (plane->GetType() == DRM_PLANE_TYPE_OVERLAY) {
+ auto op = plane->BindPipeline(this, true);
+ if (op) {
+ planes.emplace_back(op);
+ }
+ }
+ }
+ }
+ }
+
+ return planes;
+}
+
} // namespace android
diff --git a/drm/DrmDisplayPipeline.h b/drm/DrmDisplayPipeline.h
index a3e2dd9..f055c85 100644
--- a/drm/DrmDisplayPipeline.h
+++ b/drm/DrmDisplayPipeline.h
@@ -72,13 +72,15 @@ struct DrmDisplayPipeline {
static auto CreatePipeline(DrmConnector &connector)
-> std::unique_ptr<DrmDisplayPipeline>;
+ auto GetUsablePlanes()
+ -> std::vector<std::shared_ptr<BindingOwner<DrmPlane>>>;
+
DrmDevice *device;
std::shared_ptr<BindingOwner<DrmConnector>> connector;
std::shared_ptr<BindingOwner<DrmEncoder>> encoder;
std::shared_ptr<BindingOwner<DrmCrtc>> crtc;
std::shared_ptr<BindingOwner<DrmPlane>> primary_plane;
- std::vector<std::shared_ptr<BindingOwner<DrmPlane>>> overlay_planes;
std::unique_ptr<DrmDisplayCompositor> compositor;
};
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index d7b753a..f778e22 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -497,31 +497,21 @@ HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
composition_layers.emplace_back(std::move(layer));
}
- auto composition = std::make_shared<DrmDisplayComposition>(
- GetPipe().crtc->Get());
-
- // TODO(nobody): Don't always assume geometry changed
- int ret = composition->SetLayers(composition_layers.data(),
- composition_layers.size());
- if (ret) {
- ALOGE("Failed to set layers in the composition ret=%d", ret);
- return HWC2::Error::BadLayer;
- }
-
- std::vector<DrmPlane *> primary_planes;
- primary_planes.emplace_back(pipeline_->primary_plane->Get());
- std::vector<DrmPlane *> overlay_planes;
- for (const auto &owned_plane : pipeline_->overlay_planes) {
- overlay_planes.emplace_back(owned_plane->Get());
- }
- ret = composition->Plan(&primary_planes, &overlay_planes);
- if (ret) {
- ALOGV("Failed to plan the composition ret=%d", ret);
+ /* Store plan to ensure shared planes won't be stolen by other display
+ * in between of ValidateDisplay() and PresentDisplay() calls
+ */
+ current_plan_ = DrmKmsPlan::CreateDrmKmsPlan(GetPipe(),
+ std::move(composition_layers));
+ if (!current_plan_) {
+ if (!a_args.test_only) {
+ ALOGE("Failed to create DrmKmsPlan");
+ }
return HWC2::Error::BadConfig;
}
- a_args.composition = composition;
- ret = GetPipe().compositor->ExecuteAtomicCommit(a_args);
+ a_args.composition = current_plan_;
+
+ int ret = GetPipe().compositor->ExecuteAtomicCommit(a_args);
if (ret) {
if (!a_args.test_only)
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index e7ce7ef..ed29da6 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -221,6 +221,8 @@ class HwcDisplay {
std::array<float, MATRIX_SIZE> color_transform_matrix_{};
android_color_transform_t color_transform_hint_;
+ std::shared_ptr<DrmKmsPlan> current_plan_;
+
uint32_t frame_no_ = 0;
Stats total_stats_;
Stats prev_stats_;