From 9362cef4c34b9d23018d75be0cbb6ef0486bf75b Mon Sep 17 00:00:00 2001 From: Roman Stratiienko Date: Wed, 2 Feb 2022 09:53:50 +0200 Subject: 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 --- .ci/Makefile | 2 - Android.bp | 3 +- backend/Backend.cpp | 4 +- compositor/DrmDisplayComposition.cpp | 92 ---------------------------------- compositor/DrmDisplayComposition.h | 90 ---------------------------------- compositor/DrmDisplayCompositor.cpp | 27 +++------- compositor/DrmDisplayCompositor.h | 9 ++-- compositor/DrmKmsPlan.cpp | 59 ++++++++++++++++++++++ compositor/DrmKmsPlan.h | 44 +++++++++++++++++ compositor/Planner.cpp | 81 ------------------------------ compositor/Planner.h | 95 ------------------------------------ drm/DrmDisplayPipeline.cpp | 47 ++++++++++++------ drm/DrmDisplayPipeline.h | 4 +- hwc2_device/HwcDisplay.cpp | 34 +++++-------- hwc2_device/HwcDisplay.h | 2 + 15 files changed, 166 insertions(+), 427 deletions(-) delete mode 100644 compositor/DrmDisplayComposition.cpp delete mode 100644 compositor/DrmDisplayComposition.h create mode 100644 compositor/DrmKmsPlan.cpp create mode 100644 compositor/DrmKmsPlan.h delete mode 100644 compositor/Planner.cpp delete mode 100644 compositor/Planner.h 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 &layers, std::tuple Backend::GetExtraClientRange( HwcDisplay *display, const std::vector &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 -#include - -#include -#include -#include - -#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 *primary_planes, - std::vector *overlay_planes) { - std::map 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 *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 -#include - -#include -#include - -#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 *primary_planes, - std::vector *overlay_planes); - - std::vector &layers() { - return layers_; - } - - std::vector &composition_planes() { - return composition_planes_; - } - - DrmCrtc *crtc() const { - return crtc_; - } - - private: - DrmCrtc *crtc_ = nullptr; - - std::vector layers_; - std::vector 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 &layers = args.composition->layers(); - std::vector &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 -#include #include #include @@ -27,7 +25,8 @@ #include #include -#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 display_mode; std::optional active; - std::shared_ptr composition; + std::shared_ptr 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 used_planes; + std::vector>> used_planes; /* We have to hold a reference to framebuffer while displaying it , * otherwise picture will blink */ std::vector> 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 composition) + -> std::unique_ptr { + auto plan = std::make_unique(); + + auto avail_planes = pipe.GetUsablePlanes(); + + int z_pos = 0; + for (auto &dhl : composition) { + std::shared_ptr> 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 +#include + +#include "drmhwcomposer.h" + +namespace android { + +class DrmDevice; + +struct DrmKmsPlan { + struct LayerToPlaneJoining { + DrmHwcLayer layer; + std::shared_ptr> plane; + int z_pos; + }; + + std::vector plan; + + static auto CreateDrmKmsPlan(DrmDisplayPipeline &pipe, + std::vector composition) + -> std::unique_ptr; +}; + +} // 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 - -#include "drm/DrmDevice.h" -#include "utils/log.h" - -namespace android { - -std::vector Planner::GetUsablePlanes( - DrmCrtc *crtc, std::vector *primary_planes, - std::vector *overlay_planes) { - std::vector 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> Planner::ProvisionPlanes( - std::map &layers, DrmCrtc *crtc, - std::vector *primary_planes, - std::vector *overlay_planes) { - std::vector composition; - std::vector 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()); - } - - // 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()); - } - - return std::make_tuple(0, std::move(composition)); -} - -int Planner::ProvisionPlanesInternal( - std::vector *composition, - std::map &layers, std::vector *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 -#include - -#include -#include -#include - -#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 *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 *composition, - std::vector *planes, - std::pair layer) { - DrmPlane *plane = PopPlane(planes); - std::vector 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 *composition, - std::map &layers, std::vector *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> ProvisionPlanes( - std::map &layers, DrmCrtc *crtc, - std::vector *primary_planes, - std::vector *overlay_planes); - - private: - static std::vector GetUsablePlanes( - DrmCrtc *crtc, std::vector *primary_planes, - std::vector *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(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::vector>> 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; + auto GetUsablePlanes() + -> std::vector>>; + DrmDevice *device; std::shared_ptr> connector; std::shared_ptr> encoder; std::shared_ptr> crtc; std::shared_ptr> primary_plane; - std::vector>> overlay_planes; std::unique_ptr 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( - 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 primary_planes; - primary_planes.emplace_back(pipeline_->primary_plane->Get()); - std::vector 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 color_transform_matrix_{}; android_color_transform_t color_transform_hint_; + std::shared_ptr current_plan_; + uint32_t frame_no_ = 0; Stats total_stats_; Stats prev_stats_; -- cgit v1.2.3