| /* |
| * Copyright (C) 2024 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. |
| */ |
| |
| #include <unordered_map> |
| #include <vector> |
| |
| #include <android-base/unique_fd.h> |
| |
| #include "Utils.h" |
| #include "aidl/android/hardware/graphics/composer3/CommandError.h" |
| #include "aidl/android/hardware/graphics/composer3/CommandResultPayload.h" |
| #include "aidl/android/hardware/graphics/composer3/PresentFence.h" |
| #include "aidl/android/hardware/graphics/composer3/PresentOrValidate.h" |
| #include "aidl/android/hardware/graphics/composer3/ReleaseFences.h" |
| |
| namespace aidl::android::hardware::graphics::composer3 { |
| |
| struct DisplayChanges { |
| std::optional<ChangedCompositionTypes> composition_changes; |
| std::optional<DisplayRequest> display_request_changes; |
| |
| void AddLayerCompositionChange(int64_t display_id, int64_t layer_id, |
| Composition layer_composition) { |
| if (!composition_changes) { |
| composition_changes.emplace(); |
| composition_changes->display = display_id; |
| } |
| |
| ChangedCompositionLayer composition_change; |
| composition_change.layer = layer_id; |
| composition_change.composition = layer_composition; |
| composition_changes->layers.emplace_back(composition_change); |
| } |
| |
| void ClearLayerCompositionChanges() { |
| composition_changes.reset(); |
| } |
| |
| bool HasAnyChanges() const { |
| return composition_changes.has_value() || |
| display_request_changes.has_value(); |
| } |
| |
| void Reset() { |
| composition_changes.reset(); |
| display_request_changes.reset(); |
| } |
| }; |
| |
| class CommandResultWriter { |
| public: |
| explicit CommandResultWriter(std::vector<CommandResultPayload>* results) |
| : results_(results) { |
| } |
| |
| bool HasError() const { |
| return has_error_; |
| } |
| |
| void IncrementCommand() { |
| index_++; |
| has_error_ = false; |
| } |
| |
| void AddError(hwc3::Error error) { |
| CommandError command_error; |
| command_error.errorCode = static_cast<int32_t>(error); |
| command_error.commandIndex = static_cast<int32_t>(index_); |
| |
| results_->emplace_back(command_error); |
| has_error_ = true; |
| } |
| |
| void AddPresentFence(int64_t display_id, ::android::base::unique_fd fence) { |
| if (!fence.ok()) { |
| return; |
| } |
| |
| PresentFence present_fence; |
| present_fence.fence = ::ndk::ScopedFileDescriptor(fence.release()); |
| present_fence.display = display_id; |
| results_->emplace_back(std::move(present_fence)); |
| } |
| |
| void AddReleaseFence( |
| int64_t display_id, |
| std::unordered_map<int64_t, ::android::base::unique_fd>& layer_fences) { |
| ReleaseFences release_fences; |
| release_fences.display = display_id; |
| for (auto& [layer, fence] : layer_fences) { |
| if (!fence.ok()) { |
| continue; |
| } |
| |
| ReleaseFences::Layer layer_result; |
| layer_result.layer = layer; |
| layer_result.fence = ::ndk::ScopedFileDescriptor(fence.release()); |
| |
| release_fences.layers.emplace_back(std::move(layer_result)); |
| } |
| |
| results_->emplace_back(std::move(release_fences)); |
| } |
| |
| void AddChanges(const DisplayChanges& changes) { |
| if (changes.composition_changes) { |
| results_->emplace_back(*changes.composition_changes); |
| } |
| if (changes.display_request_changes) { |
| results_->emplace_back(*changes.display_request_changes); |
| } |
| } |
| |
| void AddPresentOrValidateResult(int64_t display_id, |
| const PresentOrValidate::Result& pov_result) { |
| PresentOrValidate pov_command; |
| pov_command.display = display_id; |
| pov_command.result = pov_result; |
| |
| results_->emplace_back(pov_command); |
| } |
| |
| private: |
| size_t index_{0}; |
| bool has_error_{false}; |
| std::vector<CommandResultPayload>* results_{nullptr}; |
| }; |
| }; // namespace aidl::android::hardware::graphics::composer3 |