diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-04-11 18:14:33 +0000 |
---|---|---|
committer | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-04-11 18:14:33 +0000 |
commit | d2ef124ffcff45a100ab8ac8273980a8007b2318 (patch) | |
tree | 891a69f84b586d6c435397c0425f4cfc4fd05716 | |
parent | a3110e439d0ba46294d84516177b52afc4afe23f (diff) | |
parent | 96b83c5162735cff7fd3fcea05b0a989c65002d6 (diff) | |
download | goldfish-opengl-emu-34-2-release.tar.gz |
Snap for 11702928 from 96b83c5162735cff7fd3fcea05b0a989c65002d6 to emu-34-2-releaseemu-34-2-release
Change-Id: Idcba6ddd3397cb5056132158007e86375587cccd
-rw-r--r-- | system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp | 4 | ||||
-rw-r--r-- | system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp | 4 | ||||
-rw-r--r-- | system/gralloc/gralloc_old.cpp | 2 | ||||
-rw-r--r-- | system/hwc3/AlternatingImageStorage.cpp | 41 | ||||
-rw-r--r-- | system/hwc3/AlternatingImageStorage.h | 51 | ||||
-rw-r--r-- | system/hwc3/Android.bp | 4 | ||||
-rw-r--r-- | system/hwc3/Composer.h | 4 | ||||
-rw-r--r-- | system/hwc3/ComposerClient.cpp | 494 | ||||
-rw-r--r-- | system/hwc3/ComposerClient.h | 110 | ||||
-rw-r--r-- | system/hwc3/Display.cpp | 24 | ||||
-rw-r--r-- | system/hwc3/Display.h | 1 | ||||
-rw-r--r-- | system/hwc3/GuestFrameComposer.cpp | 67 | ||||
-rw-r--r-- | system/hwc3/GuestFrameComposer.h | 16 | ||||
-rw-r--r-- | system/hwc3/hwc3.xml | 2 |
14 files changed, 468 insertions, 356 deletions
diff --git a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp index 81366dd6..f9a7a3f5 100644 --- a/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp +++ b/system/codecs/c2/decoders/avcdec/C2GoldfishAvcDec.cpp @@ -869,15 +869,15 @@ void C2GoldfishAvcDec::removePts(uint64_t pts) { if (!mOldPts2Index.empty()) { auto iter = mOldPts2Index.find(pts); if (iter != mOldPts2Index.end()) { - mOldPts2Index.erase(iter); index = iter->second; + mOldPts2Index.erase(iter); found = true; } } else { auto iter = mPts2Index.find(pts); if (iter != mPts2Index.end()) { - mPts2Index.erase(iter); index = iter->second; + mPts2Index.erase(iter); found = true; } } diff --git a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp index 14eed1f6..173dd386 100644 --- a/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp +++ b/system/codecs/c2/decoders/hevcdec/C2GoldfishHevcDec.cpp @@ -816,15 +816,15 @@ void C2GoldfishHevcDec::removePts(uint64_t pts) { if (!mOldPts2Index.empty()) { auto iter = mOldPts2Index.find(pts); if (iter != mOldPts2Index.end()) { - mOldPts2Index.erase(iter); index = iter->second; + mOldPts2Index.erase(iter); found = true; } } else { auto iter = mPts2Index.find(pts); if (iter != mPts2Index.end()) { - mPts2Index.erase(iter); index = iter->second; + mPts2Index.erase(iter); found = true; } } diff --git a/system/gralloc/gralloc_old.cpp b/system/gralloc/gralloc_old.cpp index 13228e85..0fe864e4 100644 --- a/system/gralloc/gralloc_old.cpp +++ b/system/gralloc/gralloc_old.cpp @@ -78,7 +78,7 @@ static const bool isHidlGralloc = true; static const bool isHidlGralloc = false; #endif -using android::base::guest::getCurrentThreadId; +using gfxstream::guest::getCurrentThreadId; const uint32_t CB_HANDLE_MAGIC_OLD = CB_HANDLE_MAGIC_BASE | 0x1; const int kBufferFdIndex = 0; diff --git a/system/hwc3/AlternatingImageStorage.cpp b/system/hwc3/AlternatingImageStorage.cpp new file mode 100644 index 00000000..6ca2b0b1 --- /dev/null +++ b/system/hwc3/AlternatingImageStorage.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2023 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 "AlternatingImageStorage.h" + +namespace aidl::android::hardware::graphics::composer3::impl { + +uint8_t* AlternatingImageStorage::getRotatingScratchBuffer(std::size_t neededSize, + std::uint32_t imageIndex) { + std::size_t totalNeededSize = neededSize * kNumScratchBufferPieces; + if (mScratchBuffer.size() < totalNeededSize) { + mScratchBuffer.resize(totalNeededSize); + } + + std::size_t bufferIndex = imageIndex % kNumScratchBufferPieces; + std::size_t bufferOffset = bufferIndex * neededSize; + return &mScratchBuffer[bufferOffset]; +} + +uint8_t* AlternatingImageStorage::getSpecialScratchBuffer(size_t neededSize) { + if (mSpecialScratchBuffer.size() < neededSize) { + mSpecialScratchBuffer.resize(neededSize); + } + + return &mSpecialScratchBuffer[0]; +} + +} // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/AlternatingImageStorage.h b/system/hwc3/AlternatingImageStorage.h new file mode 100644 index 00000000..31c44675 --- /dev/null +++ b/system/hwc3/AlternatingImageStorage.h @@ -0,0 +1,51 @@ +/* + * Copyright 2023 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_HWC_ALTERNATINGIMAGESTORAGE_H +#define ANDROID_HWC_ALTERNATINGIMAGESTORAGE_H + +#include <stdint.h> +#include <vector> + +#include "Common.h" + +namespace aidl::android::hardware::graphics::composer3::impl { + +// Provides storage for images when transforming images with the expectation +// that image N will no longer be used after producing image N + 1. With this, +// the storage just needs to be 2x the needed image size and the returned buffers +// can alternate back and forth. +class AlternatingImageStorage { + public: + AlternatingImageStorage() = default; + + uint8_t* getRotatingScratchBuffer(std::size_t neededSize, std::uint32_t imageIndex); + + uint8_t* getSpecialScratchBuffer(std::size_t neededSize); + + private: + static constexpr const int kNumScratchBufferPieces = 2; + + // The main alternating storage. + std::vector<uint8_t> mScratchBuffer; + + // Extra additional storage for one-off operations (scaling). + std::vector<uint8_t> mSpecialScratchBuffer; +}; + +} // namespace aidl::android::hardware::graphics::composer3::impl + +#endif diff --git a/system/hwc3/Android.bp b/system/hwc3/Android.bp index a58e1257..ccbab191 100644 --- a/system/hwc3/Android.bp +++ b/system/hwc3/Android.bp @@ -30,7 +30,7 @@ cc_binary { shared_libs: [ "android.hardware.graphics.composer@2.1-resources", "android.hardware.graphics.composer@2.2-resources", - "android.hardware.graphics.composer3-V2-ndk", + "android.hardware.graphics.composer3-V3-ndk", "libbase", "libbinder_ndk", "libcutils", @@ -56,6 +56,7 @@ cc_binary { ], srcs: [ + "AlternatingImageStorage.cpp", "ClientFrameComposer.cpp", "Common.cpp", "Composer.cpp", @@ -89,6 +90,7 @@ cc_binary { cflags: [ "-Wall", "-Werror=conversion", + "-Wthread-safety", ], vintf_fragments: ["hwc3.xml"], diff --git a/system/hwc3/Composer.h b/system/hwc3/Composer.h index e46e951a..a6286438 100644 --- a/system/hwc3/Composer.h +++ b/system/hwc3/Composer.h @@ -18,7 +18,7 @@ #define ANDROID_HWC_COMPOSER_H #include <aidl/android/hardware/graphics/composer3/BnComposer.h> -#include <utils/Mutex.h> +#include <android-base/thread_annotations.h> #include <memory> @@ -45,7 +45,7 @@ class Composer : public BnComposer { void onClientDestroyed(); std::mutex mClientMutex; - std::weak_ptr<ComposerClient> mClient GUARDED_BY(mClientMutex); + std::weak_ptr<ComposerClient> mClient; std::condition_variable mClientDestroyedCondition; }; diff --git a/system/hwc3/ComposerClient.cpp b/system/hwc3/ComposerClient.cpp index a7e0247f..0fdcd195 100644 --- a/system/hwc3/ComposerClient.cpp +++ b/system/hwc3/ComposerClient.cpp @@ -28,7 +28,7 @@ namespace aidl::android::hardware::graphics::composer3::impl { namespace { #define GET_DISPLAY_OR_RETURN_ERROR() \ - Display* display = getDisplay(displayId); \ + std::shared_ptr<Display> display = getDisplay(displayId); \ if (display == nullptr) { \ ALOGE("%s failed to get display:%" PRIu64, __FUNCTION__, displayId); \ return ToBinderStatus(HWC3::Error::BadDisplay); \ @@ -102,7 +102,7 @@ ComposerClient::ComposerClient() { DEBUG_LOG("%s", __FUNCTION__); } ComposerClient::~ComposerClient() { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); + std::lock_guard<std::mutex> lock(mDisplaysMutex); destroyDisplaysLocked(); @@ -116,7 +116,7 @@ HWC3::Error ComposerClient::init() { HWC3::Error error = HWC3::Error::None; - std::unique_lock<std::mutex> lock(mStateMutex); + std::lock_guard<std::mutex> lock(mDisplaysMutex); mResources = std::make_unique<ComposerResources>(); if (!mResources) { @@ -165,8 +165,6 @@ ndk::ScopedAStatus ComposerClient::createLayer(int64_t displayId, int32_t buffer int64_t* layerId) { DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); HWC3::Error error = display->createLayer(layerId); @@ -196,8 +194,6 @@ ndk::ScopedAStatus ComposerClient::createVirtualDisplay(int32_t /*width*/, int32 ndk::ScopedAStatus ComposerClient::destroyLayer(int64_t displayId, int64_t layerId) { DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); HWC3::Error error = display->destroyLayer(layerId); @@ -228,25 +224,18 @@ ndk::ScopedAStatus ComposerClient::executeCommands( std::vector<CommandResultPayload>* commandResultPayloads) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - - mCommandResults = std::make_unique<CommandResultWriter>(commandResultPayloads); - + CommandResultWriter commandResults(commandResultPayloads); for (const DisplayCommand& command : commands) { - executeDisplayCommand(command); - mCommandResults->nextCommand(); + executeDisplayCommand(commandResults, command); + commandResults.nextCommand(); } - mCommandResults.reset(); - return ToBinderStatus(HWC3::Error::None); } ndk::ScopedAStatus ComposerClient::getActiveConfig(int64_t displayId, int32_t* config) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getActiveConfig(config)); @@ -256,8 +245,6 @@ ndk::ScopedAStatus ComposerClient::getColorModes(int64_t displayId, std::vector<ColorMode>* colorModes) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getColorModes(colorModes)); @@ -289,8 +276,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayAttribute(int64_t displayId, int32_ DisplayAttribute attribute, int32_t* value) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayAttribute(config, attribute, value)); @@ -300,8 +285,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayCapabilities(int64_t displayId, std::vector<DisplayCapability>* outCaps) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayCapabilities(outCaps)); @@ -311,8 +294,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayConfigs(int64_t displayId, std::vector<int32_t>* outConfigs) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayConfigs(outConfigs)); @@ -322,8 +303,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayConnectionType(int64_t displayId, DisplayConnectionType* outType) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayConnectionType(outType)); @@ -333,8 +312,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData( int64_t displayId, DisplayIdentification* outIdentification) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayIdentificationData(outIdentification)); @@ -343,8 +320,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayIdentificationData( ndk::ScopedAStatus ComposerClient::getDisplayName(int64_t displayId, std::string* outName) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayName(outName)); @@ -354,8 +329,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayVsyncPeriod(int64_t displayId, int32_t* outVsyncPeriod) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayVsyncPeriod(outVsyncPeriod)); @@ -366,8 +339,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayedContentSample(int64_t displayId, DisplayContentSample* outSamples) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayedContentSample(maxFrames, timestamp, outSamples)); @@ -377,8 +348,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayedContentSamplingAttributes( int64_t displayId, DisplayContentSamplingAttributes* outAttributes) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayedContentSamplingAttributes(outAttributes)); @@ -388,8 +357,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayPhysicalOrientation( int64_t displayId, common::Transform* outOrientation) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDisplayPhysicalOrientation(outOrientation)); @@ -399,20 +366,15 @@ ndk::ScopedAStatus ComposerClient::getHdrCapabilities(int64_t displayId, HdrCapabilities* outCapabilities) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getHdrCapabilities(outCapabilities)); } -ndk::ScopedAStatus ComposerClient::getOverlaySupport(OverlayProperties* properties) { +ndk::ScopedAStatus ComposerClient::getOverlaySupport(OverlayProperties* /*properties*/) { DEBUG_LOG("%s", __FUNCTION__); - // no supported combinations - properties->combinations.clear(); - - return ToBinderStatus(HWC3::Error::None); + return ToBinderStatus(HWC3::Error::Unsupported); } ndk::ScopedAStatus ComposerClient::getMaxVirtualDisplayCount(int32_t* outCount) { @@ -428,8 +390,6 @@ ndk::ScopedAStatus ComposerClient::getPerFrameMetadataKeys( int64_t displayId, std::vector<PerFrameMetadataKey>* outKeys) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getPerFrameMetadataKeys(outKeys)); @@ -439,8 +399,6 @@ ndk::ScopedAStatus ComposerClient::getReadbackBufferAttributes( int64_t displayId, ReadbackBufferAttributes* outAttributes) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getReadbackBufferAttributes(outAttributes)); @@ -450,8 +408,6 @@ ndk::ScopedAStatus ComposerClient::getReadbackBufferFence( int64_t displayId, ndk::ScopedFileDescriptor* outAcquireFence) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getReadbackBufferFence(outAcquireFence)); @@ -461,8 +417,6 @@ ndk::ScopedAStatus ComposerClient::getRenderIntents(int64_t displayId, ColorMode std::vector<RenderIntent>* outIntents) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getRenderIntents(mode, outIntents)); @@ -472,8 +426,6 @@ ndk::ScopedAStatus ComposerClient::getSupportedContentTypes(int64_t displayId, std::vector<ContentType>* outTypes) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getSupportedContentTypes(outTypes)); @@ -483,8 +435,6 @@ ndk::ScopedAStatus ComposerClient::getDisplayDecorationSupport( int64_t displayId, std::optional<common::DisplayDecorationSupport>* outSupport) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getDecorationSupport(outSupport)); @@ -494,19 +444,29 @@ ndk::ScopedAStatus ComposerClient::registerCallback( const std::shared_ptr<IComposerCallback>& callback) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - const bool isFirstRegisterCallback = mCallbacks == nullptr; mCallbacks = callback; - for (auto& [_, display] : mDisplays) { - display->registerCallback(callback); + { + std::lock_guard<std::mutex> lock(mDisplaysMutex); + for (auto& [_, display] : mDisplays) { + display->registerCallback(callback); + } } if (isFirstRegisterCallback) { - lock.unlock(); - for (auto& [displayId, _] : mDisplays) { + std::vector<int64_t> displayIds; + { + std::lock_guard<std::mutex> lock(mDisplaysMutex); + for (auto& [displayId, _] : mDisplays) { + displayIds.push_back(displayId); + } + } + + for (auto displayId : displayIds) { + DEBUG_LOG("%s initial registration, hotplug connecting display:%" PRIu64, __FUNCTION__, + displayId); mCallbacks->onHotplug(displayId, /*connected=*/true); } } @@ -517,8 +477,6 @@ ndk::ScopedAStatus ComposerClient::registerCallback( ndk::ScopedAStatus ComposerClient::setActiveConfig(int64_t displayId, int32_t configId) { DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, configId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setActiveConfig(configId)); @@ -529,8 +487,6 @@ ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints( VsyncPeriodChangeTimeline* outTimeline) { DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, configId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus( @@ -540,8 +496,6 @@ ndk::ScopedAStatus ComposerClient::setActiveConfigWithConstraints( ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t displayId, int32_t configId) { DEBUG_LOG("%s display:%" PRIu64 " config:%" PRIu32, __FUNCTION__, displayId, configId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setBootConfig(configId)); @@ -550,8 +504,6 @@ ndk::ScopedAStatus ComposerClient::setBootDisplayConfig(int64_t displayId, int32 ndk::ScopedAStatus ComposerClient::clearBootDisplayConfig(int64_t displayId) { DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->clearBootConfig()); @@ -561,8 +513,6 @@ ndk::ScopedAStatus ComposerClient::getPreferredBootDisplayConfig(int64_t display int32_t* outConfigId) { DEBUG_LOG("%s display:%" PRIu64, __FUNCTION__, displayId); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->getPreferredBootConfig(outConfigId)); @@ -602,8 +552,6 @@ ndk::ScopedAStatus ComposerClient::setHdrConversionStrategy( ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t displayId, bool on) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setAutoLowLatencyMode(on)); @@ -612,8 +560,6 @@ ndk::ScopedAStatus ComposerClient::setAutoLowLatencyMode(int64_t displayId, bool ndk::ScopedAStatus ComposerClient::setClientTargetSlotCount(int64_t displayId, int32_t count) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus( @@ -624,8 +570,6 @@ ndk::ScopedAStatus ComposerClient::setColorMode(int64_t displayId, ColorMode mod RenderIntent intent) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setColorMode(mode, intent)); @@ -634,8 +578,6 @@ ndk::ScopedAStatus ComposerClient::setColorMode(int64_t displayId, ColorMode mod ndk::ScopedAStatus ComposerClient::setContentType(int64_t displayId, ContentType type) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setContentType(type)); @@ -645,8 +587,6 @@ ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled( int64_t displayId, bool enable, FormatColorComponent componentMask, int64_t maxFrames) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus( @@ -656,8 +596,6 @@ ndk::ScopedAStatus ComposerClient::setDisplayedContentSamplingEnabled( ndk::ScopedAStatus ComposerClient::setPowerMode(int64_t displayId, PowerMode mode) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setPowerMode(mode)); @@ -668,8 +606,6 @@ ndk::ScopedAStatus ComposerClient::setReadbackBuffer( const ndk::ScopedFileDescriptor& releaseFence) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); // Owned by mResources. @@ -695,8 +631,6 @@ ndk::ScopedAStatus ComposerClient::setReadbackBuffer( ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t displayId, bool enabled) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setVsyncEnabled(enabled)); @@ -705,8 +639,6 @@ ndk::ScopedAStatus ComposerClient::setVsyncEnabled(int64_t displayId, bool enabl ndk::ScopedAStatus ComposerClient::setIdleTimerEnabled(int64_t displayId, int32_t timeoutMs) { DEBUG_LOG("%s", __FUNCTION__); - std::unique_lock<std::mutex> lock(mStateMutex); - GET_DISPLAY_OR_RETURN_ERROR(); return ToBinderStatus(display->setIdleTimerEnabled(timeoutMs)); @@ -721,6 +653,26 @@ ndk::ScopedAStatus ComposerClient::setRefreshRateChangedCallbackDebugEnabled(int return ToBinderStatus(HWC3::Error::Unsupported); } +ndk::ScopedAStatus ComposerClient::getDisplayConfigurations( + int64_t displayId, int32_t /*maxFrameIntervalNs*/, + std::vector<DisplayConfiguration>* outDisplayConfig) { + DEBUG_LOG("%s", __FUNCTION__); + + GET_DISPLAY_OR_RETURN_ERROR(); + + return ToBinderStatus(display->getDisplayConfigurations(outDisplayConfig)); +} + +ndk::ScopedAStatus ComposerClient::notifyExpectedPresent( + int64_t displayId, const ClockMonotonicTimestamp& /*expectedPresentTime*/, + int32_t /*frameIntervalNs*/) { + DEBUG_LOG("%s", __FUNCTION__); + + GET_DISPLAY_OR_RETURN_ERROR(); + + return ToBinderStatus(HWC3::Error::Unsupported); +} + ndk::SpAIBinder ComposerClient::createBinder() { auto binder = BnComposerClient::createBinder(); AIBinder_setInheritRt(binder.get(), true); @@ -729,126 +681,143 @@ ndk::SpAIBinder ComposerClient::createBinder() { namespace { -#define DISPATCH_LAYER_COMMAND(layerCmd, display, layer, field, funcName) \ - do { \ - if (layerCmd.field) { \ - ComposerClient::executeLayerCommandSetLayer##funcName(display, layer, \ - *layerCmd.field); \ - } \ +#define DISPATCH_LAYER_COMMAND(layerCmd, commandResults, display, layer, field, funcName) \ + do { \ + if (layerCmd.field) { \ + ComposerClient::executeLayerCommandSetLayer##funcName(commandResults, display, layer, \ + *layerCmd.field); \ + } \ } while (0) -#define DISPATCH_DISPLAY_COMMAND(displayCmd, display, field, funcName) \ - do { \ - if (displayCmd.field) { \ - executeDisplayCommand##funcName(display, *displayCmd.field); \ - } \ +#define DISPATCH_DISPLAY_COMMAND(displayCmd, commandResults, display, field, funcName) \ + do { \ + if (displayCmd.field) { \ + executeDisplayCommand##funcName(commandResults, display, *displayCmd.field); \ + } \ } while (0) -#define DISPATCH_DISPLAY_BOOL_COMMAND(displayCmd, display, field, funcName) \ - do { \ - if (displayCmd.field) { \ - executeDisplayCommand##funcName(display); \ - } \ +#define DISPATCH_DISPLAY_BOOL_COMMAND(displayCmd, commandResults, display, field, funcName) \ + do { \ + if (displayCmd.field) { \ + executeDisplayCommand##funcName(commandResults, display); \ + } \ } while (0) -#define DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCmd, display, field, data, funcName) \ - do { \ - if (displayCmd.field) { \ - executeDisplayCommand##funcName(display, displayCmd.data); \ - } \ +#define DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCmd, commandResults, display, field, data, \ + funcName) \ + do { \ + if (displayCmd.field) { \ + executeDisplayCommand##funcName(commandResults, display, displayCmd.data); \ + } \ } while (0) -#define LOG_DISPLAY_COMMAND_ERROR(display, error) \ - do { \ - const std::string errorString = toString(error); \ - ALOGE("%s: display:%" PRId64 " failed with:%s", __FUNCTION__, display->getId(), \ - errorString.c_str()); \ +#define LOG_DISPLAY_COMMAND_ERROR(display, error) \ + do { \ + const std::string errorString = toString(error); \ + ALOGE("%s: display:%" PRId64 " failed with:%s", __FUNCTION__, display.getId(), \ + errorString.c_str()); \ } while (0) #define LOG_LAYER_COMMAND_ERROR(display, layer, error) \ do { \ const std::string errorString = toString(error); \ ALOGE("%s: display:%" PRId64 " layer:%" PRId64 " failed with:%s", __FUNCTION__, \ - display->getId(), layer->getId(), errorString.c_str()); \ + display.getId(), layer->getId(), errorString.c_str()); \ } while (0) } // namespace -void ComposerClient::executeDisplayCommand(const DisplayCommand& displayCommand) { - Display* display = getDisplay(displayCommand.display); +void ComposerClient::executeDisplayCommand(CommandResultWriter& commandResults, + const DisplayCommand& displayCommand) { + std::shared_ptr<Display> display = getDisplay(displayCommand.display); if (display == nullptr) { - mCommandResults->addError(HWC3::Error::BadDisplay); + commandResults.addError(HWC3::Error::BadDisplay); return; } for (const LayerCommand& layerCmd : displayCommand.layers) { - executeLayerCommand(display, layerCmd); - } - - DISPATCH_DISPLAY_COMMAND(displayCommand, display, colorTransformMatrix, SetColorTransform); - DISPATCH_DISPLAY_COMMAND(displayCommand, display, brightness, SetBrightness); - DISPATCH_DISPLAY_COMMAND(displayCommand, display, clientTarget, SetClientTarget); - DISPATCH_DISPLAY_COMMAND(displayCommand, display, virtualDisplayOutputBuffer, SetOutputBuffer); - DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, display, validateDisplay, - expectedPresentTime, ValidateDisplay); - DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, display, acceptDisplayChanges, + executeLayerCommand(commandResults, *display, layerCmd); + } + + DISPATCH_DISPLAY_COMMAND(displayCommand, commandResults, *display, colorTransformMatrix, + SetColorTransform); + DISPATCH_DISPLAY_COMMAND(displayCommand, commandResults, *display, brightness, SetBrightness); + DISPATCH_DISPLAY_COMMAND(displayCommand, commandResults, *display, clientTarget, + SetClientTarget); + DISPATCH_DISPLAY_COMMAND(displayCommand, commandResults, *display, virtualDisplayOutputBuffer, + SetOutputBuffer); + DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, commandResults, *display, + validateDisplay, expectedPresentTime, ValidateDisplay); + DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, commandResults, *display, acceptDisplayChanges, AcceptDisplayChanges); - DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, display, presentDisplay, PresentDisplay); - DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, display, presentOrValidateDisplay, - expectedPresentTime, PresentOrValidateDisplay); + DISPATCH_DISPLAY_BOOL_COMMAND(displayCommand, commandResults, *display, presentDisplay, + PresentDisplay); + DISPATCH_DISPLAY_BOOL_COMMAND_AND_DATA(displayCommand, commandResults, *display, + presentOrValidateDisplay, expectedPresentTime, + PresentOrValidateDisplay); } -void ComposerClient::executeLayerCommand(Display* display, const LayerCommand& layerCommand) { - Layer* layer = display->getLayer(layerCommand.layer); +void ComposerClient::executeLayerCommand(CommandResultWriter& commandResults, Display& display, + const LayerCommand& layerCommand) { + Layer* layer = display.getLayer(layerCommand.layer); if (layer == nullptr) { - mCommandResults->addError(HWC3::Error::BadLayer); + commandResults.addError(HWC3::Error::BadLayer); return; } - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, cursorPosition, CursorPosition); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, buffer, Buffer); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, damage, SurfaceDamage); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, blendMode, BlendMode); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, color, Color); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, composition, Composition); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, dataspace, Dataspace); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, displayFrame, DisplayFrame); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, planeAlpha, PlaneAlpha); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, sidebandStream, SidebandStream); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, sourceCrop, SourceCrop); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, transform, Transform); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, visibleRegion, VisibleRegion); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, z, ZOrder); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, colorTransform, ColorTransform); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, brightness, Brightness); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, perFrameMetadata, PerFrameMetadata); - DISPATCH_LAYER_COMMAND(layerCommand, display, layer, perFrameMetadataBlob, + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, cursorPosition, + CursorPosition); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, buffer, Buffer); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, damage, SurfaceDamage); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, blendMode, BlendMode); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, color, Color); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, composition, Composition); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, dataspace, Dataspace); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, displayFrame, + DisplayFrame); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, planeAlpha, PlaneAlpha); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, sidebandStream, + SidebandStream); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, sourceCrop, SourceCrop); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, transform, Transform); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, visibleRegion, + VisibleRegion); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, z, ZOrder); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, colorTransform, + ColorTransform); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, brightness, Brightness); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, perFrameMetadata, + PerFrameMetadata); + DISPATCH_LAYER_COMMAND(layerCommand, commandResults, display, layer, perFrameMetadataBlob, PerFrameMetadataBlobs); } -void ComposerClient::executeDisplayCommandSetColorTransform(Display* display, +void ComposerClient::executeDisplayCommandSetColorTransform(CommandResultWriter& commandResults, + Display& display, const std::vector<float>& matrix) { DEBUG_LOG("%s", __FUNCTION__); - auto error = display->setColorTransform(matrix); + auto error = display.setColorTransform(matrix); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeDisplayCommandSetBrightness(Display* display, +void ComposerClient::executeDisplayCommandSetBrightness(CommandResultWriter& commandResults, + Display& display, const DisplayBrightness& brightness) { DEBUG_LOG("%s", __FUNCTION__); - auto error = display->setBrightness(brightness.brightness); + auto error = display.setBrightness(brightness.brightness); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeDisplayCommandSetClientTarget(Display* display, +void ComposerClient::executeDisplayCommandSetClientTarget(CommandResultWriter& commandResults, + Display& display, const ClientTarget& clientTarget) { DEBUG_LOG("%s", __FUNCTION__); @@ -856,142 +825,148 @@ void ComposerClient::executeDisplayCommandSetClientTarget(Display* display, buffer_handle_t importedBuffer = nullptr; auto releaser = mResources->createReleaser(/*isBuffer=*/true); - auto error = mResources->getDisplayClientTarget(display->getId(), clientTarget.buffer, + auto error = mResources->getDisplayClientTarget(display.getId(), clientTarget.buffer, &importedBuffer, releaser.get()); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); return; } - error = display->setClientTarget(importedBuffer, clientTarget.buffer.fence, - clientTarget.dataspace, clientTarget.damage); + error = display.setClientTarget(importedBuffer, clientTarget.buffer.fence, + clientTarget.dataspace, clientTarget.damage); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); return; } } -void ComposerClient::executeDisplayCommandSetOutputBuffer(Display* display, const Buffer& buffer) { +void ComposerClient::executeDisplayCommandSetOutputBuffer(CommandResultWriter& commandResults, + Display& display, const Buffer& buffer) { DEBUG_LOG("%s", __FUNCTION__); // Owned by mResources. buffer_handle_t importedBuffer = nullptr; auto releaser = mResources->createReleaser(/*isBuffer=*/true); - auto error = mResources->getDisplayOutputBuffer(display->getId(), buffer, &importedBuffer, + auto error = mResources->getDisplayOutputBuffer(display.getId(), buffer, &importedBuffer, releaser.get()); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); return; } - error = display->setOutputBuffer(importedBuffer, buffer.fence); + error = display.setOutputBuffer(importedBuffer, buffer.fence); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); return; } } void ComposerClient::executeDisplayCommandValidateDisplay( - Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { + CommandResultWriter& commandResults, Display& display, + const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { DEBUG_LOG("%s", __FUNCTION__); - auto error = display->setExpectedPresentTime(expectedPresentTime); + auto error = display.setExpectedPresentTime(expectedPresentTime); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } DisplayChanges changes; - error = display->validate(&changes); + error = display.validate(&changes); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } else { - mCommandResults->addChanges(changes); + commandResults.addChanges(changes); } - mResources->setDisplayMustValidateState(display->getId(), false); + mResources->setDisplayMustValidateState(display.getId(), false); } -void ComposerClient::executeDisplayCommandAcceptDisplayChanges(Display* display) { +void ComposerClient::executeDisplayCommandAcceptDisplayChanges(CommandResultWriter& commandResults, + Display& display) { DEBUG_LOG("%s", __FUNCTION__); - auto error = display->acceptChanges(); + auto error = display.acceptChanges(); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeDisplayCommandPresentOrValidateDisplay( - Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { + CommandResultWriter& commandResults, Display& display, + const std::optional<ClockMonotonicTimestamp> expectedPresentTime) { DEBUG_LOG("%s", __FUNCTION__); // TODO: Support SKIP_VALIDATE. - auto error = display->setExpectedPresentTime(expectedPresentTime); + auto error = display.setExpectedPresentTime(expectedPresentTime); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } DisplayChanges changes; - error = display->validate(&changes); + error = display.validate(&changes); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } else { - const int64_t displayId = display->getId(); - mCommandResults->addChanges(changes); - mCommandResults->addPresentOrValidateResult(displayId, - PresentOrValidate::Result::Validated); + const int64_t displayId = display.getId(); + commandResults.addChanges(changes); + commandResults.addPresentOrValidateResult(displayId, PresentOrValidate::Result::Validated); } - mResources->setDisplayMustValidateState(display->getId(), false); + mResources->setDisplayMustValidateState(display.getId(), false); } -void ComposerClient::executeDisplayCommandPresentDisplay(Display* display) { +void ComposerClient::executeDisplayCommandPresentDisplay(CommandResultWriter& commandResults, + Display& display) { DEBUG_LOG("%s", __FUNCTION__); - if (mResources->mustValidateDisplay(display->getId())) { - ALOGE("%s: display:%" PRIu64 " not validated", __FUNCTION__, display->getId()); - mCommandResults->addError(HWC3::Error::NotValidated); + if (mResources->mustValidateDisplay(display.getId())) { + ALOGE("%s: display:%" PRIu64 " not validated", __FUNCTION__, display.getId()); + commandResults.addError(HWC3::Error::NotValidated); return; } ::android::base::unique_fd displayFence; std::unordered_map<int64_t, ::android::base::unique_fd> layerFences; - auto error = display->present(&displayFence, &layerFences); + auto error = display.present(&displayFence, &layerFences); if (error != HWC3::Error::None) { LOG_DISPLAY_COMMAND_ERROR(display, error); - mCommandResults->addError(error); + commandResults.addError(error); } else { - const int64_t displayId = display->getId(); - mCommandResults->addPresentFence(displayId, std::move(displayFence)); - mCommandResults->addReleaseFences(displayId, std::move(layerFences)); + const int64_t displayId = display.getId(); + commandResults.addPresentFence(displayId, std::move(displayFence)); + commandResults.addReleaseFences(displayId, std::move(layerFences)); } } void ComposerClient::executeLayerCommandSetLayerCursorPosition( - Display* display, Layer* layer, const common::Point& cursorPosition) { + CommandResultWriter& commandResults, Display& display, Layer* layer, + const common::Point& cursorPosition) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setCursorPosition(cursorPosition); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerBuffer(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerBuffer(CommandResultWriter& commandResults, + Display& display, Layer* layer, const Buffer& buffer) { DEBUG_LOG("%s", __FUNCTION__); @@ -999,218 +974,234 @@ void ComposerClient::executeLayerCommandSetLayerBuffer(Display* display, Layer* buffer_handle_t importedBuffer = nullptr; auto releaser = mResources->createReleaser(/*isBuffer=*/true); - auto error = mResources->getLayerBuffer(display->getId(), layer->getId(), buffer, + auto error = mResources->getLayerBuffer(display.getId(), layer->getId(), buffer, &importedBuffer, releaser.get()); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); return; } error = layer->setBuffer(importedBuffer, buffer.fence); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerSurfaceDamage( - Display* display, Layer* layer, const std::vector<std::optional<common::Rect>>& damage) { + CommandResultWriter& commandResults, Display& display, Layer* layer, + const std::vector<std::optional<common::Rect>>& damage) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setSurfaceDamage(damage); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerBlendMode(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerBlendMode(CommandResultWriter& commandResults, + Display& display, Layer* layer, const ParcelableBlendMode& blendMode) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setBlendMode(blendMode.blendMode); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerColor(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerColor(CommandResultWriter& commandResults, + Display& display, Layer* layer, const Color& color) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setColor(color); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerComposition( - Display* display, Layer* layer, const ParcelableComposition& composition) { + CommandResultWriter& commandResults, Display& display, Layer* layer, + const ParcelableComposition& composition) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setCompositionType(composition.composition); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerDataspace(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerDataspace(CommandResultWriter& commandResults, + Display& display, Layer* layer, const ParcelableDataspace& dataspace) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setDataspace(dataspace.dataspace); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerDisplayFrame(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerDisplayFrame(CommandResultWriter& commandResults, + Display& display, Layer* layer, const common::Rect& rect) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setDisplayFrame(rect); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerPlaneAlpha(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerPlaneAlpha(CommandResultWriter& commandResults, + Display& display, Layer* layer, const PlaneAlpha& planeAlpha) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setPlaneAlpha(planeAlpha.alpha); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerSidebandStream( - Display* display, Layer* layer, const aidl::android::hardware::common::NativeHandle& handle) { + CommandResultWriter& commandResults, Display& display, Layer* layer, + const aidl::android::hardware::common::NativeHandle& handle) { DEBUG_LOG("%s", __FUNCTION__); // Owned by mResources. buffer_handle_t importedStream = nullptr; auto releaser = mResources->createReleaser(/*isBuffer=*/false); - auto error = mResources->getLayerSidebandStream(display->getId(), layer->getId(), handle, + auto error = mResources->getLayerSidebandStream(display.getId(), layer->getId(), handle, &importedStream, releaser.get()); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); return; } error = layer->setSidebandStream(importedStream); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerSourceCrop(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerSourceCrop(CommandResultWriter& commandResults, + Display& display, Layer* layer, const common::FRect& sourceCrop) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setSourceCrop(sourceCrop); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerTransform(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerTransform(CommandResultWriter& commandResults, + Display& display, Layer* layer, const ParcelableTransform& transform) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setTransform(transform.transform); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerVisibleRegion( - Display* display, Layer* layer, const std::vector<std::optional<common::Rect>>& visibleRegion) { + CommandResultWriter& commandResults, Display& display, Layer* layer, + const std::vector<std::optional<common::Rect>>& visibleRegion) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setVisibleRegion(visibleRegion); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerZOrder(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerZOrder(CommandResultWriter& commandResults, + Display& display, Layer* layer, const ZOrder& zOrder) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setZOrder(zOrder.z); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerPerFrameMetadata( - Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setPerFrameMetadata(perFrameMetadata); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerColorTransform( - Display* display, Layer* layer, const std::vector<float>& colorTransform) { + CommandResultWriter& commandResults, Display& display, Layer* layer, + const std::vector<float>& colorTransform) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setColorTransform(colorTransform); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -void ComposerClient::executeLayerCommandSetLayerBrightness(Display* display, Layer* layer, +void ComposerClient::executeLayerCommandSetLayerBrightness(CommandResultWriter& commandResults, + Display& display, Layer* layer, const LayerBrightness& brightness) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setBrightness(brightness.brightness); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } void ComposerClient::executeLayerCommandSetLayerPerFrameMetadataBlobs( - Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, const std::vector<std::optional<PerFrameMetadataBlob>>& perFrameMetadataBlob) { DEBUG_LOG("%s", __FUNCTION__); auto error = layer->setPerFrameMetadataBlobs(perFrameMetadataBlob); if (error != HWC3::Error::None) { LOG_LAYER_COMMAND_ERROR(display, layer, error); - mCommandResults->addError(error); + commandResults.addError(error); } } -Display* ComposerClient::getDisplay(int64_t displayId) { +std::shared_ptr<Display> ComposerClient::getDisplay(int64_t displayId) { + std::lock_guard<std::mutex> lock(mDisplaysMutex); + auto it = mDisplays.find(displayId); if (it == mDisplays.end()) { ALOGE("%s: no display:%" PRIu64, __FUNCTION__, displayId); return nullptr; } - return it->second.get(); + return it->second; } HWC3::Error ComposerClient::createDisplaysLocked() { @@ -1249,7 +1240,7 @@ HWC3::Error ComposerClient::createDisplayLocked(int64_t displayId, int32_t activ return HWC3::Error::NoResources; } - auto display = std::make_unique<Display>(mComposer, displayId); + auto display = std::make_shared<Display>(mComposer, displayId); if (display == nullptr) { ALOGE("%s failed to allocate display", __FUNCTION__); return HWC3::Error::NoResources; @@ -1339,21 +1330,20 @@ HWC3::Error ComposerClient::handleHotplug(bool connected, uint32_t id, uint32_t configId, static_cast<int>(width), static_cast<int>(height), static_cast<int>(dpiX), static_cast<int>(dpiY), static_cast<int>(refreshRate))}; { - std::unique_lock<std::mutex> lock(mStateMutex); + std::lock_guard<std::mutex> lock(mDisplaysMutex); createDisplayLocked(displayId, configId, configs); } - ALOGI("Connecting display:%" PRIu32 " w:%" PRIu32 " h:%" PRIu32 " dpiX:%" PRIu32 + ALOGI("Hotplug connecting display:%" PRIu32 " w:%" PRIu32 " h:%" PRIu32 " dpiX:%" PRIu32 " dpiY %" PRIu32 "fps %" PRIu32, id, width, height, dpiX, dpiY, refreshRate); mCallbacks->onHotplug(displayId, /*connected=*/true); } else { - ALOGI("Disconnecting display:%" PRIu64, displayId); + ALOGI("Hotplug disconnecting display:%" PRIu64, displayId); mCallbacks->onHotplug(displayId, /*connected=*/false); - Display* display = getDisplay(displayId); - if (display != nullptr) { - std::unique_lock<std::mutex> lock(mStateMutex); + { + std::lock_guard<std::mutex> lock(mDisplaysMutex); destroyDisplayLocked(displayId); } } @@ -1361,4 +1351,4 @@ HWC3::Error ComposerClient::handleHotplug(bool connected, uint32_t id, uint32_t return HWC3::Error::None; } -} // namespace aidl::android::hardware::graphics::composer3::impl
\ No newline at end of file +} // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/ComposerClient.h b/system/hwc3/ComposerClient.h index 9b76d415..2cf198f6 100644 --- a/system/hwc3/ComposerClient.h +++ b/system/hwc3/ComposerClient.h @@ -18,7 +18,7 @@ #define ANDROID_HWC_COMPOSERCLIENT_H #include <aidl/android/hardware/graphics/composer3/BnComposerClient.h> -#include <utils/Mutex.h> +#include <android-base/thread_annotations.h> #include <memory> @@ -118,6 +118,11 @@ class ComposerClient : public BnComposerClient { ndk::ScopedAStatus setIdleTimerEnabled(int64_t displayId, int32_t timeoutMs) override; ndk::ScopedAStatus setRefreshRateChangedCallbackDebugEnabled(int64_t displayId, bool enabled) override; + ndk::ScopedAStatus getDisplayConfigurations(int64_t displayId, int32_t maxFrameIntervalNs, + std::vector<DisplayConfiguration>*) override; + ndk::ScopedAStatus notifyExpectedPresent(int64_t displayId, + const ClockMonotonicTimestamp& expectedPresentTime, + int32_t maxFrameIntervalNs) override; protected: ndk::SpAIBinder createBinder() override; @@ -125,72 +130,94 @@ class ComposerClient : public BnComposerClient { private: class CommandResultWriter; - void executeDisplayCommand(const DisplayCommand& displayCommand); - void executeLayerCommand(Display* display, const LayerCommand& layerCommand); + void executeDisplayCommand(CommandResultWriter& commandResults, + const DisplayCommand& displayCommand); - void executeDisplayCommandSetColorTransform(Display* display, const std::vector<float>& matrix); - void executeDisplayCommandSetBrightness(Display* display, const DisplayBrightness& brightness); - void executeDisplayCommandSetClientTarget(Display* display, const ClientTarget& command); - void executeDisplayCommandSetOutputBuffer(Display* display, const Buffer& buffer); + void executeLayerCommand(CommandResultWriter& commandResults, Display& display, + const LayerCommand& layerCommand); + + void executeDisplayCommandSetColorTransform(CommandResultWriter& commandResults, + Display& display, const std::vector<float>& matrix); + void executeDisplayCommandSetBrightness(CommandResultWriter& commandResults, Display& display, + const DisplayBrightness& brightness); + void executeDisplayCommandSetClientTarget(CommandResultWriter& commandResults, Display& display, + const ClientTarget& command); + void executeDisplayCommandSetOutputBuffer(CommandResultWriter& commandResults, Display& display, + const Buffer& buffer); void executeDisplayCommandValidateDisplay( - Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime); - void executeDisplayCommandAcceptDisplayChanges(Display* display); + CommandResultWriter& commandResults, Display& display, + const std::optional<ClockMonotonicTimestamp> expectedPresentTime); + void executeDisplayCommandAcceptDisplayChanges(CommandResultWriter& commandResults, + Display& display); void executeDisplayCommandPresentOrValidateDisplay( - Display* display, const std::optional<ClockMonotonicTimestamp> expectedPresentTime); - void executeDisplayCommandPresentDisplay(Display* display); + CommandResultWriter& commandResults, Display& display, + const std::optional<ClockMonotonicTimestamp> expectedPresentTime); + void executeDisplayCommandPresentDisplay(CommandResultWriter& commandResults, Display& display); - void executeLayerCommandSetLayerCursorPosition(Display* display, Layer* layer, + void executeLayerCommandSetLayerCursorPosition(CommandResultWriter& commandResults, + Display& display, Layer* layer, const common::Point& cursorPosition); - void executeLayerCommandSetLayerBuffer(Display* display, Layer* layer, const Buffer& buffer); + void executeLayerCommandSetLayerBuffer(CommandResultWriter& commandResults, Display& display, + Layer* layer, const Buffer& buffer); void executeLayerCommandSetLayerSurfaceDamage( - Display* display, Layer* layer, const std::vector<std::optional<common::Rect>>& damage); - void executeLayerCommandSetLayerBlendMode(Display* display, Layer* layer, - const ParcelableBlendMode& blendMode); - void executeLayerCommandSetLayerColor(Display* display, Layer* layer, const Color& color); - void executeLayerCommandSetLayerComposition(Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, + const std::vector<std::optional<common::Rect>>& damage); + void executeLayerCommandSetLayerBlendMode(CommandResultWriter& commandResults, Display& display, + Layer* layer, const ParcelableBlendMode& blendMode); + void executeLayerCommandSetLayerColor(CommandResultWriter& commandResults, Display& display, + Layer* layer, const Color& color); + void executeLayerCommandSetLayerComposition(CommandResultWriter& commandResults, + Display& display, Layer* layer, const ParcelableComposition& composition); - void executeLayerCommandSetLayerDataspace(Display* display, Layer* layer, - const ParcelableDataspace& dataspace); - void executeLayerCommandSetLayerDisplayFrame(Display* display, Layer* layer, + void executeLayerCommandSetLayerDataspace(CommandResultWriter& commandResults, Display& display, + Layer* layer, const ParcelableDataspace& dataspace); + void executeLayerCommandSetLayerDisplayFrame(CommandResultWriter& commandResults, + Display& display, Layer* layer, const common::Rect& rect); - void executeLayerCommandSetLayerPlaneAlpha(Display* display, Layer* layer, + void executeLayerCommandSetLayerPlaneAlpha(CommandResultWriter& commandResults, + Display& display, Layer* layer, const PlaneAlpha& planeAlpha); void executeLayerCommandSetLayerSidebandStream( - Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, const aidl::android::hardware::common::NativeHandle& sidebandStream); - void executeLayerCommandSetLayerSourceCrop(Display* display, Layer* layer, + void executeLayerCommandSetLayerSourceCrop(CommandResultWriter& commandResults, + Display& display, Layer* layer, const common::FRect& sourceCrop); - void executeLayerCommandSetLayerTransform(Display* display, Layer* layer, - const ParcelableTransform& transform); + void executeLayerCommandSetLayerTransform(CommandResultWriter& commandResults, Display& display, + Layer* layer, const ParcelableTransform& transform); void executeLayerCommandSetLayerVisibleRegion( - Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, const std::vector<std::optional<common::Rect>>& visibleRegion); - void executeLayerCommandSetLayerZOrder(Display* display, Layer* layer, const ZOrder& zOrder); + void executeLayerCommandSetLayerZOrder(CommandResultWriter& commandResults, Display& display, + Layer* layer, const ZOrder& zOrder); void executeLayerCommandSetLayerPerFrameMetadata( - Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, const std::vector<std::optional<PerFrameMetadata>>& perFrameMetadata); - void executeLayerCommandSetLayerColorTransform(Display* display, Layer* layer, + void executeLayerCommandSetLayerColorTransform(CommandResultWriter& commandResults, + Display& display, Layer* layer, const std::vector<float>& colorTransform); - void executeLayerCommandSetLayerBrightness(Display* display, Layer* layer, + void executeLayerCommandSetLayerBrightness(CommandResultWriter& commandResults, + Display& display, Layer* layer, const LayerBrightness& brightness); void executeLayerCommandSetLayerPerFrameMetadataBlobs( - Display* display, Layer* layer, + CommandResultWriter& commandResults, Display& display, Layer* layer, const std::vector<std::optional<PerFrameMetadataBlob>>& perFrameMetadataBlob); // Returns the display with the given id or nullptr if not found. - Display* getDisplay(int64_t displayId); + std::shared_ptr<Display> getDisplay(int64_t displayId); // Finds the Cuttlefish/Goldfish specific configuration and initializes the // displays. - HWC3::Error createDisplaysLocked(); + HWC3::Error createDisplaysLocked() EXCLUSIVE_LOCKS_REQUIRED(mDisplaysMutex); // Creates a display with the given properties. HWC3::Error createDisplayLocked(int64_t displayId, int32_t activeConfigId, - const std::vector<DisplayConfig>& configs); + const std::vector<DisplayConfig>& configs) + EXCLUSIVE_LOCKS_REQUIRED(mDisplaysMutex); - HWC3::Error destroyDisplaysLocked(); + HWC3::Error destroyDisplaysLocked() EXCLUSIVE_LOCKS_REQUIRED(mDisplaysMutex); - HWC3::Error destroyDisplayLocked(int64_t displayId); + HWC3::Error destroyDisplayLocked(int64_t displayId) EXCLUSIVE_LOCKS_REQUIRED(mDisplaysMutex); HWC3::Error handleHotplug(bool connected, // uint32_t id, // @@ -200,9 +227,8 @@ class ComposerClient : public BnComposerClient { uint32_t dpiY, // uint32_t refreshRate); - std::mutex mStateMutex; - - std::map<int64_t, std::unique_ptr<Display>> mDisplays; + std::mutex mDisplaysMutex; + std::map<int64_t, std::shared_ptr<Display>> mDisplays GUARDED_BY(mDisplaysMutex); // The onHotplug(), onVsync(), etc callbacks registered by SurfaceFlinger. std::shared_ptr<IComposerCallback> mCallbacks; @@ -213,10 +239,6 @@ class ComposerClient : public BnComposerClient { // the host using opengl. Owned by Device. FrameComposer* mComposer = nullptr; - // For the duration of a executeCommands(), the helper used to collect - // individual command results. - std::unique_ptr<CommandResultWriter> mCommandResults; - // Manages importing and caching gralloc buffers for displays and layers. std::unique_ptr<ComposerResources> mResources; }; diff --git a/system/hwc3/Display.cpp b/system/hwc3/Display.cpp index 3142e484..c221c252 100644 --- a/system/hwc3/Display.cpp +++ b/system/hwc3/Display.cpp @@ -262,6 +262,30 @@ HWC3::Error Display::getDisplayConfigs(std::vector<int32_t>* outConfigIds) { return HWC3::Error::None; } +HWC3::Error Display::getDisplayConfigurations(std::vector<DisplayConfiguration>* outConfigs) { + DEBUG_LOG("%s: display:%" PRId64, __FUNCTION__, mId); + + std::unique_lock<std::recursive_mutex> lock(mStateMutex); + + outConfigs->clear(); + outConfigs->reserve(mConfigs.size()); + + for (const auto& [configId, displayConfig] : mConfigs) { + DisplayConfiguration displayConfiguration; + displayConfiguration.configId = configId; + displayConfiguration.width = displayConfig.getWidth(); + displayConfiguration.height = displayConfig.getHeight(); + displayConfiguration.dpi = { static_cast<float>(displayConfig.getDpiX()), + static_cast<float>(displayConfig.getDpiY()) }; + displayConfiguration.vsyncPeriod = displayConfig.getVsyncPeriod(); + displayConfiguration.configGroup = displayConfig.getConfigGroup(); + + outConfigs->emplace_back(displayConfiguration); + } + + return HWC3::Error::None; +} + HWC3::Error Display::getDisplayConnectionType(DisplayConnectionType* outType) { if (IsCuttlefishFoldable() || IsAutoDevice()) { // Android Auto OS needs to set all displays to INTERNAL since they're used diff --git a/system/hwc3/Display.h b/system/hwc3/Display.h index 8ed6f919..78cd3dc3 100644 --- a/system/hwc3/Display.h +++ b/system/hwc3/Display.h @@ -83,6 +83,7 @@ class Display { HWC3::Error getColorModes(std::vector<ColorMode>* outColorModes); HWC3::Error getDisplayCapabilities(std::vector<DisplayCapability>* caps); HWC3::Error getDisplayConfigs(std::vector<int32_t>* configs); + HWC3::Error getDisplayConfigurations(std::vector<DisplayConfiguration>* outConfigs); HWC3::Error getDisplayConnectionType(DisplayConnectionType* outType); HWC3::Error getDisplayIdentificationData(DisplayIdentification* outIdentification); HWC3::Error getDisplayName(std::string* outName); diff --git a/system/hwc3/GuestFrameComposer.cpp b/system/hwc3/GuestFrameComposer.cpp index f4333fc1..f4c92678 100644 --- a/system/hwc3/GuestFrameComposer.cpp +++ b/system/hwc3/GuestFrameComposer.cpp @@ -802,11 +802,12 @@ HWC3::Error GuestFrameComposer::presentDisplay( continue; } - HWC3::Error error = composeLayerInto(layer, // - compositionResultBufferData, // - compositionResultBufferWidth, // - compositionResultBufferHeight, // - compositionResultBufferStride, // + HWC3::Error error = composeLayerInto(displayInfo.compositionIntermediateStorage, // + layer, // + compositionResultBufferData, // + compositionResultBufferWidth, // + compositionResultBufferHeight, // + compositionResultBufferStride, // 4); if (error != HWC3::Error::None) { ALOGE("%s: display:%" PRIu32 " failed to compose layer:%" PRIu64, __FUNCTION__, @@ -878,12 +879,14 @@ bool GuestFrameComposer::canComposeLayer(Layer* layer) { return true; } -HWC3::Error GuestFrameComposer::composeLayerInto(Layer* srcLayer, // - std::uint8_t* dstBuffer, // - std::uint32_t dstBufferWidth, // - std::uint32_t dstBufferHeight, // - std::uint32_t dstBufferStrideBytes, // - std::uint32_t dstBufferBytesPerPixel) { +HWC3::Error GuestFrameComposer::composeLayerInto( + AlternatingImageStorage& compositionIntermediateStorage, + Layer* srcLayer, // + std::uint8_t* dstBuffer, // + std::uint32_t dstBufferWidth, // + std::uint32_t dstBufferHeight, // + std::uint32_t dstBufferStrideBytes, // + std::uint32_t dstBufferBytesPerPixel) { ATRACE_CALL(); libyuv::RotationMode rotation = GetRotationFromTransform(srcLayer->getTransform()); @@ -955,10 +958,10 @@ HWC3::Error GuestFrameComposer::composeLayerInto(Layer* srcLayer, // framebuffer) is one of them, so only N-1 temporary buffers are needed. // Vertical flip is not taken into account because it can be done together // with any other operation. - int neededScratchBuffers = (needsFill ? 1 : 0) + (needsConversion ? 1 : 0) + - (needsScaling ? 1 : 0) + (needsRotation ? 1 : 0) + - (needsAttenuation ? 1 : 0) + (needsBlending ? 1 : 0) + - (needsCopy ? 1 : 0) - 1; + int neededIntermediateImages = (needsFill ? 1 : 0) + (needsConversion ? 1 : 0) + + (needsScaling ? 1 : 0) + (needsRotation ? 1 : 0) + + (needsAttenuation ? 1 : 0) + (needsBlending ? 1 : 0) + + (needsCopy ? 1 : 0) - 1; uint32_t mScratchBufferWidth = static_cast<uint32_t>(srcLayerDisplayFrame.right - srcLayerDisplayFrame.left); @@ -968,10 +971,10 @@ HWC3::Error GuestFrameComposer::composeLayerInto(Layer* srcLayer, AlignToPower2(mScratchBufferWidth * dstBufferBytesPerPixel, 4); uint32_t mScratchBufferSizeBytes = mScratchBufferHeight * mScratchBufferStrideBytes; - for (uint32_t i = 0; i < neededScratchBuffers; i++) { - BufferSpec mScratchBufferspec(getRotatingScratchBuffer(mScratchBufferSizeBytes, i), - mScratchBufferWidth, mScratchBufferHeight, - mScratchBufferStrideBytes); + for (uint32_t i = 0; i < neededIntermediateImages; i++) { + BufferSpec mScratchBufferspec( + compositionIntermediateStorage.getRotatingScratchBuffer(mScratchBufferSizeBytes, i), + mScratchBufferWidth, mScratchBufferHeight, mScratchBufferStrideBytes); dstBufferStack.push_back(mScratchBufferspec); } @@ -1004,7 +1007,7 @@ HWC3::Error GuestFrameComposer::composeLayerInto(Layer* srcLayer, uint32_t srcWidth = srcLayerSpec.cropWidth; uint32_t srcHeight = srcLayerSpec.cropHeight; uint32_t dst_stride_bytes = AlignToPower2(srcWidth * dstBufferBytesPerPixel, 4); - uint32_t needed_size = dst_stride_bytes * srcHeight; + uint32_t neededSize = dst_stride_bytes * srcHeight; dstBufferSpec.width = srcWidth; dstBufferSpec.height = srcHeight; // Adjust the stride accordingly @@ -1016,7 +1019,8 @@ HWC3::Error GuestFrameComposer::composeLayerInto(Layer* srcLayer, // In case of a scale, the source frame may be bigger than the default tmp // buffer size - dstBufferSpec.buffer = getSpecialScratchBuffer(needed_size); + dstBufferSpec.buffer = + compositionIntermediateStorage.getSpecialScratchBuffer(neededSize); } int retval = DoConversion(srcLayerSpec, dstBufferSpec, needsVFlip); @@ -1136,25 +1140,4 @@ HWC3::Error GuestFrameComposer::applyColorTransformToRGBA( return HWC3::Error::None; } -uint8_t* GuestFrameComposer::getRotatingScratchBuffer(std::size_t neededSize, std::uint32_t order) { - static constexpr const int kNumScratchBufferPieces = 2; - - std::size_t totalNeededSize = neededSize * kNumScratchBufferPieces; - if (mScratchBuffer.size() < totalNeededSize) { - mScratchBuffer.resize(totalNeededSize); - } - - std::size_t bufferIndex = order % kNumScratchBufferPieces; - std::size_t bufferOffset = bufferIndex * neededSize; - return &mScratchBuffer[bufferOffset]; -} - -uint8_t* GuestFrameComposer::getSpecialScratchBuffer(size_t neededSize) { - if (mSpecialScratchBuffer.size() < neededSize) { - mSpecialScratchBuffer.resize(neededSize); - } - - return &mSpecialScratchBuffer[0]; -} - } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/GuestFrameComposer.h b/system/hwc3/GuestFrameComposer.h index 196df3e2..2d2ca202 100644 --- a/system/hwc3/GuestFrameComposer.h +++ b/system/hwc3/GuestFrameComposer.h @@ -17,6 +17,7 @@ #ifndef ANDROID_HWC_GUESTFRAMECOMPOSER_H #define ANDROID_HWC_GUESTFRAMECOMPOSER_H +#include "AlternatingImageStorage.h" #include "Common.h" #include "Display.h" #include "DrmClient.h" @@ -77,9 +78,9 @@ class GuestFrameComposer : public FrameComposer { bool canComposeLayer(Layer* layer); // Composes the given layer into the given destination buffer. - HWC3::Error composeLayerInto(Layer* layer, std::uint8_t* dstBuffer, - std::uint32_t dstBufferWidth, std::uint32_t dstBufferHeight, - std::uint32_t dstBufferStrideBytes, + HWC3::Error composeLayerInto(AlternatingImageStorage& storage, Layer* layer, + std::uint8_t* dstBuffer, std::uint32_t dstBufferWidth, + std::uint32_t dstBufferHeight, std::uint32_t dstBufferStrideBytes, std::uint32_t dstBufferBytesPerPixel); struct DisplayInfo { @@ -87,6 +88,9 @@ class GuestFrameComposer : public FrameComposer { buffer_handle_t compositionResultBuffer = nullptr; std::shared_ptr<DrmBuffer> compositionResultDrmBuffer; + + // Scratch storage space for intermediate images during composition. + AlternatingImageStorage compositionIntermediateStorage; }; std::unordered_map<int64_t, DisplayInfo> mDisplayInfos; @@ -99,17 +103,11 @@ class GuestFrameComposer : public FrameComposer { // spamming logcat with DRM commit failures. bool mPresentDisabled = false; - uint8_t* getRotatingScratchBuffer(std::size_t neededSize, std::uint32_t order); - uint8_t* getSpecialScratchBuffer(std::size_t neededSize); - HWC3::Error applyColorTransformToRGBA(const std::array<float, 16>& colorTransform, // std::uint8_t* buffer, // std::uint32_t bufferWidth, // std::uint32_t bufferHeight, // std::uint32_t bufferStrideBytes); - - std::vector<uint8_t> mScratchBuffer; - std::vector<uint8_t> mSpecialScratchBuffer; }; } // namespace aidl::android::hardware::graphics::composer3::impl diff --git a/system/hwc3/hwc3.xml b/system/hwc3/hwc3.xml index 861b4b7f..7f0d8b7a 100644 --- a/system/hwc3/hwc3.xml +++ b/system/hwc3/hwc3.xml @@ -1,7 +1,7 @@ <manifest version="1.0" type="device"> <hal format="aidl"> <name>android.hardware.graphics.composer3</name> - <version>2</version> + <version>3</version> <interface> <name>IComposer</name> <instance>default</instance> |