diff options
Diffstat (limited to 'compositor')
-rw-r--r-- | compositor/DrmDisplayComposition.cpp | 92 | ||||
-rw-r--r-- | compositor/DrmDisplayComposition.h | 90 | ||||
-rw-r--r-- | compositor/DrmDisplayCompositor.cpp | 27 | ||||
-rw-r--r-- | compositor/DrmDisplayCompositor.h | 9 | ||||
-rw-r--r-- | compositor/DrmKmsPlan.cpp | 59 | ||||
-rw-r--r-- | compositor/DrmKmsPlan.h | 44 | ||||
-rw-r--r-- | compositor/Planner.cpp | 81 | ||||
-rw-r--r-- | compositor/Planner.h | 95 |
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 |