|  | /* | 
|  | * 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, Planner *planner) | 
|  | : crtc_(crtc),  // Can be NULL if we haven't modeset yet | 
|  | planner_(planner) { | 
|  | } | 
|  |  | 
|  | 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::AddPlaneDisable(DrmPlane *plane) { | 
|  | composition_planes_.emplace_back(DrmCompositionPlane::Type::kDisable, plane); | 
|  | 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; | 
|  |  | 
|  | // make sure that source layers are ordered based on zorder | 
|  | std::sort(i.source_layers().begin(), i.source_layers().end()); | 
|  |  | 
|  | std::vector<DrmPlane *> *container = nullptr; | 
|  | if (i.plane()->type() == 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 |