| /* |
| * Copyright 2021 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. |
| */ |
| |
| #pragma once |
| |
| #include <algorithm> |
| #include <limits> |
| #include <memory> |
| #include <unordered_map> |
| #include <unordered_set> |
| #include <vector> |
| |
| #include <inttypes.h> |
| #include <string.h> |
| |
| #include <aidl/android/hardware/graphics/common/BlendMode.h> |
| #include <aidl/android/hardware/graphics/composer3/ClientTargetProperty.h> |
| #include <aidl/android/hardware/graphics/composer3/Color.h> |
| #include <aidl/android/hardware/graphics/composer3/Composition.h> |
| #include <aidl/android/hardware/graphics/composer3/FloatColor.h> |
| #include <aidl/android/hardware/graphics/composer3/HandleIndex.h> |
| #include <aidl/android/hardware/graphics/composer3/IComposer.h> |
| #include <aidl/android/hardware/graphics/composer3/IComposerClient.h> |
| #include <aidl/android/hardware/graphics/composer3/PerFrameMetadata.h> |
| #include <aidl/android/hardware/graphics/composer3/PerFrameMetadataBlob.h> |
| |
| #include <aidl/android/hardware/graphics/composer3/CommandResultPayload.h> |
| #include <aidl/android/hardware/graphics/composer3/DisplayCommand.h> |
| |
| #include <aidl/android/hardware/graphics/common/ColorTransform.h> |
| #include <aidl/android/hardware/graphics/common/FRect.h> |
| #include <aidl/android/hardware/graphics/common/Rect.h> |
| #include <aidl/android/hardware/graphics/common/Transform.h> |
| |
| #include <log/log.h> |
| #include <sync/sync.h> |
| |
| #include <aidlcommonsupport/NativeHandle.h> |
| |
| using aidl::android::hardware::graphics::common::BlendMode; |
| using aidl::android::hardware::graphics::common::ColorTransform; |
| using aidl::android::hardware::graphics::common::Dataspace; |
| using aidl::android::hardware::graphics::common::FRect; |
| using aidl::android::hardware::graphics::common::Rect; |
| using aidl::android::hardware::graphics::common::Transform; |
| |
| using namespace aidl::android::hardware::graphics::composer3; |
| |
| using aidl::android::hardware::common::NativeHandle; |
| |
| namespace aidl::android::hardware::graphics::composer3 { |
| |
| // This class helps build a command queue. Note that all sizes/lengths are in |
| // units of uint32_t's. |
| class CommandWriterBase { |
| public: |
| CommandWriterBase() { reset(); } |
| |
| virtual ~CommandWriterBase() { reset(); } |
| |
| void reset() { |
| mDisplayCommand.reset(); |
| mLayerCommand.reset(); |
| mCommands.clear(); |
| mCommandsResults.clear(); |
| } |
| |
| void setError(int32_t index, int32_t errorCode) { |
| CommandError error; |
| error.commandIndex = index; |
| error.errorCode = errorCode; |
| mCommandsResults.emplace_back(std::move(error)); |
| } |
| |
| void setPresentOrValidateResult(int64_t display, PresentOrValidate::Result result) { |
| PresentOrValidate presentOrValidate; |
| presentOrValidate.display = display; |
| presentOrValidate.result = result; |
| mCommandsResults.emplace_back(std::move(presentOrValidate)); |
| } |
| |
| void setChangedCompositionTypes(int64_t display, const std::vector<int64_t>& layers, |
| const std::vector<Composition>& types) { |
| ChangedCompositionTypes changedCompositionTypes; |
| changedCompositionTypes.display = display; |
| changedCompositionTypes.layers.reserve(layers.size()); |
| for (int i = 0; i < layers.size(); i++) { |
| auto layer = ChangedCompositionLayer{.layer = layers[i], .composition = types[i]}; |
| changedCompositionTypes.layers.emplace_back(std::move(layer)); |
| } |
| mCommandsResults.emplace_back(std::move(changedCompositionTypes)); |
| } |
| |
| void setDisplayRequests(int64_t display, int32_t displayRequestMask, |
| const std::vector<int64_t>& layers, |
| const std::vector<int32_t>& layerRequestMasks) { |
| DisplayRequest displayRequest; |
| displayRequest.display = display; |
| displayRequest.mask = displayRequestMask; |
| displayRequest.layerRequests.reserve(layers.size()); |
| for (int i = 0; i < layers.size(); i++) { |
| auto layerRequest = |
| DisplayRequest::LayerRequest{.layer = layers[i], .mask = layerRequestMasks[i]}; |
| displayRequest.layerRequests.emplace_back(std::move(layerRequest)); |
| } |
| mCommandsResults.emplace_back(std::move(displayRequest)); |
| } |
| |
| void setPresentFence(int64_t display, ::ndk::ScopedFileDescriptor presentFence) { |
| if (presentFence.get() >= 0) { |
| PresentFence presentFenceCommand; |
| presentFenceCommand.fence = std::move(presentFence); |
| presentFenceCommand.display = display; |
| mCommandsResults.emplace_back(std::move(presentFenceCommand)); |
| } else { |
| ALOGW("%s: invalid present fence %d", __func__, presentFence.get()); |
| } |
| } |
| |
| void setReleaseFences(int64_t display, const std::vector<int64_t>& layers, |
| std::vector<::ndk::ScopedFileDescriptor> releaseFences) { |
| ReleaseFences releaseFencesCommand; |
| releaseFencesCommand.display = display; |
| for (int i = 0; i < layers.size(); i++) { |
| if (releaseFences[i].get() >= 0) { |
| ReleaseFences::Layer layer; |
| layer.layer = layers[i]; |
| layer.fence = std::move(releaseFences[i]); |
| releaseFencesCommand.layers.emplace_back(std::move(layer)); |
| } else { |
| ALOGW("%s: invalid release fence %d", __func__, releaseFences[i].get()); |
| } |
| } |
| mCommandsResults.emplace_back(std::move(releaseFencesCommand)); |
| } |
| |
| void setClientTargetProperty(int64_t display, const ClientTargetProperty& clientTargetProperty, |
| float whitePointNits) { |
| ClientTargetPropertyWithNits clientTargetPropertyWithNits; |
| clientTargetPropertyWithNits.display = display; |
| clientTargetPropertyWithNits.clientTargetProperty = clientTargetProperty; |
| clientTargetPropertyWithNits.whitePointNits = whitePointNits; |
| mCommandsResults.emplace_back(std::move(clientTargetPropertyWithNits)); |
| } |
| |
| void setColorTransform(int64_t display, const float* matrix, ColorTransform hint) { |
| ColorTransformPayload colorTransformPayload; |
| colorTransformPayload.matrix.assign(matrix, matrix + 16); |
| colorTransformPayload.hint = hint; |
| getDisplayCommand(display).colorTransform.emplace(std::move(colorTransformPayload)); |
| } |
| |
| void setClientTarget(int64_t display, uint32_t slot, const native_handle_t* target, |
| int acquireFence, Dataspace dataspace, const std::vector<Rect>& damage) { |
| ClientTarget clientTargetCommand; |
| clientTargetCommand.buffer = getBuffer(slot, target, acquireFence); |
| clientTargetCommand.dataspace = dataspace; |
| clientTargetCommand.damage.assign(damage.begin(), damage.end()); |
| getDisplayCommand(display).clientTarget.emplace(std::move(clientTargetCommand)); |
| } |
| |
| void setOutputBuffer(int64_t display, uint32_t slot, const native_handle_t* buffer, |
| int releaseFence) { |
| getDisplayCommand(display).virtualDisplayOutputBuffer.emplace( |
| getBuffer(slot, buffer, releaseFence)); |
| } |
| |
| void validateDisplay(int64_t display) { getDisplayCommand(display).validateDisplay = true; } |
| |
| void presentOrvalidateDisplay(int64_t display) { |
| getDisplayCommand(display).presentOrValidateDisplay = true; |
| } |
| |
| void acceptDisplayChanges(int64_t display) { |
| getDisplayCommand(display).acceptDisplayChanges = true; |
| } |
| |
| void presentDisplay(int64_t display) { getDisplayCommand(display).presentDisplay = true; } |
| |
| void setLayerCursorPosition(int64_t display, int64_t layer, int32_t x, int32_t y) { |
| common::Point cursorPosition; |
| cursorPosition.x = x; |
| cursorPosition.y = y; |
| getLayerCommand(display, layer).cursorPosition.emplace(std::move(cursorPosition)); |
| } |
| |
| void setLayerBuffer(int64_t display, int64_t layer, uint32_t slot, |
| const native_handle_t* buffer, int acquireFence) { |
| getLayerCommand(display, layer).buffer = getBuffer(slot, buffer, acquireFence); |
| } |
| |
| void setLayerSurfaceDamage(int64_t display, int64_t layer, const std::vector<Rect>& damage) { |
| getLayerCommand(display, layer).damage.emplace(damage.begin(), damage.end()); |
| } |
| |
| void setLayerBlendMode(int64_t display, int64_t layer, BlendMode mode) { |
| ParcelableBlendMode parcelableBlendMode; |
| parcelableBlendMode.blendMode = mode; |
| getLayerCommand(display, layer).blendMode.emplace(std::move(parcelableBlendMode)); |
| } |
| |
| void setLayerColor(int64_t display, int64_t layer, Color color) { |
| getLayerCommand(display, layer).color.emplace(std::move(color)); |
| } |
| |
| void setLayerCompositionType(int64_t display, int64_t layer, Composition type) { |
| ParcelableComposition compositionPayload; |
| compositionPayload.composition = type; |
| getLayerCommand(display, layer).composition.emplace(std::move(compositionPayload)); |
| } |
| |
| void setLayerDataspace(int64_t display, int64_t layer, Dataspace dataspace) { |
| ParcelableDataspace dataspacePayload; |
| dataspacePayload.dataspace = dataspace; |
| getLayerCommand(display, layer).dataspace.emplace(std::move(dataspacePayload)); |
| } |
| |
| void setLayerDisplayFrame(int64_t display, int64_t layer, const Rect& frame) { |
| getLayerCommand(display, layer).displayFrame.emplace(frame); |
| } |
| |
| void setLayerPlaneAlpha(int64_t display, int64_t layer, float alpha) { |
| PlaneAlpha planeAlpha; |
| planeAlpha.alpha = alpha; |
| getLayerCommand(display, layer).planeAlpha.emplace(std::move(planeAlpha)); |
| } |
| |
| void setLayerSidebandStream(int64_t display, int64_t layer, const native_handle_t* stream) { |
| NativeHandle handle; |
| if (stream) handle = ::android::dupToAidl(stream); |
| getLayerCommand(display, layer).sidebandStream.emplace(std::move(handle)); |
| } |
| |
| void setLayerSourceCrop(int64_t display, int64_t layer, const FRect& crop) { |
| getLayerCommand(display, layer).sourceCrop.emplace(crop); |
| } |
| |
| void setLayerTransform(int64_t display, int64_t layer, Transform transform) { |
| ParcelableTransform transformPayload; |
| transformPayload.transform = transform; |
| getLayerCommand(display, layer).transform.emplace(std::move(transformPayload)); |
| } |
| |
| void setLayerVisibleRegion(int64_t display, int64_t layer, const std::vector<Rect>& visible) { |
| getLayerCommand(display, layer).visibleRegion.emplace(visible.begin(), visible.end()); |
| } |
| |
| void setLayerZOrder(int64_t display, int64_t layer, uint32_t z) { |
| ZOrder zorder; |
| zorder.z = z; |
| getLayerCommand(display, layer).z.emplace(std::move(zorder)); |
| } |
| |
| void setLayerPerFrameMetadata(int64_t display, int64_t layer, |
| const std::vector<PerFrameMetadata>& metadataVec) { |
| getLayerCommand(display, layer) |
| .perFrameMetadata.emplace(metadataVec.begin(), metadataVec.end()); |
| } |
| |
| void setLayerColorTransform(int64_t display, int64_t layer, const float* matrix) { |
| getLayerCommand(display, layer).colorTransform.emplace(matrix, matrix + 16); |
| } |
| |
| void setLayerPerFrameMetadataBlobs(int64_t display, int64_t layer, |
| const std::vector<PerFrameMetadataBlob>& metadata) { |
| getLayerCommand(display, layer) |
| .perFrameMetadataBlob.emplace(metadata.begin(), metadata.end()); |
| } |
| |
| void setLayerFloatColor(int64_t display, int64_t layer, FloatColor color) { |
| getLayerCommand(display, layer).floatColor.emplace(color); |
| } |
| |
| void setLayerGenericMetadata(int64_t display, int64_t layer, const std::string& key, |
| const bool mandatory, const std::vector<uint8_t>& value) { |
| GenericMetadata metadata; |
| metadata.key.name = key; |
| metadata.key.mandatory = mandatory; |
| metadata.value.assign(value.begin(), value.end()); |
| getLayerCommand(display, layer).genericMetadata.emplace(std::move(metadata)); |
| } |
| |
| void setLayerWhitePointNits(int64_t display, int64_t layer, float whitePointNits) { |
| getLayerCommand(display, layer) |
| .whitePointNits.emplace(WhitePointNits{.nits = whitePointNits}); |
| } |
| |
| const std::vector<DisplayCommand>& getPendingCommands() { |
| flushLayerCommand(); |
| flushDisplayCommand(); |
| return mCommands; |
| } |
| |
| std::vector<CommandResultPayload> getPendingCommandResults() { |
| return std::move(mCommandsResults); |
| } |
| |
| protected: |
| Buffer getBuffer(int slot, const native_handle_t* bufferHandle, int fence) { |
| Buffer bufferCommand; |
| bufferCommand.slot = slot; |
| if (bufferHandle) bufferCommand.handle.emplace(::android::dupToAidl(bufferHandle)); |
| if (fence > 0) bufferCommand.fence = ::ndk::ScopedFileDescriptor(fence); |
| return bufferCommand; |
| } |
| |
| std::optional<DisplayCommand> mDisplayCommand; |
| std::optional<LayerCommand> mLayerCommand; |
| std::vector<DisplayCommand> mCommands; |
| std::vector<CommandResultPayload> mCommandsResults; |
| |
| private: |
| void flushLayerCommand() { |
| if (mLayerCommand.has_value()) { |
| mDisplayCommand->layers.emplace_back(std::move(*mLayerCommand)); |
| mLayerCommand.reset(); |
| } |
| } |
| |
| void flushDisplayCommand() { |
| if (mDisplayCommand.has_value()) { |
| mCommands.emplace_back(std::move(*mDisplayCommand)); |
| mDisplayCommand.reset(); |
| } |
| } |
| |
| DisplayCommand& getDisplayCommand(int64_t display) { |
| if (!mDisplayCommand.has_value() || mDisplayCommand->display != display) { |
| flushLayerCommand(); |
| flushDisplayCommand(); |
| mDisplayCommand.emplace(); |
| mDisplayCommand->display = display; |
| } |
| return *mDisplayCommand; |
| } |
| |
| LayerCommand& getLayerCommand(int64_t display, int64_t layer) { |
| getDisplayCommand(display); |
| if (!mLayerCommand.has_value() || mLayerCommand->layer != layer) { |
| flushLayerCommand(); |
| mLayerCommand.emplace(); |
| mLayerCommand->layer = layer; |
| } |
| return *mLayerCommand; |
| } |
| }; |
| |
| class CommandReaderBase { |
| public: |
| ~CommandReaderBase() { resetData(); } |
| |
| // Parse and execute commands from the command queue. The commands are |
| // actually return values from the server and will be saved in ReturnData. |
| void parse(const std::vector<CommandResultPayload>& results) { |
| resetData(); |
| |
| for (const auto& result : results) { |
| switch (result.getTag()) { |
| case CommandResultPayload::Tag::error: |
| parseSetError(result.get<CommandResultPayload::Tag::error>()); |
| break; |
| case CommandResultPayload::Tag::changedCompositionTypes: |
| parseSetChangedCompositionTypes( |
| result.get<CommandResultPayload::Tag::changedCompositionTypes>()); |
| break; |
| case CommandResultPayload::Tag::displayRequest: |
| parseSetDisplayRequests( |
| result.get<CommandResultPayload::Tag::displayRequest>()); |
| break; |
| case CommandResultPayload::Tag::presentFence: |
| parseSetPresentFence(result.get<CommandResultPayload::Tag::presentFence>()); |
| break; |
| case CommandResultPayload::Tag::releaseFences: |
| parseSetReleaseFences(result.get<CommandResultPayload::Tag::releaseFences>()); |
| break; |
| case CommandResultPayload::Tag::presentOrValidateResult: |
| parseSetPresentOrValidateDisplayResult( |
| result.get<CommandResultPayload::Tag::presentOrValidateResult>()); |
| break; |
| case CommandResultPayload::Tag::clientTargetProperty: |
| parseSetClientTargetProperty( |
| result.get<CommandResultPayload::Tag::clientTargetProperty>()); |
| break; |
| } |
| } |
| } |
| |
| std::vector<CommandError> takeErrors() { return std::move(mErrors); } |
| |
| bool hasChanges(int64_t display, uint32_t* outNumChangedCompositionTypes, |
| uint32_t* outNumLayerRequestMasks) const { |
| auto found = mReturnData.find(display); |
| if (found == mReturnData.end()) { |
| *outNumChangedCompositionTypes = 0; |
| *outNumLayerRequestMasks = 0; |
| return false; |
| } |
| |
| const ReturnData& data = found->second; |
| |
| *outNumChangedCompositionTypes = static_cast<uint32_t>(data.compositionTypes.size()); |
| *outNumLayerRequestMasks = static_cast<uint32_t>(data.requestMasks.size()); |
| |
| return !(data.compositionTypes.empty() && data.requestMasks.empty()); |
| } |
| |
| // Get and clear saved changed composition types. |
| void takeChangedCompositionTypes(int64_t display, std::vector<int64_t>* outLayers, |
| std::vector<Composition>* outTypes) { |
| auto found = mReturnData.find(display); |
| if (found == mReturnData.end()) { |
| outLayers->clear(); |
| outTypes->clear(); |
| return; |
| } |
| |
| ReturnData& data = found->second; |
| |
| *outLayers = std::move(data.changedLayers); |
| *outTypes = std::move(data.compositionTypes); |
| } |
| |
| // Get and clear saved display requests. |
| void takeDisplayRequests(int64_t display, uint32_t* outDisplayRequestMask, |
| std::vector<int64_t>* outLayers, |
| std::vector<uint32_t>* outLayerRequestMasks) { |
| auto found = mReturnData.find(display); |
| if (found == mReturnData.end()) { |
| *outDisplayRequestMask = 0; |
| outLayers->clear(); |
| outLayerRequestMasks->clear(); |
| return; |
| } |
| |
| ReturnData& data = found->second; |
| |
| *outDisplayRequestMask = data.displayRequests; |
| *outLayers = std::move(data.requestedLayers); |
| *outLayerRequestMasks = std::move(data.requestMasks); |
| } |
| |
| // Get and clear saved release fences. |
| void takeReleaseFences(int64_t display, std::vector<int64_t>* outLayers, |
| std::vector<int>* outReleaseFences) { |
| auto found = mReturnData.find(display); |
| if (found == mReturnData.end()) { |
| outLayers->clear(); |
| outReleaseFences->clear(); |
| return; |
| } |
| |
| ReturnData& data = found->second; |
| |
| *outLayers = std::move(data.releasedLayers); |
| *outReleaseFences = std::move(data.releaseFences); |
| } |
| |
| // Get and clear saved present fence. |
| void takePresentFence(int64_t display, int* outPresentFence) { |
| auto found = mReturnData.find(display); |
| if (found == mReturnData.end()) { |
| *outPresentFence = -1; |
| return; |
| } |
| |
| ReturnData& data = found->second; |
| |
| *outPresentFence = data.presentFence; |
| data.presentFence = -1; |
| } |
| |
| // Get what stage succeeded during PresentOrValidate: Present or Validate |
| void takePresentOrValidateStage(int64_t display, uint32_t* state) { |
| auto found = mReturnData.find(display); |
| if (found == mReturnData.end()) { |
| *state = static_cast<uint32_t>(-1); |
| return; |
| } |
| ReturnData& data = found->second; |
| *state = data.presentOrValidateState; |
| } |
| |
| // Get the client target properties requested by hardware composer. |
| void takeClientTargetProperty(int64_t display, ClientTargetProperty* outClientTargetProperty, |
| float* outWhitePointNits) { |
| auto found = mReturnData.find(display); |
| |
| // If not found, return the default values. |
| if (found == mReturnData.end()) { |
| outClientTargetProperty->pixelFormat = common::PixelFormat::RGBA_8888; |
| outClientTargetProperty->dataspace = Dataspace::UNKNOWN; |
| *outWhitePointNits = -1.f; |
| return; |
| } |
| |
| ReturnData& data = found->second; |
| *outClientTargetProperty = data.clientTargetProperty; |
| *outWhitePointNits = data.clientTargetWhitePointNits; |
| } |
| |
| private: |
| void resetData() { |
| mErrors.clear(); |
| |
| for (auto& data : mReturnData) { |
| if (data.second.presentFence >= 0) { |
| close(data.second.presentFence); |
| } |
| for (auto fence : data.second.releaseFences) { |
| if (fence >= 0) { |
| close(fence); |
| } |
| } |
| } |
| |
| mReturnData.clear(); |
| } |
| |
| void parseSetError(const CommandError& error) { mErrors.emplace_back(error); } |
| |
| void parseSetChangedCompositionTypes(const ChangedCompositionTypes& changedCompositionTypes) { |
| auto& data = mReturnData[changedCompositionTypes.display]; |
| |
| data.changedLayers.reserve(changedCompositionTypes.layers.size()); |
| data.compositionTypes.reserve(changedCompositionTypes.layers.size()); |
| for (const auto& layer : changedCompositionTypes.layers) { |
| data.changedLayers.push_back(layer.layer); |
| data.compositionTypes.push_back(layer.composition); |
| } |
| } |
| |
| void parseSetDisplayRequests(const DisplayRequest& displayRequest) { |
| auto& data = mReturnData[displayRequest.display]; |
| |
| data.displayRequests = displayRequest.mask; |
| data.requestedLayers.reserve(displayRequest.layerRequests.size()); |
| data.requestMasks.reserve(displayRequest.layerRequests.size()); |
| for (const auto& layerRequest : displayRequest.layerRequests) { |
| data.requestedLayers.push_back(layerRequest.layer); |
| data.requestMasks.push_back(layerRequest.mask); |
| } |
| } |
| |
| void parseSetPresentFence(const PresentFence& presentFence) { |
| auto& data = mReturnData[presentFence.display]; |
| if (data.presentFence >= 0) { |
| close(data.presentFence); |
| } |
| data.presentFence = dup(presentFence.fence.get()); |
| } |
| |
| void parseSetReleaseFences(const ReleaseFences& releaseFences) { |
| auto& data = mReturnData[releaseFences.display]; |
| data.releasedLayers.reserve(releaseFences.layers.size()); |
| data.releaseFences.reserve(releaseFences.layers.size()); |
| for (const auto& layer : releaseFences.layers) { |
| data.releasedLayers.push_back(layer.layer); |
| data.releaseFences.push_back(dup(layer.fence.get())); |
| } |
| } |
| |
| void parseSetPresentOrValidateDisplayResult(const PresentOrValidate& presentOrValidate) { |
| auto& data = mReturnData[presentOrValidate.display]; |
| data.presentOrValidateState = |
| presentOrValidate.result == PresentOrValidate::Result::Presented ? 1 : 0; |
| } |
| |
| void parseSetClientTargetProperty(const ClientTargetPropertyWithNits& clientTargetProperty) { |
| auto& data = mReturnData[clientTargetProperty.display]; |
| data.clientTargetProperty.pixelFormat = |
| clientTargetProperty.clientTargetProperty.pixelFormat; |
| data.clientTargetProperty.dataspace = clientTargetProperty.clientTargetProperty.dataspace; |
| data.clientTargetWhitePointNits = clientTargetProperty.whitePointNits; |
| } |
| |
| struct ReturnData { |
| int32_t displayRequests = 0; |
| |
| std::vector<int64_t> changedLayers; |
| std::vector<Composition> compositionTypes; |
| |
| std::vector<int64_t> requestedLayers; |
| std::vector<uint32_t> requestMasks; |
| |
| int presentFence = -1; |
| |
| std::vector<int64_t> releasedLayers; |
| std::vector<int> releaseFences; |
| |
| uint32_t presentOrValidateState; |
| |
| ClientTargetProperty clientTargetProperty{common::PixelFormat::RGBA_8888, |
| Dataspace::UNKNOWN}; |
| float clientTargetWhitePointNits = -1.f; |
| }; |
| |
| std::vector<CommandError> mErrors; |
| std::unordered_map<int64_t, ReturnData> mReturnData; |
| }; |
| |
| } // namespace aidl::android::hardware::graphics::composer3 |