/* * 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. */ #undef LOG_TAG #define LOG_TAG "HwcComposer" #define ATRACE_TAG ATRACE_TAG_GRAPHICS #include "AidlComposerHal.h" #include #include #include #include #include #include #include #include #include "HWC2.h" namespace android { using hardware::hidl_handle; using hardware::hidl_vec; using hardware::Return; using aidl::android::hardware::graphics::composer3::BnComposerCallback; using aidl::android::hardware::graphics::composer3::Capability; using aidl::android::hardware::graphics::composer3::ClientTargetPropertyWithBrightness; using aidl::android::hardware::graphics::composer3::PowerMode; using aidl::android::hardware::graphics::composer3::VirtualDisplay; using aidl::android::hardware::graphics::composer3::CommandResultPayload; using AidlColorMode = aidl::android::hardware::graphics::composer3::ColorMode; using AidlContentType = aidl::android::hardware::graphics::composer3::ContentType; using AidlDisplayIdentification = aidl::android::hardware::graphics::composer3::DisplayIdentification; using AidlDisplayContentSample = aidl::android::hardware::graphics::composer3::DisplayContentSample; using AidlDisplayAttribute = aidl::android::hardware::graphics::composer3::DisplayAttribute; using AidlDisplayCapability = aidl::android::hardware::graphics::composer3::DisplayCapability; using AidlHdrCapabilities = aidl::android::hardware::graphics::composer3::HdrCapabilities; using AidlPerFrameMetadata = aidl::android::hardware::graphics::composer3::PerFrameMetadata; using AidlPerFrameMetadataKey = aidl::android::hardware::graphics::composer3::PerFrameMetadataKey; using AidlPerFrameMetadataBlob = aidl::android::hardware::graphics::composer3::PerFrameMetadataBlob; using AidlRenderIntent = aidl::android::hardware::graphics::composer3::RenderIntent; using AidlVsyncPeriodChangeConstraints = aidl::android::hardware::graphics::composer3::VsyncPeriodChangeConstraints; using AidlVsyncPeriodChangeTimeline = aidl::android::hardware::graphics::composer3::VsyncPeriodChangeTimeline; using AidlDisplayContentSamplingAttributes = aidl::android::hardware::graphics::composer3::DisplayContentSamplingAttributes; using AidlFormatColorComponent = aidl::android::hardware::graphics::composer3::FormatColorComponent; using AidlDisplayConnectionType = aidl::android::hardware::graphics::composer3::DisplayConnectionType; using AidlColorTransform = aidl::android::hardware::graphics::common::ColorTransform; using AidlDataspace = aidl::android::hardware::graphics::common::Dataspace; using AidlFRect = aidl::android::hardware::graphics::common::FRect; using AidlRect = aidl::android::hardware::graphics::common::Rect; using AidlTransform = aidl::android::hardware::graphics::common::Transform; namespace Hwc2 { namespace { template To translate(From x) { return static_cast(x); } template std::vector translate(const std::vector& in) { std::vector out; out.reserve(in.size()); std::transform(in.begin(), in.end(), std::back_inserter(out), [](From x) { return translate(x); }); return out; } template <> AidlRect translate(IComposerClient::Rect x) { return AidlRect{ .left = x.left, .top = x.top, .right = x.right, .bottom = x.bottom, }; } template <> AidlFRect translate(IComposerClient::FRect x) { return AidlFRect{ .left = x.left, .top = x.top, .right = x.right, .bottom = x.bottom, }; } template <> AidlPerFrameMetadataBlob translate(IComposerClient::PerFrameMetadataBlob x) { AidlPerFrameMetadataBlob blob; blob.key = translate(x.key), std::copy(x.blob.begin(), x.blob.end(), std::inserter(blob.blob, blob.blob.end())); return blob; } template <> AidlPerFrameMetadata translate(IComposerClient::PerFrameMetadata x) { return AidlPerFrameMetadata{ .key = translate(x.key), .value = x.value, }; } template <> DisplayedFrameStats translate(AidlDisplayContentSample x) { return DisplayedFrameStats{ .numFrames = static_cast(x.frameCount), .component_0_sample = translate(x.sampleComponent0), .component_1_sample = translate(x.sampleComponent1), .component_2_sample = translate(x.sampleComponent2), .component_3_sample = translate(x.sampleComponent3), }; } template <> AidlVsyncPeriodChangeConstraints translate(IComposerClient::VsyncPeriodChangeConstraints x) { return AidlVsyncPeriodChangeConstraints{ .desiredTimeNanos = x.desiredTimeNanos, .seamlessRequired = x.seamlessRequired, }; } template <> VsyncPeriodChangeTimeline translate(AidlVsyncPeriodChangeTimeline x) { return VsyncPeriodChangeTimeline{ .newVsyncAppliedTimeNanos = x.newVsyncAppliedTimeNanos, .refreshRequired = x.refreshRequired, .refreshTimeNanos = x.refreshTimeNanos, }; } mat4 makeMat4(std::vector in) { return mat4(static_cast(in.data())); } } // namespace class AidlIComposerCallbackWrapper : public BnComposerCallback { public: AidlIComposerCallbackWrapper(HWC2::ComposerCallback& callback) : mCallback(callback) {} ::ndk::ScopedAStatus onHotplug(int64_t in_display, bool in_connected) override { const auto connection = in_connected ? V2_4::IComposerCallback::Connection::CONNECTED : V2_4::IComposerCallback::Connection::DISCONNECTED; mCallback.onComposerHalHotplug(translate(in_display), connection); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus onRefresh(int64_t in_display) override { mCallback.onComposerHalRefresh(translate(in_display)); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus onSeamlessPossible(int64_t in_display) override { mCallback.onComposerHalSeamlessPossible(translate(in_display)); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus onVsync(int64_t in_display, int64_t in_timestamp, int32_t in_vsyncPeriodNanos) override { mCallback.onComposerHalVsync(translate(in_display), in_timestamp, static_cast(in_vsyncPeriodNanos)); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus onVsyncPeriodTimingChanged( int64_t in_display, const AidlVsyncPeriodChangeTimeline& in_updatedTimeline) override { mCallback.onComposerHalVsyncPeriodTimingChanged(translate(in_display), translate( in_updatedTimeline)); return ::ndk::ScopedAStatus::ok(); } ::ndk::ScopedAStatus onVsyncIdle(int64_t in_display) override { mCallback.onComposerHalVsyncIdle(translate(in_display)); return ::ndk::ScopedAStatus::ok(); } private: HWC2::ComposerCallback& mCallback; }; std::string AidlComposer::instance(const std::string& serviceName) { return std::string(AidlIComposer::descriptor) + "/" + serviceName; } bool AidlComposer::isDeclared(const std::string& serviceName) { return AServiceManager_isDeclared(instance(serviceName).c_str()); } AidlComposer::AidlComposer(const std::string& serviceName) { // This only waits if the service is actually declared mAidlComposer = AidlIComposer::fromBinder( ndk::SpAIBinder(AServiceManager_waitForService(instance(serviceName).c_str()))); if (!mAidlComposer) { LOG_ALWAYS_FATAL("Failed to get AIDL composer service"); return; } if (!mAidlComposer->createClient(&mAidlComposerClient).isOk()) { LOG_ALWAYS_FATAL("Can't create AidlComposerClient, fallback to HIDL"); return; } ALOGI("Loaded AIDL composer3 HAL service"); } AidlComposer::~AidlComposer() = default; bool AidlComposer::isSupported(OptionalFeature feature) const { switch (feature) { case OptionalFeature::RefreshRateSwitching: case OptionalFeature::ExpectedPresentTime: case OptionalFeature::DisplayBrightnessCommand: case OptionalFeature::KernelIdleTimer: case OptionalFeature::PhysicalDisplayOrientation: return true; } } std::vector AidlComposer::getCapabilities() { std::vector capabilities; const auto status = mAidlComposer->getCapabilities(&capabilities); if (!status.isOk()) { ALOGE("getCapabilities failed %s", status.getDescription().c_str()); return {}; } return capabilities; } std::string AidlComposer::dumpDebugInfo() { int pipefds[2]; int result = pipe(pipefds); if (result < 0) { ALOGE("dumpDebugInfo: pipe failed: %s", strerror(errno)); return {}; } std::string str; const auto status = mAidlComposer->dump(pipefds[1], /*args*/ nullptr, /*numArgs*/ 0); // Close the write-end of the pipe to make sure that when reading from the // read-end we will get eof instead of blocking forever close(pipefds[1]); if (status == STATUS_OK) { base::ReadFdToString(pipefds[0], &str); } else { ALOGE("dumpDebugInfo: dump failed: %d", status); } close(pipefds[0]); return str; } void AidlComposer::registerCallback(HWC2::ComposerCallback& callback) { if (mAidlComposerCallback) { ALOGE("Callback already registered"); } mAidlComposerCallback = ndk::SharedRefBase::make(callback); AIBinder_setMinSchedulerPolicy(mAidlComposerCallback->asBinder().get(), SCHED_FIFO, 2); const auto status = mAidlComposerClient->registerCallback(mAidlComposerCallback); if (!status.isOk()) { ALOGE("registerCallback failed %s", status.getDescription().c_str()); } } void AidlComposer::resetCommands() { mWriter.reset(); } Error AidlComposer::executeCommands() { return execute(); } uint32_t AidlComposer::getMaxVirtualDisplayCount() { int32_t count = 0; const auto status = mAidlComposerClient->getMaxVirtualDisplayCount(&count); if (!status.isOk()) { ALOGE("getMaxVirtualDisplayCount failed %s", status.getDescription().c_str()); return 0; } return static_cast(count); } Error AidlComposer::createVirtualDisplay(uint32_t width, uint32_t height, PixelFormat* format, Display* outDisplay) { using AidlPixelFormat = aidl::android::hardware::graphics::common::PixelFormat; const int32_t bufferSlotCount = 1; VirtualDisplay virtualDisplay; const auto status = mAidlComposerClient->createVirtualDisplay(static_cast(width), static_cast(height), static_cast(*format), bufferSlotCount, &virtualDisplay); if (!status.isOk()) { ALOGE("createVirtualDisplay failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outDisplay = translate(virtualDisplay.display); *format = static_cast(virtualDisplay.format); return Error::NONE; } Error AidlComposer::destroyVirtualDisplay(Display display) { const auto status = mAidlComposerClient->destroyVirtualDisplay(translate(display)); if (!status.isOk()) { ALOGE("destroyVirtualDisplay failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::acceptDisplayChanges(Display display) { mWriter.acceptDisplayChanges(translate(display)); return Error::NONE; } Error AidlComposer::createLayer(Display display, Layer* outLayer) { int64_t layer; const auto status = mAidlComposerClient->createLayer(translate(display), kMaxLayerBufferCount, &layer); if (!status.isOk()) { ALOGE("createLayer failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outLayer = translate(layer); return Error::NONE; } Error AidlComposer::destroyLayer(Display display, Layer layer) { const auto status = mAidlComposerClient->destroyLayer(translate(display), translate(layer)); if (!status.isOk()) { ALOGE("destroyLayer failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::getActiveConfig(Display display, Config* outConfig) { int32_t config; const auto status = mAidlComposerClient->getActiveConfig(translate(display), &config); if (!status.isOk()) { ALOGE("getActiveConfig failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outConfig = translate(config); return Error::NONE; } Error AidlComposer::getChangedCompositionTypes( Display display, std::vector* outLayers, std::vector* outTypes) { const auto changedLayers = mReader.takeChangedCompositionTypes(translate(display)); outLayers->reserve(changedLayers.size()); outTypes->reserve(changedLayers.size()); for (const auto& layer : changedLayers) { outLayers->emplace_back(translate(layer.layer)); outTypes->emplace_back(layer.composition); } return Error::NONE; } Error AidlComposer::getColorModes(Display display, std::vector* outModes) { std::vector modes; const auto status = mAidlComposerClient->getColorModes(translate(display), &modes); if (!status.isOk()) { ALOGE("getColorModes failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outModes = translate(modes); return Error::NONE; } Error AidlComposer::getDisplayAttribute(Display display, Config config, IComposerClient::Attribute attribute, int32_t* outValue) { const auto status = mAidlComposerClient->getDisplayAttribute(translate(display), translate(config), static_cast(attribute), outValue); if (!status.isOk()) { ALOGE("getDisplayAttribute failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::getDisplayConfigs(Display display, std::vector* outConfigs) { std::vector configs; const auto status = mAidlComposerClient->getDisplayConfigs(translate(display), &configs); if (!status.isOk()) { ALOGE("getDisplayConfigs failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outConfigs = translate(configs); return Error::NONE; } Error AidlComposer::getDisplayName(Display display, std::string* outName) { const auto status = mAidlComposerClient->getDisplayName(translate(display), outName); if (!status.isOk()) { ALOGE("getDisplayName failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::getDisplayRequests(Display display, uint32_t* outDisplayRequestMask, std::vector* outLayers, std::vector* outLayerRequestMasks) { const auto displayRequests = mReader.takeDisplayRequests(translate(display)); *outDisplayRequestMask = translate(displayRequests.mask); outLayers->reserve(displayRequests.layerRequests.size()); outLayerRequestMasks->reserve(displayRequests.layerRequests.size()); for (const auto& layer : displayRequests.layerRequests) { outLayers->emplace_back(translate(layer.layer)); outLayerRequestMasks->emplace_back(translate(layer.mask)); } return Error::NONE; } Error AidlComposer::getDozeSupport(Display display, bool* outSupport) { std::vector capabilities; const auto status = mAidlComposerClient->getDisplayCapabilities(translate(display), &capabilities); if (!status.isOk()) { ALOGE("getDisplayCapabilities failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outSupport = std::find(capabilities.begin(), capabilities.end(), AidlDisplayCapability::DOZE) != capabilities.end(); return Error::NONE; } Error AidlComposer::hasDisplayIdleTimerCapability(Display display, bool* outSupport) { std::vector capabilities; const auto status = mAidlComposerClient->getDisplayCapabilities(translate(display), &capabilities); if (!status.isOk()) { ALOGE("getDisplayCapabilities failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outSupport = std::find(capabilities.begin(), capabilities.end(), AidlDisplayCapability::DISPLAY_IDLE_TIMER) != capabilities.end(); return Error::NONE; } Error AidlComposer::getHdrCapabilities(Display display, std::vector* outTypes, float* outMaxLuminance, float* outMaxAverageLuminance, float* outMinLuminance) { AidlHdrCapabilities capabilities; const auto status = mAidlComposerClient->getHdrCapabilities(translate(display), &capabilities); if (!status.isOk()) { ALOGE("getHdrCapabilities failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outTypes = translate(capabilities.types); *outMaxLuminance = capabilities.maxLuminance; *outMaxAverageLuminance = capabilities.maxAverageLuminance; *outMinLuminance = capabilities.minLuminance; return Error::NONE; } Error AidlComposer::getReleaseFences(Display display, std::vector* outLayers, std::vector* outReleaseFences) { auto fences = mReader.takeReleaseFences(translate(display)); outLayers->reserve(fences.size()); outReleaseFences->reserve(fences.size()); for (auto& fence : fences) { outLayers->emplace_back(translate(fence.layer)); // take ownership const int fenceOwner = fence.fence.get(); *fence.fence.getR() = -1; outReleaseFences->emplace_back(fenceOwner); } return Error::NONE; } Error AidlComposer::presentDisplay(Display display, int* outPresentFence) { ATRACE_NAME("HwcPresentDisplay"); mWriter.presentDisplay(translate(display)); Error error = execute(); if (error != Error::NONE) { return error; } auto fence = mReader.takePresentFence(translate(display)); // take ownership *outPresentFence = fence.get(); *fence.getR() = -1; return Error::NONE; } Error AidlComposer::setActiveConfig(Display display, Config config) { const auto status = mAidlComposerClient->setActiveConfig(translate(display), translate(config)); if (!status.isOk()) { ALOGE("setActiveConfig failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::setClientTarget(Display display, uint32_t slot, const sp& target, int acquireFence, Dataspace dataspace, const std::vector& damage) { const native_handle_t* handle = nullptr; if (target.get()) { handle = target->getNativeBuffer()->handle; } mWriter.setClientTarget(translate(display), slot, handle, acquireFence, translate( dataspace), translate(damage)); return Error::NONE; } Error AidlComposer::setColorMode(Display display, ColorMode mode, RenderIntent renderIntent) { const auto status = mAidlComposerClient->setColorMode(translate(display), translate(mode), translate(renderIntent)); if (!status.isOk()) { ALOGE("setColorMode failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::setColorTransform(Display display, const float* matrix) { mWriter.setColorTransform(translate(display), matrix); return Error::NONE; } Error AidlComposer::setOutputBuffer(Display display, const native_handle_t* buffer, int releaseFence) { mWriter.setOutputBuffer(translate(display), 0, buffer, dup(releaseFence)); return Error::NONE; } Error AidlComposer::setPowerMode(Display display, IComposerClient::PowerMode mode) { const auto status = mAidlComposerClient->setPowerMode(translate(display), translate(mode)); if (!status.isOk()) { ALOGE("setPowerMode failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) { const bool enableVsync = enabled == IComposerClient::Vsync::ENABLE; const auto status = mAidlComposerClient->setVsyncEnabled(translate(display), enableVsync); if (!status.isOk()) { ALOGE("setVsyncEnabled failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::setClientTargetSlotCount(Display display) { const int32_t bufferSlotCount = BufferQueue::NUM_BUFFER_SLOTS; const auto status = mAidlComposerClient->setClientTargetSlotCount(translate(display), bufferSlotCount); if (!status.isOk()) { ALOGE("setClientTargetSlotCount failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::validateDisplay(Display display, nsecs_t expectedPresentTime, uint32_t* outNumTypes, uint32_t* outNumRequests) { ATRACE_NAME("HwcValidateDisplay"); mWriter.validateDisplay(translate(display), ClockMonotonicTimestamp{expectedPresentTime}); Error error = execute(); if (error != Error::NONE) { return error; } mReader.hasChanges(translate(display), outNumTypes, outNumRequests); return Error::NONE; } Error AidlComposer::presentOrValidateDisplay(Display display, nsecs_t expectedPresentTime, uint32_t* outNumTypes, uint32_t* outNumRequests, int* outPresentFence, uint32_t* state) { ATRACE_NAME("HwcPresentOrValidateDisplay"); mWriter.presentOrvalidateDisplay(translate(display), ClockMonotonicTimestamp{expectedPresentTime}); Error error = execute(); if (error != Error::NONE) { return error; } const auto result = mReader.takePresentOrValidateStage(translate(display)); if (!result.has_value()) { *state = translate(-1); return Error::NO_RESOURCES; } *state = translate(*result); if (*result == PresentOrValidate::Result::Presented) { auto fence = mReader.takePresentFence(translate(display)); // take ownership *outPresentFence = fence.get(); *fence.getR() = -1; } if (*result == PresentOrValidate::Result::Validated) { mReader.hasChanges(translate(display), outNumTypes, outNumRequests); } return Error::NONE; } Error AidlComposer::setCursorPosition(Display display, Layer layer, int32_t x, int32_t y) { mWriter.setLayerCursorPosition(translate(display), translate(layer), x, y); return Error::NONE; } Error AidlComposer::setLayerBuffer(Display display, Layer layer, uint32_t slot, const sp& buffer, int acquireFence) { const native_handle_t* handle = nullptr; if (buffer.get()) { handle = buffer->getNativeBuffer()->handle; } mWriter.setLayerBuffer(translate(display), translate(layer), slot, handle, acquireFence); return Error::NONE; } Error AidlComposer::setLayerSurfaceDamage(Display display, Layer layer, const std::vector& damage) { mWriter.setLayerSurfaceDamage(translate(display), translate(layer), translate(damage)); return Error::NONE; } Error AidlComposer::setLayerBlendMode(Display display, Layer layer, IComposerClient::BlendMode mode) { mWriter.setLayerBlendMode(translate(display), translate(layer), translate(mode)); return Error::NONE; } Error AidlComposer::setLayerColor(Display display, Layer layer, const Color& color) { mWriter.setLayerColor(translate(display), translate(layer), color); return Error::NONE; } Error AidlComposer::setLayerCompositionType( Display display, Layer layer, aidl::android::hardware::graphics::composer3::Composition type) { mWriter.setLayerCompositionType(translate(display), translate(layer), type); return Error::NONE; } Error AidlComposer::setLayerDataspace(Display display, Layer layer, Dataspace dataspace) { mWriter.setLayerDataspace(translate(display), translate(layer), translate(dataspace)); return Error::NONE; } Error AidlComposer::setLayerDisplayFrame(Display display, Layer layer, const IComposerClient::Rect& frame) { mWriter.setLayerDisplayFrame(translate(display), translate(layer), translate(frame)); return Error::NONE; } Error AidlComposer::setLayerPlaneAlpha(Display display, Layer layer, float alpha) { mWriter.setLayerPlaneAlpha(translate(display), translate(layer), alpha); return Error::NONE; } Error AidlComposer::setLayerSidebandStream(Display display, Layer layer, const native_handle_t* stream) { mWriter.setLayerSidebandStream(translate(display), translate(layer), stream); return Error::NONE; } Error AidlComposer::setLayerSourceCrop(Display display, Layer layer, const IComposerClient::FRect& crop) { mWriter.setLayerSourceCrop(translate(display), translate(layer), translate(crop)); return Error::NONE; } Error AidlComposer::setLayerTransform(Display display, Layer layer, Transform transform) { mWriter.setLayerTransform(translate(display), translate(layer), translate(transform)); return Error::NONE; } Error AidlComposer::setLayerVisibleRegion(Display display, Layer layer, const std::vector& visible) { mWriter.setLayerVisibleRegion(translate(display), translate(layer), translate(visible)); return Error::NONE; } Error AidlComposer::setLayerZOrder(Display display, Layer layer, uint32_t z) { mWriter.setLayerZOrder(translate(display), translate(layer), z); return Error::NONE; } Error AidlComposer::execute() { const auto& commands = mWriter.getPendingCommands(); if (commands.empty()) { mWriter.reset(); return Error::NONE; } { // scope for results std::vector results; auto status = mAidlComposerClient->executeCommands(commands, &results); if (!status.isOk()) { ALOGE("executeCommands failed %s", status.getDescription().c_str()); mWriter.reset(); return static_cast(status.getServiceSpecificError()); } mReader.parse(std::move(results)); } const auto commandErrors = mReader.takeErrors(); Error error = Error::NONE; for (const auto& cmdErr : commandErrors) { const auto index = static_cast(cmdErr.commandIndex); if (index < 0 || index >= commands.size()) { ALOGE("invalid command index %zu", index); mWriter.reset(); return Error::BAD_PARAMETER; } const auto& command = commands[index]; if (command.validateDisplay || command.presentDisplay || command.presentOrValidateDisplay) { error = translate(cmdErr.errorCode); } else { ALOGW("command '%s' generated error %" PRId32, command.toString().c_str(), cmdErr.errorCode); } } mWriter.reset(); return error; } Error AidlComposer::setLayerPerFrameMetadata( Display display, Layer layer, const std::vector& perFrameMetadatas) { mWriter.setLayerPerFrameMetadata(translate(display), translate(layer), translate(perFrameMetadatas)); return Error::NONE; } std::vector AidlComposer::getPerFrameMetadataKeys( Display display) { std::vector keys; const auto status = mAidlComposerClient->getPerFrameMetadataKeys(translate(display), &keys); if (!status.isOk()) { ALOGE("getPerFrameMetadataKeys failed %s", status.getDescription().c_str()); return {}; } return translate(keys); } Error AidlComposer::getRenderIntents(Display display, ColorMode colorMode, std::vector* outRenderIntents) { std::vector renderIntents; const auto status = mAidlComposerClient->getRenderIntents(translate(display), translate(colorMode), &renderIntents); if (!status.isOk()) { ALOGE("getRenderIntents failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outRenderIntents = translate(renderIntents); return Error::NONE; } Error AidlComposer::getDataspaceSaturationMatrix(Dataspace dataspace, mat4* outMatrix) { std::vector matrix; const auto status = mAidlComposerClient->getDataspaceSaturationMatrix(translate(dataspace), &matrix); if (!status.isOk()) { ALOGE("getDataspaceSaturationMatrix failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outMatrix = makeMat4(matrix); return Error::NONE; } Error AidlComposer::getDisplayIdentificationData(Display display, uint8_t* outPort, std::vector* outData) { AidlDisplayIdentification displayIdentification; const auto status = mAidlComposerClient->getDisplayIdentificationData(translate(display), &displayIdentification); if (!status.isOk()) { ALOGE("getDisplayIdentificationData failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outPort = static_cast(displayIdentification.port); *outData = displayIdentification.data; return Error::NONE; } Error AidlComposer::setLayerColorTransform(Display display, Layer layer, const float* matrix) { mWriter.setLayerColorTransform(translate(display), translate(layer), matrix); return Error::NONE; } Error AidlComposer::getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat, Dataspace* outDataspace, uint8_t* outComponentMask) { if (!outFormat || !outDataspace || !outComponentMask) { return Error::BAD_PARAMETER; } AidlDisplayContentSamplingAttributes attributes; const auto status = mAidlComposerClient->getDisplayedContentSamplingAttributes(translate(display), &attributes); if (!status.isOk()) { ALOGE("getDisplayedContentSamplingAttributes failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outFormat = translate(attributes.format); *outDataspace = translate(attributes.dataspace); *outComponentMask = static_cast(attributes.componentMask); return Error::NONE; } Error AidlComposer::setDisplayContentSamplingEnabled(Display display, bool enabled, uint8_t componentMask, uint64_t maxFrames) { const auto status = mAidlComposerClient ->setDisplayedContentSamplingEnabled(translate(display), enabled, static_cast( componentMask), static_cast(maxFrames)); if (!status.isOk()) { ALOGE("setDisplayedContentSamplingEnabled failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::getDisplayedContentSample(Display display, uint64_t maxFrames, uint64_t timestamp, DisplayedFrameStats* outStats) { if (!outStats) { return Error::BAD_PARAMETER; } AidlDisplayContentSample sample; const auto status = mAidlComposerClient->getDisplayedContentSample(translate(display), static_cast(maxFrames), static_cast(timestamp), &sample); if (!status.isOk()) { ALOGE("getDisplayedContentSample failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outStats = translate(sample); return Error::NONE; } Error AidlComposer::setLayerPerFrameMetadataBlobs( Display display, Layer layer, const std::vector& metadata) { mWriter.setLayerPerFrameMetadataBlobs(translate(display), translate(layer), translate(metadata)); return Error::NONE; } Error AidlComposer::setDisplayBrightness(Display display, float brightness, float brightnessNits, const DisplayBrightnessOptions& options) { mWriter.setDisplayBrightness(translate(display), brightness, brightnessNits); if (options.applyImmediately) { return execute(); } return Error::NONE; } Error AidlComposer::getDisplayCapabilities(Display display, std::vector* outCapabilities) { const auto status = mAidlComposerClient->getDisplayCapabilities(translate(display), outCapabilities); if (!status.isOk()) { ALOGE("getDisplayCapabilities failed %s", status.getDescription().c_str()); outCapabilities->clear(); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } V2_4::Error AidlComposer::getDisplayConnectionType( Display display, IComposerClient::DisplayConnectionType* outType) { AidlDisplayConnectionType type; const auto status = mAidlComposerClient->getDisplayConnectionType(translate(display), &type); if (!status.isOk()) { ALOGE("getDisplayConnectionType failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outType = translate(type); return V2_4::Error::NONE; } V2_4::Error AidlComposer::getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) { int32_t vsyncPeriod; const auto status = mAidlComposerClient->getDisplayVsyncPeriod(translate(display), &vsyncPeriod); if (!status.isOk()) { ALOGE("getDisplayVsyncPeriod failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outVsyncPeriod = translate(vsyncPeriod); return V2_4::Error::NONE; } V2_4::Error AidlComposer::setActiveConfigWithConstraints( Display display, Config config, const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints, VsyncPeriodChangeTimeline* outTimeline) { AidlVsyncPeriodChangeTimeline timeline; const auto status = mAidlComposerClient ->setActiveConfigWithConstraints(translate(display), translate(config), translate( vsyncPeriodChangeConstraints), &timeline); if (!status.isOk()) { ALOGE("setActiveConfigWithConstraints failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outTimeline = translate(timeline); return V2_4::Error::NONE; } V2_4::Error AidlComposer::setAutoLowLatencyMode(Display display, bool on) { const auto status = mAidlComposerClient->setAutoLowLatencyMode(translate(display), on); if (!status.isOk()) { ALOGE("setAutoLowLatencyMode failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return V2_4::Error::NONE; } V2_4::Error AidlComposer::getSupportedContentTypes( Display displayId, std::vector* outSupportedContentTypes) { std::vector types; const auto status = mAidlComposerClient->getSupportedContentTypes(translate(displayId), &types); if (!status.isOk()) { ALOGE("getSupportedContentTypes failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *outSupportedContentTypes = translate(types); return V2_4::Error::NONE; } V2_4::Error AidlComposer::setContentType(Display display, IComposerClient::ContentType contentType) { const auto status = mAidlComposerClient->setContentType(translate(display), translate(contentType)); if (!status.isOk()) { ALOGE("setContentType failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return V2_4::Error::NONE; } V2_4::Error AidlComposer::setLayerGenericMetadata(Display, Layer, const std::string&, bool, const std::vector&) { // There are no users for this API. See b/209691612. return V2_4::Error::UNSUPPORTED; } V2_4::Error AidlComposer::getLayerGenericMetadataKeys( std::vector*) { // There are no users for this API. See b/209691612. return V2_4::Error::UNSUPPORTED; } Error AidlComposer::setBootDisplayConfig(Display display, Config config) { const auto status = mAidlComposerClient->setBootDisplayConfig(translate(display), translate(config)); if (!status.isOk()) { ALOGE("setBootDisplayConfig failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::clearBootDisplayConfig(Display display) { const auto status = mAidlComposerClient->clearBootDisplayConfig(translate(display)); if (!status.isOk()) { ALOGE("clearBootDisplayConfig failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::getPreferredBootDisplayConfig(Display display, Config* config) { int32_t displayConfig; const auto status = mAidlComposerClient->getPreferredBootDisplayConfig(translate(display), &displayConfig); if (!status.isOk()) { ALOGE("getPreferredBootDisplayConfig failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } *config = translate(displayConfig); return Error::NONE; } Error AidlComposer::getClientTargetProperty( Display display, ClientTargetPropertyWithBrightness* outClientTargetProperty) { *outClientTargetProperty = mReader.takeClientTargetProperty(translate(display)); return Error::NONE; } Error AidlComposer::setLayerBrightness(Display display, Layer layer, float brightness) { mWriter.setLayerBrightness(translate(display), translate(layer), brightness); return Error::NONE; } Error AidlComposer::setLayerBlockingRegion(Display display, Layer layer, const std::vector& blocking) { mWriter.setLayerBlockingRegion(translate(display), translate(layer), translate(blocking)); return Error::NONE; } Error AidlComposer::getDisplayDecorationSupport(Display display, std::optional* support) { const auto status = mAidlComposerClient->getDisplayDecorationSupport(translate(display), support); if (!status.isOk()) { ALOGE("getDisplayDecorationSupport failed %s", status.getDescription().c_str()); support->reset(); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::setIdleTimerEnabled(Display displayId, std::chrono::milliseconds timeout) { const auto status = mAidlComposerClient->setIdleTimerEnabled(translate(displayId), translate(timeout.count())); if (!status.isOk()) { ALOGE("setIdleTimerEnabled failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } Error AidlComposer::getPhysicalDisplayOrientation(Display displayId, AidlTransform* outDisplayOrientation) { const auto status = mAidlComposerClient->getDisplayPhysicalOrientation(translate(displayId), outDisplayOrientation); if (!status.isOk()) { ALOGE("getPhysicalDisplayOrientation failed %s", status.getDescription().c_str()); return static_cast(status.getServiceSpecificError()); } return Error::NONE; } } // namespace Hwc2 } // namespace android