diff options
Diffstat (limited to 'services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h')
-rw-r--r-- | services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h | 478 |
1 files changed, 0 insertions, 478 deletions
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h deleted file mode 100644 index bce438fa13..0000000000 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/LayerState.h +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Copyright 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <android-base/strings.h> -#include <compositionengine/LayerFE.h> -#include <compositionengine/LayerFECompositionState.h> -#include <compositionengine/OutputLayer.h> -#include <compositionengine/impl/OutputLayerCompositionState.h> -#include <input/Flags.h> - -#include <string> - -#include "DisplayHardware/Hal.h" -#include "math/HashCombine.h" - -namespace std { -template <typename T> -struct hash<android::sp<T>> { - size_t operator()(const android::sp<T>& p) { return std::hash<void*>()(p.get()); } -}; - -template <typename T> -struct hash<android::wp<T>> { - size_t operator()(const android::wp<T>& p) { - android::sp<T> promoted = p.promote(); - return std::hash<void*>()(promoted ? promoted.get() : nullptr); - } -}; -} // namespace std - -namespace android::compositionengine::impl::planner { - -using LayerId = int32_t; - -// clang-format off -enum class LayerStateField : uint32_t { - None = 0u, - Id = 1u << 0, - Name = 1u << 1, - DisplayFrame = 1u << 2, - SourceCrop = 1u << 3, - BufferTransform = 1u << 4, - BlendMode = 1u << 5, - Alpha = 1u << 6, - LayerMetadata = 1u << 7, - VisibleRegion = 1u << 8, - Dataspace = 1u << 9, - PixelFormat = 1u << 10, - ColorTransform = 1u << 11, - SurfaceDamage = 1u << 12, - CompositionType = 1u << 13, - SidebandStream = 1u << 14, - Buffer = 1u << 15, - SolidColor = 1u << 16, - BackgroundBlurRadius = 1u << 17, - BlurRegions = 1u << 18, -}; -// clang-format on - -std::string to_string(LayerStateField field); - -// An abstract interface allows us to iterate over all of the OutputLayerState fields -// without having to worry about their templated types. -// See `LayerState::getNonUniqueFields` below. -class StateInterface { -public: - virtual ~StateInterface() = default; - - virtual Flags<LayerStateField> update(const compositionengine::OutputLayer* layer) = 0; - - virtual size_t getHash() const = 0; - - virtual LayerStateField getField() const = 0; - - virtual Flags<LayerStateField> getFieldIfDifferent(const StateInterface* other) const = 0; - - virtual bool equals(const StateInterface* other) const = 0; - - virtual std::vector<std::string> toStrings() const = 0; -}; - -template <typename T, LayerStateField FIELD> -class OutputLayerState : public StateInterface { -public: - using ReadFromLayerState = std::function<T(const compositionengine::OutputLayer* layer)>; - using ToStrings = std::function<std::vector<std::string>(const T&)>; - using Equals = std::function<bool(const T&, const T&)>; - using Hashes = std::function<size_t(const T&)>; - - static ToStrings getDefaultToStrings() { - return [](const T& value) { - using std::to_string; - return std::vector<std::string>{to_string(value)}; - }; - } - - static ToStrings getHalToStrings() { - return [](const T& value) { return std::vector<std::string>{toString(value)}; }; - } - - static ToStrings getRegionToStrings() { - return [](const Region& region) { - using namespace std::string_literals; - std::string dump; - region.dump(dump, ""); - std::vector<std::string> split = base::Split(dump, "\n"s); - split.erase(split.begin()); // Strip the header - split.pop_back(); // Strip the last (empty) line - for (std::string& line : split) { - line.erase(0, 4); // Strip leading padding before each rect - } - return split; - }; - } - - static Equals getDefaultEquals() { - return [](const T& lhs, const T& rhs) { return lhs == rhs; }; - } - - static Equals getRegionEquals() { - return [](const Region& lhs, const Region& rhs) { return lhs.hasSameRects(rhs); }; - } - - static Hashes getDefaultHashes() { - return [](const T& value) { return std::hash<T>{}(value); }; - } - - OutputLayerState(ReadFromLayerState reader, - ToStrings toStrings = OutputLayerState::getDefaultToStrings(), - Equals equals = OutputLayerState::getDefaultEquals(), - Hashes hashes = OutputLayerState::getDefaultHashes()) - : mReader(reader), mToStrings(toStrings), mEquals(equals), mHashes(hashes) {} - - ~OutputLayerState() override = default; - - // Returns this member's field flag if it was changed - Flags<LayerStateField> update(const compositionengine::OutputLayer* layer) override { - T newValue = mReader(layer); - return update(newValue); - } - - Flags<LayerStateField> update(const T& newValue) { - if (!mEquals(mValue, newValue)) { - mValue = newValue; - mHash = {}; - return FIELD; - } - return {}; - } - - LayerStateField getField() const override { return FIELD; } - const T& get() const { return mValue; } - - size_t getHash() const override { - if (!mHash) { - mHash = mHashes(mValue); - } - return *mHash; - } - - Flags<LayerStateField> getFieldIfDifferent(const StateInterface* other) const override { - if (other->getField() != FIELD) { - return {}; - } - - // The early return ensures that this downcast is sound - const OutputLayerState* otherState = static_cast<const OutputLayerState*>(other); - return *this != *otherState ? FIELD : Flags<LayerStateField>{}; - } - - bool equals(const StateInterface* other) const override { - if (other->getField() != FIELD) { - return false; - } - - // The early return ensures that this downcast is sound - const OutputLayerState* otherState = static_cast<const OutputLayerState*>(other); - return *this == *otherState; - } - - std::vector<std::string> toStrings() const override { return mToStrings(mValue); } - - bool operator==(const OutputLayerState& other) const { return mEquals(mValue, other.mValue); } - bool operator!=(const OutputLayerState& other) const { return !(*this == other); } - -private: - const ReadFromLayerState mReader; - const ToStrings mToStrings; - const Equals mEquals; - const Hashes mHashes; - T mValue = {}; - mutable std::optional<size_t> mHash = {}; -}; - -class LayerState { -public: - LayerState(compositionengine::OutputLayer* layer); - - // Returns which fields were updated - Flags<LayerStateField> update(compositionengine::OutputLayer*); - - // Computes a hash for this LayerState. - // The hash is only computed from NonUniqueFields, and excludes GraphicBuffers since they are - // not guaranteed to live longer than the LayerState object. - size_t getHash() const; - - // Returns the bit-set of differing fields between this LayerState and another LayerState. - // This bit-set is based on NonUniqueFields only, and excludes GraphicBuffers. - Flags<LayerStateField> getDifferingFields(const LayerState& other) const; - - compositionengine::OutputLayer* getOutputLayer() const { return mOutputLayer; } - int32_t getId() const { return mId.get(); } - const std::string& getName() const { return mName.get(); } - Rect getDisplayFrame() const { return mDisplayFrame.get(); } - const Region& getVisibleRegion() const { return mVisibleRegion.get(); } - bool hasBlurBehind() const { - return mBackgroundBlurRadius.get() > 0 || !mBlurRegions.get().empty(); - } - int32_t getBackgroundBlurRadius() const { return mBackgroundBlurRadius.get(); } - hardware::graphics::composer::hal::Composition getCompositionType() const { - return mCompositionType.get(); - } - - void incrementFramesSinceBufferUpdate() { ++mFramesSinceBufferUpdate; } - void resetFramesSinceBufferUpdate() { mFramesSinceBufferUpdate = 0; } - int64_t getFramesSinceBufferUpdate() const { return mFramesSinceBufferUpdate; } - - ui::Dataspace getDataspace() const { return mOutputDataspace.get(); } - - bool isProtected() const { - return getOutputLayer()->getLayerFE().getCompositionState()->hasProtectedContent; - } - - void dump(std::string& result) const; - std::optional<std::string> compare(const LayerState& other) const; - - // This makes LayerState's private members accessible to the operator - friend bool operator==(const LayerState& lhs, const LayerState& rhs); - friend bool operator!=(const LayerState& lhs, const LayerState& rhs) { return !(lhs == rhs); } - -private: - compositionengine::OutputLayer* mOutputLayer = nullptr; - - OutputLayerState<LayerId, LayerStateField::Id> mId{ - [](const compositionengine::OutputLayer* layer) { - return layer->getLayerFE().getSequence(); - }}; - - OutputLayerState<std::string, LayerStateField::Name> - mName{[](auto layer) { return layer->getLayerFE().getDebugName(); }, - [](const std::string& name) { return std::vector<std::string>{name}; }}; - - // Output-dependent geometry state - - OutputLayerState<Rect, LayerStateField::DisplayFrame> - mDisplayFrame{[](auto layer) { return layer->getState().displayFrame; }, - [](const Rect& rect) { - return std::vector<std::string>{ - base::StringPrintf("[%d, %d, %d, %d]", rect.left, rect.top, - rect.right, rect.bottom)}; - }}; - - OutputLayerState<FloatRect, LayerStateField::SourceCrop> - mSourceCrop{[](auto layer) { return layer->getState().sourceCrop; }, - [](const FloatRect& rect) { - return std::vector<std::string>{ - base::StringPrintf("[%.2f, %.2f, %.2f, %.2f]", rect.left, - rect.top, rect.right, rect.bottom)}; - }}; - - using BufferTransformState = OutputLayerState<hardware::graphics::composer::hal::Transform, - LayerStateField::BufferTransform>; - BufferTransformState mBufferTransform{[](auto layer) { - return layer->getState().bufferTransform; - }, - BufferTransformState::getHalToStrings()}; - - // Output-independent geometry state - - using BlendModeState = OutputLayerState<hardware::graphics::composer::hal::BlendMode, - LayerStateField::BlendMode>; - BlendModeState mBlendMode{[](auto layer) { - return layer->getLayerFE().getCompositionState()->blendMode; - }, - BlendModeState::getHalToStrings()}; - - OutputLayerState<float, LayerStateField::Alpha> mAlpha{ - [](auto layer) { return layer->getLayerFE().getCompositionState()->alpha; }}; - - using LayerMetadataState = - OutputLayerState<GenericLayerMetadataMap, LayerStateField::LayerMetadata>; - LayerMetadataState - mLayerMetadata{[](auto layer) { - return layer->getLayerFE().getCompositionState()->metadata; - }, - [](const GenericLayerMetadataMap& metadata) { - std::vector<std::string> result; - if (metadata.empty()) { - result.push_back("{}"); - return result; - } - result.push_back("{"); - for (const auto& [key, value] : metadata) { - std::string keyValueDump; - keyValueDump.append(" "); - keyValueDump.append(key); - keyValueDump.append("="); - keyValueDump.append(value.dumpAsString()); - result.push_back(keyValueDump); - } - result.push_back("}"); - return result; - }, - LayerMetadataState::getDefaultEquals(), - [](const GenericLayerMetadataMap& metadata) { - size_t hash = 0; - for (const auto& [key, value] : metadata) { - size_t entryHash = 0; - hashCombineSingleHashed(entryHash, - std::hash<std::string>{}(key)); - hashCombineSingleHashed(entryHash, - GenericLayerMetadataEntry::Hasher{}( - value)); - hash ^= entryHash; - } - return hash; - }}; - - // Output-dependent per-frame state - - using VisibleRegionState = OutputLayerState<Region, LayerStateField::VisibleRegion>; - VisibleRegionState mVisibleRegion{[](auto layer) { return layer->getState().visibleRegion; }, - VisibleRegionState::getRegionToStrings(), - VisibleRegionState::getRegionEquals()}; - - using DataspaceState = OutputLayerState<ui::Dataspace, LayerStateField::Dataspace>; - DataspaceState mOutputDataspace{[](auto layer) { return layer->getState().dataspace; }, - DataspaceState::getHalToStrings()}; - - // Output-independent per-frame state - - using PixelFormatState = OutputLayerState<hardware::graphics::composer::hal::PixelFormat, - LayerStateField::PixelFormat>; - PixelFormatState - mPixelFormat{[](auto layer) { - return layer->getLayerFE().getCompositionState()->buffer - ? static_cast<hardware::graphics::composer::hal::PixelFormat>( - layer->getLayerFE() - .getCompositionState() - ->buffer->getPixelFormat()) - : hardware::graphics::composer::hal::PixelFormat::RGBA_8888; - }, - PixelFormatState::getHalToStrings()}; - - OutputLayerState<mat4, LayerStateField::ColorTransform> mColorTransform; - - using CompositionTypeState = OutputLayerState<hardware::graphics::composer::hal::Composition, - LayerStateField::CompositionType>; - CompositionTypeState - mCompositionType{[](auto layer) { - return layer->getState().forceClientComposition - ? hardware::graphics::composer::hal::Composition::CLIENT - : layer->getLayerFE() - .getCompositionState() - ->compositionType; - }, - CompositionTypeState::getHalToStrings()}; - - OutputLayerState<void*, LayerStateField::SidebandStream> - mSidebandStream{[](auto layer) { - return layer->getLayerFE() - .getCompositionState() - ->sidebandStream.get(); - }, - [](void* p) { - return std::vector<std::string>{base::StringPrintf("%p", p)}; - }}; - - OutputLayerState<wp<GraphicBuffer>, LayerStateField::Buffer> - mBuffer{[](auto layer) { return layer->getLayerFE().getCompositionState()->buffer; }, - [](const wp<GraphicBuffer>& buffer) { - sp<GraphicBuffer> promotedBuffer = buffer.promote(); - return std::vector<std::string>{ - base::StringPrintf("%p", - promotedBuffer ? promotedBuffer.get() - : nullptr)}; - }}; - - int64_t mFramesSinceBufferUpdate = 0; - - OutputLayerState<half4, LayerStateField::SolidColor> - mSolidColor{[](auto layer) { return layer->getLayerFE().getCompositionState()->color; }, - [](const half4& vec) { - std::stringstream stream; - stream << vec; - return std::vector<std::string>{stream.str()}; - }}; - - OutputLayerState<int32_t, LayerStateField::BackgroundBlurRadius> mBackgroundBlurRadius{ - [](auto layer) { - return layer->getLayerFE().getCompositionState()->backgroundBlurRadius; - }}; - - using BlurRegionsState = - OutputLayerState<std::vector<BlurRegion>, LayerStateField::BlurRegions>; - BlurRegionsState mBlurRegions{[](auto layer) { - return layer->getLayerFE().getCompositionState()->blurRegions; - }, - [](const std::vector<BlurRegion>& regions) { - std::vector<std::string> result; - for (const auto region : regions) { - std::string str; - base::StringAppendF(&str, - "{radius=%du, cornerRadii=[%f, %f, " - "%f, %f], alpha=%f, rect=[%d, " - "%d, %d, %d]", - region.blurRadius, - region.cornerRadiusTL, - region.cornerRadiusTR, - region.cornerRadiusBL, - region.cornerRadiusBR, region.alpha, - region.left, region.top, region.right, - region.bottom); - result.push_back(str); - } - return result; - }, - BlurRegionsState::getDefaultEquals(), - [](const std::vector<BlurRegion>& regions) { - size_t hash = 0; - for (const auto& region : regions) { - android::hashCombineSingle(hash, region); - } - return hash; - }}; - - static const constexpr size_t kNumNonUniqueFields = 16; - - std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() { - std::array<const StateInterface*, kNumNonUniqueFields> constFields = - const_cast<const LayerState*>(this)->getNonUniqueFields(); - std::array<StateInterface*, kNumNonUniqueFields> fields; - std::transform(constFields.cbegin(), constFields.cend(), fields.begin(), - [](const StateInterface* constField) { - return const_cast<StateInterface*>(constField); - }); - return fields; - } - - std::array<const StateInterface*, kNumNonUniqueFields> getNonUniqueFields() const { - return { - &mDisplayFrame, &mSourceCrop, &mBufferTransform, &mBlendMode, - &mAlpha, &mLayerMetadata, &mVisibleRegion, &mOutputDataspace, - &mPixelFormat, &mColorTransform, &mCompositionType, &mSidebandStream, - &mBuffer, &mSolidColor, &mBackgroundBlurRadius, &mBlurRegions, - }; - } -}; - -using NonBufferHash = size_t; -NonBufferHash getNonBufferHash(const std::vector<const LayerState*>&); - -} // namespace android::compositionengine::impl::planner |