aboutsummaryrefslogtreecommitdiffstats
path: root/compositor
diff options
context:
space:
mode:
Diffstat (limited to 'compositor')
-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
8 files changed, 115 insertions, 382 deletions
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